一、Hopfield神经网
霍普菲尔德神经网络(Hopfield neural network)是一种循环神经网络,由约翰·霍普菲尔德在1982年发明。Hopfield网络是一种结合存储系统和二元系统的神经网络。它保证了向局部极小的收敛,但收敛到错误的局部极小值(local minimum),而非全局极小(global minimum)的情况也可能发生。霍普菲尔德网络也提供了模拟人类记忆的模型。[1]
使用下述公式更新霍普菲尔德中节点的值:
公式中:
wji是节点j到节点i的权重。
si 节点i的值(状态s)。
θi节点i的阈值,常为0。
霍普菲尔德的更新有两种方式:
异步: 每个更新一个节点。此节点可以是随机选中的,也可是按照预设顺序选中的。
同步: 同时更新所有节点的状态。这种更新方式要求系统中具有中央时钟以便维持同步。这种方式被认为是不太现实的,因为在生物或物理系统中常常没有中央时钟(用于保持同步状态,即各个节点常常是自行其是的。)
Hopfield 网络的基本特点:
1. 只有单层
2. 神经元节点之间是全连接的
3. 只有输入,没有输出
二、Python实现Hopfield神经网络算法
1、 对于两个记忆模式(1, 1, 1, 1)和(-1, -1, -1, -1)(这是一个记忆模式向量非正交的例子),设计网络权值?
运行结果如下图:
import numpy as np
import numpy.matlib
import random
X=np.array([[1,1,1,1,1,1,1,1,1,-1,1,1],[1,1,1,1,-1,-1,-1,-1,-1,1,1,1]])#前四个和后四个为伪吸引子,为了满足P<0.25n的关系,整体两组模式正交
def makematrix(m, n, fill=0.0):
a = []
for i in range(m):
a.append([fill]*n)
return np.array(a)
#X=makematrix(4,2)
#X=[[1,1,1,1],[-1,-1,-1,-1]]
class Hopfield:
def __init__(self, num_in):
self.num_in=num_in
self.wight=makematrix(num_in, num_in)
def determine_wight(self,inputs):
for x in inputs:
self.wight+=np.dot(x.reshape(-1,1),x.reshape(1,-1))
return self.wight-self.wight[2][2]*numpy.matlib.identity(self.num_in)
h=Hopfield(12)
print("网络权值:\n",h.determine_wight(X))
2、现将(1, 1, 1, 1)、(-1, -1, -1, -1) 分别作为网络的输入, 判断其是否为网络的稳定状态?如将(1, 1, -1, 1)、 ……分别作为网络的输入, 计算其最终收敛的状态?
运行结果如下图:
import numpy as np
import numpy.matlib
import random
X=np.array([[1,1,1,1,1,1,1,1,1,-1,1,1],[1,1,1,1,-1,-1,-1,-1,-1,1,1,1]])#前四个和后四个为伪吸引子,为了满足P<0.25n的关系,整体两组模式正交
def makematrix(m, n, fill=0.0):
a = []
for i in range(m):
a.append([fill]*n)
return np.array(a)
def sgn(v):
if v>0:
return 1
else:
return -1
#X=makematrix(4,2)
#X=[[1,1,1,1],[-1,-1,-1,-1]]
class Hopfield:
def __init__(self, num_in,num_p): #输入维数、模式样本数
self.num_in=num_in
self.num_p=num_p
self.wight=makematrix(num_in, num_in)
self.t=numpy.matlib.rand(self.num_in,1)#误差
def determine_wight(self,inputs):
for x in inputs:
self.wight+=np.dot(x.reshape(-1,1),x.reshape(1,-1))
self.wight=self.wight-self.wight[2][2]*numpy.matlib.identity(self.num_in)
return self.wight
def fun(self,inputs):
net=np.dot(self.wight,inputs.T)-self.t
return np.sign(net.T)
def train(self,inputs,item=100):
temp=inputs
for i in range(item):
temp=self.fun(temp)
#print(temp)
return temp
def test(self,t):
return self.fun(t)
t=np.array([[1,1,1,1,1,1,1,1,1,-1,1,1],[1,1,1,1,-1,-1,-1,-1,1,-1,1,1]])
t1=np.array([[1,1,1,1,
1,1,-1,1,
1,-1,1,1],
[1,1,1,1,
-1,1,1,1,
1,-1,1,1],
[1,1,1,1,
1,-1,-1,1,
1,-1,1,1]])#伪吸引子的部分不是随机生成的[1,1,-1,1],[1,-1,-1,1][-1,1,1,1][1,1,1,-1]...
h=Hopfield(12,2)
print("网络权值:\n",h.determine_wight(X))
print("训练\n",h.train(X)[:,4:8])
a1=h.train(t)
print("现将(1, 1, 1, 1)、(-1, -1, -1, -1) \n分别作为网络的输入的输出:\n",a1[:,4:8])
a2=h.train(t1)
print("测试2:\n",a2[:,4:8])
来源:小凌のBlog—Good Times|一个不咋地的博客
[1] 维基百科
* 写的比较谁便代码有问题还请谅解!