类脑科学实验(一)——Hopfield模型的实现

版权声明:南木的博客 https://blog.csdn.net/Godsolve/article/details/90521240

实验背景

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网络,
        网络的输出是与该数字点阵最为接近的目标向量,从而实现联想记忆功能。

实验步骤

  1. 设置绘图函数
    for row in image_matrix.tolist():
        print('| ' + ' '.join(' *'[val] for val in row))
  1. 设置随机添加噪声函数
向图像中添加噪声时,使用的是random方法,将整张图片中百分之二十的点替换为随机的0或1,
其代码为:
for x in range(0,30) :
        if random.randint(0, 10) > 8:
            Data[0,x] = random.randint(0, 1)

  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,
    ])

  2. 调用模型

将数字样例存入data中,放进模型进行训练,才能够进行后续的联想记忆功能。

data = np.concatenate([zero, one, two,three,four], axis=0)
dhnet = algorithms.DiscreteHopfieldNetwork(mode='sync')
dhnet.train(data)
  1. 测试
    对每个数字样例进行随机添加噪声,然后使用模型进行联想回忆。
    得到运行结果为:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

微信公众号

同时也欢迎各位关注我的微信公众号 南木的下午茶

在这里插入图片描述


实验代码

完整代码如下:

# -*- 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)

猜你喜欢

转载自blog.csdn.net/Godsolve/article/details/90521240