神经网络|(十四)|霍普菲尔德神经网络-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处于对角线上的元素都为0np.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):breakstate = new_statereturn 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返回0new_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处于对角线上的元素都为0np.fill_diagonal(weights, 0)# 除以总模数,进行归一化操作weights /= len(patterns)return weightsdef 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返回0new_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):breakstate = new_statereturn 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方法对霍普菲尔德神经网络算法进行了初步训练和测试。
相关文章:
神经网络|(十四)|霍普菲尔德神经网络-Hebbian训练
【1】引言 前序学习进程中,除了对基本的神经网络知识进行了学习,还掌握了SOM神经网络原理,文章链接包括且不限于: 神经网络|(十一)|神经元和神经网络-CSDN博客 神经网络|(十二)|常见激活函数-CSDN博客 神经网络|(十三)|SOM神经…...
【JAVA架构师成长之路】【Redis】第13集:Redis缓存击穿原理、规避、解决方案
30分钟自学教程:Redis缓存击穿原理与解决方案 目标 理解缓存击穿的定义及核心原因。掌握互斥锁、逻辑过期时间等预防技术。能够通过代码实现高并发场景下的缓存保护。学会熔断降级、热点探测等应急方案。 教程内容 0~2分钟:缓存击穿的定义与典型场景 …...
preloaded-classes裁剪
系统预加载了哪些class类?system/etc/preloaded-classes 修改源代码? frameworks\base\config\preloaded-classes 默认位置,如果改了不生效,可能有其它模块的mk文件指定了preloaded-classes覆盖了framework模块,例如…...
爬虫案例五多进程与多线程爬取斗图网
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、多进程与多线程爬取斗图网总结 前言 提示:这里可以添加本文要记录的大概内容: 爬取斗图网 提示:以下是本篇文章正文内…...
Redis的CPU高达90%时如何处理
Redis的CPU高达90%时如何处理 1. 分析和优化2. 扩展和分片3. 缓存策略调整4. 资源提升5. 负载均衡6. 进程调整7. 代码层面改进8. 其他 当Redis的CPU使用率高达90%时,说明Redis服务器可能处于过载状态,这可能会导致响应时间变长甚至服务中断。要处理这种…...
计算机视觉之dlib人脸关键点绘制及微笑测试
dlib人脸关键点绘制及微笑测试 目录 dlib人脸关键点绘制及微笑测试1 dlib人脸关键点1.1 dlib1.2 人脸关键点检测1.3 检测模型1.4 凸包1.5 笑容检测1.6 函数 2 人脸检测代码2.1 关键点绘制2.2 关键点连线2.3 微笑检测 1 dlib人脸关键点 1.1 dlib dlib 是一个强大的机器学习库&a…...
FPGA时序约束的几种方法
一,时钟约束 时钟约束是最基本的一个约束,因为FPGA工具是不知道你要跑多高的频率的,你必要要告诉工具你要跑的时钟频率。时钟约束也就是经常看到的Fmax,因为Fmax是针对“最差劲路径”,也就是说,如果该“最差劲路径”得到好成绩,那些不是最差劲的路径的成绩当然比…...
【0013】Python数据类型-列表类型详解
如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢! 本文内容体系结构如下: Python列表,作为编程中的基础数据结构,扮演着至关重要的角色。它不仅能够存储一系…...
10.RabbitMQ集群
十、集群与高可用 RabbitMQ 的集群分两种模式,一种是默认集群模式,一种是镜像集群模式; 在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器) 被归为两类:一类是磁盘节点,一类是内存节点; 磁盘节点会把集群的所有信息(比如交换机、绑…...
Web网页开发——水果忍者
1.介绍 复刻经典小游戏——水果忍者 2.预览 3.代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…...
信息安全访问控制、抗攻击技术、安全体系和评估(高软42)
系列文章目录 信息安全访问控制、抗攻击技术、安全体系和评估 文章目录 系列文章目录前言一、信息安全技术1.访问控制2.抗攻击技术 二、欺骗技术1.ARP欺骗2.DNS欺骗3.IP欺骗 三、抗攻击技术1.端口扫描2.强化TCP/IP堆栈 四、保证体系和评估1.保证体系2.安全风险管理 五、真题在…...
【算法】009、单双链表反转
【算法】009、单双链表反转 文章目录 一、单链表反转1.1 实现思路1.2 多语言解法 二、双链表反转2.1 实现思路2.2 多语言解法 一、单链表反转 1.1 实现思路 维护 pre 变量。 从前向后遍历 head,首先记录 next head.next,其次反转指针使 head.next pr…...
物联网设备接入系统后如何查看硬件实时数据?
要在软件中实时查看硬件设备的信息,通常需要结合前后端技术来实现。以下是设计思路和实现步骤: 1. 系统架构设计 实时查看硬件设备信息的系统通常采用以下架构: 数据采集层: 硬件设备通过传感器采集数据,发送到InfluxDB。数据存…...
【Linux系统编程】初识系统编程
目录 一、什么是系统编程1. 系统编程的定义2. 系统编程的特点3. 系统编程的应用领域4. 系统编程的核心概念5. 系统编程的工具和技术 二、操作系统四大基本功能1. 进程管理(Process Management)2. 内存管理(Memory Management)3. 文…...
解决stylelint对deep报错
报错如图 在.stylelintrc.json的rules中配置 "selector-pseudo-class-no-unknown": [true,{"ignorePseudoClasses": ["deep"]} ]...
React基础之useInperativehandlle
通过ref调用子组件内部的focus方法来实现聚焦 与forwardRef类似,但是forwardRef是通过暴露整个Ref来实现,而useInperativehandle是通过对外暴露一个方法来实现的 import { forwardRef, useImperativeHandle, useRef, useState } from "react";…...
使用joblib 多线程/多进程
文章目录 1. Joblib 并行计算的两种模式多进程(Multiprocessing,适用于 CPU 密集型任务)多线程(Multithreading,适用于 I/O 密集型任务)2. Joblib 的基本用法3. Joblib 多进程示例(适用于 CPU 密集型任务)示例:计算平方4. Joblib 多线程示例(适用于 I/O 密集型任务)…...
⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II
⭐算法OJ⭐N-皇后问题【回溯剪枝】(C实现)N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…...
【数据结构初阶】---堆的实现、堆排序以及文件中的TopK问题
1.树的概念及结构 1.1树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点&…...
ubuntu20系统下conda虚拟环境下安装文件存储位置
在 Conda 虚拟环境中执行 pip install 安装软件后,安装的文件会存储在该虚拟环境专属的 site-packages 目录中。具体路径取决于你激活的 Conda 环境路径。以下是定位步骤: 1. 确认 Conda 虚拟环境的安装路径 查看所有环境: conda info --env…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...
比较数据迁移后MySQL数据库和ClickHouse数据仓库中的表
设计一个MySQL数据库和Clickhouse数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
使用python进行图像处理—图像变换(6)
图像变换是指改变图像的几何形状或空间位置的操作。常见的几何变换包括平移、旋转、缩放、剪切(shear)以及更复杂的仿射变换和透视变换。这些变换在图像配准、图像校正、创建特效等场景中非常有用。 6.1仿射变换(Affine Transformation) 仿射变换是一种…...
实现p2p的webrtc-srs版本
1. 基本知识 1.1 webrtc 一、WebRTC的本质:实时通信的“网络协议栈”类比 将WebRTC类比为Linux网络协议栈极具洞察力,二者在架构设计和功能定位上高度相似: 分层协议栈架构 Linux网络协议栈:从底层物理层到应用层(如…...
【Redis】Redis 的持久化策略
目录 一、RDB 定期备份 1.2 触发方式 1.2.1 手动触发 1.2.2.1 自动触发 RDB 持久化机制的场景 1.2.2.2 检查是否触发 1.2.2.3 线上运维配置 1.3 检索工具 1.4 RDB 备份实现原理 1.5 禁用 RDB 快照 1.6 RDB 优缺点分析 二、AOF 实时备份 2.1 配置文件解析 2.2 开启…...
