语义鸿沟 : 计算机无法从图像中直接提取出信息

近邻分类器¶

  • 近邻分类器:在训练数据种匹配最接近的数据标签
  • 衡量距离的方式
    • L1 距离:$d_1(I_1,I_2)=\sum_p|I_1^p-I_2^p|$
    • L2 距离: $d_2(I_1,I_2)=\sqrt{\sum_p\left(I_1^p-I_2^p\right)^2}$ image.png

改进:k-近邻分类器,使用最近的k个训练集数据标签进行投票,使决策边界平滑,使模型获得更高的鲁棒性

超参数:模型无法通过学习得到的参数,需要在训练之前提前设定

交叉验证: image.png

近邻分类器上的问题:

  • 无法很好的用于图像分类因为距离的概念很难描述图像之间的差距
  • 维度灾难:在高维度下距离的概念失效;需求训练集数量剧增

线性分类器¶

  • 输入:图像数据矩阵
  • 输出:不同类别的概率
  • 公式:$\mathrm{f(x,W)}=\mathrm{W(x+b)}$ image.png
  • 每个线性分类器可以学习到一个类的模板(模板匹配的过程),通过逆推我们可以看到其学习到的图像 线性分类器的问题:
    • 无法解决一些通过一条线性划分无法解决的问题

损失函数¶

在线性模型中,我们为了可以找到最佳的W,我们需要找到一个评价当前W的函数,损失函数便可以衡量W的好坏程度。

$$ L=\frac{1}{N}\sum_{i}L_{i}(f(x_{i},W),y_{i}) $$

$L_i$是衡量某一组数据和标签之间的差距(即损失)

SVM loss :¶

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

我们通过一个固定的$\Delta$(边际)来对损失进行规范,其取值是无关紧要的。真实类别得分必须比其他类别得分至少高 $\Delta$,否则会产生损失

对于某一个图像得到的分数不高于其对应正确类别的分数。

因此,多分类 SVM 的核心思想是:让 “真实类别 $y_i$ 的得分 $s_{y_i}$”,比 “所有其他类别 $j$ 的得分 $s_j$” 至少大 $\Delta$。

  • 超参数$\Delta$的影响
    • $\Delta$ 越大,模型需要学习的 “类别区分度” 越高(真实类别得分必须远高于其他类别),可能更鲁棒,但也可能更难训练(易欠拟合)。
    • 通常设为 $\Delta=1$(经验值),也可根据任务调整(如数据集类别重叠严重时,可减小 $\Delta$)。

若使用SVM损失函数进行训练,一开始随机生成的W应该会使所有分类的score接近于一个平均值,因此在一开始的损失函数计算值应该接近于 $c-1$ (c 为分类数)。我们也可以用这个特性进行Debug($\Delta = 1$时)

# 矢量化后的SVM损失函数计算
def L_i_vectorized(x,y,W):
    scores = W.dot(x)
    margins = np.maximum(0,scores-scores[y]+1)
    margins[y] = 0
    loss_i = np.sum(margins)
    return loss_i

softmax Loss:¶

使用softmax函数将原本的得分转化为概率分布 $${P(Y=k|X=x_{i})=\frac{e^{s_{k}}}{\sum_{j}e^{s_{j}}}}$$ $${L_i=-\log P(Y=y_i|X=x_i)}$$ $$\text{in summary:}\quad L_i=-\log(\frac{e^{sy_i}}{\sum_je^{s_j}})$$

同理,若使用softmax进行训练时,随机生成的W应该使一开始的损失函数接近于 $\log{C}$

softmax和SVM的对比¶

image.png

  • Softmax 关注 “真实类别概率尽可能大”(通过交叉熵损失),但不限制 “其他类别得分的绝对大小”
  • 多分类 SVM 关注 “真实类别与其他类别得分的相对间隔”,只要间隔满足 $\Delta$,不关心概率的绝对高低

正则化(Regularization)¶

为了防止模型在训练时过拟合,我们需要引入一些项来惩罚模型的复杂参数

$$L(W)=\frac{1}{N}\sum_{i=1}^NL_i(f(x_i,W),y_i)+\lambda R(W)$$

最终在衡量这一次的训练结果时,我们会使用损失函数在所有训练集上的平均值,即:$$L=\frac{1}{N}\sum_{i=1}^NL_i$$

优化(Optimization)¶

传统的梯度下降算法:

while True:
    weigths_grad = evaluate_gradient(loss_fun,data,weights)
    weigths += - step_size * weights_grad

小批量随机梯度下降(SGD):

  • 采样:从训练集选一小批数据,模拟整体数据的分布。
  • 计算梯度:用这批数据计算损失函数对参数的梯度(反映当前参数下,损失的变化趋势)。
  • 更新参数:沿梯度反方向调整参数,减小损失。
  • 循环:重复上述步骤,让参数逐渐逼近 “损失最小” 的最优解。
while True:
    data_batch = sample_training_data(data,256)
    weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
    weights += - step_size * weights_grad  # perform parameter update