cs231n笔记阅读

学习要趁早,结果就是现在资源已经下架了

感谢https://blog.csdn.net/hwl19951007/article/details/81570225的整理

本篇文章只是个人学习的过程,划了一下重点。

目录

1125阅读图像分类{上下}

从小结:实际应用k-NN中的trick

1125线性分类{上中下}

SVM 与 Softmax的比较:

1125最优化{上下}

 1126反向传播

1127神经网络1{上下}

扫描二维码关注公众号,回复: 9356864 查看本文章

1128神经网络笔记2

数据预处理

权重初始化

损失函数

1129神经网络笔记3{上下} 

梯度检查:

(最优化之前)合理性(Sanity)检查

损失函数​

训练集与验证集准确率​

参数更新

超参数调优

1130卷积神经网络

结构概述

用来构建卷积网络的各种层

层内参数

卷积层

输出体:

参数共享:

1x1卷积

扩张卷积

汇聚层

反向传播:

把全连接层转化成卷积层

层的排列规律

层的尺寸设置规律

比较有名的几种结构:

计算上的考量


1125阅读图像分类{上下}

来源:https://zhuanlan.zhihu.com/p/20900216?refer=intelligentunit

图像分类:给出一个由被标注了分类标签的图像组成的集合,要求算法能预测没有标签的图像的分类标签,并根据算法预测准确率进行评价。

  • 简单的图像分类器:最近邻分类器(Nearest Neighbor classifier)。分类器中存在不同的超参数(比如k值或距离类型的选取),要想选取好的超参数不是一件轻而易举的事。
  • 选取超参数的正确方法是:将原始训练集分为训练集和验证集,我们在验证集上尝试不同的超参数,最后保留表现最好那个。
  • 如果训练数据量不够,使用交叉验证方法,它能帮助我们在选取最优超参数的时候减少噪音。
    如果是交叉验证集,我们就不是取1000个图像,而是将训练集平均分成5份,其中4份用来训练,1份用来验证。然后我们循环着取其中4份来训练,其中1份来验证,(轮流做验证集)最后取所有5次验证结果的平均值作为算法验证结果。
    
    实际应用。在实际情况下,人们不是很喜欢用交叉验证,主要是因为它会耗费较多的计算资源。一般直接把训练集按照50%-90%的比例分成训练集和验证集。但这也是根据具体情况来定的:如果超参数数量多,你可能就想用更大的验证集,而验证集的数量不够,那么最好还是用交叉验证吧。至于分成几份比较好,一般都是分成3、5和10份。
  • 一旦找到最优的超参数,就让算法以该参数在测试集跑且只跑一次,并根据测试结果评价算法。
    测试数据集只使用一次,即在训练完成后评价最终的模型时使用
  • 最近邻分类器能够在CIFAR-10上得到将近40%的准确率。该算法简单易实现,但需要存储所有训练数据,并且在测试的时候过于耗费计算能力。
  • 最后,我们知道了仅仅使用L1和L2范数来进行像素比较是不够的,图像更多的是按照背景和颜色被分类(白色背景的狗和青蛙被放在了一起),而不是语义主体分身。

从小结:实际应用k-NN中的trick

预处理数据:对你数据中的特征进行归一化(normalize),让其具有零平均值(zero mean)和单位方差(unit variance)。

  1. 高维数据,考虑使用降维方法,比如PCA(wiki refCS229refblog ref)或随机投影
  2. 将数据随机分入训练集和验证集。按照一般规律,70%-90% 数据作为训练集。这个比例根据算法中有多少超参数,以及这些超参数对于算法的预期影响来决定。如果需要预测的超参数很多,那么就应该使用更大的验证集来有效地估计它们。如果担心验证集数量不够,那么就尝试交叉验证方法。如果计算资源足够,使用交叉验证总是更加安全的(份数越多,效果越好,也更耗费计算资源)。
  3. 在验证集上调优,尝试足够多的k值,尝试L1和L2两种范数计算方式。
  4. 如果分类器跑得太慢,尝试使用Approximate Nearest Neighbor库(比如FLANN)来加速这个过程,其代价是降低一些准确率。
  5. 对最优的超参数做记录。记录最优参数后,是否应该让使用最优参数的算法在完整的训练集上运行并再次训练呢?因为如果把验证集重新放回到训练集中(自然训练集的数据量就又变大了),有可能最优参数又会有所变化。在实践中,不要这样做千万不要在最终的分类器中使用验证集数据,这样做会破坏对于最优参数的估计。直接使用测试集来测试用最优参数设置好的最优模型,得到测试集数据的分类准确率,并以此作为你的kNN分类器在该数据上的性能表现。

1125线性分类{上中下}

在线线性分类器操作:http://vision.stanford.edu/teaching/cs231n-demos/linear-classify/

线性分类器。原型将损失函数进行可视化,画面表现的是对于2维数据的3种类别的分类。原型在课程进度上稍微超前,展现了最优化的内容

参考来源:https://zhuanlan.zhihu.com/p/21102293?refer=intelligentunit

  • 评分函数score function:从图像像素到不同类别的分类分值的映射。在本节中,评分函数是一个基于权重W和偏差b的线性函数。
  • 与kNN分类器不同,参数方法的优势在于一旦通过训练学习到了参数,就可以将训练数据丢弃了【输入数据(xi,yi)是给定且不可改变的,但参数Wb是可控制改变的,通过设置这些参数,使得计算出来的分类分值情况和训练集中图像数据的真实类别标签相符,即目前只需要直观地让正确分类的分值比错误分类的分值高即可。】。同时该方法对于新的测试数据的预测非常快,因为只需要与权重W进行一个矩阵乘法运算。
  • 介绍了偏差技巧,让我们能够将偏差向量和权重矩阵合二为一,然后就可以只跟踪一个矩阵。
  • 定义了损失函数(介绍了SVM和Softmax线性分类器最常用的2个损失函数)。损失函数能够衡量给出的参数集与训练集数据真实类别情况之间的一致性。在损失函数的定义中可以看到,对训练集数据做出良好预测与得到一个足够低的损失值这两件事是等价的。
  • SVM 与 Softmax的比较:

  • SVM使用折叶损失(hinge loss) Softmax使用交叉熵损失(cross-entropy loss)
  • SVM分类器将数值看做是分类评分,它的损失函数鼓励正确的分类的分值比其他分类的分值高出至少一个边界值。
    Softmax分类器将这些数值看做是每个分类没有归一化的对数概率,鼓励正确分类的归一化的对数概率变高,其余的变低。

    SVM看到正确分类相较于不正确分类,已经得到了比边界值还要高的分数,它就会认为损失值是0。SVM对于数字个体的细节是不关心的:如果分数是[10, -100, -100]或者[10, 9, 9],对于SVM来说没设么不同,只要满足超过边界值等于1,那么损失值就等于0。

    softmax分类器对于分数是永远不会满意的:正确分类总能得到更高的可能性,错误分类总能得到更低的可能性,损失值总是能够更小。但是,SVM只要边界值被满足了就满意了,不会超过限制去细微地操作具体分数。

  • 这可以被看做是SVM的一种特性。举例说来,一个汽车的分类器应该把他的大量精力放在如何分辨小轿车和大卡车上,而不应该纠结于如何与青蛙进行区分,因为区分青蛙得到的评分已经足够低了。

1125最优化{上下}

最优化是寻找能使得损失函数值最小化的参数W的过程。

preview

  • 信息流的总结图例。数据集中的(x,y)是给定的。权重从一个随机数字开始,且可以改变。在前向传播时,评分函数计算出类别的分类评分并存储在向量f中。损失函数包含两个部分:数据损失和正则化损失。其中,数据损失计算的是分类评分f和实际标签y之间的差异,正则化损失只是一个关于权重的函数。在梯度下降过程中,我们计算权重的梯度(如果愿意的话,也可以计算数据上的梯度),然后使用它们来实现参数的更新。

  • 将损失函数比作了一个高维度的最优化地形,并尝试到达它的最底部。最优化的工作过程可以看做一个蒙着眼睛的徒步者希望摸索着走到山的底部。在例子中,可见SVM的损失函数是分段线性的,并且是碗状的。

  • 迭代优化的思想,从一个随机的权重开始,然后一步步地让损失值变小,直到最小。

  • 函数的梯度给出了该函数最陡峭的上升方向。介绍了利用有限的差值来近似计算梯度的方法,该方法实现简单但是效率较低(有限差值就是h,用来计算数值梯度)。

  • 参数更新需要有技巧地设置步长。也叫学习率。如果步长太小,进度稳定但是缓慢,如果步长太大,进度快但是可能有风险。(可能越过最低点导致更高的损失值。)

  • 讨论权衡了数值梯度法和分析梯度法。数值梯度法计算简单,但结果只是近似(因为我们对于h值是选取了一个很小的数值,但真正的梯度定义中h趋向0的极限)且耗费计算资源(对所有维度进行迭代,在每个维度上产生一个很小的变化h,通过观察函数值变化,计算函数在该维度上的偏导数。最后,所有的梯度存储在变量grad中。)。分析梯度法计算准确迅速但是实现容易出错,而且需要对梯度公式进行推导的数学基本功。因此,在实际中使用分析梯度法(只需要计算没有满足边界值的分类的数量(因此对损失函数产生了贡献),然后乘以xi就是梯度了。),然后使用梯度检查来检查其实现正确与否,其本质就是将分析梯度法的结果与数值梯度法的计算结果对比。

  • 梯度下降算法,它在循环中迭代地计算梯度并更新参数

  • 小批量数据梯度下降(Mini-batch gradient descent):数据集肯定不会包含重复图像,那么小批量数据的梯度就是对整个数据集梯度的一个近似。因此,在实践中通过计算小批量数据的梯度可以实现更快速地收敛,并以此来进行更频繁的参数更新。

极端情况

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

 1126反向传播

导数的意义:函数变量在某个点周围的极小区域内变化,而导数就是变量变化导致的函数在该方向上的变化率。

函数关于每个变量的导数指明了整个表达式对于该变量的敏感程度。

链式法则:引入中间变量(多个中间变量,每个都是比较简单的表达式),方便求导

# 设置输入值
x = -2; y = 5; z = -4

# 进行前向传播
q = x + y # q becomes 3
f = q * z # f becomes -12

# 进行反向传播:
# 首先回传到 f = q * z
dfdz = q # df/dz = q, 所以关于z的梯度是3
dfdq = z # df/dq = z, 所以关于q的梯度是-4
# 现在回传到q = x + y
dfdx = 1.0 * dfdq # dq/dx = 1. 这里的乘法是因为链式法则
dfdy = 1.0 * dfdq # dq/dy = 1

加法门收到了输入[-2, 5],计算输出是3。既然这个门是加法操作,那么对于两个输入的局部梯度都是+1。网络的其余部分计算出最终值为-12。在反向传播时将递归地使用链式法则,算到加法门(是乘法门的输入)的时候,知道加法门的输出的梯度是-4。如果网络如果想要输出值更高,那么可以认为它会想要加法门的输出更小一点(因为负号),而且还有一个4的倍数。继续递归并对梯度使用链式法则,加法门拿到梯度,然后把这个梯度分别乘到每个输入值的局部梯度(就是让-4乘以xy的局部梯度,x和y的局部梯度都是1,所以最终都是-4)。可以看到得到了想要的效果:如果x,y减小(它们的梯度为负),那么加法门的输出值减小,这会让乘法门的输出值增大。

因此,反向传播可以看做是门单元之间在通过梯度信号相互通信,只要让它们的输入沿着梯度方向变化,无论它们自己的输出值在何种程度上升或降低,都是为了让整个网络的输出值更高。 

知道表达式中哪部分的局部梯度计算比较简洁非常有用,这样他们可以“链”在一起,让代码量更少,效率更高。 

  • 只需要将表达式分成不同的可以求导的模块(模块可以是矩阵向量的乘法操作,或者取最大值操作,或者加法操作等),然后在反向传播中一步一步地计算梯度。

  • 加法门单元把输出的梯度相等地分发给它所有的输入,这一行为与输入值在前向传播时的值无关。这是因为加法操作的局部梯度都是简单的+1,所以所有输入的梯度实际上就等于输出的梯度,因为乘以1.0保持不变。

    取最大值门单元对梯度做路由。和加法门不同,取最大值门将梯度转给其中一个输入,这个输入是在前向传播中值最大的那个输入。这是因为在取最大值门中,最高值的局部梯度是1.0,其余的是0。上例中,取最大值门将梯度2.00转给了z变量,因为z的值比w高,于是w的梯度保持为0。

    乘法门单元相对不容易解释。它的局部梯度就是输入值,但是是相互交换之后的,然后根据链式法则乘以输出值的梯度。

1127神经网络1{上下}

  • 生物神经元的粗略模型:每个神经元都对它的输入和权重进行点积,然后加上偏差,最后使用非线性函数(或称为激活函数)。

    二分类Softmax分类器。也就是逻辑回归。因为sigmoid函数输出限定在0-1之间,所以分类器做出预测的基准是神经元的输出是否大于0.5。

    二分类SVM分类器。在神经元的输出外增加一个最大边界折叶损失(max-margin hinge loss)函数,将其训练成一个二分类的支持向量机。

    ?正则化损失从生物学角度可以看做逐渐遗忘,因为它的效果是让所有突触权重w在参数更新过程中逐渐向着0变化。

  • 激活函数,其中ReLU是最佳推荐;sigmod函数

    从完全不激活(0)到在求和后的最大频率处的完全饱和(saturated)的激活(1)。有两个主要缺点:

  1. Sigmoid函数饱和使梯度消失sigmoid神经元有一个不好的特性,就是当神经元的激活在接近0或1处时会饱和:在这些区域,梯度几乎为0。回忆一下,在反向传播的时候,这个(局部)梯度将会与整个损失函数关于该门单元输出的梯度相乘。因此,如果局部梯度非常小,那么相乘的结果也会接近零,这会有效地“杀死”梯度,几乎就有没有信号通过神经元传到权重再到数据了。还有,为了防止饱和,必须对于权重矩阵初始化特别留意。比如,如果初始化权重过大,那么大多数神经元将会饱和,导致网络就几乎不学习了。
  2. Sigmoid函数的输出不是零中心的。这导致神经网络后面层中的神经元得到的数据将不是零中心的。这一情况将影响梯度下降的运作,因为如果输入神经元的数据总是正数,那么梯度在反向传播的过程中,将会要么全部是正数,要么全部是负数。这将会导致梯度下降权重更新时出现z字型的下降。然而,可以看到整个批量的数据的梯度被加起来后,对于权重的最终更新将会有不同的正负,这样就从一定程度上减轻了这个问题。因此,该问题相对于上面的神经元饱和问题来说只是个小麻烦,没有那么严重。

tanh函数

它将实数值压缩到[-1,1]之间。和sigmoid神经元一样,它也存在饱和问题,但是和sigmoid神经元不同的是,它的输出是零中心的。

ReLU。一个关于0的阈值(如上图左侧)。优缺点:

  • 优点:对于随机梯度下降的收敛有巨大的加速作用,据称这是由它的线性,非饱和的公式导致的。
  • 优点:无耗费计算资源的操作(指数运算),简单地通过对一个矩阵进行阈值计算得到。
  • 缺点:在训练的时候,有ReLU单元神经元不会被激活的情况。举例来说,当一个很大的梯度流过ReLU的神经元的时候,可能会导致梯度更新到一种特别的状态,在这种状态下神经元将无法被其他任何数据点再次激活。如果这种情况发生,那么从此所以流过这个神经元的梯度将都变成0。也就是说,这个ReLU单元在训练中将不可逆转的死亡,因为这导致了数据多样化的丢失。例如,如果学习率设置得太高,可能会发现网络中40%的神经元都会死掉(在整个训练集中这些神经元都不会被激活)。通过合理设置学习率,这种情况的发生概率会降低。

Leaky ReLU。解决“ReLU死亡”问题。ReLU中当x<0时,函数值为0。而Leaky ReLU则是给出一个很小的负数梯度值,比如0.01。但是其效果并不是很稳定。

PReLU,把负区间上的斜率当做每个神经元中的一个参数。然而该激活函数在在不同任务中均有益处的一致性并没有特别清晰。

Maxout。对ReLU和leaky ReLU的一般化归纳,拥有ReLU单元的所有优点(线性操作和不饱和),而没有它的缺点(死亡的ReLU单元)。然而和ReLU对比,它每个神经元的参数数量增加了一倍,这就导致整体参数的数量激增。

在同一个网络中混合使用不同类型的神经元是非常少见的,虽然没有什么根本性问题来禁止这样做。

应用:用ReLU非线性函数。注意设置好学习率>Leaky ReLU或者Maxout>tanh>sigmoid

  • 介绍了神经网络,神经元通过全连接层连接,层间神经元两两相连,但是层内神经元不连接;人工神经网络(Artificial Neural Networks 缩写ANN)或者多层感知器(Multi-Layer Perceptrons 缩写MLP)当我们说N层神经网络的时候,我们没有把输入层算入。因此,单层的神经网络就是没有隐层的(输入直接映射到输出)。输出层输出数值(分类评分或者回归值)度量神经网络的尺寸的标准主要有两个:一个是神经元的个数,另一个是参数的个数
  • 分层的结构(不断重复的矩阵乘法与激活函数交织。)能够让神经网络高效地进行矩阵乘法和激活函数运算;全连接层的前向传播一般就是先进行一个矩阵乘法,然后加上偏置并运用激活函数。
  • 神经网络(拥有至少一个隐层的神经网络)是一个通用函数近似器(定义了一个由一系列函数组成的函数族,网络的权重就是每个函数的参数。但是该性质与其广泛使用无太大关系。之所以使用神经网络,是因为它们对于实际问题中的函数的公式能够某种程度上做出“正确”假设。增加层的数量和尺寸时,网络的容量上升了。即神经元们可以合作表达许多复杂函数,所以表达函数的空间增加。
  • 更大网络的优势是可以分类更复杂的数据。然而更大容量的模型一定要和更强的正则化(比如更高的权重衰减)配合,否则它们就会过拟合。(不足是可能造成对训练数据的过拟合。过拟合(Overfitting)是网络对数据中的噪声有很强的拟合能力,而没有重视数据间(假设)的潜在基本关系。)

    使用(L2正则化,dropout和输入噪音等)方法来控制过拟合比减少网络神经元数目要好得多,主要原因在于小网络更难使用梯度下降等局部方法来进行训练。应该进尽可能使用大网络,然后使用正则化技巧来控制过拟合。

1128神经网络笔记2

  • 设置数据和模型
    • 数据预处理

    • 均值减法(Mean subtraction是预处理最常用的形式。它对数据中每个独立特征减去平均值,从几何上可以理解为在每个维度上都将数据云的中心都迁移到原点。
    • 归一化(Normalization是指将数据的所有维度都归一化,使其数值范围都近似相等。两种常用方法:
    1. 先对数据做零中心化(zero-centered)处理,然后每个维度都除以其标准差。
    2. 对每个维度都做归一化,使得每个维度的最大和最小值是1和-1。

PCA和白化(Whitening先对数据进行零中心化处理,然后计算协方差矩阵,它展示了数据中的相关性结构。

  1. PCA主成分分析:特征向量是按照特征值的大小排列的,只要使用前面的小部分特征向量,丢弃掉那些包含的数据没有方差的维度(留下了数据中包含最大方差的有限个维度。)通常使用PCA降维过的数据训练线性分类器和神经网络会达到非常好的性能效果,同时还能节省时间和存储器空间。
  2. 白化:输入是特征基准上的数据,然后对每个维度除以其特征值来对数值范围进行归一化。该变换的几何解释是:如果数据服从多变量的高斯分布,那么经过白化后,数据的分布将会是一个均值为零,且协方差相等的矩阵。(可能会夸大数据中的噪声,这是因为它将所有维度都拉伸到相同的数值范围,这些维度中也包含了那些只有极少差异性(方差小)而大多是噪声的维度。可以用更强的平滑来解决)

在图像处理中,由于像素的数值范围几乎是一致的(都在0-255之间),所以进行这个额外的预处理步骤并不是很必要。

推荐的预处理操作是对数据的每个特征都进行零中心化,然后将其数值范围都归一化到[-1,1]范围之内

应该先分成训练/验证/测试集,只是从训练集中求图片平均值,然后各个集(训练/验证/测试集)中的图像再减去这个平均值。

  • 权重初始化

  1. 小随机数初始化。将权重初始化为很小的数值(但并不代表数值越小结果越好)。其思路是:如果神经元刚开始的时候是随机且不相等的,那么它们将计算出不同的更新,并将自身变成整个网络的不同部分。不能全零初始化,权重被初始化为同样的值,神经元之间就失去了不对称性的源头。
  2. 稀疏初始化(Sparse initialization将所有权重矩阵设为0,每个神经元都同下一层固定数目的神经元随机连接(其权重数值由一个小的高斯分布生成),以打破对称性。
  3. 偏置(biases)的初始化。通常将偏置初始化为0,这是因为随机小数值权重矩阵已经打破了对称性。对于ReLU非线性激活函数,有研究人员喜欢使用如0.01这样的小数值常量作为所有偏置的初始值(让所有的ReLU单元一开始就激活,这样就能保存并传播一些梯度)。

  • 批量归一化(Batch Normalization)让激活数据在训练开始前通过一个网络,网络处理数据使其服从标准高斯分布。全连接层(或者是卷积层)与激活函数之间添加一个BatchNorm层,批量归一化可以理解为在网络的每一层之前都做预处理,只是这种操作以另一种方式与网络集成在了一起。
  • 使用批量归一化。
  • 正则化(L2/L1/Maxnorm/Dropout)通过控制神经网络的容量来防止其过拟合的,是正则化强度
  1. L2通过惩罚目标函数中所有参数的平方,对于大数值的权重向量进行严厉惩罚,倾向于更加分散的权重向量(分散的小数字)。(使网络更倾向于使用所有输入特征,而不是严重依赖输入特征中某些小部分特征。)
  2. L1正则化对每个w加一个|w|,让权重向量在最优化的过程中变得稀疏(即非常接近0)。(使用L1正则化的神经元最后使用的是它们最重要的输入数据的稀疏子集,同时对于噪音输入则几乎是不变的了。)
  3. 最大范式约束(Max norm constraints)。给每个神经元中权重向量的量级设定上限,并使用投影梯度下降来确保这一约束。
  4. 随机失活(Dropout)与L1正则化,L2正则化和最大范式约束等方法互为补充。在训练的时候,随机失活的实现方法是让神经元以超参数p【一般默认设为0.5】的概率被激活或者被设置为0。(反向随机失活(inverted dropout)在训练时就进行数值范围调整,从而让前向传播在测试时保持不变。)
  • 使用L2正则化和随机失活的倒置版本。

损失函数

  • 正则化损失部分:对模型复杂程度的某种惩罚
  • 数据损失部分:衡量分类算法的预测结果(即分类评分)和真实标签结果之间的一致性。【有监督学习,对所有样本的数据损失求平均。】
  1. 分类问题:SVM和softmax【类别数目巨大要使用分层Softmax(Hierarchical Softmax)】
  2. 属性(Attribute)分类/二分类问题。假设每个样本可能有,也可能没有某个属性,而且属性之间并不相互排斥呢:一个方法:为每个属性创建一个独立的二分类的分类器。另一个方法:对每种属性训练一个独立的逻辑回归分类器。
  3. 回归问题:预测实数的值,通常是计算预测值和真实值之间的损失。然后用L2平方范式或L1范式度量差异。【使用n个独立的分类器的效果一般比使用一个回归损失要好很多。一般而言,尽量把你的输出变成二分类,然后对它们进行分类,从而变成一个分类问题。】
  4. 结构化预测(structured prediction)。标签可以是任意的结构,例如图表、树或者其他复杂物体的情况。通常,假设结构空间非常巨大,不容易进行遍历。结构化SVM背后的基本思想就是在正确的结构y和得分最高的非正确结构之间画出一个边界。【针对具体问题的特殊解决方案】

1129神经网络笔记3{上下} 

梯度检查:

  • 把解析梯度和数值计算梯度进行比较,提示、技巧和注意:
  1. 使用中心化公式。

  2. 使用相对误差来比较。差值占两个梯度绝对值的比例。

    相对误差>1e-2 通常就意味着梯度可能出错
    1e-2>相对误差>1e-4 可能有问题,但网络的深度越深,相对误差就越高
    1e-4>相对误差 对于有不可导点的目标函数是OK的。否则还是太高。
    1e-7或者更小 好结果
  3. 使用双精度。
  4. 保持在浮点数的有效范围。(通常绝对值小于1e-10就绝对让人担心)。
  5. 目标函数的不可导点(kinks)。在计算损失的过程中是可以知道不可导点有没有被越过的。在具有max(x,y)形式的函数中持续跟踪所有“赢家”的身份,就可以实现这一点。其实就是看在前向传播时,到底x和y谁更大。如果在计算f(x+h)和f(x-h)的时候,至少有一个“赢家”的身份变了,那就说明不可导点被越过了,数值梯度会不准确。
  6. 使用少量数据点。含有不可导点的损失函数(例如:因为使用了ReLU或者边缘损失等函数)的数据点越少,不可导点就越少,所以在计算有限差值近似时越过不可导点的几率就越小,还能让梯度检查更迅速高效。
  7. 谨慎设置步长h。1e-4或者1e-6,梯度检查可能就恢复正常。
  8. 在操作的特性模式中梯度检查。即使是在特定点上梯度检查成功了,也不能马上确保全局上梯度的实现都是正确的。最好让网络学习(“预热”)一小段时间,等到损失函数开始下降之后再进行梯度检查。在第一次迭代就进行梯度检查的危险就在于,不正常的边界情况掩盖了梯度没有正确实现的事实。
  9. 不要让正则化吞没数据。通常损失函数是数据损失和正则化损失的和(例如L2对权重的惩罚)。梯度主要来源于正则化部分(正则化部分的梯度表达式通常简单很多),会掩盖掉数据损失梯度的不正确实现。先关掉正则化对数据损失做单独检查,然后对正则化做单独检查。
  10. 记得关闭随机失活(dropout)和数据扩张(augmentation)。关闭网络中任何不确定的效果的操作。
  11. 检查少量的维度。在实际中,梯度可以有上百万的参数,在这种情况下只能检查其中一些维度然后假设其他维度是正确的。注意确认在所有不同的参数中都抽取一部分来梯度检查,不要随机地从向量中取维度

(最优化之前)合理性(Sanity)检查

  1. 寻找特定情况的正确损失值。在使用小参数进行初始化时,确保得到的损失值与期望一致。最好先单独检查数据损失(让正则化强度为0)。

  2. 提高正则化强度时导致损失值变大。

  3. 对小数据子集过拟合。最后也是最重要的一步,在整个数据集进行训练之前,尝试在一个很小的数据集上进行训练(比如20个数据),然后确保能到达0的损失值。(最好让正则化强度为0,不然它会阻止得到0的损失。)除非能通过这一个正常性检查,不然进行整个数据集训练是没有意义的。

损失函数

x轴通常都是表示周期(epochs)单位,该单位衡量了在训练中每个样本数据都被观察过次数的期望(一个周期意味着每个样本数据都被观察过了一次)。一般更倾向跟踪周期,这是因为迭代次数(iterations)与数据的批尺寸(batchsize)有关,而批尺寸的设置又可以是任意的。

左图展示了不同的学习率的效果。过低——线性的。高一些——几何指数下降,更高的——很快下降但不低(绿线)。这是因为最优化的“能量”太大,参数在混沌中随机震荡,不能最优化到一个很好的点上。

右图显示了一个典型的随时间变化的损失函数值——这个损失函数值曲线看起来比较合理(虽然可能学习率有点小,但是很难说),而且指出了批数据的数量可能有点太小(因为损失值的噪音很大)。损失值的震荡程度和批尺寸(batch size)有关,当批尺寸为1,震荡会相对较大。当批尺寸就是整个数据集时震荡就会最小,因为每个梯度更新都是单调地优化损失函数(除非学习率设置得过高)。

训练集与验证集准确率

  • 权重:更新比例——权重中更新值的数量和全部值的数量之间的比例,应该在1e-3左右。如果更低,说明学习率可能太小,如果更高,说明学习率可能太高
  • 每层的激活数据与梯度分布:输出网络中所有层的激活数据和梯度分布的柱状图
  • 可视化:卷积神经网络,可以将第一层的权重可视化 

参数更新

  1. 一阶(随机梯度下降)方法:沿着负梯度方向改变参数(因为梯度指向的是上升方向,但是我们通常希望最小化损失函数
  2. 动量方法,Nesterov动量方法:通过动量更新,参数向量会在任何有持续梯度的方向上增加速度。

推荐的两个更新方法是SGD+Nesterov动量方法,或者Adam方法。

  • 学习率退火(衰减学习率)随着训练进行学习率衰减。比如,在固定多少个周期后让学习率减半(1),或者当验证集准确率下降的时候:
  1. 随步数衰减:每进行几个周期(如5个周期)就根据一些因素降低学习率。
  2. 指数衰减
  3. 1/t衰减
  • 二阶方法:最优化方法(L-BFGS应用的一个巨大劣势是需要对整个训练集进行计算,耗时耗空间)
  • 逐参数适应学习率方法(Adagrad,RMSProp)
  1. Adagrad缺点是,在深度学习中单调的学习率被证明通常过于激进且过早停止学习。

  2. RMSprop非常高效,但没有公开发表,使用了度平方的滑动平均,更新不会让学习率单调变小。

  3. Adam。RMSProp的动量版,推荐的参数值eps=1e-8, beta1=0.9, beta2=0.999。作为默认的算法,完整的Adam更新算法也包含了一个偏置(bias)矫正机制,因为m,v两个矩阵初始为0,在没有完全热身之前存在偏差,需要采取一些补偿措施。

超参数调优

  1. 神经网络最常用的设置有:初始学习率。学习率衰减方式(例如一个衰减常量)。正则化强度(L2惩罚,随机失活强度)。

  2. 仆程序持续地随机设置参数然后进行最优化。

  3. 一个尺寸合理的验证集可以让代码更简单,不需要用几个数据集来交叉验证。

  4. 超参数范围。在对数尺度上进行超参数搜索。

  5. 使用随机搜索(不要用网格搜索)来搜索最优的超参数。分阶段从粗(比较宽的超参数范围训练1-5个周期)到细(窄范围训练很多个周期)地来搜索。

  6. 对于边界上的最优值要小心。在一个不好的范围内搜索超参数(比如学习率)时,可能错过更好的其他搜索范围。

  7. 从粗到细地分阶段搜索。进行粗搜索的时候,让模型训练一个周期,第二个阶段缩小的范围进行搜索,让模型运行5个周期,而最后一个阶段就在最终的范围内进行仔细搜索,运行很多次周期。

  8. 贝叶斯超参数最优化。在超参数空间中更高效的导航算法。其核心的思路是在不同超参数设置下查看算法性能时,要在探索和使用中进行合理的权衡。

  • 模型集成来获得额外的性能提高。
  1. 同一个模型,不同的初始化。
  2. 在交叉验证中发现最好的模型。
  3. 一个模型设置多个记录点。
  4. 在训练的时候跑参数的平均值。

1130卷积神经网络

链接:https://zhuanlan.zhihu.com/p/22038289?refer=intelligentunit

由神经元组成,神经元中有具有学习能力的权重和偏差。每个神经元都得到一些输入数据,进行内积运算后再进行激活函数运算。整个网络依旧是一个可导的评分函数:该函数的输入是原始的图像像素,输出是不同类别的评分。在最后一层(往往是全连接层),网络依旧有一个损失函数(比如SVM或Softmax)

在 CNN 出现之前,图像对于人工智能来说是一个难题,有2个原因:

图像需要处理的数据量太大,导致成本很高,效率很低

图像在数字化的过程中很难保留原有的特征,导致图像处理的准确率不高。

卷积神经网络的输入数据是图像,将结构调整得更加合理,CNN能够将大数据量的图片有效的降维成小数据量(并不影响结果),能够保留图片的特征,类似人类的视觉原理。

具体地,卷积层负责提取图像中的局部特征;池化层用来大幅降低参数量级(降维);全连接层类似传统神经网络的部分,用来输出想要的结果。

这使得前向传播函数实现起来更高效,并且大幅度降低了网络中参数的数量

缺点:(同神经网络)需要大量数据进行训练、训练要求很高的硬件配置、模型处于「黑箱状态」,难以理解内部机制、元参数(Metaparameter)与网络拓扑选择困难

结构概述

常规神经网络对于大尺寸图像效果不尽人意全连接方式效率低下,大量的参数也很快会导致网络过拟合。

神经元的三维排列。卷积神经网络的各层中的神经元是3维排列的:宽度、高度和深度(这里的深度指的是激活数据体的第三个维度【通道】,而不是整个网络的深度,整个网络的深度指的是网络的层数)
层中的神经元将只与前一层中的一小块区域连接,最后部分将会把全尺寸的图像压缩为包含分类评分的一个向量,向量是在深度方向排列的。

卷积神经网络的每一层都将3D的输入数据变化为神经元3D的激活数据并输出


用来构建卷积网络的各种层

卷积神经网络主要由三种类型的层构成:卷积层,汇聚(Pooling)层和全连接层(全连接层和常规神经网络中的一样)。通过将这些层叠加起来,就可以构建一个完整的卷积神经网络。

输入层-卷积层-ReLU层-汇聚层-全连接层

  • 层内参数

卷积层和全连接层(CONV/FC)对输入执行变换操作的时候,不仅会用到激活函数,还会用到很多参数(神经元的突触权值和偏差)。而ReLU层和汇聚层则是进行一个固定不变的函数操作。
卷积层和全连接层中的参数会随着梯度下降被训练,使得卷积神经网络计算出的分类评分能和训练集中的每个图像的标签吻合
计算整个滤波器和输入数据任一处的内积。当滤波器沿着输入数据的宽度和高度滑过后,会生成一个2维的激活图(activation map),激活图给出了在每个空间位置处滤波器的反应。

  • 卷积层

卷积层是构建卷积神经网络的核心层,它产生了网络中大部分的计算量。

卷积层的参数是有一些可学习的滤波器集合构成的。每个滤波器在空间上(宽度和高度)都比较小,但是深度和输入数据一致。

前向传播的时候,让每个滤波器都在输入数据的宽度和高度滑动(更精确地说是卷积),然后计算整个滤波器和输入数据任一处的内积。当滤波器沿着输入数据的宽度和高度滑过后,会生成一个2维的激活图(activation map),激活图给出了在每个空间位置处滤波器的反应。直观地来说,网络会让滤波器学习到当它看到某些类型的视觉特征时就激活

滤波器每个都会生成一个不同的二维激活图。将这些激活映射在深度方向上层叠起来就生成了输出数据。

局部连接:每个神经元只与输入数据的一个局部区域连接。该连接的空间大小叫做神经元的感受野(receptive field),它的尺寸是一个超参数(滤波器的空间尺寸 局部宽度x局部高度x输入量深度)。

卷积层中的每个神经元都只是与输入数据体的一个局部在空间上相连,但是与输入数据体的所有深度维度全部相连(所有颜色通道)。在深度方向上有多个神经元(本例中5个——即下文深度列),它们都接受输入数据的同一块区域(感受野相同)。

神经元计算权重和输入的内积,然后进行激活函数运算,只是它们的连接被限制在一个局部空间

  • 输出体:

3个超参数控制着输出数据体的尺寸:深度(depth),步长(stride)零填充(zero-padding)

  1. 深度:和使用的滤波器的数量一致,(每个滤波器在输入数据中寻找一些不同的东西),沿着深度方向排列、感受野相同的神经元集合称为深度列(depth column)或纤维(fibre)。
  2. 步长:当步长为1,滤波器每次移动1个像素。当步长为2(2以上有但少见),滤波器滑动时每次移动2个像素,会让输出数据体在空间上变小
  3. 零填充(zero-padding)的尺寸大小:将输入数据体用0在边缘处进行填充,控制输出数据体的空间尺寸(最常用的是用来保持输入数据体在空间上的尺寸,这样输入和输出的宽高都相等)。

输出数据体在空间上的尺寸可以通过输入数据体尺寸(W),卷积层中神经元的感受野尺寸(F),步长(S)和零填充的数量(P)的函数来计算。(假设输入数组的空间形状是正方形,即高度和宽度相等)输出数据体的空间尺寸为(W-F +2P)/S+1。比如输入是7x7,滤波器是3x3,步长为1,填充为0,那么就能得到一个5x5的输出。如果步长为2,输出就是3x3。

一般说来,当步长S=1时,零填充的值是P=(F-1)/2,这样就能保证输入和输出数据体有相同的空间尺寸。

步长的限制:注意这些空间排列的超参数之间是相互限制的。设定无效:结果不是整数,这就是说神经元不能整齐对称地滑过输入数据体。

  • 参数共享:

在卷积层中使用参数共享是用来控制参数的数量。

是将深度维度上一个单独的2维切片看做深度切片(depth slice)
在每个深度切片上的神经元都使用同样的权重和偏差。
【不共享就一个神经元一个权重和偏差】


在反向传播的时候,要计算每个神经元对它的权重的梯度。
共享权重的梯度:把同一个深度切片上的所有神经元对权重的梯度累加,这样,每个切片只更新一个权重集。

小结

  • 1x1卷积

1x1卷积就是在高效地进行n维点积(因为输入深度是n个通道)。实现了不同通道同一位置的信息融合,提高了网络的非线性表达;实现通道数的降维或升维;

  • 扩张卷积

让滤波器中元素之间有间隙也是可以的,这就叫做扩张。扩张卷积与正常卷积结合起来非常有用,因为在很少的层数内更快地汇集输入图片的大尺度特征。

  • 汇聚层

它的作用是逐渐降低数据体的空间尺寸,这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。汇聚层使用MAX操作,对输入数据体的每一个深度切片独立进行操作,改变它的空间尺寸。
在实践中,最大汇聚层通常只有两种形式:一种是F=3,S=2,也叫重叠汇聚(overlapping pooling),另一个更常用的是F=2,S=2。对更大感受野进行汇聚需要的汇聚尺寸也更大,而且往往对网络有破坏性。

  • 反向传播:

函数的反向传播可以简单理解为将梯度只沿最大的数回传。因此,在向前传播经过汇聚层的时候,通常会把池中最大元素的索引记录下来(有时这个也叫作道岔(switches)),这样在反向传播的时候梯度的路由就很高效。

  • 把全连接层转化成卷积层

将滤波器的尺寸设置为和输入数据体的尺寸一致了。因为只有一个单独的深度列覆盖并滑过输入数据体

使用转化后的卷积神经网络进行一次前向传播计算要高效得多,因为每次计算都在共享计算资源。

  • 层的排列规律

INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC

其中*指的是重复次数,POOL?指的是一个可选的汇聚层。其中N >=0,通常N<=3,M>=0,K>=0,通常K<3

几个小滤波器卷积层的组合比一个大滤波器卷积层好:

多个卷积层与非线性的激活层交替的结构,比单一卷积层的结构更能提取出深层的更好的特征。直观说来,最好选择带有小滤波器的卷积层组合,而不是用一个带有大的滤波器的卷积层。前者可以表达出输入数据中更多个强力特征,使用的参数也更少。【有C个通道,那么单独的7x7卷积层将会包含Cx7x7xC个参数,而3个3x3的卷积层的组合仅有3x(Cx(3x3xC))=27CxC个参数。】唯一的不足是,在进行反向传播时,中间的卷积层可能会导致占用更多的内存。

  • 层的尺寸设置规律

  1. 输入层(包含图像的)2的n次方。

  2. 卷积层应该使用小尺寸滤波器(比如3x3或最多5x5),使用步长【使用1的步长?在实际应用中,更小的步长效果更好。步长为1可以让空间维度的降采样全部由汇聚层负责,卷积层只负责对输入数据体的深度进行变换。,对输入数据进行零填充【为何使用零填充1)让卷积层的输出数据保持和输入数据在空间维度的不变,2)提高算法性能。否则,如果卷积层值进行卷积而不进行零填充,那么数据体的尺寸就会略微减小,那么图像边缘的信息就会过快地损失掉。,这样卷积层就不会改变输入数据在空间维度上的尺寸

  3. 汇聚层负责对输入数据的空间维度进行降采样。最常用的设置是用2x2感受野的最大值汇聚,步长为2。【注意这一操作将会把输入数据中75%的激活数据丢弃(因为对宽度和高度都进行了2的降采样)。】次常用的设置是使用3x3的感受野,步长为2。最大值汇聚的感受野尺寸很少有超过3的,因为汇聚操作过于激烈,易造成数据信息丢失,这通常会导致算法性能变差。

  4. 减少尺寸设置的问题:上文中所有的卷积层都能保持其输入数据的空间尺寸,汇聚层只负责对数据体从空间维度进行降采样。

    内存限制所做的妥协:因为GPU通常因为内存导致性能瓶颈,人们倾向于在网络的第一个卷积层做出妥协。例如,在第一个卷积层使用步长为2,尺寸为7x7的滤波器(比如在ZFnet中)。在AlexNet中,滤波器的尺寸的11x11,步长为4。

  • 比较有名的几种结构:

  1. LeNet: 第一个成功的卷积神经网络应用
  2. AlexNetAlexNet卷积神经网络在计算机视觉领域中受到欢迎,这个网络的结构和LeNet非常类似,但是更深更大,并且使用了层叠的卷积层来获取特征(之前通常是只用一个卷积层并且在其后马上跟着一个汇聚层)。
  3. ZF Net:它通过修改结构中的超参数来实现对AlexNet的改良,具体说来就是增加了中间卷积层的尺寸,让第一层的步长和滤波器尺寸更小。
  4. GoogLeNet:它主要的贡献就是实现了一个奠基模块,它能够显著地减少网络中参数的数量(AlexNet中有60M,该网络中只有4M)。还有,这个论文中没有使用卷积神经网络顶部使用全连接层,而是使用了一个平均汇聚,把大量不是很重要的参数都去除掉了。GoogLeNet还有几种改进的版本,最新的一个是Inception-v4
  5. VGGNet:它主要的贡献是展示出网络的深度是算法优良性能的关键部分。他们最好的网络包含了16个卷积/全连接层。网络的结构非常一致,从头到尾全部使用的是3x3的卷积和2x2的汇聚。VGGNet不好的一点是它耗费更多计算资源,并且使用了更多的参数,导致更多的内存占用(140M)。其中绝大多数的参数都是来自于第一个全连接层。后来发现这些全连接层即使被去除,对于性能也没有什么影响,这样就显著降低了参数数量。
  6. ResNet残差网络(Residual Network)使用了特殊的跳跃链接,大量使用了批量归一化(batch normalization)。这个结构同样在最后没有使用全连接层。
  • 计算上的考量

在构建卷积神经网络结构时,最大的瓶颈是内存瓶颈。大部分现代GPU的内存是3/4/6GB,最好的GPU大约有12GB的内存。要注意三种内存占用来源:

  1. 来自中间数据体尺寸:卷积神经网络中的每一层中都有激活数据体的原始数值,以及损失函数对它们的梯度(和激活数据体尺寸一致)。通常,大部分激活数据都是在网络中靠前的层中(比如第一个卷积层)。在训练时,这些数据需要放在内存中,因为反向传播的时候还会用到。但是在测试时可以让网络在测试运行时候每层都只存储当前的激活数据,然后丢弃前面层的激活数据,这样就能减少巨大的激活数据量。
  2. 来自参数尺寸:即整个网络的参数的数量,在反向传播时它们的梯度值,以及使用Adagrad或RMSProp等【momentum、】方法进行最优化时的每一步计算缓存。因此,存储参数向量的内存通常需要在参数向量的容量基础上乘以3或者更多。
  3. 卷积神经网络实现还有各种零散的内存占用,比如成批的训练数据,扩充的数据等等。

一旦对于所有这些数值的数量有了一个大略估计(包含激活数据,梯度和各种杂项),数量应该转化为以GB为计量单位。【把这个值乘以4,得到原始的字节数(因为每个浮点数占用4个字节,如果是双精度浮点数那就是占用8个字节),然后多次除以1024分别得到占用内存的KB,MB,最后是GB计量。】如果网络工作得不好,由于绝大多数的内存都是被激活数据消耗掉了,一个常用的方法是降低批尺寸(batch size)

发布了46 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36808245/article/details/103238989