企业级AI技术内幕:深度学习框架开发+机器学习案例实战+Alluxio解密
上QQ阅读APP看书,第一时间看更新

2.3 实现神经网络层之间节点的连接

神经网络多层次实现的时候涉及权重以及层与层之间的连接。神经元网络的权重较复杂,权重涉及两个层,权重是两个层之间的连接线,有来源节点及目标节点。接下来我们实现神经网络层之间节点的连接。在创建不同层连接的时候需实现权重,在entity目录下创建Weight.py的实体,在Weight.py中创建一个权重类(Weight)。

chapter2_Create_AI_Framework的Weight.py源代码如下:

第5~10行代码:设置和访问权重的ID。权重类的set_weight_index方法第一个参数是self,因为创建权重实例的时候可以有很多实体,因此传入self创建实例。

第12~17行代码:设置和访问权重的来源节点。权重涉及前面一层的节点,也涉及后面一层的节点。例如,输入层与隐藏层之间的连接权重。神经元节点的Index很重要,这里权重的from_node_index就设置为来源节点的Index。

第20~25行代码:设置和访问权重的目标节点。

第27~32行代码:设置和访问权重的值,权重的核心内容是权重值。

接下来实现权重与不同的神经元网络层的连接。在service目录中创建一个业务类NetworkConnection.py。前面创建了神经元的网络结构,但没有创建层之间的连接,现在要把不同的网络层连接起来。如果不把不同的网络层连接起来,激活函数就无法把前一层的内容传递给下一层。

chapter2_Create_AI_Framework版本的NetworkConnection.py(v1)源代码如下:

第8行代码:构建create_Weights()方法。神经网络有多层时,第一层的输出是第二层的输入,第二层的输出是第三层的输入,以此类推。建立网络之间的连接要做第一件事情是创建权重,不同层之间都通过权重连接,网络图中的一条条连线就是权重。神经网络有很多不同的层,而且有很多不同的权重。create_Weights()方法中不需知道层的信息,因为神经元节点中已经包含层的信息。create_Weights()方法传入的第一个参数是神经元节点集,第二个参数是输入特征数,第三个参数是隐藏层神经元节点列表。

第9行代码:创建一个权重列表,存放所有的权重信息。

第12行代码:获取整个神经网络的层数。两个层次之间中间会有权重,整个神经网络的层数=输入层数+隐藏层数+输出层数。如图2-19所示,这里的输入层是1层,输出层是1层,再加上隐藏层的层数。

第15行代码:定义权重的ID。因为有很多个权重,通过weight_index记录权重的ID。

第18行代码:进行外层循环,循环遍历不同的层构成权重,权重代表了神经网络中前后层之间的联系。图2-19中有4层,输入层、第一个隐藏层、第二个隐藏层、输出层,构建的权重会有3列,权重发生于前后两个层之间,所以循环的次数要从总的层数量中减去1,代表有多少个不同类型的权重。

第21~58行代码:进行内层循环,遍历所有的神经元节点。神经网络层与层之间会有很多的权重。

图2-19 整个神经网络的层数

第24行代码:判断当前节点nodes[j]所在的具体的层。每个节点都有自己的索引,如果当前节点nodes[j]所在的层等于i,此时已经获得了一个当前节点nodes[j]。

第26行代码:再次循环遍历所有的节点,核心目的是判断不同节点之间的层的先后关系,考虑刚才的节点nodes[j]和现在的节点nodes[k]之间的层关系,如果是前一个层,那两个节点nodes[j]、nodes[k]之间就有权重。这时候可能会有性能问题,但我们主要关注神经网络的实现,暂不考虑性能的问题。判断一下当前获得节点nodes[k]的层是否等于i+1,目的是找到节点nodes[k]前面的层的某个节点,只要是前一个层的节点,那它们之间就有权重关系,构成权重的前提条件是有前后相邻的层关系,如图2-20所示。

图2-20 构建权重

第33~36行代码:创建权重的时候必须设置权重的源节点、目标节点以及权重的index。权重的set_from_index、set_to_index需填写是什么节点的index,这个比较关键,因为从nodes[j]触发到nodes[k]之间创建权重,节点所在的层ID越小,就越在前面,这里nodes[j]在第i层,而nodes[k]在第i+1层,因此,weight.set_from_index设置为出发点nodes[j].get_index(),weight.set_to_index设置为目的点nodes[k].get_index()。