Stanford curriculum cs231n学习记录(1)神经网络前期知识
一、计算机视觉历史回顾与介绍
- 边缘定义了形状,大脑对视觉信息的的处理是基于边缘与形状的。
- 视觉处理从一些简单的形状开始,而不是一个整体;视觉是分层的。
- Convolutional Neural Network (CNN) has become an important tool for object recognition
- Convolutional Neural Network (CNN) is not invented overnight
- The quest for visual intelligence goes far beyond object recognition…
- 图像分类关注图的整体是什么,物体检测表示图像中某个物体在什么地方
- 计算机视觉应用于人体动作捕捉,医疗卫生,无人驾驶,人脸识别,机器人导航,机器人抓取等方面,深海探测。
二、数据驱动的图像分类
- 挑战:照射角度、光照强度、物体形变、部分遮挡、背景混入、同类演变,需要算法具有一定的鲁棒性。
- 图像分类的尝试算法:由物体的部分到整体。
- 近邻算法
例如有500图像,10个类别的训练集,100张图像作为测试集。图像的大小是32*32,通道数目为3。
训练:
将所有的图像拉直(32*32*3=3072),则训练集形成了一个500×3072的矩阵。训练集的标签为500*1的矩阵。
测试:
测试集的每一个图片遍历,图片此时是1*3072大小,将其与训练集形成500*3072矩阵的每一行进行减法求绝对值然后相加的运算(距离度量方法L1范数),在500个计算结果中选择最小的行号作为结果。该结果作为训练集标签矩阵的索引值就可以得到测试结果的类别。
因此,很明显,这种分类算法的速度取决于训练数据的大小。 - k近邻算法
近邻算法通过选择最小的距离度量(例如,L2范数)作为分类结果,但是这种距离度量方式仅仅取决于不同图像对应位置像素值的相似性,具有很大的错误可能。一种改进的方式称为K近邻,选择度量方式中比较小的k个结果,然后通过投票的方式从K个结果中选择出最终的类别判定,对于回归任务,则对k个结果取平均或者其他操作。可以对近邻算法做出一些优化。这就是k近邻算法。
Attention!
不能使用测试集调试参数,否则会导致算法的泛化性能差,过拟合。
可以选择使用交叉验证的方式选择最佳的K值。 - 存在的问题
从效果上看:
基于像素比较的相似和感官上以及语义上的相似是不同的。
这种方式图像的相似度更多的是以背景为主导而不是图片语义本身。
从实际应用中看:
需要将训练集数据(一般都会很大)被保存在内存空间中,占用了太多的资源。
一般情况下,我们认为系统的训练时间长一些,当实际使用的时候,时间短一些,不会影响系统的运行,但对于KNN来说,训练时间就是把图像读入存储,时间很短,测试的时候却需要把每一副测试图像和每一个训练集数据进行对比,时间很长。
Read more: https://zhuanlan.zhihu.com/p/20894041?refer=intelligentunit
三、线性分类器、损失函数、优化问题、反向传播
- 假设有10个类别的图像,现在要测试一副图像或者其他经过一个函数或者多个函数后哪个类别的得分值最高。这个函数叫分类器,也叫得分函数。
线性分类器
模型:f(W,x)=Wx+b(W权重矩阵:n个类别×每个类别的参数,x输入矩阵,b偏置)
xi是图片拉伸后的结果,W的每一行代表一种类别的参数。
使用过程中,为了方便处理,常常把b添加到w当中,把x增加一个大小为1的维度。
一种思考:线性分类器只是在模仿K近邻,不同的是它仅仅是使用的是一种学习到的模板。
Read more: https://zhuanlan.zhihu.com/p/20918580?refer=intelligentunit
损失函数
在得到每一个类别的得分值以后,如何判断该分类器是否达到了理想的效果呢?
我们使用损失函数、损失值来表示,损失函数更重要的作用是为了后面的用于调整参数W,需要说明的是损失值越大,得到的结果与真实结果相差越大(通过输入图像的标签来判断),这里使用两类损失函数一类是多类别SVM损失(Multiclass SVM loss),一类是交叉熵损失。
Li表示后面内容的累加和:是错误类别的得分值(Sj)减去正确类别的得分值(Syi)加上一个安全系数(这里为1),然后选择其结果与0中的较大值。
理解一下:
1、先不考虑安全系数,如果错误类别的得分值都小于正确类别,公式的结果为0,说明分对了。反之,得分值大于0,说明分错了。
2、如果错误类别的得分值远远大于正确类别的得分值,则结果也将变得很大。表示分类效果不好
3、增加了安全系数表明,即使分对了,但是错误类别的得分值只是比正确类别的得分值低一点(小于安全系数)。我们也认为这次分类是不准确的,因为它没有将错误类别与正确类别很好的留出一定的安全距离。
4、上述这个损失方式也叫hinge loss。可以通过加平方项扩大损失值。
这种损失值的计算方式关注了每次进行分类的得分值,但是像素的权重对于得分值的大小没有影响,考虑下面一种情况是:
参数w1和w2相比,虽然得到的结果相同,但是w2使用了所有的像素值,而w1的有效数据其实只有一个,而使用更少的原始数据可能意味着过拟合。
通过引入正则化惩罚项可以使得w1和w2的损失值不一样,使得w值(像素的权重值)尽可能的分散.
这里引入一种L2惩罚项:
损失函数的最终版本是:
超参数\lambda通过交叉验证选择合适的值。
Read more:https://zhuanlan.zhihu.com/p/20945670?refer=intelligentunit
5.交叉熵损失(cross-entry loss)(也叫softmax分类器)
交叉熵损失的公式:
根据公式的一个例子:
1、第一步是将得分值取e为底的指数函数,这样做可以增大得分值之间的差距。
2、归一化此时将得分值转变成为了概率分布,表示经过测试后的数据为其他每一个类别的概率。
3、最后使用log函数进行求损失值,-log自变量的取值范围在0到1之间,函数值的取值范围在0到+无穷大之间,则归一化正确分类的数值越小,损失值也就越大。
4、在svm的损失函数中,假设一种情况是如果所有的类别都分对了,并且类别的得分值差距大于安全距离,则损失值为0。现在错误类别的得分值改变了(仍然满足上述条件),但是损失值依然为0,不管错误类别的得分值是多么接近正确类别或者是远离正确类别,损失值都不改变,这种情况是不好的。而使用交叉熵损失则可以改变这种情况。
read more:https://zhuanlan.zhihu.com/p/21102293?refer=intelligentunit
5、优化问题
优化问题是什么样的W可以使得系统的损失值最小。
1、随机搜索策略:在程序中使用产生随机数的程序,随机产生所需要的参数W,每次生成参数后计算损失值并与前一次的损失值比较,如果优于前一次,则保留,否则就舍弃,这就是随机搜索策略。
2、本地随机搜索策略:这个方式与随机搜索策略大致相同,不同的是每一次随机生成一组W后,需要乘上一个学习率,然后将这个结果加到上一次的W中,然后比较损失值是否减小,不减小的话就丢弃掉,否则更新新的W。Wnew=Wold+step×Wrandom。这里相当于在寻找下降的梯度。
3、跟随策略:实际上下降的梯度并不需要寻找,可以通过计算得到,这个就是下降的梯度,代替2中每次生成的新的W值。
read more:https://zhuanlan.zhihu.com/p/21360434?refer=intelligentunit
4、梯度下降的计算方式
(1)有限差值计算梯度:这里就是使用3中的梯度计算方法,给w增加一个h,然后计算损失值f(x+h)。这样最终得到了梯度的方向,用df表示。
使用:Wnew=Wold-step×df,step表示步长,也叫学习率learning rate(步长过大?步长过小?)。更新参数W。这里为什么使用的是减号?
当计算梯度大于0的时候,这个时候表示上山,函数递增,我们想往损失值更小的地方去,就需要反方向行走,因此需要加个负号。
实践表明:中心差值公式具有更好的效果。
(2) 微分计算梯度,偏微分就是梯度,因此可以通过偏微分的方式计算梯度,在线性回归中,就是直接通过偏微分直接计算梯度的。
5、梯度下降的训练
之前是通过全部的样本进行更新一个参数,这样浪费了大量的时间。一种方式是小批量数据梯度下降(Mini-batch gradient descent),每跟新一个参数更新只从训练样本中获取部分样本数据。一种更加极端的方式选择一个样本用于训练,称为随机梯度下降(Stochastic Gradient Descent 简称SGD)。
注:梯度下降是对神经网络的损失函数最优化中最常用的方法。
保留一些疑问:多个训练图像如何的梯度是如何确定的?随机梯度下降的方式?
Read more:https://zhuanlan.zhihu.com/p/21387326?refer=intelligentunit
6、该部分的流程
四、反向传播
反向传播是使用链式求导法则从最终输出端往回分段求导,最终得到输入对输出的梯度的过程。这里所说的梯度就是倒数。其实反向传播就是求导过程,我们知道:对于复杂函数的求导过程可以使用链式求导法则去求。
得到的梯度反应了输入对于输出的影响,相当于某一个输入的参数每增加“一份”,输出结果增加“梯度份”的过程。
反向传播中有加法门操作,乘法门操作,其实就是加法和乘法。还有一种是MAX门操作,这种操作是取输入中较大的梯度为1,较小的梯度为0。
一个反向传播计算的例子:https://www.cnblogs.com/charlotte77/p/5629865.html
Read more:https://zhuanlan.zhihu.com/p/21407711?refer=intelligentunit