CS231N-Lecture4 Backpropagation&Neural Network

一、概述

上一集结束之后,学到了score function,可以用SVM或者Softmax计算loss,可以在loss中增加regularization来获取更加合理的W,并且最后可以用Analytic Gradient(微积分)的方式计算loss function相对于Wgradient来更新W。如下图。

这里写图片描述

这一集讲了如何使用链式法则来反向传播gradients,来更新Wb,这个gradients反向传播的过程叫做Backpropagation

Backpropagation之后,进入了Neural Network的介绍。

二、Backpropagation

  1. Computational Graph 在计算gradient并进行backpropagate(bp)的时候,借助computational graphs(cg)可以让整个过程更加清晰(对于新手来说更是这样)。在学习的起步阶段,可以借助它来理解bp的原理。但是当神经网络复杂了之后,再转换成cg看起来就很头疼了。就像这样。 tensorboardcg可视化的一个很强大的工具。 一个computational graph是对整个神经网络的直观图形表述。 上图中,每一个矩形代表着input xW;每一个圆代表着一个操作;箭头指明了元素在这个神经网络中的流向,从输入开始,一直到最终的loss输出。 其中,圆被称为一个门gate。数据每流经一个门,都会经过相应的数学变换。
  2. bp如何实现 上图已经完成了forward pass的过程,输入从左到右,经过+,*,得到结果f。 上图中有三个输入,x,y,z;一个+ gate q;一个* gate f;最后得到输出f = 12。 红色框中,是+这个操作相对于xy的求导; 蓝色框中,是*这个操作相对于+,z的求导; bp的过程,就是将运算顺序倒过来,从cg的最右端开始,利用链式法则(Chain Rule),依次将所有前面已经计算的到的导数,和当前元素的导数相乘,就是当前元素的gradient。 从最右端开始,f相对于自身的导数是1。如下图: 继续往左运算,遇到了* gate;这个门的算式就是f = qz,蓝色框中的算式。 要求出zgradient,就是将之前已经计算出的gradient df / df = 1,与z本身的gradient相乘,即(df / df) * (df / dz)。 先求f相对于z的导数,df / dz = q; 由于q = 3,因此,zgradient df / dz = (df / df) * q = 3。 这个3意味着,z的变化对于f是正向的。如果z增加任意H个单位,那么f相应增加3H个单位。 计算结果如图。 下面计算qgradient df / dq。 蓝色框中已经写了,df / dq = z,并且z = -4。 因此,df / dq = (df / df) * z = -4。如图。 接下来计算xgradient。 根据Chain Rulexgradient df / dx = (df / dq) * (dq / dx)。 因此,df / dx = -4 * 1 = -4。如图。 点击去看Khan Academy对于Chain Rule的讲解。 以此类推,ygradient也就能计算出来了。 下图展示了bp的一个简易流程。 图中,xyfz各是一个节点,称之为node,每个node在python中是一个class。当xy流经f的时候,f这个node已经知道自身相对于xgradient了,这个gradient叫做local gradient。在这个简单的网络作forward propagate的时候,node f就再已经保存了df / dx的信息,比如,存放在变量self.local_gradient中,便于之后back propagate的时候取出来使用。 而bp的整个过程,就是最右边开始,把每个节点的local gradient拿出来,与处于该节点右边的所有节点的local gradient相乘,就是该节点的最终gradientz节点右边没有节点了,因此z节点的local gradient就是dz / dz = 1,存在self.local_gradient中。 x节点的gradient就可以根据f.local_gradient * z.local_gradient来得到。 问题:如果一个节点被多个节点使用,这个节点的gradient如何计算?如下图,如果一个节点被多个节点使用,这个节点的gradient = local gradient + sum(all_previous_gradients) 左边的节点作为输入被之后的两个节点使用,那么在back propagate的时候,右边两个节点的gradient要加起来,再乘以左边节点的local gradient才能得到左边节点最终的gardient。 下图是forward passback propagate的一个简单python实现。 在实践中,在数学允许的情况下,多个gate可以被合并成一个gate,那么之前多个gategradient的计算,可以合并到这一个gate中进行计算。如下面两张图。 上图中,所有的gradient都是一个一个依次计算的。但那是其中4gate可以合并。 上图中,蓝色框中的多个gate,可以组合成一个sigmoid gate,那么其中4个单独gategradient计算可以合并成一个sigmoid gategradient计算,其结果不变。
  3. 乐高积木 这里写图片描述 上图看的不是很清楚,大意就是,TorchGit repo中可以看到,这个框架就是一大堆神经网络的layer集合。所以,玩深度学习,玩神经网络,就像是玩乐高积木一样,把自己需要的积木块(layer)拿出来,拼接在一起,最后组成一个能完成任务的结构。 同样的情况在Caffe框架中也能看到。
  4. Gradients for vectorized code以及Vectorized operations 这一小节关于Jcobian matrix以及Vectorized operations不是很懂,还需要再查资料体会一下。 视频中说到了Jacobian matrix会是一个维度很高的matrix,实践中是不会去算出整个Jacobian matrix的。 Jacobian matrixmax()作为activation function的时候,又有一种特殊的结构,就是只有左上到右下对角线上才有值,可能是0,可能是非0,而其他值都是0。 不是很明白为什么说Vectorized operations效率很高,同时提到这个Jacobian matrix是为了什么…

三、神经网络(Neural Network)

这里讨论的神经网络和大脑的神经网络有一些联系,就是计算机神经网络借鉴了一些大脑神经元的工作原理。但是其复杂度是无法相提并论的,大脑神经元的复杂度远高于计算机神经网络。

  1. 更加复杂的神经网络 所有之前涉及的内容,是一个最简单的一层神经网络f = Wx。如下图。 下面,就可以再进一步,增加复杂度,构造一个2层神经网络 上图中,2层神经网络max activation function变成了一个hidden layer。在这个hidden layer之后,再和W2作运算,得到一个Output。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HjMwMTIK-1587400552234)(http://img.blog.csdn.net/20170518181228612?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVpc2VqaXVodWNoZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)] 上图中,hidden layer100个神经元neuron,这会使这个神经网络比起之前简单的版本要强大很多。比如说在下图中: 记得对之前简单的Linear Classification进行训练之后得到的这些模板,汽车和马的模板会出现不同的朝向和颜色问题。因为一层的神经网络不能处理不同的颜色,不同的朝向。这个问题在增加hidden layer和大量的神经元之后就能得到进一步的解决。 每个神经元neuron的作用就是细分前面输入的数据。比如说,一个神经元可以专门检测红色的,朝向前的汽车;一个神经元可以专门检测黄色的,朝向右边的汽车;以此类推。那么这个神经网络有具备了分类各种颜色和朝向汽车的能力。 在hidden layer中的每个神经元,可以看作是一个简单的Linear Classifier。多个神经元组合在一起,就可以学习很复杂的模型。 只需要通过扩展下图中的公式,就能构造层数更多,更加复杂的神经网络。 合理的数学编排,可以解决现实生活中很复杂的问题。
  2. 2层神经网络的简单Python实现 上图是Andrew Trask对2层神经网络的实现,其中用的是logistic loss,没有使用SVM或者Softmax,但是原理是一样的。
  3. 编排神经网络 经过编排的神经网络看起来是这样的,中间的hidden layer和最后的output layer被称作fully-connected layers。 问题:为什么要将神经网络编排成这个样子?像这样将神经网络组织成层是为了更高效率的计算(Vectorized operation),输入只需要按照编排好的顺序一层一层流过所有的层即可,不需要额外考虑任何的顺序等因素。
  4. 不同的neuron数量和regularization时lambda的值 hidden layer中的neuron数量,差不多就像regularization function中的lambda的值一样,被当作hyper parameter来调整。 一般来说,neuron的数量越多越好。neuron越多,这个神经网络越强大。如下图。 上图中,neuron数量越多,分类的效果越好。 但是考虑到时间成本等因素(越多的neuron训练时间相应就越长),找到一个平衡点上的neuron数量才是最好的。 另外,可以看到regularization时的lambda的值,也影响着最后的分类效果。如下图。 在当前情况下,lambda的值越小,分来效果也就越好。 点击这里去玩Andrej写的神经网络分类的Demo。

四、总结

到这里,已经知道如何进行反响传播backpropagation

知道能将神经网络编排成层。

这些层的编排,可以让vectorized operation很方便的进行。

知道了神经网络并不是大脑中的神经网络。

通常情况下,神经网络越复杂,越强大。但是复杂的神经网络意味着更长的训练时间和更小心的规范化(regularization)。