神经网络——Python实现Hopfield神经网络算法(理论+例子+程序)

一、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]  维基百科

  *   写的比较谁便代码有问题还请谅解!

猜你喜欢

转载自blog.csdn.net/Linyun2tt/article/details/129900495
今日推荐