Hamming网络采用Hamming距离度量两向量的距离。因此Hamming网络是专门为求解二值(问题中输入向量的每个元素只能是两个可能值中的一个,本文取-1和+1两个值)模式识别问题而设计的。它同时采用了前馈网络和递归网络,并且两层的神经元个数相同。Hamming网络的目标:是判定哪个原型向量最接近于输入向量,判定的结果由递归层的输出表示。每个标准模式均对应递归层中的一个神经元,当递归层收敛后,递归层中只有一个神经元的输出值为非0值,该神经元指明了哪一个标准模式与输入向量最接近。本文结合水果分类问题详细说明Hamming网络的工作原理。
1. 问题
某商贩有一个存储各种水果和蔬菜的货仓。当将水果放进货仓时,不同类型的水果可能会混淆在一起,所以商贩非常希望能够有一台能够帮他将水果自动分类摆放的机器。假设从水果卸车的地方到货仓之间有一条传关带。传送带要通过一组特定的传感器,这组传感吕可以分别测量水果的三个特征:外形、质地和重量。如下图所示:
这些传感 器功能比较简单。如果水果基本是圆形的,外形传感器的输出就为1;如果水果更接近椭圆,那么外形传感器的输出就为-1.如果水果表面光滑,质地传感器的输出就为1;如果水果表面比较粗糙,那么质传感器的输出就为-1.当水果重量超过1磅时,重量传感器的输出为1;水果重量轻于1磅时,重量传感器的输出为-1.
本文介绍的Hamming网络就能够很好解决这个问题。最终的效果是:三个传感器的输出输入到Hamming神经网络。然后网络输出水果的类型,接着把不同类型的水果分别送到相应的储存仓内。
2. 前馈层
前馈层用于实现每个标准模式和输入模式之间的相关检测或求内积。为了使得前馈层能够完成其功能,可以用标准模式设置其权值矩阵的行,该权值矩阵用连接矩阵表示。对于苹果/橘子实例而言,有
前馈层采用的是线性传输函数,偏置值向量中的每个元素均等于。其中,是输入向量中的元素个数。据此,可以将该实例中偏置值向量设置为
用权值矩阵和偏置值向量的这些选择,前馈层的输出为
注意:前馈层的输出等于输入和每个标准模式的内积加。对于这两个等长(范数)向量而言,内积在两个向量指向同方向时最大,指向相反时值最小。把内积加上是为保证前馈层的输出不会都是负数值,这是递归层正常操作所必需要的。
3. 递归层
Hamming网络的递归层就是所谓的“竞争”层。该层的神经元用前馈层的输出进行初始化,此输出指出原型模式和输入向量之间的关系。然后递归层中的神经元相互竞争以决定谁是胜利者。竞争后只有一个神经元的输出值不等于0.竞争取胜的神经元就表示提供给网络的输入的类别(比如在我们的实例中,就是苹果和橘子两种类别)。描述竞争的等式为 和 其中,传输函数对于正值而言是线性函数,对于负值而言取值为0.权值矩阵的形式为 (两种类别时)
(三种类别时)
因此,可知的对角元素全为1,其他元素全为。 此处,为小于的一个数,为递归层的神经元的个数。
递归层的每次迭代过程可以用下式表示:
从上式可以看出,向量每个元素都减云另一个元素的一部分,而减少的比例相同,均为。由此可知,具有较大值的元素减云的量较少,而具有较小值的元素减去的量较大,这将导致元素值的大小差别进一步扩大,最终使得除了初始值最大的元素的值继续保持较大的值以外,其他元素的值将逐步变为0。而输出值大于0的元素所对应的神经元便对应于以Hamming距离和输入模式最靠近的标准模式。
4. 一个例子
此部分讲解利用Hamming网络解决开头的水果分类问题。为了使问题更加简单,现假设传送带上只有两种类型的水果:苹果和橘子。我们可以用一个三维的向量来表示一个水果:
所以,一个标准的橘子可表示为: 一个标准的苹果可表示为:
对于传送带上的水果,Hamming网络可接收到一个三维输向量,并且必须判断它是一个橘子()还是一个苹果()。
此时,假定一个椭圆形的橘子被送上传送带,我们通过它来看Hamming网络是如何工作的。
- 初始化前馈层的权值
- 初始化递归层的权值
- 计算前馈层的输出值
- 迭代计算递归层的输出,直到收敛
由于,故递归层收敛。第一维不为零,故此水果被判定为橘子。
下面给出程序:
import numpy as np
import copy
class HammingNet:
def __init__(self, W1, outputs):
self.outputs = outputs
self.W1 = W1
self.b1 = len(self.W1[0])*np.ones((len(self.W1), 1))
self.W2 = np.eye(len(self.W1))
self.W2[self.W2==0] = -(1.0/(len(self.W1)))
self.max_iters = 100
def fit(self, x):
a1 = self.purelin(x)
a2 = copy.deepcopy(a1)
for i in range(self.max_iters):
new_a2 = self.poslin(a1)
if new_a2.tolist() == a2.tolist():
a2 = copy.deepcopy(new_a2)
break
a2 = copy.deepcopy(new_a2)
a2 = a2.reshape(-1)
a2[a2>0] = 1
output_type = self.outputs[a2.tolist().index(1)]
print("This is an "+output_type)
def purelin(self, x):
return np.dot(self.W1, x)+self.b1
def poslin(self, x):
a2 = np.dot(self.W2, x)
a2[a2<0] = 0
return a2
outputs = ["orange", "apple"]
W1 = np.array([[1, -1, -1] # the prototype of orange
,[1, 1, -1] # the prototype of apple
])
hammingnet = HammingNet(W1, outputs)
x = np.array([-1, -1, -1] # a ellipsoidal orange
).reshape(-1, 1)
hammingnet.fit(x)
6. 总结
本篇介绍了Hamming网络的目标、工作原理、方法,最后还给出一个例子与程序用以说明Hamming网络的工作过程。Hamming网络由前馈层与递归层组成的两层神经网络,两层的权值都是需要预先设计,也就是说,Hamming网络的结构与参数是人为设定好的。与其他神经网络(参数与结构至少有一个是可以通过学习得到)相比,Hamming网络是一种非常初级的神经网络。尽管如此,Hamming网络中的主要工作原理:在内积操作层(前馈层)之后紧跟一个动态竞争层(递归层)
,被后来很多人工神经网络借鉴,这些网络被称为自组织网络。但与Hamming网络的静态性不一样,这些网络可以根据提供的输入向量对原型向量进行学习与调整。
Hamming网络的动态竞争层具有两个特点:1)横向抑制;2)胜者全得。 横向抑制:每个神经元的输出都将对所有其他的神经元产生一种抑制作用; 胜者全得:只有一个神经元有非零输出,这就被叫作胜者全得竞争。
7. 参考文献
[1] Hagan M , Hagan, 戴葵. 神经网络设计[M]. 机械工业出版社, 2002.