CS231n 斯坦福李飞飞视觉识别课程

本文是个人在学习《CS231n 斯坦福李飞飞视觉识别课程》的学习笔记。

第一讲:课程简介

课时1 计算机视觉概述
课时2 计算机视觉历史背景
课时3 课程后勤

选读书籍《DeepLearning》
软件包: TensorFlow, Torch, PyTorch
先修条件:Python, NumPy, 微积分, 线性代数, 计算机图像, 机器学习,
课程网站: http://cs231n.stanford.edu/(作业,资源)

第二讲:图像分类

课时4 数据驱动方法
作业一:
1.实现自己的K-最近邻分类器(KNN)
2.实现几种不同的线性分类器(SVM, Softmax)
3.实现两层神经网络分类器
(运用Python, NumPy, Matlab, 谷歌云)

数据驱动思路: 收集图片数据集->训练机器分类这些图片->机器以某种方式总结分类规则生成模型->用训练出来的模型识别新的图片

算法过程: 训练函数(接收图片和标签)->训练出模型->预测函数(接收模型和测试图片)

CIFAR-10数据集(5万张训练数据图平均分成10个不同类别, 1万张额外测试图片)

L1距离(曼哈顿距离): 用来比较两幅图像,每一个对应像素的差值的绝对值的总和
在这里插入图片描述
最近邻算法思路: 训练函数->训练出模型->预测函数(用L1距离比较测试图片与哪幅训练图片最接近,即将测试图片归为该训练图片的类别)

K-最近邻算法思路(KNN): 不只寻找最近的点(这里的点代表数据),而是找最近的K个点,然后这些点当中同一类别最多的点获胜,即将该区域归为这类点的类别.少数服从多数)
当我们使用最近邻分类器时,我们总会给K赋一个比较大的值,这样会使决策边界更加平滑,从而得到更好的结果.对于没有最近点的区域可大胆将其归为周围的某一个类别.

课时5 k-最近邻算法
L2距离(欧式距离): 取平方和的平方根
L1距离取决于所选择的坐标系, 当我们转动坐标轴,将会改变点之间的L1距离, 而改变坐标轴对L2距离毫无影响.
在这里插入图片描述
超参数(hyperparameters): 像K值和距离函数这种无法通过训练得到,而是需要提前设定好的量称为超参数.
我们需要选取恰当的K值和距离函数来获得好的效果, 一般地,当特征向量的各个元素有着实际的意义,选用L1距离可能好一些,相反如果没有具体的实际意义选用L2距离可能好一些.但是超参数的选择因具体问题和数据而异.所以最佳方法是多种选择都尝试一下,然后选取效果更好的一种.

如何选取超参数:
方法1: 将数据集分为3组,大部分作为训练集,然后是验证集和测试集.
一般做法:在训练集上用不同超参训练算法,在验证集上进行评估,选择在验证集上表现的最好的一组超参的分类器,在测试集上跑,所获得的的数据才是要写到论文中的数据.(这种方法能让我们知道我们的算法在未知的新数据上表现如何)
方法2:(交叉验证) (在小数据集中更常用,在深度学习中不常用)
和方法1一样,首先将数据集中的一部分留作测试集,但是剩下的部分不是分为训练集和验证集,而是分成很多份,轮流将每一份当做验证集,剩下的部分作为训练集来,以此来看哪一组超参数的效果更好.
在这里插入图片描述
训练集,验证集,测试集的区别: 训练集训练出来模型, 然后对验证集分类,通过验证集原始的标签和被分类的类别是否一致来计算分类器的准确率,最后选取准确率最高的分类器来对测试集分类.

KNN的缺点: (在图像分类中很少用到的原因)

  1. 测试时运算时间很长
  2. L1距离和L2距离在比较图像上不太合适
  3. 维度灾难

课时6 线性分类I (Linear Classification)
f(x,W)=Wx+b
x是输入数据(输入矩阵)
W是参数或权重(权重矩阵/参数矩阵),通过训练过程得到.
b是一个偏置向,它不与训练数据交互,给出数据独立的偏好值,仅仅针对一类的偏好值.

过程: 拿到一张图片->将其拉伸成一个长的向量(一个三维长向量(32,32,3):表示高度和宽度都是32像素,3则代表颜色通道红绿蓝(RGB))->把这个代表图片像素的列向量当做输入x, 和W共同带入公式转化成10个数字评分(这10个数字对应CIFAR-10里的各个分类的得分)->哪一种类得分最高就将图片归为哪一类.

第三讲:损失函数和优化

课时7 损失函数

损失函数的引入: 课时6线性分类过程中我们得到不同W下的10个数字评分,如果用肉眼观察我们可以看出哪些W得出的评分效果更好,但是为了节约时间和精力我们不想用肉眼来看,我们想要写一个函数来自动决定哪些W是最优的,这个函数就是损失函数.
损失函数的使用: 把W当做输入,然后看一下分数,定量地估计W的好坏.
优化: 在损失函数定量分析出哪些W是好的情况下,我们要找一种有效的方式,来从W的可行域里找到W取什么值,是最不坏的情况,这个过程是一个优化过程.

损失函数公式:
在这里插入图片描述
N: N个样本
x: 输入,在图像分类里是图片每个像素点所构成的数据集
y: 我们希望算法预测出来的东西,通常称为标签或目标,比如在图像分类里我们如果用CIFAR-10, y的取值范围就是10个数,代表CIFAR-10里的10个类别.
f: 预测函数, 给出预测的分数
Li: 损失函数, 通过函数f给出的预测分数和目标y比较之后可以定量地描述训练样本预测的好不好.
L: 最终的损失函数,在整个数据集N个样本的损失函数总和的平均.

多分类SVM损失函数:

对单个样本的损失函数Li的计算方式:
在这里插入图片描述
yi: 真实的分类
Syi: 正确分类的分数, 训练集的第i个样本的真实分类的分数
Sj: 错误分类的分数

基本思路: 除了真实的分类yi以外,我们对所有的分类y的损失都做加和,也就是说我们在所有错误的分类上将损失做和.
具体过程: 第一种理解: 比较正确分类的分数和错误分类的分数,如果正确分类的分数比错误分类的分数高出某个安全的边距(我们把这个边际设为1),那么损失为0; 否则,损失为Sj-Syi+1.  然后把每个错误分类的损失加起来就可以得到数据集中这个样本最终损失.  然后还是一样的对整个训练集取平均.
第二种理解: 用max(0, Sj-Syi+1)来直接计算损失.

在NumPy库中实现的代码片段:
在这里插入图片描述
margin[y] = 0 // 把想要跳过的那个清零

问题1: 当我们初始化这些参数并且开始从头训练,通常我们先使用一些很小的随机值来初始化W,得到的分数的结果在训练的初期倾向于呈现较小的均匀分布的值.然后问题在于如果所有的S(分类类别所得的分数)都近乎为0并且差不多相等,那么当我们使用多分类SVM损失函数时,损失函数预计会如何呢?
回答: 结论是分类的数量减去1
分析: 因为如果我们对所有不正确的类别遍历了一遍,实际上是遍历了C-1个类别(C为分类的数量), 在这些类别中的每一个的两个比较的分数Sj和Syi差不多,所以根据Sj-Syi+1就会得到一个值为1的损失项,最终所有项求和之后我们将会得到C-1.
结论用处: 当我们刚开始训练的时候,我们应该想到预期的损失函数该是多大,如果在第一次迭代的时候损失函数并不等于C-1, 意味着我们的程序可能存在bug, 需要去检查一下.

问题2: 具备损失值为0的W是不是唯一的.
回答: 不是, 2W的损失值仍然为0.

问题3: 通过损失函数我们可以得到使损失为0的多个W,怎么进一步选择更优的W呢?
回答: 引入正则项
分析: 损失函数给出的只是数据方面的损失.只能拟合训练数据,但我们更关心的是对测试数据的效果.引入正则项之后可以很好的解决这个问题,使其对测试数据的效果更好.
在这里插入图片描述
R: 正则项(回归项) λ: 超参数

一些正则化类型:
在这里插入图片描述

Softmax损失函数:
公式:在这里插入图片描述公式解释: Li=-logP

  1. P是一个概率,取值在0-1之间.

  2. 将得到的分数指数化以便结果都是正数

  3. 因为log是一个单调函数,概率最大时log值最大,然而损失函数是用来度量坏的程度,所以在前面加了一个负号.

    实例使用:
    在这里插入图片描述
    问题1: 同SVM损失函数的问题1(参看前面),
    回答: 结论是logC.
    结论用处: 所以当我们在用Softmax损失来训练一个模型时,我们应该在第一次迭代中检查损失是不是logC,如果不是,那么可能出了问题.

课时8 优化
计算梯度不同的方法:
1. 有限差分估计: 用来计算数值梯度,这个方法很慢且结果区分度不大,但是写起来很简单,我们总是可以通过这种方式得到梯度.
2. 用解析梯度计算: 计算速度很快,且精确
在实际中的策略: 我们用解析梯度计算,同时用数值梯度来检查我们的实现结果.
梯度下降(Gradient Descent):每一步都往下坡方向走,一直重复,最终将会走到最低点.
梯度下降算法:
在这里插入图片描述
(解释: 1.首先初始化W为随机值,当为真时,计算损失和梯度,然后向梯度相反的方向更新权重值,因为梯度是指向函数的最大增加方向,所以梯度减小则指向函数最大减小的方向,所以我们向梯度减小的方向前进一小步,然后一直重复,最后网络就会收敛.
2.步长是一个超参数,告诉我们每次计算梯度时在那个方向前进多少距离,这个步长也叫
学习率
,当在训练网络时,确定这一步长或学习率是我们要检查的第一个超参数,其他比如模型大小,需要多少正则化,可以晚点再做)

因为在实际情况中,在计算损失时最后进行平均的N特别大,用一般的梯度下降法效率非常低,更新一个W值我们需要等待很长时间,所以实际操作中,我们往往使用随机梯度下降.
随机梯度下降(Stochastic Gradient Descent (SGD)) : 它并非计算整个训练集的误差和梯度值,而是在每一次迭代中,选取一小部分训练样本称为minibatch(小批量),按照惯例,这里都取2的n次幂,如32,64,128是常用数字.然后我们利用这一minibatch来估算误差总和以及实际梯度.
随机梯度下降算法:
在这里插入图片描述
(解释: 为真时,随机取一些minibatch数据,评估minibatch的误差值和梯度,然后基于这一误差值的计算更新各个参数以及梯度的估计)
图像特征: 当我们拿到照片,首先计算图片的各种特征代表,例如可以计算与图片形象有关的数值,然后将不同的特征向量合到一块,得到图像的特征表述,将其作为输入源传入线性分类器,而不是将图片的原始像素传入分类器.

前面学习内容总结: (对图像进行分类的步骤)

在这里插入图片描述

  1. 用函数f定义一个分类器,函数f的参数是权重矩阵W,输入数据x并对想要分类的每个类别都输出一个对应的得分向量.
  2. 定义一个损失函数,比如SVM损失函数,表示对模型预测的不满意的程度.
  3. 定义一个总的损失函数,即L,这个L是由训练数据带来的损失结合和一个正则项得到的,正则项表示我们模型的复杂程度,为了更好地泛化,我们倾向取简单的模型.
  4. 然后为了找到与最小损失对应的参数W,我们要最小化损失函数,为了做到这一点,我们要找到L在W方向上的梯度.

第四讲:介绍神经网络

课时9 反向传播
如何计算任意复杂函数的解析梯度:
计算图: 一个框架,作用是用这类图来表示任意函数,其中图的节点表示我们要执行的每一步计算.
一旦我们能用计算图来表示一个函数,那就能用反向传播技术递归地调用链式法则来算一下计算图中每个变量的梯度.
反向传播是如何工作的?
反向传播是链式法则的递归调用.
链式法则:
在这里插入图片描述
一个例子:
在这里插入图片描述
注: 1.初始第一个反向梯度的值恒为1,因为将整个式子看成X,然后fc(x)求导为1.
2.反向传播到最前面w0*x0处时,结点为乘法结点,乘法结点对于某一输入的梯度值恰好是另一个输入的值.

Sigmoid函数:
在这里插入图片描述
注: 我们能聚合我们想要的任意节点,比如这里我们可以用Sigmoid函数来代替一系列的小结点,只要我们能写出它的本地梯度.
补充:
1.Max门:
在这里插入图片描述
梯度传回来完全赋给较大值,较小值梯度为0.

一个向量化的例子:
在这里插入图片描述
在这里插入图片描述
注:变量梯度的向量大小应该和变量向量大小一致.这在实际应用中是非常有用的完整性检查.

本节总结:
大体思路在前向传播中计算结点输出,反向传播中计算梯度。当我们使用神经网络时,它非常庞大和复杂,将所有参数的梯度公式写下来是不现实的,所以为了得到这些梯度,我们应该使用反向传播,在我们有了计算图之后反向传播就是一个链式法则的递归应用。

具体过程:通过前向传播得到计算结果,并存储所有将会在反向传播计算中用到的中间值,然后在反向传播中使用链式法则将上游梯度和本地梯度相乘,计算在输出结点方向上的梯度,然后将它传递给下一个连接的结点。


课时10 神经网络
一般来说,神经网络就是由简单函数构成的一组函数,我们用一种层次化的方式将它们堆叠在一起,形成一个更复杂的非线性函数。

小例子:
在这里插入图片描述
自己理解:W1和x先计算出一个中间值h1,然后W2和h1再计算出一个中间值h2,最后W3和h2计算出最终结果,就构成了一个简单的3层神经网络,这就是深度神经网络的由来。(W1,W2,W3分别是每一次计算时候的权重,非线性过程发生在计算出h之前)

有一种非线性机制与神经元实际的生理行为最为相似,这种非线性函数就是ReLU非线性函数。

ReLU函数:如果输入是负值则输出值为0,输入值大于0时则是一个线性函数。

几种激活函数:
在这里插入图片描述
神经网络结构:
在这里插入图片描述
我们可以认为每一个隐藏层是一个向量,一组神经元的集合,利用矩阵乘法来计算神经元的值,通过一次矩阵乘法我们得出了该层所有神经元的输出结果。

第五讲: 卷积神经网络

课时11 历史
卷积神经网络:它与常规神经网络的构想基本一致,不同的是需要训练卷积层,因为卷积层更能保留输入的空间结构。

课时12 卷积和池化
全连接层工作原理:(一个例子)
在这里插入图片描述
解释:我们有一张三维图片,32323大小,现在将所有的像素展开,得到一个3072维的向量,把向量和我们得到的权重矩阵相乘,最终得到激活值,也就是这一层的输出。

卷积层工作原理:
在这里插入图片描述
解释:
针对32323大小的三维图片,不像全连接层那样展开为一行,而是用一个553的卷积核去对图片的局部区域进行点积,通过在图片上滑动以使图片的全部区域得以覆盖,滑动的长度叫做步长

一个卷积层采用多个卷积核,每一个卷积核产生一个激活映射,从而得到多个激活映射,可以观察到这些层叠加成一个ConvNet,最后的结果是我们完成了对这组卷积核的学习。前面几层的卷积核一般代表了一些低阶的图像特征,比如边缘特征,中间层稍微复杂,比如斑点,而后面的层则代表一些高阶特征,内容比斑点更加丰富。

卷积之后输出结果的尺寸:
在这里插入图片描述
N:输入的维度 F:卷积核大小 stride: 步长

常用的卷积核大小为33, 55, 7*7等.卷积核的个数为2的次方数,如32,64,128等。

0填充:
在这里插入图片描述
为了保持输出的尺寸和输入一样大,我们在边缘处采用0填充.

填充的宽度为(F-1)/2.

问题1:针对下方例子,输出图像尺寸大小是多少?
在这里插入图片描述
问题2:针对下方例子,输出的层上一共有多少个参数?
在这里插入图片描述
其中1为偏差向那一个参数。

关于卷积的总结:

在这里插入图片描述
课时13 视觉之外的卷积神经网络

卷积核的数量就是所谓的深度。

全连接层中的每一个神经元都连接着平展后的所有输入,所以神经元是与全体输入量都发生关联。而卷积核只与图像一个局部区域发生关联。

卷积网络的结构:由卷积层,非线性层,池化层,全连接层堆叠而成。每隔几个卷积层,就会有些池化层夹在中间,还有一些非线性层(比如ReLU),最后是一个全连接层,连接所有的卷积输出,并用其获得一个最终的分值函数。

池化层的作用:
在这里插入图片描述
1.池化层做的是让所生成的表示更小更容易控制,这是为了最后有更少的参数。
2.池化层在做的是降低采样率处理(降采样)。
3.我们不会在深度方向上做池化处理,而是只做平面上的,所以输入的深度和输出的深度是一样的。

最常见的方法是最大池化法:
在这里插入图片描述
:1.对于池化层来说,我们通常设置步长使滤波器在图片上滑动的部分不重叠。
2.一般不在池化层做填零,因为池化层只做降采样。

训练卷积网络的演示程序:
http://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html

本节总结:

小卷积核和更深的网络结构是一个趋势。另一个趋势是完全弃用池化和全连接层。

典型结构:卷积,ReLU重复N次,每次做一个池化,最后来到全连接ReLU层,最后用softmax得到类别分数。

第六讲: 训练神经网络(上)

课时14 激活函数
最小批量随机梯度下降:
在这里插入图片描述
步骤:

  1. 对数据进行连续的批量抽样
  2. 通过使用计算图或神经网络将数据进行正向传播,最终得到损失值
  3. 通过整个网络的反向传播来计算梯度
  4. 使用这个梯度来更新网络中的参数或者权重

神经网络训练过程中的细节:

包括: 刚开始时如何建立神经网络,选择什么样的激活函数,怎样做数据预处理、权重初始化、正则化和梯度检查,训练中的动态变化,如何监控这个学习过程,如何选择参数的特定更新规则,怎样做超参数优化来选取最佳超参数。

激活函数:
       主要使用ReLU

数据预处理:
       主要做零均值化

如何初始化网络的权值:
       可使用Xavier方法


课时15 批量归一化

       批量归一化:

       观察学习过程:
              数据预处理,选择网络结构,初始化权值,完整性检查,开始训练(调整学习率

       怎样选择超参数(参数优化):


课时16 更好的优化

       带有动量的SGD优化法

       Nesterov动量优化法

       AdaGrad算法优化策略(通常来说,在做神经网络训练时不倾向于使用AdaGrad)

       RMSProp算法优化策略

       Adam算法优化策略:一个非常好的优化算法,用来解决任何新问题的默认算法
beta1设置为0.9 beta2设置为0.999 学习率设置为1e-3或者5e-4
无论使用什么网络框架,都从这个设定开始

设置学习率的方法:
       通常一开始先不用学习率衰减,当我们想要让神经网络开始工作,我们应该挑选一个不带学习率衰减的不错的学习率来作为开始。尝试在交叉验证中同时调学习率衰减和初始学习率。
       设置学习率的方法是:先尝试不用衰减,看看会发生什么,然后仔细观察损失曲线,看看我们希望在哪个地方开始衰减。
       使用学习率衰减的方式:刚开始时用较大的一些学习率,然后在训练的过程中逐渐衰减地越来越小。
              策略1:步长衰减。比如在第10万次迭代时,可以衰减一个因子,然后继续训练。
              策略2:指数衰减。这种是在训练时持续衰减。

模型集成


课时17 正则化

正则化: 一种可以提高单一模型效果的方法。我们在模型中加入一些成分,来防止训练集上的过拟合,从而使测试集上的效果得到提升。

Dropout: 一个在神经网络中非常非常常用的正则化方法。

Batch Normalization: 目前大多数网络使用的方法。大多数情况下,单独使用它就够了,有时当我们发现网络过拟合,如果batch normalization单独使用不太够,我们可以增加dropout或一些其他的东西。

数据增强

在各种不同的正则化中,普遍的模式是:在深度学习的训练中加入像噪声一类的随机因素,以此防止结果过拟合,然后在测试时再将噪声边缘化,使测试时消除这些随机性。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lil Wing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值