cs231n深度学习笔记记录更新

按照网上的学习顺序:https://blog.csdn.net/mingqi1996/article/details/81279806

numpy

环境简介:

https://zhuanlan.zhihu.com/p/20878530?refer=intelligentunit

numpy的常用方法:

https://www.dataquest.io/blog/numpy-cheat-sheet/?imm_mid=0f1262&cmp=em-data-na-na-newsltr_20170426

计算机视觉概述

卷积神经网络、ImageNet

图像分类——数据驱动方法

语义鸿沟

由于计算机获取的图像的视觉信息与用户对图像理解的语义信息的不一致性而导致的低层和高层检索需求间的距离(即人对图像相似性的判别依据与计算机对相似性的判别依据之间的不同造成的)。是基于内容的图像检索CBIR ( Content-based image retrieval)系统中广泛存在的问题。

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

算法应针对视角、明暗、变形、遮挡、背景混乱、类内差异等场合均具有鲁棒性

边缘识别、特征提取的方法(易错、普适性差)

数据驱动方法

一个理解:https://blog.csdn.net/dawningblue/article/details/75119639

课程中提出的简单分类器方法实现:

1)搜集图像和标签的数据集(如从网上抓取目标图片)

2)使用机器学习训练分类器(训练机器来分类这些图片,机器会针对收集的数据集以一定的方式进行总结,生成一个模型,总结出对象的核心知识要素)

3)使用分类器对图像进行识别

最近邻分类器

如果将测试图片与训练图片集进行比较,将获得很多不同的结果,需要一种判定方法,采取最近邻分类器,即测试计算图片每个像素与训练集样本的距离,距离越小得到的结果越相近。距离衡量方式也不一样,一般可取曼哈顿距离(L1距离)。

(参见:https://blog.csdn.net/tyzttzzz/article/details/41695007

如下图:

实际测试过程由于需要每次将样本与测试目标进行比较,过程十分慢。而我们希望的是训练过程慢(在具有相当硬件条件的训练中心完成)而测试时间短(测试设备相对普遍低廉)。

图像分类——K-最近邻算法

(该文章KNN讲的很细:https://blog.csdn.net/c406495762/article/details/75172850

针对上面的最近邻分类器而言,有时候距离最近并不一定在人类视觉中就是类似的个体,而且与其距离相对较近的训练集中也可能有多个测试图片的同类。于是可以选择多个相近的实例,这些实例中,大多数属于哪个类,可以判定测试图片属于那个类。

可以看出适当增大K值,可以避免噪声带来的干扰和边界处对个别数据过分敏感。

容易出现的问题:

a)K取值过大,临近点选取过多,导致判断出现误差。

b)K选取过小,出现过拟合。

改进:距离标准选择

除了选用L1距离,还可选择L2距离,即欧式距离。一般而言欧氏距离更加自然,但是由于两种衡量标准不同,构造空间的结构也不一样,有时候L1距离更适合(曼哈顿距离是坐标绝对值的和,空间中是正方形,而L2距离是圆)

<最好是两种方法均进行尝试>

此外,还可以对距离进行加权等。参见:https://blog.csdn.net/tyzttzzz/article/details/41695007

评估方法

将数据集随机分为三部分:训练集、验证集、测试集

1)训练集:采用不同的超参数(如上述分类器的K和距离度量)进行样本的训练,得到不同超参数的分类器

2)验证集:对训练得到的不同分类器进行验证测试,进行效果评估,遴选出表现上佳的分类器

3)测试集:将验证过程得到的效果不错的分类器,用尚未接触过全新测试集进行分类测试,得到分类器对未知数据的最终预测结果,这才是正确的结果。该过程要确保测试集的封闭性, ,否则数据不具有可信度。

另一种方法:交叉验证

适合小数据集(略);

运行时间长,验证复杂;

但是准确,能用的情况下,计算资源比较充足时,还是可以用一下的。

总结

KNN不适合图像分类:

(1)处理时间太长

(2)向量化的距离度量并不能很好反映人类视觉的图像感知差异

(3)维度灾难:需要密集分布的巨大数据去训练

用python写的KNN程序,采用L2度量训练小样本点集:https://blog.csdn.net/mingqi1996/article/details/81293314

(程序已测试,可运行2018.7.30)

图像分类——线性分类

神经网络就像是乐高玩具,将不同的模块进行组合训练得到期望的效果,如课程提到:卷积神经网络只关注图像,而循环神经网络只关注语言,将两者进行结合一块训练可以得到能够解释图片内容的系统。线性分类器就像是这些巨型网络的基础模块。

CIFAR-10 图像分类数据集——提供大量图片样本

输入x为测试图片的像素矩阵,W为权重设置,可以进行调节优化,得到的输出为不同分类的得分,如cifar-10中是32*32尺寸的图片,总计有3072(三通道)个像素点,通过一定的评价函数得将输入矩阵与权值向量计算后(最简单是相乘),得到评分,根据评分取出最为类似的分类。图中3072*10是为了得到最终的10*1的分数列向量而设置的权值矩阵。有时候还加上偏置项原因也是由于不同分类的特征差异,人为进行调整,比如数据集不平均,如上图说的猫比较多啊之类的。下图为例:

学习训练方法的改进技巧偏差和权重的合并

它能够将我们常用的参数Wb合二为一:

\displaystyle f(x_i,W,b)=Wx_i+b

分开处理这两个参数(权重参数W和偏差参数b)有点笨拙,一般常用的方法是把两个参数放到同一个矩阵中,同时x_i向量就要增加一个维度,这个维度的数值是常量1,这就是默认的偏差维度。这样新的公式就简化成下面这样:

\displaystyle f(x_i,W)=Wx_i

还是以CIFAR-10为例,那么x_i的大小就变成[3073x1],而不是[3072x1]了,多出了包含常量1的1个维度)。W大小就是[10x3073]了。W中多出来的这一列对应的就是偏差值b,具体见下图:

————————————————————————————————————————

偏差技巧的示意图。左边是先做矩阵乘法然后做加法,右边是将所有输入向量的维度增加1个含常量1的维度,并且在权重矩阵中增加一个偏差列,最后做一个矩阵乘法即可。左右是等价的。通过右边这样做,我们就只需要学习一个权重矩阵,而不用去学习两个分别装着权重和偏差的矩阵了。

线性分类器的理解

(1)从模板匹配的观点理解线性分类器:

上图中权重矩阵是3*4的,即有三个类,四个元素,可以认为每四个像素构成一个类,线性分类器按照这三个类作为模板对图像进行匹配,得到测试集的最佳匹配结果。如下图是一个训练好的分类器,将权值矩阵10*(32*32)的每行像素提取出来,并且将其还原成32*32的原图幅,可以得到如下结果:

可以看出每行元素构成的类只能通过大量训练学习到一个模板,通过该模板对测试集进行该模板匹配度的打分!(相比KNN每张图片的比较效率高了很多,当然,训练时间还是很长,但是没关系,重点是:测试时间大大缩短!)

(2)从图像的观点理解线性分类器:

把每张图像想象成高维空间的一个点,线性分类器相当于在这些点中划线区分不同的类,经过不断的训练,划出的线越来越精确地根据训练集来区分图片的类,从而可以对测试集进行正确分类。

线性分类器有很大的局限,其仅仅是进行空域的划分,而很多情况不是一个平面或者一条直线就能简单分割的,如下图:

补充:https://zhuanlan.zhihu.com/p/20918580?refer=intelligentunit

图像数据预处理

在上面的例子中,所有图像都是使用的原始像素值(从0到255)。在机器学习中,对于输入的特征做归一化(normalization)处理是常见的套路。而在图像分类的例子中,图像上的每个像素可以看做一个特征。在实践中,对每个特征减去平均值来中心化数据是非常重要的。在这些图片的例子中,该步骤意味着根据训练集中所有的图像计算出一个平均图像值,然后每个图像都减去这个平均值,这样图像的像素值就大约分布在[-127, 127]之间了。下一个常见步骤是,让所有数值分布的区间变为[-1, 1]。零均值的中心化是很重要的,等我们理解了梯度下降后再来详细解释。

损失函数和优化

损失函数(Loss Function)

上个部分中的线性分类器有一个很重要的权值矩阵W,需要对它进行合理的确定才能得到期望的分类器。可以用一个函数将W作为输入,然后看一下该W下的图像得分,定量地估计该剧镇的好坏,该函数即损失函数。当评分与真实结果的差别越大,损失函数的输出也越大。

多类别SVM损失函数 / 多类支持向量机(SVM)损失函数

这个不太好直接理解,转述一下:https://zhuanlan.zhihu.com/p/20945670?refer=intelligentunit

损失函数的具体形式多种多样。首先,介绍常用的多类支持向量机(SVM)损失函数。SVM的损失函数想要SVM在正确分类上的得分始终比不正确分类上的得分高出一个边界值\Delta。我们可以把损失函数想象成一个人,这位SVM先生(或者女士)对于结果有自己的品位,如果某个结果能使得损失值更低,那么SVM就更加喜欢它。

让我们更精确一些。回忆一下,第i个数据中包含图像x_i的像素和代表正确类别的标签y_i。评分函数输入像素数据,然后通过公式f(x_i,W)来计算不同分类类别的分值。这里我们将分值简写为s。比如,针对第j个类别的得分就是第j个元素:s_j=f(x_i,W)_j。针对第i个数据的多类SVM的损失函数定义如下:


\displaystyle L_i=\sum_{j\not=y_i}max(0,s_j-s_{y_i}+\Delta)

举例:用一个例子演示公式是如何计算的。假设有3个分类,并且得到了分值s=[13,-7,11]。其中第一个类别是正确类别,即y_i=0。同时假设\Delta是10(后面会详细介绍该超参数)。上面的公式是将所有不正确分类(j\not=y_i)加起来,所以我们得到两个部分:

\displaystyle Li=max(0,-7-13+10)+max(0,11-13+10)

可以看到第一个部分结果是0,这是因为[-7-13+10]得到的是负数,经过max(0,-)函数处理后得到0。这一对类别分数和标签的损失值是0,这是因为正确分类的得分13与错误分类的得分-7的差为20,高于边界值10。而SVM只关心差距至少要大于10,更大的差值还是算作损失值为0。第二个部分计算[11-13+10]得到8。虽然正确分类的得分比不正确分类的得分要高(13>11),但是比10的边界值还是小了,分差只有2,这就是为什么损失值等于8。简而言之,SVM的损失函数想要正确分类类别y_i的分数比不正确类别分数高,而且至少要高\Delta。如果不满足这点,就开始计算损失值。

那么在这次的模型中,我们面对的是线性评分函数(f(x_i,W)=Wx_i),所以我们可以将损失函数的公式稍微改写一下:


\displaystyle L_i=\sum_{j\not=y_i}max(0,w^T_jx_i-w^T_{y_i}x_i+\Delta)

其中w_j是权重W的第j行,被变形为列向量。然而,一旦开始考虑更复杂的评分函数f公式,这样做就不是必须的了。

还必须提一下的属于是关于0的阀值:max(0,-)函数,它常被称为合页损失(hinge loss)。有时候会听到人们使用平方折叶损失SVM(即L2-SVM),它使用的是max(0,-)^2,将更强烈(平方地而不是线性地)地惩罚过界的边界值。不使用平方是更标准的版本,但是在某些数据集中,平方折叶损失会工作得更好。可以通过交叉验证来决定到底使用哪个。

上述应该是讲的最清楚的,

个人理解

损失函数是为了判断权值矩阵的有效性,也就是W和测试集图像数据运算f(w,x_i)后,得到的分数s能否有效达到分类的目的,那么对于下面损失函数:

\displaystyle L_i=\sum_{j\not=y_i}max(0,s_j-s_{y_i}+\Delta)

可以看出s_j - s_y_i有两种情况:

(1)大于0:说明该次训练得到的错误分类标签比正确标签的打分还要高,那么显然是不允许的,所以把这个值取出来进行累加到损失值中去,作为衡量该权值矩阵性能的因素。

(2)小于0:说明分类基本正确,但是提出了更严格的要求——安全距离,只有在打分结果不仅正确、而且大于一个安全距离的情况对下,才认为是分类成功的,损失值为0,否则的话也计算损失值,该损失惩罚大小取决于打分差,线性增大。这样进一步保证分类的安全性,避免偶然和噪声干扰。

注意一点是,损失函数计算的是不包括正确分类标签的全部偏差打分结果。

合页损失函数也就不难理解了,横坐标是真实分数,纵坐标是损失值,上图中取得是安全距离为1。s_j是非正确分数的打分,于是如图所展示,只有在真实分数比错误打分高出一定的范围(安全距离),才会被分类为正确标签,十分严格了,否则计算损失值进行取舍。

下为例练习:

当然,算完单个标签的损失值,还要求和平均!!!

 

正则化

往往在训练过程,机器会追求完美数据而出现如上图情景:只有蓝色点作为训练集时,他会训练出复杂的蓝色曲线模型,而实际的曲线应为绿色的,比如加入测试集绿点后,原来的模型你和结果就非常糟糕了,为了解决这个问题,一般会在损失函数中加入正则项R(w),同时引入超参数lambda进行损失值和正则项的平衡,以追求曲线的简约性,鼓励模型选择更为简单的权值矩阵。

即正则化是为了防止过拟合,提高模型泛化性能。

正则化方法:

该博客中详细列举了各种方法的原理和实现:https://www.cnblogs.com/yxwkf/p/5268577.html

该期课程不清楚的地方,知乎专栏的补充:https://zhuanlan.zhihu.com/p/20945670?refer=intelligentunit

 

Softmax损失函数

相对于SVM分类器得到的权值矩阵评价分数是不具有实际意义的,仅仅用于比较高低从而判断矩阵的性能;而softmax分类器的输出具有物理意义,和概率是相关的。

在Softmax分类器中,函数映射f(x_i;W)=Wx_i保持不变,但将这些评分值视为每个分类的未归一化的对数概率,并且将折叶损失(hinge loss)替换为交叉熵损失cross-entropy loss)。公式如下:

\displaystyle Li=-log(\frac{e^{f_{y_i}}}{\sum_je^{f_j}}) 或等价的 L_i=-f_{y_i}+log(\sum_je^{f_j})

其中函数f_j(z)=\frac{e^{z_j}}{\sum_ke^{z_k}}被称作softmax 函数:其输入值是一个向量,向量中元素为任意实数的评分值(z中的),函数对其进行压缩,输出一个向量,其中每个元素值在0到1之间,且所有元素之和为1。

理解

取幂指数运算是为了将打分结果全部化为正值,然后归一化到[0,1],可以将原来没有具体意义的分数转换为概率,在对其求取对数,因为定义域的[0,1]映射到log()函数中正好是负无穷到0,然后因为是惩罚,去一个负号,就是零到无穷,实现了损失函数的转化。在损失函数中:

我们期望的真实标签在测试集中得到准确分类,概率为1,即L_i=0,损失函数为0,而实际归一化后的概率只能是“期望”在真实标签附近

计算方法图示如下:

例子:

softmax和SVM的比较:

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

最优化方法

https://zhuanlan.zhihu.com/p/21360434?refer=intelligentunit

图像分类三大部分:评分函数-损失函数-最优化方法

损失函数可以量化某个具体权重集W的质量。而最优化的目标就是找到能够最小化损失函数值的W 。即最优化是寻找能使得损失函数值最小化的参数W的过程。

核心思想:迭代优化。认为要从整个权值选择中直接找到最有权重矩阵是非常难以至于不可能的,那么可以把问题转化为,只要下一步取优的权值矩阵使损失值相比上一个要小即可,进而通过反复迭代得到最优解,简化了计算过程。

梯度:一维空间中的斜率,当函数有多个参数的时候,梯度就是在每个维度上偏导数所形成的向量。梯度是函数值增大最快的方向,负梯度是函数值下降最快的方向(采用负梯度方向减少损失值)。这是数学上可以直接计算出的最陡峭处,从而避免了随机迭代的大量复杂计算。

步长:梯度指明了函数在哪个方向是变化率最大的,但是没有指明在这个方向上应该走多远,而这就是步长决定的。小步长下降稳定但进度慢,大步长进展快但是风险更大。采取大步长可能导致错过最优点,让损失值上升。步长(后面会称其为学习率)将会是我们在调参中最重要的超参数之一。

数值梯度法和分析梯度法:使用有限差值近似计算梯度比较简单,但缺点在于终究只是近似(因为我们对于h值是选取了一个很小的数值,但真正的梯度定义中h趋向0的极限),且耗费计算资源太多。第二个梯度计算方法是利用微分来分析,能得到计算梯度的公式(不是近似),用公式计算梯度速度很快,唯一不好的就是实现的时候容易出错。为了解决这个问题,在实际操作时常常将分析梯度法的结果和数值梯度法的结果作比较,以此来检查其实现的正确性,这个步骤叫做梯度检查

小批量数据梯度下降

神经网络介绍

反向传播

核心问题

给定函数f(x) ,其中x是输入数据的向量,需要计算函数f关于x的梯度,也就是\nabla f(x)

(对于简单的函数直接采用微积分知识进行链式法则求偏微分运算或许不难,但是对于较为复杂的函数,采用反向传播求取梯度会比较简便,而且理解该方法对于理解、实现、设计和调试神经网络非常关键。)

可视化计算步骤

(1)根据函数做出前向传播计算图,并计算各节点的输入输出

(2)各门单元将计算的回传的梯度乘以它对其的输入的局部梯度

(3)全部相乘得到函数的梯度

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

注意事项:

对前向传播变量进行缓存:在计算反向传播时,前向传播过程中得到的一些中间变量非常有用。在实际操作中,最好代码实现对于这些中间变量的缓存,这样在反向传播的时候也能用上它们。如果这样做过于困难,也可以(但是浪费计算资源)重新计算它们。

(如果输入的为矩阵形式,则需要计算雅克比矩阵,注意计算方式)

神经网络

摘:

那么该用那哪种激活函数?”用ReLU非线性函数。注意设置好学习率,或许可以监控你的网络中死亡的神经元占的比例。如果单元死亡问题困扰你,就试试Leaky ReLU或者Maxout,不要再用sigmoid了。也可以试试tanh,但是其效果应该不如ReLU或者Maxout。

命名规则。当我们说N层神经网络的时候,我们没有把输入层算入。因此,单层的神经网络就是没有隐层的(输入直接映射到输出)。

注意:层与层之间的神经元是全连接的,但是层内的神经元不连接。

输出层。和神经网络中其他层不同,输出层的神经元一般是不会有激活函数的(或者也可以认为它们有一个线性相等的激活函数)。这是因为最后的输出层大多用于表示分类评分值,因此是任意值的实数。

确定网络尺寸。用来度量神经网络的尺寸的标准主要有两个:一个是神经元的个数,另一个是参数的个数。

前向传播。全连接层的前向传播一般就是先进行一个矩阵乘法,然后加上偏置并运用激活函数。

表达能力。单层神经网络即可实现任意连续函数的逼近,但是可操作性差,因而强调多层。但是层数到4-5层后性能提升并不明显。然而卷积神经网络不同,对于一个良好的识别系统来说,深度是一个极端重要的因素(比如数十(以10为量级)个可学习的层)。对于该现象的一种解释观点是:因为图像拥有层次化结构(比如脸是由眼睛等组成,眼睛又是由边缘组成),所以多层处理对于这种数据就有直观意义。

设置层的数量和尺寸。有更多神经元的神经网络可以表达更复杂的函数。然而这既是优势也是不足,优势是可以分类更复杂的数据,不足是可能造成对训练数据的过拟合。但是提高网络泛化能力的方法很多,不能通过减少神经元层数实现,否则会出现更多的不稳定性。

猜你喜欢

转载自blog.csdn.net/mingqi1996/article/details/81280690