CS231N笔记——从KNN到反向传播
来源:互联网 发布:银河历险记3 mac 下载 编辑:程序博客网 时间:2024/05/20 21:22
图像分类中的KNN
在图像分类的任务中,最简单的方法之一是采用NN(Nearest Neighbor),即将图像分类为与其距离最近的图像所处的类别。这里的距离有多种计算方式,最常见的是L1和L2。NN可以扩展为KNN,即不仅参考距离最近的一张图像,而是参考距离最近的前K张图像,将图像分类为K张图像中出现次数最多的类别。
KNN的优点和缺点
优点:
- 算法简单,易于实现
- 无须训练,仅需存下所有的训练集用于搜索
缺点:
- 预测很耗时,需要在所有训练数据中进行搜索
- 在图像这样的高维数据面前,L1和L2距离无法准确体现相关性,比如背景相似的图片由于大量的像素点相似,会被视为同一类
调参及Cross-Validation
上文中有两处可以调试的选项,即用何种方式计算距离及K取什么值。为了确定这两个参数,需要分别尝试不同的参数组合,并在数据集上测试哪一种组合的效果最优。由于测试集是用来估计模型的泛化效果,即在新数据上可能的效果,所以不能用来调参,否则其结果不能反映泛化结果。一个简单的做法是将测试集留出一部分用来验证不同参数组合的结果。这个留出的数据集就称为验证集(Validation Set)。
当数据量较小,或需要调整的参数较多时,为了更好的估计不同参数组合的效果,往往将测试集等分为N份。在验证某一个参数组合的效果时,依次取某一份为验证集,其余为训练集,最后再取N次验证结果的平均值作为结果。这样的方法就称为Cross-Validation。
线性模型
hinge loss和cross-entropy loss
L1和L2 regularization
优化
numerical gradient和analytic gradient
反向传播是什么?
反向传播是在神经网络中,用来求损失函数的梯度的方法。由于神经网络本质上是一个复合了许多层的复杂函数,直接推导梯度的表达式十分困难。但是每一个神经元中的函数并不复杂,可以方便地推出局部的梯度。于是可以从整个网络的输出开始,每次反向取一层网络,计算出局部的梯度,再利用复合函数求导的链式法则,逐步将梯度值反向传播,直到计算出每一层权重的梯度,就可以更新权重了。
反向传播的过程
每一次反向传播都在一次正向传播之后。正向传播获取了网络的输出,用来计算损失函数的值,也用来求损失函数对输出的梯度,再开始反向传播。而且在实践中,由于许多局部梯度的计算牵涉到局部的输出,比如sigmod函数
需要注意的是,某一个变量可能作为不同神经元的输入,而计算了多次的局部梯度,应当将这些梯度都累加起来,而不要错误地用后计算出的梯度值覆盖了之前的梯度值。
向量化数据的梯度计算
上文中提到的梯度计算,实际上是针对某一个变量计算偏导,只是约定俗称的简易说法。
实际上计算真正的梯度时,是针对一组数据并行处理的。在计算向量化输出对向量化输入的梯度时,只需要注意计算出的梯度的维度一定和权重本身的维度一致,就可以知道计算梯度的表达式。因为能得到相应维度的梯度的计算表达式是唯一的。
对于一个函数求导,输入输出可能分别是标量,向量,矩阵,张量。若输入输出中某一项为标量,导数的维度则等于不为标量的一项。若输入输出都不为标量,那么导数的维度,就成了输出的维度,乘上输入的维度,这个数量是爆炸性的。以输入输出都为
而这种办法是在一个同样维度但每一维都比较简单的情况下——如每维取2,3这样的大小——试着求输出中某一个元素对输入中某一个元素的导数,然后找出这个导数的规律,规律可能与下标相关。最后根据规律直接写出该局部导数的表达式。(如何应用到3维及以上的数据?)
forward-mode differentiation和reverse-mode differentiation
Calculus on Computational Graphs: Backpropagation
在计算图中,某一个节点对两一个节点求导,可以视为在连接两个节点的所有路径上的导数相加,而每条路径上的导数是将每条边的导数相乘。
但在实际中,两个节点之间的路径可能有很多,这个时候一条条路径分别计算导数再相加的效率就低了。
这个时候forward-mode differentiaiton和reverse-mode differentiation的优势就体现出来了。这两种方法分别从起始节点和终止节点逐层推进,一步步求导,计算量就少了许多。
神经网络中reverse-mode differentiation的优势
在神经网络的实际应用中,计算导数靠reverse-mode(即反向传播),而不是forward-mode。这是因为我们需要求的,是损失函数对每一个参数的导数。在这种情况下,只需一遍反向传播,就可以获得所有的导数。但是在输出多于输入的情况下,正向传播就更有优势了。假设要求的是N个输出变量分别对1个输入的导数,如果采用反向传播,就需要N轮计算,而用正向传播只需一轮计算即可。
反向传播就这么简单吗?
反向传播本质上就是一种链式求导法则的应用,为什么这么久才被人们发现?
在反向传播提出的时候,还没有许多人研究神经网络。而且那个时候也不清楚梯度下降是否是恰当的训练方法。如果那时有人想要在神经网络上使用梯度下降的话,人们会自然而然的想说,首先你肯定会卡在局部最优解,其次要计算所有这些梯度太麻烦了。只有当人开始认真思考如何快速地计算梯度时,才有可能提出反向传播。然而大部分人根本不会认真思考这一问题,因为他们不清楚即使这个问题解决了,梯度下降真的有用吗。只有当我们已经知道了梯度下降真的有用之后,才会把反向传播视为理所当然。