一、摘要 
本文使用二维伊辛模型进行蒙特卡洛模拟,观察了不同温度下系统平均磁矩随时间的演化关系,并且观察到了温度变化时产生的二级相变现象,证明使用如此简单的模型也可以模拟部分物理学现象。
之后以伊辛模型为基础,简要实现了一种神经网络,即 Hopefield Neural Network(HNN),可以根据给定的训练集来生成关系矩阵,并可以用来还原加入噪声的信号。
二、原理 
1、二维伊辛模型 
伊辛模型是一个以物理学家恩斯特·伊辛为名的数学模型,用于描述物质的铁磁性。该模型中包含了可以用来描述单个原子磁矩的参数 
我们定义总能量
其中 
当 
当
这样随着循环次数的增加,系统总会趋向于一个能量最低的地方,至于是局部最低还是全局最低则取决于温度和外磁场,可以使用平均场理论进行粗略的计算。
二维伊辛模型有一个相变点,临界温度 
为模拟方便,这里我们取 
2、HNN 
大脑中的神经网络可以看作是无数神经元节点相互连接,相互影响所形成的。因此我们可以利用与之类似的伊辛模型来进行模拟,只是这里的相互作用参数不再是一个定值,而是变为一个 
对于给定的输入,要使系统能量最低,相互作用参数为
一旦生成了该矩阵,我们就可以对新的输入进行计算,从而使用与 1 中类似的方法得到系统能量最低的状态,也就是经过 HNN 处理后的输出信号。
由于该模型比较简陋,因此在训练时对于相近的输入区分度不是很好,而且会有存储上限(
三、模拟 
1、二维伊辛模型 
下面的代码默认采用 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 import  numpy as  npimport  matplotlib.pyplot as  pltclass  ising (object ):    def  __init__ (self, lenth = 20 ,temperature = 1 , total_time = 1000  ):         self.l = lenth         self.T = temperature         self.t = total_time         self.lattice = np.random.choice((1 ,-1 ), (self.l, self.l))           self.magnet = [np.sum (self.lattice) / (self.l ** 2 )]     def  energy (self, i, j ):                  neighbors = self.lattice[i][(j+1 ) % (self.l)] + self.lattice[i][(j-1 ) % (self.l)] + self.lattice[(i+1 ) % self.l][j] + self.lattice[(i-1 ) % self.l][j]         return  2  * self.lattice[i][j] * neighbors     def  run (self ):         for  t in  range (1 , self.t):             for  i in  range (self.l):                 for  j in  range (self.l):                     energy = self.energy(i, j)                     if  energy <= 0 :                         self.lattice[i][j] *= -1                      elif  np.random.random() < np.exp(-energy / self.T):                         self.lattice[i][j] *= -1              mag = np.sum (self.lattice) / (self.l ** 2 )             self.magnet.append(mag)     def  show (self ):         plt.title('Magnetization versus Time  T = %s' % self.T)         plt.xlabel('Time' )         plt.ylabel('Magnetization' )         plt.ylim((-1.2 , 1.2 ))         plt.plot(range (self.t), self.magnet) if  __name__ == '__main__' :    k = 221      plt.figure(figsize = (12 , 12 ), dpi = 80 )     for  i in  (1 , 2 , 2.27 , 4 ):         a = ising(temperature = i)         a.run()         plt.subplot(k)         a.show()         k += 1      plt.show() 
可以看到,当 
当 
而当 
这种有磁性、无磁性两相之间的转变,是一种连续相变,即二级相变。
下面我们绘制系统的平均磁矩随温度变化的图像,可以更直观的反应这种二级相变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 mag = [] for  i in  np.arange(0.1 , 5 , 0.1 ):    a = ising(temperature = i, total_time = 1000 , lenth = 10 )     a.run()     mag.append(np.mean(np.abs (a.magnet))) plt.figure(figsize = (10 , 10 ), dpi = 80 ) plt.plot(np.arange(0.1 , 5 , 0.1 ), mag, 'o' , markersize = 3 ) plt.grid(True ) plt.title('Magnetization versus Temperature' ) plt.xlabel('Temperature' ) plt.ylabel('Magnetization' ) plt.ylim((0 , 1 )) plt.show() 
可以很明显的发现在 
2、HNN 
这部分的模拟中使用了MNIST 手写数字数据为基础,其格式为 
我从数据集中提取了0-9十个数字并转化为 npy 文件,为了满足输入的要求,将其进行了二值化处理。由于模型限制,只采用了三个数字进行输入得到关系矩阵,简单测试了生成的神经网络对于信号的还原功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import  numpy as  npimport  matplotlib.pyplot as  pltdef  train (train_data ):    J = np.zeros((784 , 784 ))     for  s in  train_data:         J += np.outer(s, s)     return  J / 3  def  recall (J, test_in, steps = 5  ):    sgn = np.vectorize(lambda  x: -1  if  x<0  else  +1 )     for  i in  range (steps):         test_out = sgn(np.dot(test_in, J))     return  test_out def  destroy (J, possible ):    for  i in  range (784 ):         for  j in  range (784 ):             if  np.random.rand() < possible:                 J[i][j] = 0      return  J def  test (J, test_data, steps = 5  ):    plt.figure(figsize = (8 ,12 ), dpi = 80 )     k = 321      for  n in  test_data:         test_noise = n + np.random.binomial(2 , 0.4 , 784 )          new = recall(J, test_noise, steps)          plt.subplot(k)         plt.title('Image with Noise' )         plt.imshow(test_noise.reshape(28 , 28 ), cmap = 'gray' )         k += 1          plt.subplot(k)         plt.title('Image after HNN' )         plt.imshow(new.reshape(28 , 28 ), cmap = 'gray' )         k += 1      plt.show() if  __name__ == '__main__' :    train_data = np.load('./asset/nor_train.npy' )[[0 , 2 , 7 ]]      J = train(train_data)     plt.figure(figsize = (8 ,8 ), dpi = 80 )     plt.title('Image of J' )     plt.imshow(J.reshape(784 , 784 ), cmap = 'gray' )     plt.show()     test(J, train_data) 
下面验证一下 HNN 的抗干扰能力,首先随机将 
1 2 3 4 5 6 7 J = train(train_data) J = destroy(J, 0.8 ) plt.figure(figsize = (8 ,8 ), dpi = 80 ) plt.title('Image of J with 80% 0' ) plt.imshow(J.reshape(784 , 784 ), cmap = 'gray' ) plt.show() test(J, train_data, 30 ) 
可以看到即使关系矩阵绝大部分信息消失,剩余部分仍然可以较好的还原输入的信号,说明 HNN 抗干扰能力还是很不错的。
下面分别测试 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 J = train(train_data) J = destroy(J, 0.90 ) plt.figure(figsize = (8 ,8 ), dpi = 80 ) plt.title('Image of J with 90% 0' ) plt.imshow(J.reshape(784 , 784 ), cmap = 'gray' ) plt.show() test(J, train_data, 20 ) J = train(train_data) J = destroy(J, 0.95 ) plt.figure(figsize = (8 ,8 ), dpi = 80 ) plt.title('Image of J with 95% 0' ) plt.imshow(J.reshape(784 , 784 ), cmap = 'gray' ) plt.show() test(J, train_data, 20 ) 
可以看出其保留性能的极限基本在 
四、总结 
本文使用蒙特卡洛方法对伊辛模型进行模拟,得到了无外磁场作用时系统二级相变的直观图像,表明伊辛模型虽然简单,但是物理内涵和应用范围都十分广泛。
之后以伊辛模型为理论基础的 HNN 也验证了这一点。但是我们可以看到这种简单的神经网络模型应用范围其实十分有限,更多的是采用其他更加复杂的神经网络模型。但就是这么一个简单的神经网络,也展现出了其抗干扰能力强、训练简单的优势,可以在此基础上引入改进增强性能,如玻尔兹曼机等。
五、致谢