week 3 10/22-10/28
神经网络初步:cs231n_2018_lecture04(http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture04.pdf )
观看视频 p9 和 p10,学习反向传播算法笔记(https://zhuanlan.zhihu.com/p/21407711)
反向传播算法的数学补充(http://cs231n.stanford.edu/handouts/derivatives.pdf)
例子(http://cs231n.stanford.edu/handouts/linear-backprop.pdf)
及博客(http://colah.github.io/posts/2015-08-Backprop)
作业:
- 理解并推导反向传播算法
- 完成 assignment1 中的
softmax.ipynb
和two_layer_net.ipynb
笔记
反向传播的直观理解
反向传播是一个优美的局部过程。在整个计算线路图中,每个门单元都会得到一些输入并立即计算两个东西:1. 这个门的输出值,和2.其输出值关于输入值的局部梯度。门单元完成这两件事是完全独立的,它不需要知道计算线路中的其他细节。然而,一旦前向传播完毕,在反向传播的过程中,门单元门将最终获得整个网络的最终输出值在自己的输出值上的梯度。链式法则指出,门单元应该将回传的梯度乘以它对其的输入的局部梯度,从而得到整个网络的输出对该门单元的每个输入值的梯度。
这里对于每个输入的乘法操作是基于链式法则的。该操作让一个相对独立的门单元变成复杂计算线路中不可或缺的一部分,这个复杂计算线路可以是神经网络等。
模块化:Sigmoid例子
上面介绍的门是相对随意的。任何可微分的函数都可以看做门。可以将多个门组合成一个门,也可以根据需要将一个函数分拆成多个门。现在看看一个表达式:
在后面的课程中可以看到,这个表达式描述了一个含输入x和权重w的2维的神经元,该神经元使用了sigmoid激活函数。但是现在只是看做是一个简单的输入为x和w,输出为一个数字的函数。这个函数是由多个门组成的。除了上文介绍的加法门,乘法门,取最大值门,还有下面这4种:
其中,函数使用对输入值进行了常量的平移,将输入值扩大了常量倍。它们是加法和乘法的特例,但是这里将其看做一元门单元,因为确实需要计算常量的梯度。整个计算线路如下:
在上面的例子中可以看见一个函数操作的长链条,链条上的门都对w和x的点积结果进行操作。该函数被称为sigmoid函数。sigmoid函数关于其输入的求导是可以简化的(使用了在分子上先加后减1的技巧):
可以看到梯度计算简单了很多。举个例子,sigmoid表达式输入为1.0,则在前向传播中计算出输出为0.73。根据上面的公式,局部梯度为(1-0.73)*0.73~=0.2,和之前的计算流程比起来,现在的计算使用一个单独的简单表达式即可。
实现提示:分段反向传播。上面的代码展示了在实际操作中,为了使反向传播过程更加简洁,把向前传播分成不同的阶段将是很有帮助的。比如我们创建了一个中间变量dot,它装着w和x的点乘结果。在反向传播的时,就可以(反向地)计算出装着w和x等的梯度的对应的变量(比如ddot,dx和dw)。
本节的要点就是展示反向传播的细节过程,以及前向传播过程中,哪些函数可以被组合成门,从而可以进行简化。知道表达式中哪部分的局部梯度计算比较简洁非常有用,这样他们可以“链”在一起,让代码量更少,效率更高。
反向传播实践:分段计算
看另一个例子。假设有如下函数:
首先要说的是,这个函数完全没用,读者是不会用到它来进行梯度计算的,这里只是用来作为实践反向传播的一个例子,需要强调的是,如果对或进行微分运算,运算结束后会得到一个巨大而复杂的表达式。然而做如此复杂的运算实际上并无必要,因为我们不需要一个明确的函数来计算梯度,只需知道如何使用反向传播计算梯度即可。
回传流中的模式
一个有趣的现象是在多数情况下,反向传播中的梯度可以被很直观地解释。例如神经网络中最常用的加法、乘法和取最大值这三个门单元,它们在反向传播过程中的行为都有非常简单的解释。先看下面这个例子:
——————————————————————————————————————————
一个展示反向传播的例子。加法操作将梯度相等地分发给它的输入。取最大操作将梯度路由给更大的输入。乘法门拿取输入激活数据,对它们进行交换,然后乘以梯度。
——————————————————————————————————————————
从上例可知:
加法门单元把输出的梯度相等地分发给它所有的输入,这一行为与输入值在前向传播时的值无关。这是因为加法操作的局部梯度都是简单的+1,所以所有输入的梯度实际上就等于输出的梯度,因为乘以1.0保持不变。上例中,加法门把梯度2.00不变且相等地路由给了两个输入。
取最大值门单元对梯度做路由。和加法门不同,取最大值门将梯度转给其中一个输入,这个输入是在前向传播中值最大的那个输入。这是因为在取最大值门中,最高值的局部梯度是1.0,其余的是0。上例中,取最大值门将梯度2.00转给了z变量,因为z的值比w高,于是w的梯度保持为0。
乘法门单元相对不容易解释。它的局部梯度就是输入值,但是是相互交换之后的,然后根据链式法则乘以输出值的梯度。上例中,x的梯度是-4.00x2.00=-8.00。
非直观影响及其结果。注意一种比较特殊的情况,如果乘法门单元的其中一个输入非常小,而另一个输入非常大,那么乘法门的操作将会不是那么直观:它将会把大的梯度分配给小的输入,把小的梯度分配给大的输入。在线性分类器中,权重和输入是进行点积,这说明输入数据的大小对于权重梯度的大小有影响。例如,在计算过程中对所有输入数据样本乘以1000,那么权重的梯度将会增大1000倍,这样就必须降低学习率来弥补。这就是为什么数据预处理关系重大,它即使只是有微小变化,也会产生巨大影响。对于梯度在计算线路中是如何流动的有一个直观的理解,可以帮助读者调试网络。
反向传播算法的数学补充
1.3 雅克比:输入向量,输出向量
f: N维向量输入,M维输出。f在x处的导数,称为Jacobian,是一个M*N偏导数矩阵,写法如下:
其中x维度:N*1;dy/dx维度:M*N;y维度:M*1。dy/dx*△x 维度为:(M*N)*(N*1) = (M*1)。
2. Backpropagation with Tensors
以具体例子为例,f是一个线性层,输入是a minibatch of N vectors, each of dimension D;输出a minibatch of N vectors, each of dimension M。
即x矩阵维度:N*D,w是D*M,y = f(x,w) = x*w,维度为(N*D)*(D*M) = (N*M)。
Jacobian dy/dx矩阵是维度是:(N*M)*(N*D)。即使y的维度乘以x的维度。在神经网络中,这将会非常大,因此它几乎不可能被存储或计算。
然而,证明大多数神经网络,我们计算(dy/dx)(dL/dy)不需要明确的计算雅克比dy/dx。
我们知道,dL/dx里面的买个元素是个标量,x的部分导数如下:
Thinking one element at a time, the chain rule tells us that
其中:
即:
最终dL/dx为:
-->这个公式应该是笔误了,应该是dl/dy*wT??
最终的结果是有趣的,因为它允许我们有效的计算dL/dx,而没有使用雅可比dy/dx。
例子
---------------------
作者:Sousky
来源:CSDN
原文:https://blog.csdn.net/Sousky/article/details/83414042
版权声明:本文为博主原创文章,转载请附上博文链接!