Deep Learning - 2 反向传播
深度神经网络的学习基于两个关键技术:
- Stochastic Gradient Descent
- Backpropagation
利用 SGD 算法学习 Weights 和 Biases,利用 Backpropagation 算法来快速计算 Cost Function 的 Gradient 。
反向传播是一种快速的学习算法,能够让我们深入地了解改变 Weights 和 Biases 的值,是如何改变整个网络的行为的。
Weights
- $W_{jk}^{l}$表示从第 $l-1$ 层的第 k 个神经元,到第 $l$ 层的第 $j$ 个神经元的连接的权重。
Biases and Activations
- $b_j^l$ 表示第 $l$ 层第 $j$ 个神经元的 Biases
- $a_j^l$ 表示第 $l$ 层第 $j$ 个神经元的 Activations(激活值)
神经元的视角
每个神经元的激活值可以这样表示:
$$
a_j^l = \sigma \left(\sum_k w_{jk}^{l} a_{k}{l-1}+b_{j}{l}\right)
$$
层视角
通过使用矩阵:
- 每一层 $l$ 定义一个权重矩阵 $w^l$ ,$w^l$ 中的第 $j$ 行第 $k$ 列的元素就是 $w_{jk}^{l}$ 。
- $b^l$ 代表第 $l$ 层的 Biases 向量。
- 将 $\sigma$ 函数向量化,即对向量 $v$ 中的每一项,都单独地应用 $\sigma$ 函数,记为 $\sigma(v)$ 。
- $a^l$代表第 $l$ 层的神经元的激活值向量。
每层的激活值可以这样表示:
$$
a^l = \sigma ( w^l a^{l-1} + b^l )
$$
- 将权值矩阵作用于上一层的激活值
- 然后加上偏置向量
- 最后用 $\sigma$ 函数作用于这个结果
- 就得到了本层的激活值
Weighted Input
$z^l \equiv w^l a^{l-1} + b^l$ ,$z^l$ 成为对第 $l$ 层神经元激活函数的加权输入。
$$
a^l = \sigma (z^l)
$$
Cost Function 的两个假设
MSE代价函数:
$$
C = \frac{1}{2n} \sum_x ||y(x)-aL(x)||2
$$
- n是训练样本数量
- $\sum_x$是对每个独立训练样本 $x$ 求和
- $y=y(x)$ 是每个独立训练样本 $x$ 的预期输出结果
- $L$ 是神经网络的层数
- $a^L = a^L (x)$是输入为 $x$ 时网络的激活函数的输出向量
为了能够使用反向传播,我们需要对代价函数C进行两个假设。
假设一
假设代价函数能够写成这样的形式
$$
C = \frac{1}{n} \sum_x C_x
$$
- $C_x$ 是每个独立训练样本 $x$ 的代价函数。
当代价函数是MSE时,$C_x = \frac{1}{2} ||y-a||^2$ 。
假设二
假设代价函数可以写成关于神经网络输出结果的函数。
MSE代价函数满足这个要求,因为单一训练样本x的二次代价可以表示为:
$$
C = \frac{1}{2} ||y-aL||2 = \frac{1}{2} \sum_j ( y_j - a_j^L )^2
$$
因为输入的训练样本 x 是固定的,所以期望的输出 y 也是固定的。x 和 y 不是神经网络所学习的东西,我们不能通过改变 Weights 和 Biases 来修改它。
所以这里可以把 C 视为是只关于输出 $a^L$ 的函数。
Hadamard Product
反向传播会用到 Hadamard Product ,假设 s 和 t 两个向量有相同的维数
$$
( s \odot t )_j = s_j t_j
$$
其中,$s \odot t$ 表示两个向量的对应元素相乘
反向传播背后的四个基本等式
$$
\delta^L = \nabla a C \odot \sigma'(z^L) \
\delta^l = ((w{l+1})T \delta^{l+1}) \odot \sigma' (z^l) \
\frac{\partial C}{\partial b_j^l} = \delta_j^l \
\frac{\partial C}{\partial w_{jk}^l} = a_{k}^{l-1} \delta_j^l
$$
反向传播算法
输入一组训练数据
对于训练数据中的每个样本 x
计算输入层的激活函数值 $a^{x,1}$,并执行下面的步骤:
Feedforward(正向传播)
计算样本x在每一层的激活函数值 $a^{x,l}$
$$
l=2,3,\dots ,L \
z^{x,l} = w^l a^{x,l-1} + b^l \
a^{x,l} = \sigma ( z^{x,l} )
$$
输出层的误差
计算样本x在输出层的误差向量
$$
\delta^{x,L} = \nabla_a C_x \odot \sigma' ( z^{x,L} )
$$
将误差反向传播
使用输出层的误差,计算样本x在之前每一层的误差
$$
l = L-1,L-2,\dots ,2 \
\delta^{x,l} = (( w^{l+1} )^T \delta^{x,l+1} ) \odot \sigma'( z^{x,l} )
$$
Gradient Descent
使用样本x在每一层的误差,更新 Weights 和 Biases
$$
l = L,L-1,\dots,2 \
w^l \rightarrow w^l - \frac{\eta}{m} \sum_x \delta^{x,l} (a{x,l-1})T\
b^l \rightarrow b^l - \frac{\eta}{m} \sum_x \delta^{x,l}
$$
反向传播算法的实现
初始化网络
self.num_layers = len(sizes)
self.sizes = sizes
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
self.weights = [np.random.randn(y, x)
for x, y in zip(sizes[:-1], sizes[1:])]
对于5层的神经网络,初始化后 Weights 和 Biases 的结构如下
size = [748, 40, 30, 20, 10]
biases [(40, 1), (30, 1), (20, 1), (10, 1)]
weights [(40, 784), (30, 40), (20, 30), (10, 20)]
随机梯度下降
随机
def SGD(self, training_data, epochs, mini_batch_size, eta,
test_data=None):
for j in range(epochs):
# 随机打散
random.shuffle(training_data)
# 分批
mini_batches = [
training_data[k:k+mini_batch_size]
for k in range(0, n, mini_batch_size)]
for mini_batch in mini_batches:
# 使用小批样本快速学习
self.update_mini_batch(mini_batch, eta)
if test_data:
print("Epoch {} : {} / {}"
.format(j,self.evaluate(test_data),n_test));
else:
print("Epoch {} complete".format(j))
梯度下降
def update_mini_batch(self, mini_batch, eta):
# 每一层每个神经元的偏置和权值
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
for x, y in mini_batch:
# 对于每一个样本x,反向传播,计算每一层每个神经元的梯度
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
# 将样本x的误差梯度汇总到批次梯度上
nabla_b = [nb+dnb for nb, dnb
in zip(nabla_b, delta_nabla_b)]
nabla_w = [nw+dnw for nw, dnw
in zip(nabla_w, delta_nabla_w)]
# 使用批次梯度更新权值和偏置
self.weights = [w-(eta/len(mini_batch))*nw
for w, nw in zip(self.weights, nabla_w)]
self.biases = [b-(eta/len(mini_batch))*nb
for b, nb in zip(self.biases, nabla_b)]
反向传播
def backprop(self, x, y):
# 每一层的偏置向量和权值矩阵
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
# 正向传播
activation = x
activations = [x] # 样本x在每一层的激活值向量
zs = [] # 样本x在每一层的加权输入向量
# 逐层计算样本x在加权输入向量和激活值向量
for b, w in zip(self.biases, self.weights):
z = np.dot(w, activation)+b
zs.append(z)
activation = sigmoid(z)
activations.append(activation)
# 反向传播
# 计算样本x在输出层的误差和梯度
delta = self.cost_derivative(activations[-1], y) * \
sigmoid_prime(zs[-1])
nabla_b[-1] = delta
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
# 使用输出层的误差和梯度,逐层向前计算样本x在每一层的误差梯度和权值梯度
for l in range(2, self.num_layers):
z = zs[-l]
sp = sigmoid_prime(z)
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
nabla_b[-l] = delta
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
return (nabla_b, nabla_w)
反向传播算法为什么更高效
待更新
反向传播整体描述
我们对 $w_{jk}^{l}$ 作出一个小的改变$\triangle w_{jk}^l$
这个改变量会导致与它相连的神经元的输出激活值改变
然后,这个激活着会影响下一层的所有激活值
这样一层一层地,最终引起代价函数的改变,并且这个改变我们可以算出。
Deep Learning - 2 反向传播的更多相关文章
- (3)Deep Learning之神经网络和反向传播算法
往期回顾 在上一篇文章中,我们已经掌握了机器学习的基本套路,对模型.目标函数.优化算法这些概念有了一定程度的理解,而且已经会训练单个的感知器或者线性单元了.在这篇文章中,我们将把这些单独的单元按照一定 ...
- Deep Learning基础--随时间反向传播 (BackPropagation Through Time,BPTT)推导
1. 随时间反向传播BPTT(BackPropagation Through Time, BPTT) RNN(循环神经网络)是一种具有长时记忆能力的神经网络模型,被广泛用于序列标注问题.一个典型的RN ...
- Deep Learning 学习笔记(7):神经网络的求解 与 反向传播算法(Back Propagation)
反向传播算法(Back Propagation): 引言: 在逻辑回归中,我们使用梯度下降法求参数方程的最优解. 这种方法在神经网络中并不能直接使用, 因为神经网络有多层参数(最少两层),(?为何不能 ...
- Deep learning:五十一(CNN的反向求导及练习)
前言: CNN作为DL中最成功的模型之一,有必要对其更进一步研究它.虽然在前面的博文Stacked CNN简单介绍中有大概介绍过CNN的使用,不过那是有个前提的:CNN中的参数必须已提前学习好.而本文 ...
- 李宏毅机器学习笔记4:Brief Introduction of Deep Learning、Backpropagation(后向传播算法)
李宏毅老师的机器学习课程和吴恩达老师的机器学习课程都是都是ML和DL非常好的入门资料,在YouTube.网易云课堂.B站都能观看到相应的课程视频,接下来这一系列的博客我都将记录老师上课的笔记以及自己对 ...
- Deep Learning基础--CNN的反向求导及练习
前言: CNN作为DL中最成功的模型之一,有必要对其更进一步研究它.虽然在前面的博文Stacked CNN简单介绍中有大概介绍过CNN的使用,不过那是有个前提的:CNN中的参数必须已提前学习好.而本文 ...
- 【深度学习Deep Learning】资料大全
最近在学深度学习相关的东西,在网上搜集到了一些不错的资料,现在汇总一下: Free Online Books by Yoshua Bengio, Ian Goodfellow and Aaron C ...
- Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN
http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...
- Deep Learning 23:dropout理解_之读论文“Improving neural networks by preventing co-adaptation of feature detectors”
理论知识:Deep learning:四十一(Dropout简单理解).深度学习(二十二)Dropout浅层理解与实现.“Improving neural networks by preventing ...
随机推荐
- 使用webmagic爬虫对百度百科进行简单的爬取
分析要爬取的网页源码: 1.打开要分析的网页,查看源代码,找到要爬取的内容: (选择网页里的一部分右击审查元素也行) 2.导入jar包,这个就直接去网上下吧: 3.写爬虫: package com.g ...
- python(leetcode)-66加一问题
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 1: 输入 ...
- 基于Mono和VSCode打造轻量级跨平台IDE
近期Visual Studio推出Mac版本号的消息迅速在技术圈里刷屏,当project师们最喜欢的笔记本电脑Mac,邂逅地球上最强大的集成开发环境Visual Studio的时候,会碰撞出如何精 ...
- Android数据保存之SharedPreference
前言: 程序中处理的大部分问题都与数据有关,读取数据显示在UI上,读取的数据可以是本地的,也可以是网络的.保存用户数据到存储空间,可以是本地的数据库,文件等,也可以是保存到网络服务器.总之大部分的程序 ...
- salesforce lightning零基础学习(十一) Aura框架下APP构造实现
前面的一些lightning文章讲述了aura的基础知识,aura封装的常用js以及aura下的事件处理.本篇通过官方的一个superbadge来实现一个single APP的实现. superbad ...
- MySQL GTID你知多少
MySQL在5.6的版本推出了GTID复制,相比传统的复制,GTID复制对于运维更加友好,这个事务是谁产⽣,产⽣多少事务,⾮常直接的标识出来,当然GTID也有限制,对于什么是GTID可以参考我之前的文 ...
- mysql 多表删除
删除用户数据,我们就需要删除有关用户的所有数据. 主表是有数据的,其他关联表不一定有数据,我们可以用left join 来关联删除的表. eg:table1 是主表,t2,t3是关联表. SELECT ...
- Maven三种仓库的配置
转自:https://www.cnblogs.com/jack1995/p/6925879.html Maven三种仓库的配置 1 本地仓库的配置 在第一篇中我们介绍过,Maven的仓库有三类,这里不 ...
- MyBatis源码解析(五)——DataSource数据源模块之非池型数据源
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6675633.html 1 回顾 上一篇中我解说了数据源接口DataSource与数据源工厂 ...
- gops —— Go 程序诊断分析工具
GitHub: https://github.com/google/gops 一个用于列出和诊断分析系统中正在运行的 Go 程序的命令行工具 安装 go get -u github.com/googl ...