人工智能AI系统的学习过程和人类的学习过程一样,你要么从过去的经验中学到一些东西,然后改进,要么就是视而不见。我们传统的编程方式是过去有误差,但代码编写以后,对里面的行为没有改进,所以传统编程方式不如神经网络AI系统。AI系统的强大在于对预测的结果和实际的值的误差反推过去的步骤,沿着从后往前的链条不断往前反推,反推前面的哪些步骤对结果负的责任是什么,前面哪些因素导致了最后这个结果。这个过程跟人类反思过去事情经历的过程是一样的,反思过去哪些因素导致了这个结果,并修正它,并期待下一次做同样事情的时候能够改进。这就是所谓的Back Propagation。

       从我们从后往前推,看哪些因子对我们的结果进行负责的时候,我们改进的是权重。那要不要改输入数据呢?不需要改输入数据,输入数据肯定不可以改;要不要改中间层神经元的数据呢?从后往前推的时候也不应该改。从后往前推的时候改的是权重,知道哪些对你重要,哪些对你不重要。但是下一次运行的时候,输入instances的第一条数据[0,0],由于都是0,这里没什么变化;当输入instances的第二条数据[0,1]、第三条数据[1,0]……的时候,由于权重已经发生了变化,进行Forward propagation的时候,从理论上讲,下面第一个隐藏层所有的神经元要跟着权重的改变而改变,这跟上一次运行一个Epoch的内容不一样了,由于权重改变了,第二层隐藏层的值是由前一个隐藏层的值和相应的权重构成的,第二层隐藏层的值也会改变;同样的,第三层隐藏层的值也会改变;由于第三层隐藏层的值改变了,而且权重发生了改变,所以最后的输出层值也会发生改变。如果Back Propagation算法没有问题的话,它会进行改进。

       在TensorFlow的控制台,我们恢复TensorFlow为初始状态,记录一下第三层隐藏层第一个神经元的权重是0.090,第二个神经元的权重是0.029。如图所示。

          

(20)Back Propagation算法_Back

图 1- 31初始权重示意图

类似的,我们自研盘古人工智能框架所有网络的初始状态赋值是在Create_AI_Framework_In5Classes(Class1)的NetworkConnection.py中实现的,这是我们前一节中从零起步一行一行编码写的。

这里TensorFlow控制台中0.090,0.029是初始网络状态的赋值,单击里TensorFlow控制台的运行按钮,这里运行了19次Epoch,把所有的数据运行了19次,发现第三层隐藏层第一个神经元的权重变了,从0.090变成了-1.2,第二个神经元的权重也变了,从0.029变成了-0.032,如图所示。

(20)Back Propagation算法_数据_02


图 1- 32权重变化示意图

       每次Epoch把训练的数据运行一遍,由于权重改变了,输出结果也改变了。输出结果改变,我们期待是向好的地方转变,而我们的Back Propagation里面的算法就是让它达到更准确,更向实际靠近进行计算的算法,这也是神经网络最核心、最精髓的部分。

这里描述的Back Propagation过程其实就是梯度下降(Gradient Descendent),梯度下降就是根据你的误差结果反思过去哪些行为对这些结果负责,然后调整这个行为,调整的过程就是梯度下降过程。我们在自研盘古框架中使用的梯度下降算法是Sigmoid算法,这是我们从零起步一行行写代码实现的,然后根据这个算法在计算梯度的时候,需如何调整这个变化,从数学的角度就是求导数,导数计算的是变化率,然后进行调整。

回到TensorFlow的控制台,一条数据运行1次,从前往后运行得到一个误差,再从后往前看,我们看的是权重,权重代表影响因子对我们的重要性,从后往前推是一个链条,权重从后往前推的过程中会遍历每个神经元。例如,最后一个隐藏层只有2个神经元,从后往前推,需看这2个神经元对误差的结果负责的程度,第一个神经元是什么程度的导致了输出结果的误差,第二个神经元是什么程度的导致了输出结果的误差,这样从后往前推的时候需乘上它的权重。