Hopfield神经网络模型是一种循环神经网络,从输出到输入有反馈连接。
Hopfield网络有离散型和连续型两种。
反馈神经网络由于其输出端有反馈到其输入端;所以,Hopfield网络在输入的激励下,会产生不断的状态变化。
当有输入之后,可以求取出Hopfield的输出,这个输出反馈到输入从而产生新的输出,这个反馈过程一直进行下去。
如果Hopfield网络是一个能收敛的稳定网络,则这个反馈与迭代的计算过程所产生的变化越来越小,一旦到达了稳定平衡状态;那么Hopfield网络就会输出一个稳定的恒值。
对于一个Hopfield网络来说,关键是在于确定它在稳定条件下的权系数。
加深对Hopfield模型的理解,能够使用Hopfield模型解决实际问题
根据Hopfield神经网络的相关知识,设计一个具有联想记忆功能的离散型Hopfiled神经网络。
要求该网络可以正确识别0-9这10个数字,当数字被一定的噪声干扰后,仍具有较好的识别效果。
(1) 设计6*5数字点阵。有数字部分用1表示,空白部分用0表示,将数字0-9的矩阵设计好存储到列表中。
(2) 创建网络。
(3) 产生带噪声的数字点阵。带噪声的数字点阵,即点阵的某些位置的值发生了变化。
模拟产生带噪声的数字矩阵方法有很多种,如固定噪声产生法和随机噪声产生法。
(4) 数字识别测试。将带噪声的数字点阵输入到创建好Hopfiled网络,
网络的输出是与该数字点阵最为接近的目标向量,从而实现联想记忆功能。
for row in image_matrix.tolist():
print('| ' + ' '.join(' *'[val] for val in row))
向图像中添加噪声时,使用的是random方法,将整张图片中百分之二十的点替换为随机的0或1,
其代码为:
for x in range(0,30) :
if random.randint(0, 10) > 8:
Data[0,x] = random.randint(0, 1)
设置数字样例
zero = np.matrix([
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0
])
one = np.matrix([
0, 1, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0
])
two = np.matrix([
1, 1, 1, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 1, 0,
0, 1, 1, 0, 0,
1, 0, 0, 0, 0,
1, 1, 1, 1, 1,
])
three = np.matrix([
1, 1, 1, 1, 1,
0, 0, 0, 0, 1,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
0, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
four = np.matrix([
0, 0, 1, 1, 0,
0, 1, 0, 1, 0,
1, 0, 0, 1, 0,
1, 1, 1, 1, 1,
0, 0, 0, 1, 0,
0, 0, 0, 1, 0,
])
five = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 0,
1, 1, 1, 0, 0,
0, 0, 1, 1, 1,
0, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
six = np.matrix([
0, 0, 1, 1, 0,
0, 1, 0, 0, 0,
1, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0,
])
seven = np.matrix([
1, 1, 1, 1, 1,
0, 0, 0, 0, 1,
0, 0, 0, 1, 0,
0, 0, 1, 0, 0,
0, 1, 0, 0, 0,
1, 0, 0, 0, 0,
])
eight = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
nine = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
0, 0, 0, 1, 0,
1, 1, 1, 0, 0,
])
调用模型
将数字样例存入data中,放进模型进行训练,才能够进行后续的联想记忆功能。
data = np.concatenate([zero, one, two,three,four], axis=0)
dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync')
dhnet.train(data)
完整代码如下:
# -*- coding: utf-8 -*-
"""
Created on Thu May 16 15:37:25 2019
@author: Dell
"""
import numpy as np
from neupy import algorithms
import random
#绘图
def draw_bin_image(image_matrix):
for row in image_matrix.tolist():
print('| ' + ' '.join(' *'[val] for val in row))
#加噪函数,在记忆样本的基础上增加30%的噪声:
def addnoise(Data):
for x in range(0,30) :
if random.randint(0, 10) > 8:
Data[0,x] = random.randint(0, 1)
return Data
zero = np.matrix([
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0
])
one = np.matrix([
0, 1, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0,
0, 0, 1, 0, 0
])
two = np.matrix([
1, 1, 1, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 1, 0,
0, 1, 1, 0, 0,
1, 0, 0, 0, 0,
1, 1, 1, 1, 1,
])
three = np.matrix([
1, 1, 1, 1, 1,
0, 0, 0, 0, 1,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
0, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
four = np.matrix([
0, 0, 1, 1, 0,
0, 1, 0, 1, 0,
1, 0, 0, 1, 0,
1, 1, 1, 1, 1,
0, 0, 0, 1, 0,
0, 0, 0, 1, 0,
])
five = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 0,
1, 1, 1, 0, 0,
0, 0, 1, 1, 1,
0, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
six = np.matrix([
0, 0, 1, 1, 0,
0, 1, 0, 0, 0,
1, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0,
])
seven = np.matrix([
1, 1, 1, 1, 1,
0, 0, 0, 0, 1,
0, 0, 0, 1, 0,
0, 0, 1, 0, 0,
0, 1, 0, 0, 0,
1, 0, 0, 0, 0,
])
eight = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
])
nine = np.matrix([
1, 1, 1, 1, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 1, 1, 1, 1,
0, 0, 0, 1, 0,
1, 1, 1, 0, 0,
])
draw_bin_image(zero.reshape((6, 5)))
print("\n")
draw_bin_image(one.reshape((6, 5)))
print("\n")
draw_bin_image(two.reshape((6, 5)))
print("\n")
draw_bin_image(three.reshape((6, 5)))
print("\n")
draw_bin_image(four.reshape((6, 5)))
print("\n")
draw_bin_image(five.reshape((6, 5)))
print("\n")
draw_bin_image(six.reshape((6, 5)))
print("\n")
draw_bin_image(seven.reshape((6, 5)))
print("\n")
draw_bin_image(eight.reshape((6, 5)))
print("\n")
draw_bin_image(nine.reshape((6, 5)))
print("\n")
data = np.concatenate([zero, one, two,three,four], axis=0)
dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync')
dhnet.train(data)
'''
half_zero = np.matrix([
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
])'''
ran_zero = addnoise(zero)
print("对数字0进行随机添加噪声")
draw_bin_image(ran_zero.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_zero)
print("对数字0进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_one = addnoise(one)
print("对数字1进行随机添加噪声")
draw_bin_image(ran_one.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_one)
print("对数字1进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_two = addnoise(two)
print("对数字2进行随机添加噪声")
draw_bin_image(ran_two.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_two)
print("对数字2进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_three = addnoise(three)
print("对数字3进行随机添加噪声")
draw_bin_image(ran_three.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_three)
print("对数字3进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_four = addnoise(four)
print("对数字4进行随机添加噪声")
draw_bin_image(ran_four.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_four)
print("对数字4进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
data = np.concatenate([five, six, seven, eight, nine], axis=0)
dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync')
dhnet.train(data)
'''
from neupy import utils
utils.reproducible()
dhnet.n_times = 400
'''
ran_five = addnoise(five)
print("对数字5进行随机添加噪声")
draw_bin_image(ran_five.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_five)
print("对数字5进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_six = addnoise(six)
print("对数字6进行随机添加噪声")
draw_bin_image(ran_six.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_six)
print("对数字6进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_seven = addnoise(seven)
print("对数字7进行随机添加噪声")
draw_bin_image(ran_seven.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_seven)
print("对数字7进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_eight = addnoise(eight)
print("对数字8进行随机添加噪声")
draw_bin_image(ran_eight.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_eight)
print("对数字8进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
ran_nine = addnoise(nine)
print("对数字9进行随机添加噪声")
draw_bin_image(ran_nine.reshape((6, 5)))
print("\n")
result = dhnet.predict(ran_nine)
print("对数字9进行联想记忆得到结果")
draw_bin_image(result.reshape((6, 5)))
print("\n")
'''
half_two = np.matrix([
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 1, 1, 0, 0,
1, 0, 0, 0, 0,
1, 1, 1, 1, 1,
])
draw_bin_image(half_two.reshape((6, 5)))
print("\n")
result = dhnet.predict(half_zero)
draw_bin_image(result.reshape((6, 5)))
print("\n")
result = dhnet.predict(half_two)
draw_bin_image(result.reshape((6, 5)))
print("\n")
'''
'''
half_two = np.matrix([
1, 1, 1, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 1, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
])
result = dhnet.predict(half_two)
draw_bin_image(result.reshape((6, 5)))
print("\n")
from neupy import utils
utils.reproducible()
dhnet.mode = 'async'
dhnet.n_times = 400
result = dhnet.predict(half_two)
draw_bin_image(result.reshape((6, 5)))
print("\n")
result = dhnet.predict(half_two)
draw_bin_image(result.reshape((6, 5)))
print("\n")
from neupy import plots
import matplotlib.pyplot as plt
plt.figure(figsize=(14, 12))
plt.title("Hinton diagram")
plots.hinton(dhnet.weight)
plt.show()
'''
另一种实现方法:
# -*- coding: utf-8 -*-
"""
Created on Thu May 16 15:09:00 2019
@author: Dell
"""
import numpy as np
import random
from neupy import utils
from neupy import algorithms
from neupy import plots
import matplotlib.pyplot as plt
#根据Hebb学习规则计算神经元之间的连接权值
def calcWeight(savedsample):
N = len(savedsample[0])
P = len(savedsample)
print(N)
print(P)
mat = [0]*N
returnMat = []
for i in range(N):
m = mat[:]
returnMat.append(m)
for i in range(N):
for j in range(N):
if i==j:
continue
sum = 0
for u in range(P):
sum += savedsample[u][i] * savedsample[u][j]
returnMat[i][j] = sum/float(N)
return returnMat
#根据神经元的输入计算神经元的输出(静态突触)
#假设计算第t次循环后神经元的输出时,输入的参数inMat表示第t-1次循环后神经元的输出。即用上一次循环的输出做本次循环的输入。
def calcXi(inMat , weighMat):
returnMat = inMat
choose = []
for i in range(len(inMat)//5):
#随机改变N/5个神经元的值,该参数可调,也可同时改变所有神经元的值
choose.append(random.randint(0,len(inMat)-1))
for i in choose:
sum = 0
for j in range(len(inMat)):
sum += weighMat[i][j] * inMat[j]
if sum>=0:
returnMat[i] = 1
else: returnMat[i] = -1
return returnMat
#记忆样本,10个6x5的矩阵(来源于网络,分别表示0-9)
sample = [[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,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]]
#加噪函数,在记忆样本的基础上增加30%的噪声:
def addnoise(mytest_data,n):
for x in range(n):
for y in range(n):
if random.randint(0, 10) > 7:
mytest_data[x * n + y] = -mytest_data[x * n + y]
return mytest_data
#标准输出函数
def regularout(data,N):
for j in range(N):
ch = ""
for i in range(N):
ch += " " if data[j*N+i] == -1 else "X"
print(ch)
#测试代码及结果
weightMat = calcWeight(sample)
regularout(sample[0],5)
print("\n")
test = addnoise(sample[0],5)
regularout(test,5)
print("\n")
for i in range(2000):
test = calcXi(test,weightMat)
regularout(test,5)