小白也能看懂的BP反向传播算法之Further into Backpropagation

本文相关代码可以从Backpropagation下载

在上一篇文章小白也能看懂的BP反向传播算法之Let's practice Backpropagation,我们计算了一个带sigmoid函数的嵌套网络的反向传播!从这篇文章开始,我们正式进入实际的神经网络的反向传播!本文将以一个两层的神经网络结构为例子,并且利用矩阵的方法实现神经网络的反向传播训练算法!

Lets get started!!!

神经网络的结构如下:

image.png

上图的神经网络包括两层网络。第一层是输入层,包括三个神经元,第二层也就是输出层,包括了两个神经元。标准的神经网络中,sigmoid层也就是激活函数,是输出层的一部分,这里为了反向传播时计算微分更直观,就将其分开!

对于不了解基本神经网络的同学可以参考,对于不了解激活函数的同学可以参考‘神经网络’初探

我们下面来分析这个神经网络。首先,三个输入值被输入到输入层的三个节点中,因此我们的输入,用矩阵表示,应该是三维的。然后输入层将和各自的权重相乘,得到输出层,这里和权重的相乘,可以简化成矩阵的乘法运算。然后再输入到sigmoid函数中,进行激活计算,得到一个0-1之间的输出值。最后输出到cost function中,进行误差的计算,这里的cost function可以选取不同的计算函数,这里我们用交叉熵函数作为代价函数, cross-entropy 。单纯对于研究反向传播来说,我们都可以不需要知道这些一层层的函数是干嘛的,因为我们反向传播要求的只是微分而已。只要这些函数是可微的,不管结构在复杂,无非是链式求导的时候多求几个微分而已!反向传播的本质就是在微分的计算!

Aim

误差当然是越小越好,所以我们训练网络的目标是将cost function的值减小,这和我们之前几篇文章将输出结果增加正好是相反的,其实也很简单,只需要在更新的时候,减去步长和微分的乘积就行,将之前的+变成-!具体可以参考梯度下降法 这里我们要更新的是权重的值,所以更新的方法如下:

image.png

这里的Wij代表,第i个输入节点到第j的输出节点的权重! 只需要求出costfunction关于每个权重的微分即可!

首先,我们自然要先进行正向传播,也就是正向计算最后的输出cost function!

Forward Propagation

首先,我们将输入矩阵化,就是一个1*3的矩阵:

image.png

如果我们有多个样本的输入值,比如有n个输入,那么输入矩阵就可以写成n*3的矩阵!

权重矩阵如下:

image.png

然后输入层到输出层的计算,就可以简化成,两个矩阵的相乘:

image.png

正好得到一个 1x2 的矩阵,对应输出层的两个神经元,符合我们的预期,然后我们给第一个输出层的神经元标记y1,给第二个神经元标记为y2。

image.png

然后再进行激活函数的计算

image.png

Cost function 得到输出层的输出并进行激活函数计算之后,就要输入到cost function中计算errors!。这里我们采用的交叉熵代价函数, cross-entropy

image.png

这里p是预期的值,q是我们经过神经网络计算得到的预测值,具体交叉熵函数的意义,可以参考 cross-entropy

image.png

而我们只要知道我们要将C的值降低,利用反向传播算法,降低C的输出,所以我们就要求得C的微分,首先我们把C展开:

image.png

然后将我们网络中计算得到的输出层的输出带入进去:

image.png

这样我们就分析完了怎么进行这个神经网络的正向传播!

Backpropagation

反向传播之前,我们先回顾一下,每一层的输出结果

激活函数层的输出结果

image.png

输出层的输出结果

image.png

权重矩阵

image.png

输入层

image.png

明确了每层的值之后,我们要切记,我们反向传播所需的就是关于权重的微分,也就是

image.png

也就是我们要想办法求出C关于各个权重的微分! 求微分的基本思路和之前是一样的,不管网络的结构多复杂,根本都是利用链式法则,一层层的从输出求导到输入!这里,我们会采取矩阵的算法来进行微分的求解,这可以让我们的求解方法更适合于编写程序,并且更直观!

首先我们看输出C是关于sigmoid层的输出y0的函数,然后y0又是关于输出层的输出y的函数,y同时又是输入层x与权重相乘而得来的。所以,基本就明确了,我们需要先求取C关于y0的微分,再求取y0关于y的微分,然后求取y关于w的微分,最后又链式法则相乘在一起,就得到了C关于w的微分!

  • 首先从cost function到sigmoid layer

image.png

我们可以很容易写出微分:

image.png

写成矩阵的形式

image.png

  • 从sigmoid层到输出层的微分,就是求取sigmoid函数的微分

image.png

变成矩阵的形式就是:

image.png

  • 从输出层到输入层的微分就是关于权重的微分,我们先看y关于权重的形式

image.png

从这个形式不难得出关于权重的微分就是:

image.png

这样我们就可以运用链式法则,求取C关于权重W的微分了:

image.png

将每个微分的值带入:

image.png

将六个微分全部求取出来就是:

image.png

不难写成矩阵的形式:

image.png

这里T代表矩阵的转置,X代表矩阵的乘法,圆圈加点代表矩阵对应元素相乘,也就是element-wise product。

最后,我们就可以得到完整的权重更新的法则:

image.png

根据以上计算出的更新法则,编写python代码就很直观了

import numpy as np


def sigmoid(x):
    return 1/(1+np.exp(-x))


def derivative_sigmoid(x):
    return np.multiply(sigmoid(x), (1-sigmoid(x)))


# initialization
# X : 1*3
X = np.matrix("2, 4, -2")
# W : 3*2
W = np.random.normal(size=(3, 2))
# label
ycap = [0]
# number of training of examples
num_examples = 1
# step size
h = 0.01
# forward-propogation
y = np.dot(X, W)
y_o = sigmoid(y)
# loss calculation
loss = -np.sum(np.log(y_o[range(num_examples), ycap]))
print(loss)     # outputs 3.6821105514(for you it would be different due to random initialization of weights.)
# backprop starts
temp1 = np.copy(y_o)
# implementation of derivative of cost function with respect to y_o
temp1[range(num_examples), ycap] = 1 / -(temp1[range(num_examples), ycap])
temp = np.zeros_like(y_o)
temp[range(num_examples), ycap] = 1
# derivative of cost with respect to y_o
dcost = np.multiply(temp, temp1)
# derivative of y_o with respect to y
dy_o = derivative_sigmoid(y)
# element-wise multiplication
dgrad = np.multiply(dcost, dy_o)
dw = np.dot(X.T, dgrad)
# weight-update
W -= h * dw
# forward prop again with updated weight to find new loss
y = np.dot(X, W)
yo = sigmoid(y)
loss = -np.sum(np.log(yo[range(num_examples), ycap]))
print(loss)     # 3.45476397276 outpus (again for you it would be different!)

运行程序,就会看到,进行反向传播,C的值也就是代价函数减少了!(由于初始权重是随机生成的,所以每次运行结果就不尽相同,但可以确定的,反向传播后的输出结果相对之前一定是减小的)

待续

这篇文章将会在此结束!我们已经成功将反向传播的计算扩展到真实的两层的神经网络中,并且将计算过程矩阵化!下一篇就是反向传播算法的终结篇,将会实现一个多层的神经网络的反向传播,并且运用动态规划算法对反向传播中微分的计算进行优化!

本文相关代码可以从Backpropagation下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI科技评论

开发 | 监督学习最常见的五种算法,你知道几个?

AI科技评论按:本文作者李东轩,原文载于作者个人博客,AI科技评论已经获得授权。 在机器学习中,无监督学习(Unsupervised learning)就是聚类...

40290
来自专栏机器学习算法与Python学习

机器学习(6) -- SVM

本篇主要是对支持向量机(support vector machine , SVM) 总结性的文章,想详细的理解SVM的请看之前所发的支持向量机系列文章。 Co...

37650
来自专栏AlgorithmDog的专栏

EM算法原理和应用

EM算法是带隐变量概率模型的推断算法。今天我们介绍 EM 算法的原理和应用。我们先介绍推导出 EM 算法的一般方法,再介绍另一种 EM 算法推导方法...

507100
来自专栏AI研习社

监督学习最常见的五种算法,你知道几个?

在机器学习中,无监督学习(Unsupervised learning)就是聚类,事先不知道样本的类别,通过某种办法,把相似的样本放在一起归位一类;而监督型学习(...

424110
来自专栏磐创AI技术团队的专栏

使用Keras进行深度学习:(三)使用text-CNN处理自然语言(下)

前言:在上一篇文章中,已经介绍了Keras对文本数据进行预处理的一般步骤。预处理完之后,就可以使用深度学习中的一些模型进行文本分类。在这篇文章中,将介绍text...

45740
来自专栏智能算法

从感知机到神经网络简略

最热门的深度学习,想必很多人都想了解学习,网络上也有不少资料;小编也希望可以从头开始,更为透彻地去理解原理机制,这样在日后可以在深度学习框架实战的学习上更为轻松...

37360
来自专栏Petrichor的专栏

深度学习: GoogleNet 网络

提出了 Inception_v1,开启了伟大的Inception系列,并刷新了网络的深度新记录。

30320
来自专栏机器学习算法与Python学习

特征学习之卷积神经网络

今天介绍卷积神经网络(cnn)的训练方法,即:随机梯度下降和误差反向传播。 先说下推导的思路: (1)说明CNN是一种局部连接和权值共享...

35370
来自专栏AI研习社

手把手教你如何用 TensorFlow 实现 CNN

CNN 的引入 在人工的全连接神经网络中,每相邻两层之间的每个神经元之间都是有边相连的。当输入层的特征维度变得很高时,这时全连接网络需要训练的参数就会增大很...

750120
来自专栏杨熹的专栏

常用激活函数比较

本文结构: 什么是激活函数 为什么要用 都有什么 sigmoid ,ReLU, softmax 的比较 如何选择 ---- 1. 什么是激活函数 如下图,在神经...

50480

扫码关注云+社区

领取腾讯云代金券