跳转至

1 Image Classification Pipeline

文本统计:约 2122 个字 • 20 行代码

图像识别是计算机视觉的核心任务,对于人来说,识别一只猫是一件和容易的事情,但是对于计算机来说,得到的只是一系列的像素数字,这被称为语义鸿沟。那么对于计算机来说,相应的挑战有如下几点:

  • Viewpoint variation 当照相机移动的时候,每个像素都会发生相应的变化

  • Illumination 在不同的光照条件下,图片色彩有很大的不同

  • Background Clutter

  • Occlusion

  • Deformation

  • Intraclass variation

之前我们曾经采用过一些根据图像边缘,并识别特征角的方式来识别图片,但是这样的方法需要为每个物体定制,同时这样的方法正确率也不高。于是我们引入了 Data-Driven 的方法

  • Collect a dataset of images and labels
  • Use Machine Learning algorithms to train a classifier
  • Evaluate the classifier on new images

大致的流程如下:

def train(images,labels):
    #machine learning
    return model
def predict(model, test_images):
    #Use model to predict labels
    return test_labels

1.1 Nearest Neighbor Classifier

我们第一个学习的分类器是 Nearest Neighbor Classifier, 大致思路就是将测试图片与数据库已分类好的图片进行匹配,找到最相似的那张图,然后根据那张图的类别去判断测试图片的类别

那么如何定义两张图片的距离呢?可以简单地将各个像素的值的绝对值差相加来定义距离

我们得到的结果往往如下所示,有以下缺点:

  • 容易受到噪声和异常值的影响,因为只考虑最近的一个邻居。
  • 决策边界可能非常复杂和不规则,导致过拟合问题

KNN

于是我们对其进行改进,采取 K-Nearest Neighbors 的方法,即 Instead of copying label from nearest neighbor, take majority vote from K closest points

关于距离的定义,有L1 (曼哈顿距离)L2 (欧拉距离) 两种

运用不同的求解距离的方式,会得到不同的结果

Hyperparameters

在机器学习和更广泛的领域中,超参数(Hyperparameter)是指在模型训练之前需要设定的参数,它们不是通过训练数据学习得到的,而是由实践者根据经验或实验来确定的。这些超参数控制了学习过程和模型结构,对模型的性能有着至关重要的影响.

在这里,K 和 L1/L2 的选择就是超参数的选择

那么我们应当如何设置超参数呢?有下列三种方法:

  • Choose hyperparameters that work best on the training data

  • Choose hyperparameters that work best on test data

  • Split data into train, val; choose hyperparameters on val and evaluate on test

第一种方法显然是不可取的,因为 K=1 永远在训练集中表现最优。第二种方法也是不可取的,因为我们并不知道其对新的数据的表现,只是建立在测试集上。所以一般采用第三种方法来调参。

还有一种方法是交叉验证,是第三种方法的一种进阶,其对于小数据集比较有用。

Example

比如说这个例子就是利用交叉验证训练的统计表,当K = 7 的时候效果是最好的

当然对于图像利用 KNN 训练有很多缺点,以至于这种方法实际上是不怎么使用的

  • 测试时间过长,良好的训练模式应该是训练用很长时间,测试则非常快。KNN这个算法则刚好反过来。

  • k-Nearest Neighbor with pixel distance never used. Distance metrics on pixels are not informative

比如说右边三幅图和左边的原图的欧氏距离是相同的,但是很明显这三张图片有着很大的区别

  • Curse of dimensionality 随着数据维度的增加,数据点之间的距离分布会发生显著变化,导致k-NN等基于距离的算法性能下降。具体来说:
  1. 数据稀疏性:当维度增加时,数据点在高维空间中的分布变得非常稀疏。例如,在一维空间中,4个点可以均匀分布在一条线上;在二维空间中,16个点可以均匀分布在4x4的网格上;而在三维空间中,需要64个点才能均匀分布在4x4x4的立方体中。这意味着在高维空间中,需要更多的数据点才能保持相同的密度。
  2. 距离失真:在高维空间中,所有数据点之间的距离趋于相似,使得“最近邻居”的概念变得不那么有意义。换句话说,即使是最近的邻居也可能离得很远,而较远的邻居可能与最近的邻居距离相差不大。

1.2 Linear Classification

函数f(x, W):这是一个映射函数,它接受两个输入:

  • x:代表输入图像的数值数组(即3072个数值)。
  • W:代表模型的参数或权重,这些参数决定了如何将输入图像转换为类别分数。

10 numbers giving class scores:函数f(x, W)的输出是10个数字,每个数字对应一个可能的类别(例如,在CIFAR-10数据集中,有10个类别)。这些数字表示输入图像属于各个类别的得分或概率。

Example

在二维空间中,线性分类器可以被看作是一条直线,它将空间分为两个区域,每个区域对应一个类别。在更高维度的空间中,线性分类器则是一个超平面,将空间分割成多个区域,每个区域对应一个类别。

但在某些情况下,这种简单的线性分割无法有效地对数据进行分类

接下来面对的问题就是,如何选择一个好的 W 来进行分类?

  • 定义损失函数:定义一个损失函数(Loss Function),用于量化模型在训练数据上的预测得分与真实标签之间的差距。损失函数衡量了模型的“不满意度”,即模型预测结果与期望结果之间的差异。常见的损失函数包括交叉熵损失、均方误差损失等。

  • 优化参数:找到一种有效的方法来最小化损失函数,即找到最优的权重矩阵 \(W\)。这通常通过优化算法实现,如梯度下降法(Gradient Descent)、随机梯度下降法(Stochastic Gradient Descent, SGD)等。这些算法通过迭代更新权重矩阵 WW,逐步减小损失函数的值,最终使模型在训练数据上达到较好的分类效果。

损失函数用于量化当前分类器的好坏程度。给定一个包含 \(N\) 个样本的数据集 \(\{(x_i, y_i)\}_{i=1}^N\),其中:

  • \(x_i\) 表示第 \(i\) 个样本的特征向量(图像),
  • \(y_i\) 表示第 \(i\) 个样本的真实标签(整数标签),

损失函数 \(L\) 定义为所有样本损失的平均值:

\[ L = \frac{1}{N} \sum_{i} L_i(f(x_i, W), y_i) \]

其中,\(L_i(f(x_i, W), y_i)\) 表示第 \(i\) 个样本的损失,它衡量了模型预测得分与真实标签之间的差距。

SVM Loss

给定一个样本 \((x_i, y_i)\),其中:

  • \(x_i\) 是图像,
  • \(y_i\) 是(整数)标签,

使用得分向量的简写形式:\(s = f(x_i, W)\)

多分类 SVM 损失的形式为:

\[ L_i = \sum_{j \neq y_i} \begin{cases} 0 & \text{if } s_{y_i} \geq s_j + 1 \\ s_j - s_{y_i} + 1 & \text{otherwise} \end{cases} \]

也可以写作:

\[ L_i = \sum_{j \neq y_i} \max(0, s_j - s_{y_i} + 1) \]

Example

Question

Q1: What happens to loss if car scores decrease by 0.5 for this training example?

A1: Nothing happened

Q2: what is the min/max possible SVM loss Li?

A2: \(0/+\infty\)

Q3: At initialization W is small so all s ≈ 0. What is the loss Li , assuming N examples and C classes?

A3: 在初始化时,每个样本的损失 \(L_i\)\(C−1\),总损失 \(L\)\(C−1\)

Q4: What if we used \(L_i = \sum_{j \neq y_i} \max(0, s_j - s_{y_i} + 1)^2\)

A4: 平方损失函数对错误分类的惩罚更大,特别是当错误分类的得分与正确分类的得分差距较大时。这使得模型在优化过程中更加关注减少这些较大的误差。

def L_i_vectorized(x, y, W):    
    # First calculate scores    
    scores = W.dot(x)        

    # Then calculate the margins s_j - s_yi + 1    
    margins = np.maximum(0, scores - scores[y] + 1)        

    # only sum j is not yi, so when j = yi, set to zero.    
    margins[y] = 0        

    # sum across all j    l
    oss_i = np.sum(margins)        

    return loss_i

Softmax classifier

Putting it all together:

\[ L_i = -\log \left( \frac{e^{s_{y_i}}}{\sum_j e^{s_j}} \right) \]

Question

Q1: What is the min/max possible softmax loss \(L_i\) ?

A1: \(0/+\infty\)

Q2: At initialization all \(s_j\) will be approximately equal; what is the softmax loss \(L_i\) , assuming C classes?

A2: \(\log C\)

Summary

评论区

对你有帮助的话请给我个赞和 star => GitHub stars
欢迎跟我探讨!!!