使用Python构建Hopfield网络的教程

热的东西显然会变凉。房间会会人沮丧地变得凌乱。几乎同样,消息会失真。逆转这些情况的短期策略分别是重新加热、 做卫生和使用 Hopfield 网络。本文向您介绍了三者中的最后一个,它是一个只需要特定的参数就可以消除噪声的算法。net.py 是一个特别简单的 Python 实现,将向您展示它的基本部分如何结合到一起,以及为何 Hopfield 网络有时可以自失真的图案中 重新得到原图案。尽管这个实现有局限性,不过仍然可以让您获得关于 Hopfield 网络的很多有益且有启发作用的经验。
您寻求的是什么?

我假定您是因为遇到了一些计算上的问题而来阅读本文。有人向您建议,一些神经网络算法可能会提供解决方案。具体说, 建议是说您可以使用一个 Hopfield 网络。我进一步假设您需要有一个大致的想法,以使得您可以决定那个建议是否切实 可行而且确保深入的研究。下面这个 Hopfield 网络的非常缩略的应用可能会引导您着手解决问题。

首先,您的问题有一组基本的用 -1 和 +1 编码的图案。如果需要,它们可以用 0 和 +1 编码。这些图案可以是邮票的规格化的 二进制图案(参阅 参考资料)。下一个要素是偏离这一基础的一组图案。您寻求的是创建代码,以 使得可以输入不正常的图案而输出应得的一个基本图案。因而您寻求的将是一个算法,可以输入一个对特定邮票的编码描述,然后 输出应得的一个基本邮票图案。您搜索不确定会成功。有可以接受的对您的计划产生负面影响的失败率。对您来说,会有一个不 会显著地影响您的项目的邮票误识别的比率。

如果这使您想起了您的问题,下面可能会是您的解决方案设计的开始。在结束之前,您最好应该能回答出基本的问题。 这个 Hopfield 是什么?它如何工作?它的局限性是什么?它可以为我做什么?我希望用更多的时间来研究它吗?

图案及其失真

让我们首先来看将会失真而随后被重新获得的五个任意图案。它们可以可视化地表示为 10 乘 10 的黑白方块矩阵。图 1 展示了第一个图案,p1。
图 1. p1 的可视化表示

点击 net.py 中 p2到 p5 的任意一个,可以显示其他的图案。为了编码,这五个图案被初始描述为 Python 列表。 这样,举例来说,第一个图案的描述见清单 1。
清单 1. 图案 p1

    p1 = [ [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] ]

黑色和白色的方块分别对应于 -1 和 +1。这个列表随后被转化为一个数组。(请参阅 参考资料 ,获得 我使用的 Python 库的参考。)对应于这类图案中的每一个元素,-1 或者 +1,在节点数组中都有一个节点对象。

一个节点对象有三个主要属性:

  1. 一个节点对象有一个值,它是图案中的一个元素。
  2. 一个节点还有一个地址,也就是在数组中它的地址。
  3. 每个节点还有一个颜色,以使得它可以显示出来。

如前所述,Hopfield 的一个功能是消除噪声。为实现这一功能,需要有一种方法来给图案引入噪声。点击 Add Noise 恰好 可以完成此任务。向 p1 添加噪声生成了图 2。
图 2. 失真的 p1

为了给一个图案引入噪声,Hopfield 要访问节点数组中的每一个地址。然后它会在 [0,1) 中取一个随机数,也就是 0 到 1 之间 包括 0 但不包括 1。如果数字小于某个固定的标准,网络就会改变节点的值和颜色,否则就会保持不变。默认情况下,这个标准设置 为 0.20,这样任意给定的节点就有百分之二十的可能会改变其值和颜色。您可以用调节滑块来改变这个概率。调为 0% 时,不会有噪声, 调为 100% 时,节点数组会简单地反转。取这区间的值,会出现所有其他通常的可能。每个值都会给一个图案引入特定程度的噪声。由于 Hopfield 网络是一个消除噪声的算法,它可以输入一个如图 2 所示的失真的图案,然后输出图 1 中的原始图案。

尽管有时会因不合适的解释而变得晦涩,相关的算法实现起来还是相当简单的。接下来,我将向您完整地介绍算法的一个实现, 然后我将简短解释为什么这些算法可以消除噪声。

权重

如 David Mertz 和我在以前的一篇 developerWorks 文章 An introduction to neural nets 中所述, 人类的大脑由大约 1 千亿个神经元构成,平均每个神经元要连接到几千个其他神经元。神经元既接收也发送不同的能量。 神经元的一个重要特性是,它们接收到能量后不会马上反应。而是,它们积累所接收到的能量,只有当积累的能量达到一定临界 极限时,它们才会向其他神经元发送自己的能量。

当大脑在学习时,可以认为它是在调整这些连接的数目和强度。毫无疑问,这是一个极其简化的生物学事实。 在这个例子中,对于实现控制神经网络而言,简化可以是实用的,尤其是当它们被作为模型来使用时。从生物学到算法的转换是通过 将连接转化为权重来实现的。(感知器以一种不同的而且可能更为直观的方式来使用权重。阅读这里之前,您可能会希望再读一遍 An introduction to neural nets。)

权重对象主要封装一个表示一个节点与另一个节点之间的权重的数值。权重对象还有一个地址和一个颜色。地址是它在权重数组中的位置。 颜色用于显示。图 3 是权重数组的一种可能的表示。Net.py(请参阅 参考资料 中的链接)保持了对最低和最高 权重的追踪,它将权重显示中显示颜色数值的一个键。
图 3. 权重数组的一种可视化表示

在权重数组的每一行上,是一个给定节点与所有其他节点间权重的一个列表。Hopfield 网络有两种形式。一种形式的节点有一个到 自身的权重,另一种形式则没有。通过 net.py 获得的经验表明,当节点不是自权重(self-weighted)时,节点数组不会总是重构到自身。 选择 No Self Weight 选项,然后尝试重构 p3 或 p5。有一百个节点,所以有一万个通常冗余的权重。默认情况下,当节点是 自权重时,就会有 5050 个非冗余权重,否则就只有 4950 个。
图 4. 权重的起源

清单 2. 权重生成算法

PAT = { x: x is a RxC pattern }
WA = { x: x is a (R*C)x(R*C) weight array }
For all (i,j) and (a,b) in the range of R and C:
 SUM = 0
 for p in PAT:
         SUM += p(i,j) * p(a,b)
 WA( (R*i)+j, (C*a)+b ) = SUM

受生物学启发的概念是 1949 年 Donald Hebb 研究所得的 Hopfield 网络的基础。他假定如果一对节点同时向对方发送它们的能量, 那么它们之间的权重就要大于只有一个发送自己的能量的情况。他写道:“当细胞 A 的一个轴突距离 B 足够近以至于能刺激它,而且 能反复持久地参与对它的激发时,一个或者全部两个细胞中就会发生一些成长过程或新陈代谢的变化,这样,作为激发 B 的一个细胞, A 的功效就会增长”(参阅 参考资料 以获得详细资料)。就 Hopfield 网络来说,当一对节点有相同的 值时,换句话说是 -1 或 +1,它们之间的权重就更大。所有可能的节点对的值的乘积的和决定的权重数组的内容。当两个值相同时,它们 的乘积就是正的,和就会增加。在不同的值的情况下,这个和就会减小。

更详细地讲,权重是哪里来的?首先,Hopfield 网络必须可以访问一个库或者一组基本图案。在这里即 p1 到 p5。权重的生成首先由 Hopfield 网络在基本图案矩阵的界限内选择一对坐标。然后它访问每个图案中的对应节点。在每一步,它将节点值的乘积添加到一个 正在使用的和。(见图 4)。当网络访问过每一个图案后,它将一个权重对象的值设置为这个和。给出一对位于(i,j)和(a,b)的 节点,它会设置在权重数组中位于(i*10+j,a*10+b)的权重对象的值。

这就是权重如何构造的过程,不过,它如何作用于更大的 Hopfield 算法?它如何作用于图案的重构?

重构

如果在手边有一个权重数组和一个失真的或有噪声的图案,Hopfield 网络有时可以输出原始图案。没有保证,但是 网络正确次数的百分比高得惊人。它既可以同步完成,也可以异步完成。

如果是异步完成,网络会遍历失真的图案,在每一个节点 N,它会询问 N 的值应该设置为 -1 还是 +1。

要确定这一设置,网络会去遍历权重数组中包含 N 与其他节点间所有权重的的行。不要忘记,节点可能是也可能不是自权重的。

在第二次遍历的每一步,它会计算出(1)N 与另一个节点之间的权重与(2)另一个节点的值的乘积。正如您所预料的,网络会 保持这些乘积的一个使用中的计数器。

现在,网络就可以做出判定。至少在当前的实现中,如果这个和小于 0,网络就将节点设置为 -1,如果它大于或等于 0,则网络将 节点的值设置为 +1。
图 5. 重构:不遗留任何节点

清单 3. 重构

For every node, N, in pattern P.
 SUM = 0
 For every node, A, in P:
  W = weight between N and A
  V = value of A
  SUM += W * V
 if SUM < 0:
  set N's value to -1
 else:
  set N's value to +1

默认的更新是异步的,因为网络只是在确定的这个值应该是什么之后才去设置一个节点的值。如果网络在做出了所有判定 后再去设置节点的值,那么它就可以是同步的。在这种情况下,它将存储它的判定,然后在最后一个判定做出后更新数组的节点。 在 net.py(参见 参考资料)中,重构默认情况下异步进行的,不过要注意 同步重构 的选项。

当您体验 net.py,当重构成功时,Hopfield 网络的行为令人震惊。这种行为之一是,甚至当权重数组严重退化时,它仍可以 重构图案。我的简单实现的退化权重(Degrade Weights)会遍历权重数组并随机地将权重设置为 0。对权重数级的显示给出了 破坏程度的一个视图。在这里,正确的重构说明 Hopfield 网络的容错性远超过大脑。它是如何工作的?数学的描述不会短。取而 代之的,这里给出了一个结构简介。

发生了什么

Hopfield 网络的算法细节说明了为什么它有时可以消除噪声。和通常算法分析一样,最麻烦的部分是数学细节。在当前的例子中,这些 是难以描绘和想像的。幸运的是,有一些密切相关的现象,可以使 Hopfield 网络的工作原理清楚明白地显示出来。

当一个弹球掉入一个简单曲面构成的碗中时,它会滚到最低点。碗的曲率就像是一个规则,输入弹球的入口点,然后返回最低点, 即碗底。更为复杂的曲率将类似于一个函数,它输入一个入口点并返回几个局部最低点中的其中之一。

能量是这些简单现象的一个基本部分。不管是在简单的还是在复杂的例子中,进入的弹球都具有一定度量的能量。随时间的过去, 这个能量会减少。它最终会达到一个稳定状态,不能再变小。在复杂的例子中,可能会有一个更低的能量级别,但是弹球无法达到。

类似地,不管有没有失真,一个图案都可以被认为具有特定度量的能量。所以,图案 p1 到 p5 有能量级别。
图案能量级别

图案的能量级别的计算并不复杂。Hopfield 网络计算每一个可能的节点对的值与它们之间权重的乘积。图案的 能量级别是用负 2 去除这些乘积的和所得的结果。 Net.py 显示了任意给定图案或节点 数组的能量级别。当您重构图案时,我认为并希望您将能够看到图案能量级别的下降。

在重构中,网络基于其他节点的值及它们之间的权重的乘积的和做出翻转一个节点的判定。当和小于 0 时,节点设置为 -1,否则设置为 +1。当值与权重的乘积是正的时,它有助于促使和大于 0。不过这样会将网络推向将节点值设置为 +1 的趋势。当乘积是负的时,和被推进到或者小于 0。于是,网络被推向到将节点的设置为 -1 的趋势。权重的变化 会引起度量的变化以及网络进行判定过程中被推向的趋势的变化。图案可能会失真很严重,导致网络不会被推向到做出 正确判定的趋势。如果表述没有问题,网络在绝大部分时候会被推向正确的趋势。

如果您重构那五个图案中的任意一个,您将发现每个图案会重构到自身。它应该是这样,因为每个图案已经占据了一个 局部最低能量的点。没有重构过程可以再降低图案的能量级别。如果您成功地重构了一个失真的图案,Hopfield 就已经将 图案的能量级别降到了某个图案的级别。当失败时,它是已经将失真图案的能量级别降到了一个假的局部低点。在两种情况下, 能量级别都不能再有任何降低。换句话说,它已经达到了一种稳定状态。以能量的方式来描述 Hopfield 网络有着有趣而且 重要的意义。在此基础之上,它可以以数学的方式建立起来,以使得重复应用重构算法可以最终得到一个稳定的图案。(参阅 参考资料以获得详细资料。)

结束语

您应该意识到 Hopfield 网络的局限性。一个经常被提及的明显局限是,它的图案必须可以被编码为一个数组,这个数组或者由 -1 和 +1 构成,或者由 0 和 +1 构成。您已经知道,Hopfield 可能会稳定于一个假的局部低点。这个更为明显的局限在于,当图案 的数目超过节点数组中的节点数目的大约 14% 时,网络稳定于某个假的局部低点的概率会增加。也就是说,每增加一个基本图案, 就必须多大约 7 个节点。尽管有这样的局限性,但是,这里所讨论的图案重构还是有可能成为解决您特定计算问题的直观向导。 现在您已经大概了解了最初提及的 Hopfield 算法。如果它能满足您的需要,现在您已经明白了构建您自己的实现的上部构造。 这包括计算权重数组的算法、重构失真图案的方式以及计算图案的能量级别的算法。

(0)

相关推荐

  • 使用Python中的cookielib模拟登录网站

    前面简单提到了 Python 模拟登录的程序,但是没写清楚,这里再补上一个带注释的 Python 模拟登录的示例程序.简单说一下流程:先用cookielib获取cookie,再用获取到的cookie,进入需要登录的网站. # -*- coding: utf-8 -*- # !/usr/bin/python import urllib2 import urllib import cookielib import re auth_url = 'http://www.nowamagic.net/' h

  • python操作ie登陆土豆网的方法

    本文实例讲述了python操作ie登陆土豆网的方法.分享给大家供大家参考.具体如下: 这里利用ie操作登陆土豆网,很简单,仅做一下记录,以备后用. # -*- coding: utf-8 -*- import win32com.client import time ie6=win32com.client.Dispatch("InternetExplorer.Application") ie6.Navigate("http://login.tudou.com/login.do?

  • Python模仿POST提交HTTP数据及使用Cookie值的方法

    本文实例讲述了在Python中模仿POST HTTP数据及带Cookie提交数据的实现方法,分享给大家供大家参考.具体实现方法如下: 方法一 如果不使用Cookie, 发送HTTP POST非常简单: 复制代码 代码如下: import urllib2, urllib data = {'name' : 'www', 'password' : '123456'} f = urllib2.urlopen(         url     = 'http://www.jb51.net/',      

  • 用Python编写脚本使IE实现代理上网的教程

    厂里上个网需要设置代理服务器,切换各种环境『包括但不仅限于开发环境.QA.预上线.验收.生产环境.压力测试.Demo--』都需要给浏览器设置不同的代理服务器. 虽然俺有神器Firefox+Change Host+HostAdmin+Proxy Selector的组合来轻松切换Host,切换浏览器代理,但是-凡是就怕『但是』. 但是碰到一些IE才有的bug时候不得不换浏览器啊!!还要开虚拟机进去搞IE6.IE8.360.搜狗这些奇葩浏览器啊!!! 有同事建议搞个bat脚本来做这些,但没人肯动手--

  • Python的Bottle框架中获取制定cookie的教程

    这两天为用bottle+mongodb写的一个项目加上登录功能,无奈怎么都获取不到保存的cookie,文档给出让我们这样操作cookie的代码片段: @route('/login') def login (): username = request .forms .get('username ') password = request .forms .get('password ') if check_user_credentials(username, password): response

  • python cookielib 登录人人网的实现代码

    先上脚本吧,等下来讲下知识点: 复制代码 代码如下: #!/usr/bin/env python #encoding=utf-8 import sys import re import urllib2 import urllib import cookielib class Renren(object): def __init__(self): self.name = self.pwd = self.content = self.domain = self.origURL = '' self.o

  • Python自动调用IE打开某个网站的方法

    本文实例讲述了Python自动调用IE打开某个网站的方法.分享给大家供大家参考.具体实现方法如下: import win32gui import win32com import win32com.client import pythoncom import time class Test: def runtest(self): print 'test' class EventHandler: def OnVisible(self,visible): global bVisibleEventFir

  • 使用Python构建Hopfield网络的教程

    热的东西显然会变凉.房间会会人沮丧地变得凌乱.几乎同样,消息会失真.逆转这些情况的短期策略分别是重新加热. 做卫生和使用 Hopfield 网络.本文向您介绍了三者中的最后一个,它是一个只需要特定的参数就可以消除噪声的算法.net.py 是一个特别简单的 Python 实现,将向您展示它的基本部分如何结合到一起,以及为何 Hopfield 网络有时可以自失真的图案中 重新得到原图案.尽管这个实现有局限性,不过仍然可以让您获得关于 Hopfield 网络的很多有益且有启发作用的经验. 您寻求的是什

  • 利用Python构建Flutter应用的教程详解

    目录 关于FLET 如何安装 FLET 简单介绍 Flutter 用 FLET 构建简单的应用程序 用户界面 你知道可以用 Python 来构建 flutter 应用吗? Flutter 在软件研发领域是非常流行的,今天就让我们深入了解一下,用 Python 构建 flutter 应用程序的世界! 关于FLET 在开始学习前,了解一下什么是 FLET? FLET 可以使开发人员通过 Python,轻松地构建实时 Web.移动和桌面应用程序,更加疯狂的是不需要你有前端经验,也能让你开发出稳定的 W

  • python神经网络Keras构建CNN网络训练

    目录 Keras中构建CNN的重要函数 1.Conv2D 2.MaxPooling2D 3.Flatten 全部代码 利用Keras构建完普通BP神经网络后,还要会构建CNN Keras中构建CNN的重要函数 1.Conv2D Conv2D用于在CNN中构建卷积层,在使用它之前需要在库函数处import它. from keras.layers import Conv2D 在实际使用时,需要用到几个参数. Conv2D( nb_filter = 32, nb_row = 5, nb_col = 5

  • Python构建网页爬虫原理分析

    既然本篇文章说到的是Python构建网页爬虫原理分析,那么小编先给大家看一下Python中关于爬虫的精选文章: python实现简单爬虫功能的示例 python爬虫实战之最简单的网页爬虫教程 网络爬虫是当今最常用的系统之一.最流行的例子是 Google 使用爬虫从所有网站收集信息.除了搜索引擎之外,新闻网站还需要爬虫来聚合数据源.看来,只要你想聚合大量的信息,你可以考虑使用爬虫. 建立一个网络爬虫有很多因素,特别是当你想扩展系统时.这就是为什么这已经成为最流行的系统设计面试问题之一.在这篇文章中

  • Python 数据处理库 pandas 入门教程基本操作

    pandas是一个Python语言的软件包,在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础编程库.本文是对它的一个入门教程. pandas提供了快速,灵活和富有表现力的数据结构,目的是使"关系"或"标记"数据的工作既简单又直观.它旨在成为在Python中进行实际数据分析的高级构建块. 入门介绍 pandas适合于许多不同类型的数据,包括: 具有异构类型列的表格数据,例如SQL表格或Excel数据 有序和无序(不一定是固定频率)时间序列数据.

  • Python构建XML树结构的方法示例

    本文实例讲述了Python构建XML树结构的方法.分享给大家供大家参考,具体如下: 1.构建XML元素 #encoding=utf-8 from xml.etree import ElementTree as ET import sys root=ET.Element('color') #用Element类构建标签 root.text=('black') #设置元素内容 tree=ET.ElementTree(root) #创建数对象,参数为根节点对象 tree.write(sys.stdout

  • python构建深度神经网络(续)

    这篇文章在前一篇文章:python构建深度神经网络(DNN)的基础上,添加了一下几个内容: 1) 正则化项 2) 调出中间损失函数的输出 3) 构建了交叉损失函数 4) 将训练好的网络进行保存,并调用用来测试新数据 1  数据预处理 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017-03-12 15:11 # @Author : CC # @File : net_load_data.py from numpy import

  • python构建深度神经网络(DNN)

    本文学习Neural Networks and Deep Learning 在线免费书籍,用python构建神经网络识别手写体的一个总结. 代码主要包括两三部分: 1).数据调用和预处理 2).神经网络类构建和方法建立 3).代码测试文件 1)数据调用: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017-03-12 15:11 # @Author : CC # @File : net_load_data.py # @Soft

  • Python 机器学习库 NumPy入门教程

    NumPy是一个Python语言的软件包,它非常适合于科学计算.在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础库. 本文是对它的一个入门教程. 介绍 NumPy是一个用于科技计算的基础软件包,它是Python语言实现的.它包含了: 强大的N维数组结构 精密复杂的函数 可集成到C/C++和Fortran代码的工具 线性代数,傅里叶变换以及随机数能力 除了科学计算的用途以外,NumPy也可被用作高效的通用数据的多维容器.由于它适用于任意类型的数据,这使得NumPy可以无缝和

  • Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】

    本文实例讲述了Python面向对象程序设计OOP.分享给大家供大家参考,具体如下: 类是Python所提供的最有用的的工具之一.合理使用时,类可以大量减少开发的时间.类也在流行的Python工具中使用,例如,tkinter GUI API. 为何使用类 与面向对象的Java一样,类是对现实世界的一种抽象. 从更具体的程序设计观点来看,类是Python的程序组成单元,就像函数和模块一样:类是封装逻辑和数据的另一种方式.实际上,类也定义新的命名空间,在很大程度上就像模块.但是类有三个重要的独到之处,

随机推荐