2017 CS231n学习笔记(三)----损失函数和最优化(Loss Functions and Optimization )

video:https://study.163.com/course/courseMain.htm?courseId=1004697005
slides:http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture3.pdf
course notes:http://cs231n.github.io/
文章所有内容来自Stanford university 课程 CS231n 2017 spring

上一节课 讲了图像分类器的设计和线性分类器的解释,说明了如何通过参数 W 和 b 得到对应的类别分数,来判断图片究竟属于哪一个类别。但是没有说如何得到参数 W 和 b,这一节课通过讲解多元 SVM 损失函数、softmax loss 来衡量预测结果与ground truth label的差别和如何根据loss函数通过梯度下降(Gradient decent)来求解参数 W 和 b。

1. 损失函数(loss function)

损失函数(loss function)又叫代价函数(cost function)、目标函数(objective function)。是用来衡量预测labels 与 ground truth labels 一致性的度量指标。

1.1 多元支持向量机损失(Multiclass Support Vector Machine, SVM loss),

损失函数有很多种,本节课的第一个例子是多元支持向量机损失(Multiclass Support Vector Machine, SVM loss), SVM loss 目的是想要每一张图像的正确的类别分数比其他不正确的类分数高一个固定的阈值 Δ \Delta Δ

下面给出精确的数学公式,假设 x i x_i xi 是图片 i i i 的像素值, y i y_i yi 为图片的label(正确的类的索引)。 s s s f ( x i , W , b ) f(x_i, W, b) f(xi,W,b) 的结果, s j = f ( x i , W , b ) j s_j = f(x_i, W, b)_j sj=f(xi,W,b)j 代表分数向量 s s s 的第 j j j 个元素。由此,SVM loss为:
L i = ∑ j ≠ y i max ( 0 , s j − s y i + Δ ) L_i = \sum_{j\neq y_i} \text{max} (0, s_j - s_{y_i} + \Delta ) Li=j̸=yimax(0,sjsyi+Δ)
在这里插入图片描述
如果将 Δ = 1 \Delta = 1 Δ=1 ,则 loss function 如图中 “Hinge loss” 所示。一上图第一张猫的分数求对应的 loss function L i L_i Li 计算过程及结果如下图所示:
在这里插入图片描述
值得注意的是,最后整个数据集上的loss是所有单个图像loss的平均:
L = 1 N ∑ i = 1 N L i L = \frac 1N \sum_{i=1}^N L_i L=N1i=1NLi

针对SVM loss 这里有一些问题需要回答。

  • 当某张图片的loss为0时,如果图片改变一点点,loss 会发生怎样的变化?
    答:不会发生变化。SVM loss 只关注与正确的分数大于不正确的分数 Δ \Delta Δ, 在这种情况下,正确类的分数比其它分数都要大,如果该类的分数改变一点点,此时这个阈值 Δ \Delta Δ 依然有效,loss 并不会改变。
  • SVM loss 的最大值和最小值是多少?
    答: [ 0 , + ∞ ] [0, +\infty] [0,+]
  • 如果初始化 W 为一个很小的值以至于所有 s ≈ 0 s \approx0 s0, loss 等于多少?
    答: l o s s = ( C − 1 ) ∗ Δ loss = (C - 1) * \Delta loss=(C1)Δ ( C C C代表类别数量)
  • 如果loss在所有类上都求和(包括 j = y i j = y_i j=yi)会如何?
    答:loss会再加上 Δ \Delta Δ
  • 如果用平均代替求和会怎么样?
    答:没有影响。
  • 如果loss选择使用L2-SVM, 即 L i = ∑ j ≠ y i max ( 0 , s j − s y i + Δ ) L_i =\sum_{j\neq y_i}\text{max}(0, s_j - s_{y_i} + \Delta) Li=j̸=yimax(0,sjsyi+Δ) 会如何?
    答:L2-SVM 将会更加激烈的惩罚违反边界的行为,SVM loss显得更加稳定,具体选择需要根据不同的应用进行抉择,可以在cross-validation进行选择。

值得注意的是,一是 Δ \Delta Δ 的选择并没有什么特定的要求,你可以根据实际的数据集作出相应的调整。二是最优参数 W (将参数b扩展进W)的值并不唯一,比如2W也可以使得 L = 0 L = 0 L=0

在这里插入图片描述

我们知道,当我们在训练时,如果过度拟合训练集的数据,则很容易才测试的时候出现问题,这就是典型的过拟合(overfitting)问题。为解决这样的问题,可以添加正则项(Regularization term) 去惩罚权重W。于是得到整个loss函数,如下图所示:
在这里插入图片描述

正则项的意义

正则化的目的是为了解决模型过拟合的问题,提高模型的泛化性,添加正则项只是其中一种方法

假设权重 W 可以正确的分类所有的样本( l o s s = 0 loss = 0 loss=0),则会出现一个问题, W W W 不是唯一的, λ W ( λ > 1 ) \lambda W(\lambda > 1) λW(λ>1) 也可以是的 loss 为0。所以我们需要加入一些偏好使得消除这些模糊性,并使得参数 W W W 尽量简单,即 λ = 1 \lambda = 1 λ=1。通过在 loss 函数中加入一个正则项 R ( W ) R(W) R(W) 来惩罚参数 W W W 使得参数 W W W 尽量小。

除此之外,惩罚大权重也可以提高模型的泛化能力,如果存在输入向量 x = [ 1 , 1 , 1 , 1 ] x = [1, 1, 1, 1] x=[1,1,1,1], 假设有参数为 w 1 = [ 1 , 0 , 0 , 0 ] w _ { 1 } = [ 1,0,0,0 ] w1=[1,0,0,0] w 2 = [ 0.25 , 0.25 , 0.25 , 0.25 ] w_2 = [0.25, 0.25, 0.25, 0.25] w2=[0.25,0.25,0.25,0.25], 则 w 1 T x = W 2 T x = 1 w_1^Tx = W_2^Tx = 1 w1Tx=W2Tx=1, 很明显 w 2 w_2 w2 是一个更好的选择,因为它显得更加分散,不会过分依赖某一个特征。

最常见的正则项是 L2 正则:

R ( W ) = ∑ k ∑ l W k , l 2 R ( W ) = \sum _ { k } \sum _ { l } W _ { k , l } ^ { 2 } R(W)=klWk,l2

1.2 Softmax Classifier (Multinomial Logistic Regression)

另一个比较流行的 loss 函数是softmax, softmax 函数的本质就是将一个K维的任意实数向量压缩(映射)成另一个K维的实数向量,其中向量中的每个元素取值都介于(0,1)之间。将最终计算的分数通过 softmax 函数。
softmax函数形式如下:

σ ( z ) j = e z j ∑ k = 1 K e z k \sigma ( z ) _ { j } = \frac { e ^ { z _ { j } } } { \sum _ { k = 1 } ^ { K } e ^ { z _ { k } } } σ(z)j=k=1Kezkezj

其中j=1,2,…,K。

然后将结果通过交叉熵作为loss, 即:

H ( p , q ) = − ∑ x p ( x ) log ⁡ q ( x ) H ( p , q ) = - \sum _ { x } p ( x ) \log q ( x ) H(p,q)=xp(x)logq(x)

p 代表真实的概率值,q代表预测的概率值。

2. Optimization

我们已经通过一个 score function 将输入数据映射到了类别分数,而且使用loss function 测量了预测结果与实际结果的偏差。

现在我们需要去找到最优的参数 W W W 去最小化 loss function。这一过程称之为 优化(Optimization)

这里总共有三种优化策略。

2.1 随机搜索(Random Search)

这是最简单的方法,效果极差,就是简单的选择很多随机的权重,然后就算他们的loss,选择最优的权重。程序如下:

# assume X_train is the data where each column is an example (e.g. 3073 x 50,000)
# assume Y_train are the labels (e.g. 1D array of 50,000)
# assume the function L evaluates the loss function

bestloss = float("inf") # Python assigns the highest possible float value
for num in xrange(1000):
  W = np.random.randn(10, 3073) * 0.0001 # generate random parameters
  loss = L(X_train, Y_train, W) # get the loss over the entire training set
  if loss < bestloss: # keep track of the best solution
    bestloss = loss
    bestW = W
  print 'in attempt %d the loss was %f, best %f' % (num, loss, bestloss)

# prints:
# in attempt 0 the loss was 9.401632, best 9.401632
# in attempt 1 the loss was 8.959668, best 8.959668
# in attempt 2 the loss was 9.044034, best 8.959668
# in attempt 3 the loss was 9.278948, best 8.959668
# in attempt 4 the loss was 8.857370, best 8.857370
# in attempt 5 the loss was 8.943151, best 8.857370
# in attempt 6 the loss was 8.605604, best 8.605604
# ... (trunctated: continues for 1000 lines)

优化的核心思想其实是迭代修正,想要直接找到最优的权重基本上是不可能的,所以采用的方式是随机初始化权重,然后迭代修正发现更好的权重。

2.2 随机局部搜索(Random Local Search)

这种方法是,基于当前的权重,选择一个随机的方向走一小步,观察结果。比如存在权重参数 W W W,然后我们随机的向一个方向走一步 δ W \delta W δW, 如果在 W + δ W W + \delta W W+δW 处的 loss 小于在 W W W 处的 loss,则更新 W W W。程序如下:

W = np.random.randn(10, 3073) * 0.001 # generate random starting W
bestloss = float("inf")
for i in xrange(1000):
  step_size = 0.0001
  Wtry = W + np.random.randn(10, 3073) * step_size
  loss = L(Xtr_cols, Ytr, Wtry) # compute the loss
  if loss < bestloss:
    W = Wtry
    bestloss = loss
  print 'iter %d loss is %f' % (i, bestloss)
2.3 跟随梯度(Following the Gradient)

其实我们可以计算出权重更新最佳的方向 ------- 梯度的负方向

有两种方式计算梯度,一种是数值梯度法(numerical gradient)分析梯度发(analytic gradient).

  1. 数值梯度法(numerical gradient): 一种缓慢的,近似地估计,但却容易的方法。
  2. 分析梯度法(analytic gradient):一种快速的,精确的,但却容易在求积分的时候出错。

3. 梯度下降(Gradient Descent)

我们计算出了loss function的梯度,现在我可以迭代地更新权重参数了。该过程叫做梯度下降,最简单的程序如下:

# Vanilla Gradient Descent

while True:
  weights_grad = evaluate_gradient(loss_fun, data, weights)
  weights += - step_size * weights_grad # perform parameter update

这里的 step_size 是模型的一个超参数,可以叫做步长或学习率(learning rate),它代表你要朝更新方向一步走的步长大小,越大代表更新的越快,得到结果越快。但是太大的步长会使得得不到最优解,因为你可能一步踏过了最优解,然后一直在最优解边上徘徊。

mini-batch gradient descent

首先解释一下什么是batch,batch是一批,一堆的意思,整个数据集的数据可以叫做一个batch,由于有些数据集的数据量很大,计算一次整个数据集上的梯度需要大量的时间,所以提出mini-batch的概念。比如我们可以将一个mini-batch的batch size设置为32,则计算32张图片后就可以进行一次梯度下降。程序如下:

# Vanilla Minibatch Gradient Descent

while True:
  data_batch = sample_training_data(data, 256) # sample 256 examples
  weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
  weights += - step_size * weights_grad # perform parameter update

当 batch size 为 1 时,称之为随机梯度下降(Stochastic Gradient Descent ,SGD).

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值