上一节课我们学习了如何使用参数化的函数定义一个分类器,有了input dataX,权重W,打分,通过一个损失函数(SVM loss或者softmax loss等)计算loss。另外损失函数可以带上正则化项,表示我们希望如何简化模型以及简化的程度。接下来的事就是如何最小化loss,利用迭代朝着负梯度方向最小化我们的loss。关于如何计算梯度,提出了两种方法,一种是数值方法,近似、很慢,一般用来验证,一种是解析方法,快速、精确。
今天我们就要学习另外一种计算任意复杂函数梯度的方法——在computational graph上使用back propagation。
back propagation
从一个简单的例子开始:
函数f的计算图如下图右边
输入时-2,5,4,绿色的是各个结点的输出。
我们将f函数拆成简单的组成部分,可以很容易得到各部分的导数:
现在我们要求的是f对x,y,z的导数,该如何求呢?
我们的做法是从计算图的末尾开始从后往前计算单个结点的导数,并把他们连接起来。
1.最末端是f对f求导,结果为1
2.然后先从简单的开始计算f对z的导数,即为q,=3
3.计算f对q的导数,为z,=-4
4.计算f对x的导数,利用求导的链式法则,我们有:f对x的导数=(f对q的导数)*(q对y导数),计算f对y的导数同理
5.计算q对x的导数,为1;q对y的导数,为1
6.连接起来,f对x的导数=-4*1=-4;f对y的导数=-4*1=-4
计算图的核心就是将一个复杂函数分解成简单函数,简单函数的导数很容易求得,这样既可以得到这个结点的梯度,我们称之为局部梯度——local gradient,然后利用链式法则将简单函数串联起来求得函数对初始变量的梯度。
接下来我们看一个复杂一点的例子:
首先,简单函数的导数我们都会计算,
这一步是easy的,然后我们要执行BP算法,
1.在末尾,f对f的导数=1
2.反函数结点的梯度,-1/(1.37)^2*1 = -0.53
3.+1结点处的梯度,1 * (-0.53) = -0.53
4.exp处的梯度,e^(-1) * (-0.53) = -0.2
5.*-1处的梯度,-1 * (-0.2) = 0.2
6.倒数第一个 + 处的梯度,导数是1,梯度还是0.2
7.f对w2的梯度可以求出来了,1 * 0.2=0.2
8.倒数第二个 + 处的梯度还是后面的梯度传播过去,=0.2
9.上面 * 结点处的梯度,对w0: -1 * 0.2 = -0.2; 对x0: 2 * 0.2 = 0.4
10.下面 * 结点处的梯度,对w1: -2 * 0.2 = -0.4; 对x1: 2 * 0.3 = 0.6
其实我们可以看出这是一个对sigmoid函数的复合函数,sigmoid函数导数我们容易求得,可以把最后的四个结点简化为一个sigmoid结点,达到简化计算图的目的:
一些BP算法里梯度传播的模式:
加: 直接传播——distributor
Max: 梯度选择——router
乘:交换——switcher
重点:我们如何计算向量化输入的梯度呢?
雅克比矩阵——一阶偏导数排列成的矩阵:
假设输入是4096维——>max(0,x)——>输出4096维
Q1:雅克比矩阵的size是?
4096*4096
很大,实际上我们并不或真去求这么大的矩阵,而是采用entire minibatch的策略
Q2:这里的雅克比矩阵结构是怎样的?
对角阵--(why?)
下面看一个例子:
首先得到各个结点的导数,
可以计算出,q结点的梯度为[0.44 0.52].T,
接下来计算q对W的导数。一个一个来,q1对W11的导数为x1=0.2,则f对W11的梯度为0.44*0.2 =0.088;q1对W12的导数为x2=0.4,则f对W12的梯度为0.44 * 0.4 = 0.176.
同理,f对W21的梯度为0.52 * 0.2=0.2 0.104,f对W21的梯度为0.52 * 0.4=0.208。
函数1()表示条件为真时=1,否则为0.
在计算的时候我们要随时检查对哪组变量的梯度的size应当与这组变量的size相同。
写成向量的形式就是
同理,f对X的导数为:
写成向量的形式
最终,
在深度学习框架中,例如caffe,其实里面就是将计算图模块化(gate --> FF/BP)来构建API的,
Neural Networks
线性score function:W1X;
2层神经网络:W2max(0,W1X);
3层神经网络:W3max(0,W2max(0,W1X))
这里需要指出一点,我们必须有一层非线性方程,才能构建复杂函数,如果都是线性函数级联,最后也只能得到一个线性分类器。
W1由于直接和X联系,因此W1可视化之后可以直观理解成类别的template,当然W21,W3…也有着某种意义。
一个两层神经网路的实现:
神经网络与生物学上的神经
强烈指出,这种模仿十分初级:
1.神经元有许多种不同的类型
2.树突可以实现非常复杂的非线性计算
3.轴突并不简单是一个权重而是一个复杂的非线性动态系统
4.神经元也并不简单的是基于比率进行判断,神经元之间的信号传递更加复杂
一些激活函数:
神经网络结构:
总结:
1.神经网络是layers之间的级联
2.layer里我们可以使用向量化的代码
3.神经网络并不真的是生物学上的神经