cs231n深度学习与计算机视觉结合

689 阅读8分钟

一、卷积介绍

众所周知,计算机视觉 是一个多学科融合的领域,从计算机科学到数学,从生物学到心理学,计算机视觉都有很大的用武之地:

image.png

视觉的由来与机器视觉的演变

地球诞生生命之初,谁都不知道地球是什么样子的——因为没有生物有眼睛,慢慢的,为了更好的捕食,5亿年前第一批生物进化出了最基础的视觉,又经过漫长的时间,等到人类已经可以制造出机器,最初的机器视觉物体产生了:照相机! 而后,在20世纪,计算机视觉(机器视觉)的发展空前迅速,时间来到20世纪中叶这个重要的节点,两名哈弗的学生为了了解视觉神经的处理机制,做了一个实验:将金属探针接入猫的基础视觉皮质层中(primary visual cortex,处理大量和视觉相关的工作,但是位置在后脑勺处,并且大脑中有接近50%的神经元都参与着视觉处理的过程),并记录神经元的状态,发现猫在注视照片时并不会引起神经元的活动,但是当他们在切换照片的过程中,会激活部分神经元,这是开启深度学习的一个重大发现,他们得到的结论是:视觉处理流程的第一步,是对简单的形状结构处理,如边缘,排列等,并且凭借这一发现获得了1981年的诺贝尔医学奖。

97cb7669bd9d664b403617ce0f046a1e_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

计算机视觉在这一发现之后有了突飞猛进的发展:
而现代计算机视觉领域的先驱是谁呢?是Lary Roberts在1963年的论文《Block world》,他的论文中提到边缘是决定物体形状的关键,并且解析出物体边缘的信息,属于行业内的开创性文章;

192245bcd03573ff475483b6d98c74ac_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

而后1966年,麻省理工成立人工智能研究室(MIT AI lab),使得计算机视觉成为人工智能中最为发展快速的领域;

接下来是David Marr,他在1970年的Vision一书中提出了另一个可以称之为深度学习基石的理论:视觉是分层的,并且我们可以建立一个分层的模型,将图像分为边缘结构->2.5D结构(因为物体之间是存在遮挡的,但是人类的大脑是可以分辨出来的,而且世界是三维的,但是我们的视觉成像是二维的)->3D结构,这是一个最基础但是也很抽象的视觉认知模型;

00003d89b6603d4953e2272d54329221_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

而后MIT与斯坦福分别对视觉模型进行研究,并且建立了简单的模型,MIT模型认为一切物体都是由简单的形状组成,例如圆柱体,只是观察角度不同;而斯坦福则认为物体是由简单形状构成,但是形状之间是由弹簧连接起来的;

f1bcda2ee1777c92cd8524d407c3066b_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

接下来进入90年代,计算机视觉进入彩色世界,Normalized Cut被提出用来进行图像分割,人类视觉对于图形的分类是很奇特的,而计算机却没有办法做到完美的分组,这也使得感知分组变成视觉领域最为重要的问题,即使到现在也没有得到很好的答案;

接下来计算机视觉跳入了一个新的领域:物体识别领域,1999年的物体识别与2001年的人脸检测是这一领域的两大标志性产物,这一领域也变成目前人工智能主攻的课题;

计算机视觉的崛起

接下来进入20世纪,很多的挑战比赛加速了深度学习的进程,2006-2012年的PASCAL Vsiual Object Challenge 是一个将图片进行20分类任务的挑战,比赛持续的几年分类错误率在持续下降;

c943f4232cebfe801c3b739f4fa15056_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

到了2009年,IMAGENET挑战横空出世,包含1000种类别的140万张标注图像提供给参赛者进行认知分类,而IMAGENET比赛进行的第三年,也就是2012年,卷积神经网络一举夺魁拿下当年比赛的桂冠,这也就是深度学习理论的开端,并且以后每一年的IMAGENET冠军都是卷积神经网络显示出最好的成绩;

其实早在1998年,LeCun就使用了卷积神经网络来进行了手写字的识别,而2012年冠军的AlexNet几乎是照搬的LeCun的网络,除了激活函数由Sigmoid变成了ReLU,而能够让卷积神经网络能有如此之进化的效果很大一部分程度上要归功于硬件的革新;

计算机视觉接下来的挑战

计算机视觉所要专注的问题其实远远不止物体识别,对图片进行密集标记,动作识别,识别与3D整合,这些都是深度学习面临的挑战;计算机视觉针对图像,若是可以让计算机进行“看图说话”,或者让计算机理解图片中的深层语义,这些都是计算机视觉可以达到且应该达到的目标;

深度学习有着很好的发展前景,即使目前正是深度学习的“瓶颈期”,可它在图像领域仍然走在各种方法的前列,学好深度学习,走向美好人生,我们的梦想是星辰与大海!

二、图像分类

分类图片的多变性

目前的感知分类问题最重要的就是标签与图像,通常图像都是由庞大的数字列表组成,例如一张800x600x3的图片(其中3是指颜色的三个通道,一般医学图像为单独的1个灰度通道),数值在0-255之间:

image.png

而且在现实情况下,相机在拍照过程中也会对物体进行旋转,平移,缩放,增加亮度等操作;不止如此,一些同一类别物体也会有不同的造型,姿势,或者部分被遮挡,我们在进行分类过程中要对这些问题具有很好的鲁棒性:

7747ee3e8cc1d4a7a924a573411ca381_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

图片分类器的原型

图像分类器是什么样子的呢,我们要构建一个三维空间,定义一个函数,使用算法将猫的图片输进去,得到猫的标签。但是,普通的算法很难达到,通常我们想到的是构建猫的轮廓,或者某一部分的特点:

23f54bf99d6facfabc1f494166ef0161_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

但是当给你一个其他的类别,再进行轮廓识别然后再寻找特点会使情况变得过于复杂,这时,机器学习体现了它的能力,我们可以通过训练数据训练一个分类模型,当你把一个新的测试数据带入模型中时,可以得到测试数据最接近的类别:

Machine Learning: Data-Driven Approach\

机器学习:数据驱动的方法

1.收集图像和标签的数据集。
2.使用机器学习训练分类器。
3.对新图像进行分类器的评估。

Example training set

示例训练设置

image.png

1.近邻算法分类器

1.记忆所有数据和标签

def train( images, labels):
#Machine learning机器学习
  return model

2.预测最相似的训练图像的标签

def predict(model, test_images):
#Use model to predict labels使用模型预测标签
  return test_labels

这里举一个例子:记住所有训练数据与标签,然后当测试数据预测时,计算预测数据与每一张训练数据的每一个像素的差值,然后求和,得到的数值就是两张图片的L1距离(曼哈顿距离),然后得到的那个距离最小的差值,就将测试数据分入那个类别之中,这就是一个简单的近邻算法分类器:

比较图像的距离度量Distance Metric to compare images

L1 距离:d1(I1,I2)=pI1pI2pd_1(I_1,I_2)=\sum_p|I_1^p-I_2^p|

test image 测试图像 training image训练图像 pixel-wise absolute value differences 像素绝对值差值

29535a675283e3fefb6817c186f726ab_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

但是,根据刚才的例子,可以看出测试时候的速度是非常缓慢的,如何能够提高测试速度呢(这里可以使训练速度相对的慢一些)?

2.K近邻分类器

什么是K近邻分类器呢?上面例子是将测试数据归类为最邻近训练数据的标签,为什么只用最相似的1张图片的标签来作为测试图像的标签呢?这不是很奇怪吗!是的,使用K近邻分类器就能做得更好。它的思想很简单:与其只找最相近的那1个图片的标签,我们找最相似的k个图片的标签,然后让他们针对测试图片进行投票,最后把票数最高的标签作为对测试图片的预测。所以当k=1的时候,K近邻分类器就是近邻分类器。

e7879b48e9757eee3e11b4aeb27ec02b_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

上图可以看出每个训练数据的图片区域分类情况,其中k=1时找到两个不同分类的中点来分类区域;当k增大时,分类区域由临近的k张训练数据共同决定,从直观感受上就可以看到,更高的k值可以让分类的效果更平滑,使得分类器对于异常值更有抵抗力。其中白色区域为最邻近的几个区域投票数相同,无法准确分类的区域。

除去k值,还有在近邻选择中使用L2距离(欧式距离)进行分类:

K-最近邻:距离度量

L1(曼哈顿)距离=d1(I1,I2)=pI1pI2pd_1(I_1,I_2)=\sum_p|I_1^p-I_2^p|

L2(欧几里得)距离=d1(I1,I2)=p(I1pI2p)2d_1(I_1,I_2)= \sqrt{\sum_p(I_1^p-I_2^p)^2}

3008ac7598740043ff95ca0cc18d61a4_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

k与L1、L2距离选择这两个参数就决定了分类器的泛化能力,那么如何对这两个超参数进行选择呢?需要从我们的数据入手,首先将数据分为训练数据与测试数据:

20190325132738783.png 当整个训练数据被我们用来训练并且k = 1时,整个训练数据的准确率都是100%的,这样没办法看出我们算法的表现能力,所以我们要将训练数据分为训练数据与验证数据,并且只训练训练数据,在验证数据上进行验证,以了解我们训练数据的算法泛化能力:

20190325132850253.png

再进一步,我们可以将训练数据分为x份,使每一份数据都做一次验证数据,这样我们就得到了x个准确率,取其中的平均值,就得到了当k取任意值时的准确率如何,这样再选择准确率最高时的k值,就得到了一个表现最为良好的算法:

6d45a361d393dec254b4ce586d60de91_20190325132914189.png

所得到的准确率随k的选择变化折线图如下图所示,可以看到当k取7时准确率达到最高,所以这个模型的话,取k=7可以达到效果最好的分类结果:

设置超参数 Setting Hyperparamete

image.png

虽然K近邻算法在理论上可行性很高,但是实际问题中一般不会被使用,一是因为它计算的像素之间的差值会因为物体在图像内的平移,遮盖,变色而产生很大的差别,即使还是原来的物体;另一个原因是它的计算复杂度非常之高,当检测的维度升高以后参数的个数呈指数上涨;最后一个也是最重要的原因,通过这个方法进行分类时更多注意的是背景信息(背景信息在图片中一般比物体更多),并不是我们需要的语义信息。

23f1822da64b888e88f0954d10944e7a_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

维数灾难 curse of dimensionality

image.png

线性分类器

线性分类器就是我们所认识的神经网络,要识别一个物体属于哪一种类别(假设10类),我们需要将输入图片(假设图片为32x32x3的数组,一共3072个数字)通过包含权重参数的线性变换,得到10种类别所得到的分数,让它在它的标签下的类别得到很高的分数,其他类别表现很低的分数,我们所要学习的就是这个线性变换的函数,或者准确说学习w的权重值,一般我们要在学习中加入一个偏置参数b,以让图片在分类时对它属于的标签有更大的偏置:

参数化方法:线性分类器 Parametric Approach: Linear Classifier 5c259d8ca50a3f2ab840d9400de974ca_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png


以下是一个具体例子:

将像素拉伸成列 Stretch pixels into column

176915fd02ad8e4e9d3138d323197fc8_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

上面的方法将原图的2x2个像素排列成一列,也可以直接使用矩阵相乘方法:

b2a4a10b2469cf13e7f16420fa094aaf_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

因为猫得到的分数不是很高,所以这并不是一个很好的分类器,需要重新设置w与b;下图是一个将设置权重可视化的图片,可以看出10个类别权重都有各自的特点,比如飞机的权重中蓝色通道分量高于其他分量,使得蓝色通道权重可以取得更高的分数,红色与绿色通道取得较低的分数,更容易找到在天空中的飞机:

20190325134119873.png

从几何观点来看,下图中三条颜色的线分别表示在三类分类中分数为0的位置,但是当向各自的箭头方向延伸时,那么对应类别的分数也会越来越高:

评价分类分数

接下来是针对输出结果的评价指标,看到下图种使用10个分类权重分别对三张图片得到的结果:

20190325134305255.png

三、损失函数与优化

损失函数

说到损失,损失一定要很好的体现出来使用权值而产生结果与最优结果的差值,我们将使用损失函数(Loss Function)(有时也叫代价函数Cost Function或目标函数Objective)来衡量我们对结果的不满意程度。直观地讲,当评分函数输出结果与真实结果之间差异越大,损失函数输出越大,反之越小。针对多个测试数据,损失是整体数据损失的平均值。

image.png

损失函数告诉我们当前的分类器
有多好给定一个示例数据集 (xi,yi)i=1N{(x_i,y_i)}^N_{i=1}
其中xix_i是图像,yiy_i是(整数)标签

数据集损失是示例损失的总和:

L=1NiLi(f(xi,W),yi)L=\frac{1}{N}\sum_iL_i(f(x_i,W),y_i)

多类支持向量机损失

多类SVM损失:一种两分类支持向量机的泛化,具体的损失函数如下:

Li=jyi{0ifsyisj+1sjsyi+1otherwise=jyimax(0,sjsyi+1)L_i=\sum_{j \neq y_i} \left\{\begin{matrix}0 \qquad \qquad \qquad if \quad s_{y_i}\geqslant s_j +1 \\s_j-s_{y_i}+1 \qquad otherwise \end{matrix}\right. =\sum_{j \neq y_i}max(0,s_j-s_{y_i}+1)

其中sjs_{j} 为非正确类的分数,syi s_{y_i} 为分类正确的分数,这两者的差值再加上偏置参数1的结果与0取大值,最后对所有得分结果取和,就可以得到该图片最后所得损失结果,注意不计算j=yij=y_i ,具体例子如下:

image.png 最后得到的损失为平均值:

20190325203058959.png 提出几个问题来巩固一下这个损失函数的知识:

  1. 当车辆的分数改变一些会发生什么?
    答:当某一类别的分数升高时,在最终结果上只会改变相应的很小一部分。
  2. j=yij=y_i也被记入损失时,结果会如何?
    答:结果只会增加偏置参数的值(最后平均后),一般在写程序时会直接将这一项取0,为不影响损失函数判断。
  3. 在每次结果使用平均代替相加会有什么变化?
    答:最后的损失函数表示的是此分类器的W权重设置优劣,当选择平均时,虽然最后的损失值变小了,但是这也只是在原来的结果上加了一个类别个数的倒数的系数(此例为1/3),并不会对最终的结果产生影响,我们最后想要得到的其实是使W/loss最小化。
  4. 当我们使用平方时有什么影响?即Li=jyimax(0,sjsyi+1)2L_i = \sum_{{j} \ne {y_i}}\max(0,s_j - s_{y_i} + 1)^2(公式内为j不等于yiy_i 答:说到这里必须提一下SVM损失:max(0,)max(0,−)函数,它常被称为折叶损失(hinge loss)。 有时候会听到人们使用平方折叶SVM损失(即L2-SVM),它使用的是max(0,)2max(0,-)^2,将更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好。可以通过交叉验证来决定到底使用哪个。
  5. 当在初始化权重矩阵时,w的数值都是很小的所得到的分数也是很小,约等于0,这样得到的损失是多少?
    答:是分类数减去1,因为除了正确分类本身,其他每一次max的结果都为1。
#代码实现方法
def L_i_vectorized(x, y, W):
  delta = 1.0
  scores = W.dot(x)
  margins = np.maximum(0, scores - scores[y] + delta)
  margins[y] = 0                           #将j = yi的损失设为0
  loss_i = np.sum(margins)
  return loss_i

正则化

当我发现一个权重矩阵,使得损失降为0,这个权重矩阵是唯一的吗?答案是并不是唯一的,因为可以从SVM损失函数中看出,当分类正确的数值大于其他数值时,损失为0,可是当W取λW(λ>1)时,会使各个分数都乘以λ,这样最终结果损失都为0,可是这样的λ W会使其他分类错误的的损失也相应的扩大了λ倍:

20190325205856731.png

这显然不是我们想要的,因为不同的W会使其他分类错误的误差成比例增大,那么我们可不可以对W也加一些偏好来消除其他分类所带来的模糊性?这个方法就是向损失函数添加一个正则化惩罚R ( w ) ,正则化惩罚有很多种方式,常见的有L1正则化、L2正则化、Dropout、BatchNomalization等等:

简单实例:
L2正则化:R(w)=klWk,l2R(w)=\sum_k\sum_lW^2_{k,l}
L1正则化:R(w)=klWk,lR(w)=\sum_k\sum_l|W_{k,l}|
弹性网(L1+L2):R(w)=klβWk,l2+Wk,lR(w)=\sum_k\sum_l\beta W^2_{k,l}+|W_{k,l}|

更复杂:
丢弃
批量规范化
随机深度、分数池等

这样我们的损失函数就由两部分组成:数据损失(data loss),即所有样例的的平均损失LiL_i,以及正则化损失(regularization loss)。完整公式如下所示: 20190325210452454.png 也可以将其展开:

L=1Nijyi[max(0,f(xi;W)jf(xi;W)yi+Δ)]+λklWk,l2L=\frac{1}{N}\sum_i\sum_{j \neq y_i}[max(0,f(x_i;W)_j-f(x_i;W)_{y_i}+\Delta )]+\lambda\sum_k\sum_lW_{k,l}^2

正则化是为了权衡训练损失和用于测试集的泛化损失,最常用的正则化惩罚是L 2 L2L2范式,L 2 L2L2范式通过对所有参数进行逐元素的平方加和惩罚来抑制大数值的权重,举个例子,假设输入向量 x=[1,1,1,1],两个权重向量w1=[1,0,0,0] w_1=[1,0,0,0]w2=[0.25,0.25,0.25,0.25]w_2=[0.25,0.25,0.25,0.25]。那么w1Tx=w2T=1 w^T_1x=w^T_2=1,两个权重向量都得到同样的内积,但是w1w_1 的 L2惩罚是1.0,而w24L2惩罚是0.25。因此,根据L2惩罚来看, w_24 的L2 惩罚是0.25。因此,根据 L2惩罚来看, w_2更好,因为它的正则化损失更小。从直观上来看,这是因为 更好,因为它的正则化损失更小。从直观上来看,这是因为w_2$ 的权重值更小且更分散。既然L 2 L2L2惩罚倾向于更小更分散的权重向量,这就会鼓励分类器最终将所有维度上的特征都用起来,而不是强烈依赖其中少数几个维度,这样可以防止过拟合。

Softmax分类器

Softmax分类器又被称为二元逻辑回归分类器(Multinomial Logistic Regression),与SVM分类器相比,Softmax的输出(归一化的分类概率)更加直观,并且从概率上可以解释,在Softmax分类器中,函数映射f(xi;W)=Wxif(x_i;W)=Wx_i 保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失(hinge loss)替换为交叉熵损失(cross-entropy loss)。公式如下:

Li=logP(Y=yiX=xi)L_i=-logP(Y=y_i|X=x_i)
P(Y=kX=xi)=eskjeskP(Y=k|X=x_i)=\frac{e^sk}{\sum_je^sk}

这里举一个例子便于理解:

Softmax Classifier (Multinomial Logistic Regression) Softmax分类器(多项式逻辑回归)
Want to interpret raw classifier scores as probabiliti 想要将原始分类器分数解释为概率

ef3117a653d29d570e78a22d9161b333_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

上图中因为猫与车的概率在归一化后分别为0.13与0.87, 所以可以看出它在猫这个类别的表现比较差,所以损失为-log(0.13)=2.04(一般log为以e为底,在原ppt中出现了两种情况,另一种以10为底)。

提出几个问题来巩固一下这个损失函数的知识:

  1. 损失函数的最大值与最小值为多少?

    答:最小值为0,最大值为无穷大。

  2. 在初始化时所有权重参数都很小,使得分数约等于0,最后得到的损失是多少?

    答:既然所得分数约为为0,那么他们的exp都为1,这样的到的正确分类的概率为1/分类 数,那么这个值的-log就是log(分类数)。

SVM与Softmax比较

两者在之前的权重参数计算得到的结果是相同的,只在最后评估时不同,看下一个例子:

matrix multiply + bias offset矩阵乘+偏置偏移
hinge loss (SVM)铰链损耗
cross-entropy loss (Softmax)交叉熵损失(Softmax)

78a5dd3ef3c6804886182cfc7f639b32_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png 可以看出来SVM只对分类正确项关注,而当其他分类分数上下浮动时,只要不超过浮动边界(结果不大于0),对最后结果无影响,而softmax则不同,它观测的是所有分类标签的可能性,当其他分类浮动时,结果会产生或大或小的影响。
其实正则化项会对Softmax损失结果产生很大的影响,例如: 6557675cf21d49d5af9efb93742eb62d_20190326141902775.png

这里假如WW 并不是最好的权重,而经过正则化之后变为12W\frac{1}{2}W 那么结果看起来就更加分散了:

cacd19d7938e39c04c92a8ab9637160a_20190326142255401.png

以下是整体损失示意图:

image.png

最优化

对于图像数据 xix_i ,如果基于参数集权重参数W W做出的分类预测与真实情况比较一致,那么计算出来的损失值L L 就很低。最优化是寻找能使得损失函数值最小化的权重参数W W的过程。

随机搜索

随机搜索其实就是随机尝试很多不同的权重,然后看其中哪个最好。这真的就是一个完全随机的过程,训练集中找到最好的权重W,在测试集中可能会比完全随机分类好上一些hhh。很好的比喻就是将权重看成一个盆地,你要做的就是蒙着眼睛瞎闪现(因为是随机权重),以求能闪到盆地的最低点,每闪一下你的损失就相当于该点的海拔。

跟随梯度

如果说我们找到了一个很好的权重,为什么不在这个权重上进行更新,这样不是比随机搜索更加有效吗?说干就干!针对损失在这一步长上所产生的导数,即为优化的方向,针对每一个权重因子w,每一次都随机增加或减少一小步,这样能算出因为这一小步损失值的变化,以得到梯度(数值梯度法):

df(x)dx=limh0f(x+h)f(x)h \frac{df(x)}{dx}=lim_{h \rightarrow 0}\frac{f(x+h)-f(x)}{h}

83666bbcf07f96cd97bcc863ba412ba1_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

但是这样做的缺点是太耗时,每一次更新都要算出损失,当参数太多时会很笨重;这时,微分就能很好的帮助我们,在实际操作时常常将分析梯度法的结果和数值梯度法的结果作比较,以此来检查其实现的正确性,这个步骤叫做梯度检查。

用SVM的损失函数在某个数据点上的计算来举例:

Li=j=yi[max(0,wjTxiwyiTxi+Δ)]L_i= \sum_{j'=y_i}[max(0,w_j^T x_i−w_{y_i}^Tx_i+Δ)]

可以对函数进行微分。比如,对wyiw_{y_i} 进行微分得到:

jTLi=(j=yiL(wjTxiwyiTxi+Δ>0))xi∇_j^TL_i=-(\sum_{j'=y_i}L(w_j^Tx_i-w_{y_i}^Tx_i+Δ>0))x_i

上式中L(wjTxiwyiTxi+Δ>0)L(w_j^Tx_i-w_{y_i}^Tx_i+Δ>0)表示当内部条件为真时返回1,否则返回0。

梯度下降

了解了上述所示的数值梯度法和微分梯度法之后就可以进行梯度下降操作了,梯度下降有两个重要的参数,一个是步长(学习速率),即每一次梯度下降所走的长度,另一个是正则化参数,二者平衡之后就是完整的梯度下降算法:

605bd3b75ae9f1d911f39b83343db767_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

小批量数据梯度下降法

在梯度下降时,训练数据可以达到百万级量级。如果像这样计算整个训练集,来获得仅仅一个参数的更新就太浪费了。小批量数据梯度下降(Mini-batch gradient descent):一个常用的方法是计算训练集中的小批量数据。就是深度学习中一个常说的参数:Batch,将所有数据分为很多个batch的集合,在一次梯度下降时,只针对一个batch,batch大小的选择基于你的CPU(GPU)的能力,这个小批量数据就用来实现一个参数更新:这个方法之所以效果不错,是因为训练集中的数据都是相关的。要理解这一点,可以想象一个极端情况:在ILSVRC中的120万个图像是1000张不同图片的复制(每个类别1张图片,每张图片有1200张复制)。那么显然计算这1200张复制图像的梯度就应该是一样的。对比120万张图片的数据损失的均值与只计算1000张的子集的数据损失均值时,结果应该是一样的。实际情况中,数据集肯定不会包含重复图像,那么小批量数据的梯度就是对整个数据集梯度的一个近似。因此,在实践中通过计算小批量数据的梯度可以实现更快速地收敛,并以此来进行更频繁的参数更新。

随机梯度下降法

小批量数据策略有个极端情况,那就是每个批量中只有1个数据样本,这种策略被称为随机梯度下降(Stochastic Gradient Descent 简称SGD),有时候也被称为在线梯度下降。这种策略在实际情况中相对少见,因为向量化操作的代码一次计算100个数据 比100次计算1个数据要高效很多。即使SGD在技术上是指每次使用1个数据来计算梯度,你还是会听到人们使用SGD来指代小批量数据梯度下降(或者用MGD来指代小批量数据梯度下降,而BGD来指代则相对少见)。小批量数据的大小是一个超参数,但是一般并不需要通过交叉验证来调参。它一般由存储器的限制来决定的,或者干脆设置为同样大小,比如32,64,128等。之所以使用2的指数,是因为在实际中许多向量化操作实现的时候,如果输入数据量是2的倍数,那么运算更快。

需要注意的是,目前在做项目的时候,一般意义上SGD是指代着mini-batch gradient descent的。

图像特征

之前的图像分类大多数都是人为挑选重要的特征或者有利的特征放入SVM分类中进行训练,例如比较常见的颜色特征,边缘梯度特征:

image.png

而之后的深度学习中,并不需要人为挑选特征,而是让机器去从像素开始训练,这样的特征提取更加高效,从而完成整个训练过程:

lmage features vs Convnets 图像特征与卷积神经网络

08f7b05305ebf93e8a23ee248c2fa673_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3F3ZXF3cnF3,size_16,color_FFFFFF,t_70.png

小结

损失函数作为衡量权重参数的效果函数,需要根据情况来选择,本节主要讨论了两个损失函数:

  1. 多分类SVM损失:
    Li=jyimax(0,sjsyi+1)L_i=\sum_{j \neq y_i}max(0,s_j-s_{y_i}+1)

  2. Softmax分类器:
    Li=log(eskjesk)L_i=-log(\frac{e^sk}{\sum_je^sk})

两者的比较可以看出Softmax更加关注全局分数。

最优化操作是为了寻找最优权重使损失函数最小化的过程,从随机搜索到随机梯度下降,再到后来的Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam越来越多的梯度下降算法应运而生,以后有机会要好好讨论一下这些梯度下降的优缺点(目前别人总结的都很全面了hh)