接下来我们将Backward Propagation的过程以代码的方式实现。

  • 首先,我们先写一个接口BackPropagation.py,BackPropagation.py的实现将和我

们刚才描述的Backward Propagation的过程是一样的。applyBackPragation方法的参数中instances是所有的输入数据, nodes是所有的节点, weights是权重, learning_rate是学习率。进行一次完整的训练以后将结果返回,返回的结果是所有的节点nodes,及更新的权重weights 。训练以后返回一个训练好的神经网络,这个是TensorFlow静态图的概念,PyTorch在训练以后也可以调整,这也是PyTorch最吸引人的地方。这里返回的是节点和权重,下次在输入数据的时候,把输入数据经过权重的处理,进入下一层的节点;然后把数据再经过权重的处理,再进入下一层的节点;再经过权重的处理,再进入下一层的节点;最后经过权重的处理,计算出结果。理想情况下,计算的结果和真实的结果是一样的。

 

Create_AI_Framework_In5Classes(Day3)版本的BackPropagation.py接口:


class BackPropagation:
def applyBackPragation(instances, nodes, weights, learning_rate):
…….
return nodes, weights

2)我们在Neuron_Network_Entry.py中要应用BackPropagation.py,一般情况下要运行多少次Epoch,这里假设Epoch为1万次,对所有训练的数据集重复运行1万次;learning_rate是一个调优参数,在优化的时候使用,这里设置为0.1,暂时不用关注,因为有没有learning_rate,以及不同的learning_rate,不会对网络的收敛Converge,即达到梯度下降的极值产生影响。我们在Create_AI_Framework_In5Classes(Day2)版本的基础上对Neuron_Network_Entry.py进行修改。

Create_AI_Framework_In5Classes(Day2)版本的Neuron_Network_Entry.py代码:


# -*- coding: utf-8 -*-
from service.NetworkStructure import NetworkStructure
from service.NetworkConnection import NetworkConnection
from service.ForwardPropagation import ForwardPropagation
#from entity.Node import Node
#Exclusive OR: 只有第一个元素和第二个元素不同的时候,结果才是1,否则为0
instances = [[0,0,0],
[0,1,1],
[1,0,1],
[1,1,0]]


num_of_features = len(instances[0]) - 1 #在这里是只有第一列和第二列是features,第三列是根据某种关系而得出的结果


#hidden_layers = [4,2] #这里hardcode为两个Hidden layer,第一个Hidden Layer有4个Neuron,第二个Hidden Layer有连个Neuron
hidden_layers = [8,4,2]
nodes = NetworkStructure.create_nodes(num_of_features,hidden_layers)

#ID为0、3、8的Node为Bias
#for i in range(len(nodes)):
# print("This is a bias:" + str(nodes[i].get_is_bias_unit()))


weights = NetworkConnection.create_Weights(nodes,num_of_features, hidden_layers)


#从Input Layer触发,经过所有的Hidden Layers的处理,最终得出Output Layer的结果。


for i in range(len(instances)):
instance = instances[i]

ForwardPropagation.applyForwardPropagation(nodes, weights, instance)

#得出此次Forward Propagation的输出结果
#print("Prediction: " + str(nodes[len(nodes) - 1].get_value()))


print("Prediction: " + str(nodes[len(nodes) - 1].get_value()) +
" while real value is: " + str(instance[num_of_features]))

Create_AI_Framework_In5Classes(Day3)版本的Neuron_Network_Entry.py,与

Create_AI_Framework_In5Classes(Day2)版本相比:

 上段代码中第4行之后新增代码,新增自研BackPropagation类的导入。

 上段代码中第22行之后新增代码,新增epoch、learning_rate变量的定义及调用BackPropagation.applyBackPragation方法。



…….
from service.BackPropagation import BackPropagation
……..
#对所有训练的数据集重复运行1万次
epoch = 10000
learning_rate = 0.1
for i in range(epoch):
nodes, weights = BackPropagation.applyBackPragation(instances, nodes, weights, learning_rate)
print("Congratulations! Back Propagation is completed!!!")
…….

通过BackPropagation.applyBackPragation方法训练好以后,权重都达到了最佳的状态,然后对输入数据再应用一次applyForwardPropagation,将达到最佳的预测结果,这个预测结果肯定比没有做Back Propagation的结果精确的多。因为如果不是这样,表明梯度下降的算法有问题,而梯度下降的算法基本不会有问题,因为梯度下降的算法都是一些数学家大神几十年的研究成果,例如Sigmoid的梯度下降的求导,ReLU的梯度下降的求导,它们是不同时期的研究成果,这2者之间有很大的不同,由于应用场景不一样,Sigmoid在一些情况并不理想,而ReLU算法是非常理想的。因此,人工智能背后的理论出奇的复杂,背后的原理机制可能需数学专业的博士生、研究生或同等学力的研究人员进行研究。对于AI框架的应用而言,Python的一些框架已经将这些数学公式进行了封装,我们可以直接调用框架的接口进行调用。