SVM

https://zhuanlan.zhihu.com/p/21478575?refer=baina

SVM是线性分类算法中的一种,准确率和softmax差不多。

具体实现,对于一个32x32x3的图像可以转换一个3073x1的二维矩阵,这个二维矩阵与W[10x3072]的矩阵相乘,会得到一个[1x10] 的二维矩阵,那么这个10个维度就代表着10个类别
(更多的细节参考ppt:http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture02.pdf)

当然SVM的目的就是希望[1x10]能够准确的预测所有该分类的图片,所以就有了如下推断:

如图所示:
x[i]对应第i个样本,y[i]对应着它的分类,那么SVM希望预测准确的情况下,结果集中y[i]项的得分最高。
也就有了其右下角的公式,L[i]为样本i的loss,也就是说如果对所有样本求loss,如果所有预测都是准确的那么对loss的求和就是0,否则会大于0,SVM希望这个loss求和比较小,进而这个图像分类的问题,就转换为一个求极值的问题。(与softmax不同之处就是这个loss的求法不同而已)
(ppt参考:http://cs231n.stanford.edu/slides/2018/cs231n_2018_lecture03.pdf)

公式中虽然只有一个W,单却是两个参数,分别是W(y[i])和W(j);

基于损失函数求梯度:为了是loss减少,提高分类的准确率

基于W(y[i])和W(j)的导数分别为上图所示(矩阵求导和和函数求导都差不多,只是矩阵要进行转置X.T),分别代表着W(y[i])和W(j)上的变化方向。
其中j 的范围为(1~C,j!=y[i]),每当 loss大于0时都要对W(y[i])和W(j)进行更新(每个样本最多会有C-1个loss,也就是更新C-1次,当j=y[i]时不需要计算)

如下通过循环的方式进行更新,对应num_train个样本,每个样本对应num_classes个分类,

矢量版的损失函数,两重的循环往往都能转换成矩阵运算(性能的改善,可以参考https://www.zhihu.com/question/64659178):

数值梯度应接近分析梯度

grad_check_sparse这个函数随机抽取10个位置,然后打印出该位置的数值梯度和分析梯度,以及它们之间的相对差

来自 http://www.bkjia.com/rgznjc/1312998.html

def grad_check_sparse(f, x, analytic_grad, num_checks=10, h=1e-5):
"""
sample a few random elements and only return numerical
in this dimensions.
"""

for i in range(num_checks):
ix = tuple([randrange(m) for m in x.shape])

oldval = x[ix]
x[ix] = oldval + h # increment by h
fxph = f(x) # evaluate f(x + h)
x[ix] = oldval - h # increment by h
fxmh = f(x) # evaluate f(x - h)
x[ix] = oldval # reset

grad_numerical = (fxph - fxmh) / (2 * h)
grad_analytic = analytic_grad[ix]
rel_error = abs(grad_numerical - grad_analytic) / (abs(grad_numerical) + abs(grad_analytic))
print('numerical: %f analytic: %f, relative error: %e' % (grad_numerical, grad_analytic, rel_error))

你可能感兴趣的:(SVM)