神经网络|(十四)|霍普菲尔德神经网络-Hebbian训练

【1】引言

前序学习进程中,除了对基本的神经网络知识进行了学习,还掌握了SOM神经网络原理,文章链接包括且不限于:

神经网络|(十一)|神经元和神经网络-CSDN博客

神经网络|(十二)|常见激活函数-CSDN博客

神经网络|(十三)|SOM神经网络-CSDN博客

在此基础上,本篇文章学习一个新的神经网络:霍普菲尔德神经网络。

【2】霍普菲尔德神经网络原理

霍普菲尔德神经网络和SOM神经网络一样不走寻常路,SOM神经网络着力于找出和输入最近的点,霍普菲尔德神经网络更关注两两元素之间成对的程度

到这里可以直接进入代码学习,通过代码的设计来读懂霍普菲尔德神经网络的原理。

理解霍普菲尔德神经网络需要至少在神经网络算法和神经网络模型两个层面上完成理解。需要注意的是:神经网络算法是神经网络模型的训练手段,模型是大框架,算法是执行方法。

霍普菲尔德神经网络算法具体训练时有两种方法供选择,一种是Hebbian方法,另一种是Storkey方法。

【3】代码理解

【3.1】Hebbian方法训练霍普菲尔德神经网络

【3.1.1】准备工作

首先是完成准备工作,引入必要模块:

import numpy as np #引入numpy模块
import matplotlib.pyplot as plt #引入matplotlib模块
【3.1.2】主函数

直接阅读主函数是我们链接整改程序的关键,主函数通过把算法实施过程拆解为调用不同的子函数,直观表达了程序运行框架。

# 示例:创建一些简单的模式
patterns = [
    np.array([1, 1, 1, -1, -1, -1]),
    np.array([-1, -1, -1, 1, 1, 1])
]

# 初始化权重
n_neurons = len(patterns[0])
weights = initialize_weights(n_neurons)

# 训练网络
weights = train(weights, patterns)

# 测试回忆功能
initial_state = np.array([1, 1, 1, -1, -1, -1])
recalled_pattern = recall(weights, initial_state)

主函数直接调用了initialize_weights()、train()和recall()三个子函数,它们分别执行权重初始化、模型训练和测试回忆功能,下一步即可对这些子函数进行学习。

【3.1.3】子函数
【3.1.3.1】initialize_weights()函数
# 定义初始化函数
def initialize_weights(n_neurons):
    """
    初始化霍普菲尔德网络的权重矩阵
    :param n_neurons: 神经元的数量
    :return: 初始的权重矩阵
    """
    # 返回一个(n_neurons行, n_neurons列)纯0矩阵
    return np.zeros((n_neurons, n_neurons))

initialize_weights()函数生成的是 (n_neurons行, n_neurons列)纯0矩阵,作为权重weights的初始值。

【3.1.3.2】train()函数
# 训练模型传入的参数有weights和patterns
def train(weights, patterns):
    """
    使用 Hebbian 学习规则训练网络
    :param weights: 权重矩阵
    :param patterns: 训练模式的列表
    :return: 训练后的权重矩阵
    """
    for pattern in patterns:
        # 将pattern转化为一个列向量
        pattern = pattern.reshape(-1, 1)
        # weights是在自身的基础上叠加pattern自身的平方
        weights += np.dot(pattern, pattern.T)
    # 确保对角线元素为 0
    # 通过内置函数,让weights处于对角线上的元素都为0
    np.fill_diagonal(weights, 0)
    # 除以总模数,进行归一化操作
    weights /= len(patterns)
    return weights

train()函数调用weights和patterns两个参数,先将patterns转置为纯列向量,然后自身和自身作矩阵点乘运算,点乘运算结果是一个 (n_neurons行, n_neurons列)矩阵,所以可以和weights矩阵按位置做加法。

由于霍普菲尔德神经网络认为元素两两之间有关系,但自己和自己不能用权重来衡量。

weights矩阵的对角线就代表了元素自己和自己的连接权重,所以需要调用一个np.fill_diagonal()函数让新获得的weights矩阵对角线上的元素为0。

然后把weights做了归一化处理。

【3.1.3.3】recall()函数
def recall(weights, initial_state, max_iterations=100):
    """
    从初始状态回忆模式
    :param weights: 权重矩阵
    :param initial_state: 初始状态
    :param max_iterations: 最大迭代次数
    :return: 回忆出的模式
    """
    # state是对state的复制
    state = initial_state.copy()
    for _ in range(max_iterations):
        # 新的state通过update函数更新
        new_state = update(weights, state)
        if np.array_equal(new_state, state):
            break
        state = new_state
    return state

recall()函数要求调用update()函数生成新状态,用新状态来覆盖旧状态。

【3.1.3.4】update()函数
def update(weights, state):
    """
    更新网络状态
    :param weights: 权重矩阵
    :param state: 当前网络状态
    :return: 更新后的网络状态
    """
    # state转化为列向量
    state = state.reshape(-1, 1)
    # 先用weights和state矩阵相乘,然后用np.sign()函数返回1,-1和0
    # np.sign()函数,参数为正返回1,参数为负返回-1,参数为0返回0
    new_state = np.sign(np.dot(weights, state))
    return new_state.flatten()

代码运行获得的图像为:

图1 hebbian训练效果

此时的完整代码为:

import numpy as np #引入numpy模块
import matplotlib.pyplot as plt #引入matplotlib模块

# 定义初始化函数
def initialize_weights(n_neurons):
    """
    初始化霍普菲尔德网络的权重矩阵
    :param n_neurons: 神经元的数量
    :return: 初始的权重矩阵
    """
    # 返回一个(n_neurons行, n_neurons列)纯0矩阵
    return np.zeros((n_neurons, n_neurons))

# 训练模型传入的参数有weights和patterns
def train(weights, patterns):
    """
    使用 Hebbian 学习规则训练网络
    :param weights: 权重矩阵
    :param patterns: 训练模式的列表
    :return: 训练后的权重矩阵
    """
    for pattern in patterns:
        # 将pattern转化为一个列向量
        pattern = pattern.reshape(-1, 1)
        # weights是在自身的基础上叠加pattern自身的平方
        weights += np.dot(pattern, pattern.T)
    # 确保对角线元素为 0
    # 通过内置函数,让weights处于对角线上的元素都为0
    np.fill_diagonal(weights, 0)
    # 除以总模数,进行归一化操作
    weights /= len(patterns)
    return weights


def update(weights, state):
    """
    更新网络状态
    :param weights: 权重矩阵
    :param state: 当前网络状态
    :return: 更新后的网络状态
    """
    # state转化为列向量
    state = state.reshape(-1, 1)
    # 先用weights和state矩阵相乘,然后用np.sign()函数返回1,-1和0
    # np.sign()函数,参数为正返回1,参数为负返回-1,参数为0返回0
    new_state = np.sign(np.dot(weights, state))
    return new_state.flatten()


def recall(weights, initial_state, max_iterations=100):
    """
    从初始状态回忆模式
    :param weights: 权重矩阵
    :param initial_state: 初始状态
    :param max_iterations: 最大迭代次数
    :return: 回忆出的模式
    """
    # state是对state的复制
    state = initial_state.copy()
    for _ in range(max_iterations):
        # 新的state通过update函数更新
        new_state = update(weights, state)
        if np.array_equal(new_state, state):
            break
        state = new_state
    return state


# 示例:创建一些简单的模式
patterns = [
    np.array([1, 1, 1, -1, -1, -1]),
    np.array([-1, -1, -1, 1, 1, 1])
]

# 初始化权重
# 获得patterns第一个元素,也就是np.array([1, 1, 1, -1, -1, -1])中数字的数量
n_neurons = len(patterns[0])
weights = initialize_weights(n_neurons)

# 训练网络
weights = train(weights, patterns)

# 测试回忆功能
initial_state = np.array([1, 1, 1, -1, -1, -1])
recalled_pattern = recall(weights, initial_state)

# 可视化结果
plt.figure(figsize=(12, 4))

plt.subplot(1, 3, 1)
plt.imshow(initial_state.reshape(1, -1), cmap='gray')
plt.title('Initial State')

plt.subplot(1, 3, 2)
plt.imshow(recalled_pattern.reshape(1, -1), cmap='BuGn')
plt.title('Recalled Pattern')

plt.subplot(1, 3, 3)
plt.imshow(patterns[0].reshape(1, -1), cmap='Blues')
plt.title('Original Pattern')

plt.show()

update()函数根据weights和state矩阵点乘的结果,调用内置函数np.sign()函数进行判断,当矩阵点乘的结果为正返回1,为负返回-1,为0返回0。

因为weights是一个(n_neurons行, n_neurons列)矩阵,state是一个(n_neurons行, 1列)矩阵,所以计算获得的new_state是一个(n_neurons行, 1列)矩阵,update()函数返回的是(1行, n_neurons列)矩阵。

【3.1.4】综合分析

经过对主函数和子函数的阅读理解,可以发现,Hebbian方法的霍普菲尔德神经网路算法遵循原则是:

如果元素组成为:X=[X1,X2,...,Xn],就可以按照这个大小生成一个nXn的权重矩阵weights;

让所有的元素两两相乘,也获得nXn的dot(X,XT)(XT是X的转置),再让dot(X,XT)和weights同一位置的元素相加,这样就获得新的权重。新的权重实际上叠加了元素相乘的积,所以权重本身含有元素的大小。

实际上到这一步,就已经完成了训练,下一步是测试功能,所以会有recall()函数来进行检验。

recall函数会要求先更新权重,这是因为训练过程中已经计算出新权重,测试数据和原始数据已经不一样,所以要依据权重数据和测试数据的关系,对状态数据进行更新,更新后的状态数据会覆盖旧有的状态数据。

recall函数在新的状态下,成功摸索出了原有状态。

【4】细节说明

对于weights矩阵的训练过程,有一个归一化的操作。

weights /= len(patterns)

【5】总结

探索了霍普菲尔德神经网络的基本知识,基于python语言,调用hebbian方法对霍普菲尔德神经网络算法进行了初步训练和测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/983794.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hive八股

Hive八股 说一下GC模型遇到过gc调优吗yarn有哪些了解讲讲hqI转化为MR源码hbase读写流程hive数据倾斜page cache和buffer的区别和相同近来你关注了大数据生态哪些领域的发展,比如新的feature,新的领域等 Hive1Hive1hive简介2hive架构3hive与Hadoop的关系4…

Docker 部署 Graylog 日志管理系统

Docker 部署 Graylog 日志管理系统 前言一、准备工作二、Docker Compose 配置三、启动 Graylog 服务四、访问 Graylog Web 界面总结 前言 Graylog 是一个开源的日志管理平台,专为实时日志收集、分析和可视化设计。它支持强大的搜索功能,并且与 Elastics…

im即时聊天客服系统SaaS还是私有化部署:成本、安全与定制化的权衡策略

随着即时通讯技术的不断发展,IM即时聊天客服系统已经成为企业与客户沟通、解决问题、提升用户体验的重要工具。在选择IM即时聊天客服系统时,企业面临一个重要决策:选择SaaS(软件即服务)解决方案,还是进行私…

MySQL(单表)知识点

文章目录 1.数据库的概念2.下载并配置MySQL2.1初始化MySQL的数据2.2注册MYSQL服务2.3启动MYSQL服务2.4修改账户默认密码2.5登录MYSQL2.6卸载MYSQL 3.MYSQL数据模型3.1连接数据库 4.SQL简介4.1SQL的通用语法4.2SQL语句的分类4.3DDL语句4.3.1数据库4.3.2表(创建,查询,修改,删除)4…

同为科技智能PDU在数据中心场景的应用与解决方案

数据中心当前处于一个快速发展和技术变革的特殊时期,全新的人工智能应用正在重塑整个世界,为社会带来便捷的同时,也为数据中心的发展带来了新的机遇和挑战。智能算例的爆发式增长,对数据中心提出了大算力、高性能的新需求&#xf…

基于Asp.net的零食购物商城网站

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

Redis|Springboot集成Redis

文章目录 总体概述本地Java连接Redis常见问题集成Jedis集成lettuce集成RedisTemplate——推荐使用连接单机连接集群 总体概述 jedis-lettuce-RedisTemplate三者的联系 jedis第一代lettuce承上启下redistemplate着重使用 本地Java连接Redis常见问题 bind配置请注释掉保护模式…

【编译器】VSCODE编译C语言

【编译器】VSCODE编译C语言 文章目录 [TOC](文章目录) 前言一、下载配置二、代码1.main.c2.lanuch3.task 三、编译运行——方法一:编译器运行1.编译:终端-运行生成任务(ctrlshiftB)2.运行:运行-启动调试(F5…

信息安全访问控制、抗攻击技术、安全体系和评估(高软42)

系列文章目录 信息安全访问控制、抗攻击技术、安全体系和评估 文章目录 系列文章目录前言一、信息安全技术1.访问控制2.抗攻击技术 二、欺骗技术1.ARP欺骗2.DNS欺骗3.IP欺骗 三、抗攻击技术1.端口扫描2.强化TCP/IP堆栈 四、保证体系和评估1.保证体系2.安全风险管理 五、真题在…

1 、六气概念-六气内涵

复泰中医体系里,木火土金水,属于传统中医理论的5分法。 有六气:厥阴风木、少阴君火、少阳相火、太阴湿土、阳明燥金、太阳寒水,属于6分法。 五行的体系用在补虚的体系里。 六气的体系用于泻实的体系里。 一、六气概念 天有六气&a…

svn删除所有隐藏.svn文件,文件夹脱离svn控制

新建一个文件,取名remove-svn-folders.reg,输入如下内容: Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] "Delete SVN Folders" [HKEY_LOCAL_MACHINE\SOFTWARE\Class…

【Python 数据结构 10.二叉树】

目录 一、二叉树的基本概念 1.二叉树的定义 2.二叉树的特点 3.特殊的二叉树 Ⅰ、斜树 Ⅱ、满二叉树 Ⅲ、完全二叉树 Ⅳ、完全二叉树和满二叉树的区别 4.二叉树的性质 5.二叉树的顺序存储 Ⅰ、完全二叉树 Ⅱ、非完全二叉树 Ⅲ、稀疏二叉树 6.二叉树的链式存储 7.二叉树的遍历概念…

Windsuf 连接失败问题:[unavailable] unavailable: dial tcp...

问题描述 3月6日,在使用Windsuf 时,遇到以下网络连接错误: [unavailable] unavailable: dial tcp 35.223.238.178:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of…

Hadoop八股

Hadoop八股 HadoopMapReduce考点MR on Yarn 分布式工作原理shuffle:MapTask 和 ReduceTask的处理流程MR中的MapTask 和 ReduceTask 的数量决定MR和Spark两者Shuffle的区别简单讲一下map- reduce 原理**MapReduce 的核心概念****MapReduce 的工作流程****MapReduce 的…

Android15请求动态申请存储权限完整示例

效果: 1.修改AndroidManifest.xml增加如下内容: <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-perm

10.RabbitMQ集群

十、集群与高可用 RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式&#xff1b; 在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点&#xff1b; 磁盘节点会把集群的所有信息(比如交换机、绑…

ajax之生成一个ajax的demo示例

目录 一. node.js和express ​二. 使用express创建后端服务 三. 创建前端 一. node.js和express ajax是前端在不刷新的情况下访问后端的技术&#xff0c;所以首先需要配置一个后端服务&#xff0c;可以使用node.js和express。 首先生成一个空项目&#xff0c;新建main目录…

unity学习64,第3个小游戏:一个2D跑酷游戏

目录 学习参考 素材资源导入 1 创建项目 1.1 创建1个2D项目 1.2 导入素材 2 背景图bg 2.0 bg素材 2.1 创建背景 2.2 修改素材&#xff0c;且修改摄像机等 2.2.1 修改导入的原始prefab素材 2.2.2 对应调整摄像机 2.2.3 弄好背景 2.3 背景相关脚本实现 2.3.1 错误…

PyTorch系列教程:编写高效模型训练流程

当使用PyTorch开发机器学习模型时&#xff0c;建立一个有效的训练循环是至关重要的。这个过程包括组织和执行对数据、参数和计算资源的操作序列。让我们深入了解关键组件&#xff0c;并演示如何构建一个精细的训练循环流程&#xff0c;有效地处理数据处理&#xff0c;向前和向后…

PX4中的DroneCAN的实现库Libuavcan及基础功能示例

简介 Libuavcan是一个用C编写的可移植的跨平台库&#xff0c;对C标准库的依赖小。它可以由几乎任何符合标准的C编译器编译&#xff0c;并且可以在几乎任何体系结构/OS上使用。 在 DroneCAN 中&#xff0c;Libuavcan 有一个 DSDL 编译器&#xff0c;将 DSDL 文件转换为 hpp 头…