您的位置:首页 > 理论基础 > 计算机网络

神经网络深入(连载2)直接编码

2017-01-25 13:07 316 查看
游戏编程中的人工智能技术



连载2:直接编码

 


11.2直接编码(DirectEncoding)

EANN编码有2种方法: 直接编码间接编码。直接编码,就是直接利用基因组中的神经细胞数目、连接数目等信息的编码,来描述网络的准确结构。而间接编码则利用了生长规则(growth rules),这种规则甚至可以用方式来定义网络结构。我们马上就会讨论这两种编码,我们下面先来考察直接编码的一些例子。


11.2.1 GENITOR(基因子)

GENITOR是已找到的几种最简单的编码方法中的一种,而且也是最早被发现的一种。所谓的GENITOR方法也有不同版本,典型的版本是用一个二进制数串来作为基因组的编码。每个基因用9 bit编码。其中第一bit用来指示神经细胞之间是否存在有效连接,其余的bit代表权重(-127~127)。例如,给定图11.2所示的网络, 则基因组的编码为:

         110010000  000000010  101000011  000000101  110000011

            -16          2           35           5          -3



图11.2  GENITOR编码。用淡灰色显示的连接表示被禁止的连接

其中用粗体显示的bit就是指示联接性(connectivity)的bit。编码下面的数字是与该二进制编码对应的十进制数。这是为了易于和图中的数字进行对照而添加的。

这种编码方法的缺点在于,它和我们迄今已探讨过的许多编码技术一样,为了在基因组内表示所有可能出现的连接,必须为牵涉到的每一个问题预先设计好一个最大的网络拓扑结构。另外,采用这一种编码要想避免竞争约定问题也是很麻烦的。


11.2.2二进制矩阵编码(Binary Matrix Encoding)

直接编码的一种流行方法是使用一个二进制的邻接矩阵(adjacency matrix)。作为一个例子,我们考察图11.3所示的网络。



图11.3  一个简单的5节点网络的二进制矩阵表示

你能看出,这一网络中神经细胞之间的连接关系可以用一个二进制数字(0,1)的矩阵来表示,其中1代表对应行和列的神经细胞之间有连接,而0代表它们不连接。这样,整个染色体的编码只要把矩阵每一行(或列)的数字赋值给基因就行了。如:

00110 00010 00001 00001 00000

但是,由于所显示的网络整个地是前向网络,这种编码所用代码是很浪费的,因为矩阵元素中总有一半全为零。认识到这一点,我们可以如图11.4那样,仅仅考虑矩阵的一半,由此就把染色体编码简化成为下面的形式:

0110 010 01 1

这一编码形式,我想你一定能同意,它是非常高效了!



图11.4  调整后的矩阵

一旦编码完成之后,二进制数字串就可以通过遗传算法去演化拓扑。在每一个代中对染色体进行译码,所得网络以随机的权重实行初始化。然后训练这一网络,并相应地赋给它一个适应性分数。如果训练机制采用了backprop方法,适当性函数的输出可以与所产生的误差成比例关系,为了使网络尺寸达到最小,可以对连接的增加采用附加惩罚。

显然,如果你的训练方法能够处理任何形式的连接性,不仅仅是前向网络,整个矩阵都有可能要用来表示相应的连接关系。如图11.5所示就是一个这样的例子。采用遗传算法的训练方式就可以应用到这一类的网络,但采用标准的反向传播方法则不行。


11.2.2.1几个相关问题(Some related Prolems)

已经证明,当使用矩阵编码(和另一些形式的直接编码)时,随着染色体尺寸的不断增加,演化的性能会变坏。且因尺寸的增加和神经细胞个数的平方成比例,性能变坏的速度极快。这就是所谓的可伸缩性问题(scalabilityproblem)。另外,为了创建矩阵,用户必须首先确定最大的网络所用神经细胞有多少。并且,这种类型的表示方法也无法提交和解决我们前面讨论过的竞争约定问题。当使用这编码时,很有可能 2个或更多个的染色体显现相同的性能。如果这些染色体进行配对杂交,则产出的子代的适应性很难有机会超过它们的父母一代。为了这一缘故,一种相当普遍的做法就是完全放弃杂交操作。



图11.5  有返回连接的网络


11.2.3基于节点的编码(Node-Based Encoding)

基于节点的编码处理问题的方法是,在基因中为每个神经细胞要求的全部信息进行编码。对于每一个神经细胞(或节点),它的基因所包含的信息是:与它连结的其他神经细胞,以及与这些连接相联系的权重。在基于节点的编码中,有的甚至走得更远,把相关的激励函数和学习率也包括在其中。(不要忘记,当网络采用反向传播那样的梯度下降法来训练时,就需要利用到学习率。)

因本章的代码工程采用了基于节点的编码,故稍后我会非常详细地来介绍这一技术,但现在你只要了解它的思想就行了。下面让我们来举一个简单的例子,看怎样为网络的连接关系进行编码。

图11.6画出了2个简单的网络和它们的染色体。每个基因包含一个节点标识和一个进入该节点的节点连接表。如用代码,一个简化的基因和基因组结构将有下面的形式:

structSGene

{
     int              NodeID;

     vector<Node*>    vecpNodes;

}

    

structSGenome

{

     vector<SGene>    chromosome;

     double           fitness;

};






图11.6  基于节点的编码

使用这种编码的突变操作可以有不同类型,并且也都很容易实现。它们可能的突变包括:增加一个链接、删除一个链接、增加一个节点、删除一个节点。但杂交操作就完全是另一种情况了。为了保证杂交所产生的子代确实有效,且不让任何神经细胞出现既无输入又无输出的这种宭境,必须非常谨慎地来从事这种操作。

图11.7显示了由图11.6中的2个染色体的第3个基因 (“C”基因) 配对后所产生出来的子代。

有效的遗传算法操作一旦定义了之后,利用所描述方式编码的神经网络可按下列的步骤来进行演化(我们假设它们采用了和类似反向传播那样的梯度下降算法相关的训练集来训练的):

 



图11.7  杂交操作过程

   1. 创建染色体的一个随机的初始群体。

   2. 训练各个网络,并根据每个网络的总体误差值来分配适应性分数(误差是指:目标输出减去训练最佳的输出)。也可以给尺寸增长得快的网络打一个惩罚分。这有利于具有较少神经细胞和链接的群体。

   3. 使用你所喜爱的选择法(如锦标赛选择或与适应性成比例的选择等) 选取2个父代。

   4. 在合适的场合使用杂交操作。

   5. 在合适的场合使用突变操作。

   6. 重复步骤3、4和5,直到新的群体创建出来。

   7. 转到步骤2去重复,直到演化出满意的网络时结束。

在本章后面,我将会告诉大家怎样利用基于节点的编码去演化拓扑并同时演化连接权重。


11.2.4基于路径的编码(Path-Based Encoding)

用基于路径的编码定义神经网络结构的办法是:为每一条从输入神经细胞到输出神经细胞之间的路径进行编码。例如,当已知图11.8所描述的网络时,则所需路径是:

1-> A -> C -> 3

1 ->D -> B -> 4

1-> D -> C -> 3

2 ->D -> C -> 3

2 ->D -> B -> 4

 

因每条路径总是从一个输入神经细胞出发,并总是到一个输出神经细胞结束,这种类型的编码确保了在染色体中不会有无用的神经细胞。重组所用的操作是2点杂交。(这保证染色体总是以输入和输出神经细胞为边界点)。突变操作典型地是使用下面几种:

o       创建一条新路径并插入到染色体。

o        选择一节(section)路径并加以删除。

o        选择一段(segment)路径并插入一个神经细胞。

o       选择一段(segment)路径并删除一个神经细胞。

     由于利用这种编码类型所定义的网络可以不限于前向网络(也就是说,链接可以是循环的) , 为了确定理想的连接权重,必须使用遗传算法那样的训练方法。






   图11.8  基于路径的编码



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息