SVM与学习的基本思路

来源:互联网 发布:c语言 f是什么意思 编辑:程序博客网 时间:2024/05/04 04:31

根据CS231n所描述的,实现了一个用SVM loss来衡量权重矩阵、用梯度下降来改进权重矩阵的算法,效果拭目以待(目前的正确率是32.48%,还不太好,还需要进行优化)

1. 分类算法的三个部分(很重要)

1.1 权重算法
这一部分是指,如何把一个图像(reshape成了一个一维向量),映射成一个数,这个数代表的就是认为是该类别的分值。如果有多个映射关系,就可以映射成多个数,这若干个数就可以组成一个向量,这个乘出来的向量的每一维就代表着目前的分类器(也就是这个权重矩阵),所认为输入的图像分别可能是什么类别的。这个映射关系可以是线性的,也可以是更复杂的(比如卷积函数)

1.2 损失函数

损失函数就标志着,在当前的分类映射关系下,分类出来的好坏。因为是supervised learning,所以是通过与原有标签进行比对来判断有没有正确地进行分类

1.3 优化方法

优化方法就是指,如何对权重函数进行调整,使得在不断进行训练的过程中每次算出来的误差越来越小,最后做到与训练集尽可能的匹配

2. Loss

2.1 SVM Loss

SVM loss的形态就是这样的

L_i = \sum_{j\neq y_i}max(0,s_j-s_{y_i}+\delta)
L = \frac{1}{n}\sum_n^iL_{i}

第一个公式是说,对于某一条图像的数据,Sj是该图像经过权重函数判别出的分类syi是这个图像正确的分类,如果他们的分值的差比设定的delta要大,那么分类就正确,系统就认为没有loss,反之就有一定的loss(sj-syi+delta<0的意思就是说,syi-sj>delta,就是说这个图像正确的分类的分数越高越好,并且至少比错误的分类高出delta)
第二个公式就是把所有图像的loss在数据集上平均一下

2.2 Softmax Loss

softmax方法用来判别loss的公式是这样的

L_{i} = -\log(\frac{e^{f_{y_{i}}}}{\sum_{j}e^{f_{j}}})

直观的理解就是说,正确的分类的分值,占所有的分类的分值的百分比(先取指数然后取对数姑且直观地理解为还原了吧),这个比值越高,loss就越低
对于softmax的损失函数还有一个优化,因为值取对数会很大,可能会造成计算的不稳定性,所以进行一个简单的变换

L_{i} = -\log(\frac{e^{f_{y_{i}}}}{\sum_{j}e^{f_{j}}})=-\log(\frac{Ce^{f_{y_{i}}}}{C\sum_je^{f_j}})=-log(\frac{e^{f_{y_{i}}+lgC}}{\sum_je^{f_j+lgC}})

并且一般取

lgC=max(f_{y_i})

这样就可以避免产生指数爆炸的数值计算问题

3. 梯度下降与链式法则

3.1 梯度下降

梯度的计算,就是指对于一个多元函数,求在各个分量上的变化最快的方向,在这个方向上增加一个delta,函数的值增加的是最快的

比如说对于一个最简单的函数

f(x,y)=xy
\nabla f =[ \frac{\partial f}{\partial x},\frac{\partial f}{\partial y} ] = [ y,x ]

计算完梯度之后,在原来的函数上减去梯度,就可以进行优化
所以计算梯度,也就是计算对每一个变量的偏导,而计算偏导,往往就要用到链式法则

3.2 链式法则

链式法则的理论和高等数学里介绍的是一样的

但是在实现上有时候会有些不一样。因为对一些复杂的复合函数,直接通过链式法则求偏导会非常的复杂,采用另外一种实现方法
比如说这个函数

f(x,y)=\frac{x+\delta(y)}{\delta(x)+(x+y)^2}
\delta(x) = \frac{1}{1+e^{-x}}

对这个式子,如果直接计算对x和y的偏导的话,就太复杂了,我们不需要一个能直接计算的式子,我们只要对于每一个值能够计算就可以了
先计算foward propogation, 然后计算back propogation

sigx = 1 / ( 1 + math.exp(-x) )sigy = 1 / ( 1 + math.exp(-y) )xpy = x + yxpysqr = xpy ** 2num = x + sigyden = sigx + xpysqrinvden = 1 / denf = num * invden

back propogation的计算过程就是这样的

dx = 0dy = 0dnum = invdendinvden = numdden = - 1.0 / (den**2) * dinvdendsigx = 1 * ddendxpysqr = 1 * ddendx += 1 * dnumdsigy = 1 * dnumdxpy = 2 * xpy * dxpysqrdx += dxpydy += dxpydx += (1-sigx)*sigx * dsigxdy += (1-sigy)*sigy * dsigy

4. batch优化

训练的数据集一般会很大,如果直接通过整个数据集来求梯度然后平均可能会比较慢。所以选择通过选取batch的方式,每次从整个数据集里面随机选取一些数据(比如128个,256个,512个),就假设这些随机选取的数据样本可以代表整个数据集,在它上面算梯度对权重矩阵进行调整。其实实际上这些数据就能很好的代表整个数据集

random.sample( data, BATCH_SIZE )
0 0
原创粉丝点击