图像分类
图像分类的任务,就是对于一个给定的图像,预测它属于的那个分类标签(或者给出属于一系列不同标签的可能性)。图像是3维数组,数组元素是取值范围从0到255的整数。数组的尺寸是宽度x高度x3,其中这个3代表的是红、绿和蓝3个颜色通道。
以该图为例,计算机看到的是像素矩阵
且有可能因为某些因素改变(包括遮挡,光照等等)而导致整个矩阵大不相同,也就是说代表同一类别的图片,从像素矩阵上来看是不同的。这是图像分类的挑战
那么如何分类,我们不可能在写算法时指明要分类的物体是什么样的,有哪些特征,这很困难。所以一般通过给计算机大量的数据集,让它们自己去学习每个类具备的特征,这就是数据驱动方式
那么在数据驱动方式下,图像分类过程可以分为以下三步:
-
输入:输入是包含N个图像的集合,每个图像的标签是K种分类标签中的一种。这个集合称为训练集。
-
学习:这一步的任务是使用训练集来学习每个类到底长什么样。一般该步骤叫做训练分类器或者学习一个模型。
-
评价:让分类器来预测它未曾见过的图像的分类标签,并以此来评价分类器的质量。我们会把分类器预测的标签和图像真正的分类标签对比。毫无疑问,分类器预测的分类标签和图像真正的分类标签如果一致,那就是好事,这样的情况越多越好。
分类器
上述步骤中第二步,我们可以看作是机器的学习过程,或者说训练过程,最终的目的是得到一个分类器或者说模型,通过这个分类器可以对新输入的图片进行分类。
分类器有很多种,cs231n的第二章中主要介绍了Nearest Neighbor分类器和它的“升级版”k-Nearest Neighbor分类器,后面还会讲到线性分类器,这里先不提。
1.Nearest Neighbor分类器
它的原理就是通过将待测图片与训练集中的每一个图片进行比较,找到最相似的图片然后将测试图片贴上这个最相似图片的标签
那么如何衡量两个图片的相似程度?通过计算它们之间的距离,具体有两种:
L1距离(曼哈顿距离):单纯比较每个点的像素差取绝对值,然后将这些差值求和,得到的就是L1距离
L2距离(欧式距离):将像素差值平方后求和再开平方,得到的就是L2距离。
选择哪个距离作为衡量标准也是有讲究的,具体的要视你的应用场景而定,L1是依赖与坐标系统的,也就是说一旦改变坐标系统,L1距离也会发生变化,而L2是不受此影响。所以如果你输入的特征向量的值是有特殊含义的,那么L1显然更合适,若只是空间中的通用向量,而你不知道其中的不同元素实际上代表的含义,那么L2可能更自然一些(这句话是课程视频中Justin Johnson说的,我不是很理解,什么叫有特殊含义,这和坐标轴的改变有什么样的关系)
2.k-Nearest Neighbor分类器
如果只用最相似的1张图片的标签来作为测试图像的标签,会怎么样呢?课件中给出了一幅图
可以看到这样的分类效果是不太好的,原因在于每个颜色的边界很粗糙,而且绿色部分中间单独划出一块黄色也显得很突兀。
其实大可不必通过找到 最 相似的那 一 个图片来贴类标签,而是可以找到k个最相似的图片,然后由它们中的多数标签来决定测试图片属于哪一类,这称为投票。这就避免出现如图所示的情况了
上图最直观的感受就是k越大,边界(决策边界)越平滑,精确程度相对降低。当k取1时,实际上就是最邻近分类器。
超参数(hyperparameters)
上面讲到的距离选择L1和L2,K邻近分类器的K,都属于超参数。理论上它们不是通过算法得来的,而是根据经验提前设置好的。
那么如何去确定超参?
一般是通过验证集调优,也就是在验证集上面不断尝试,找到表现最好的那个参数保留下来。
当我们拿到一份数据集,通常是分为训练集和测试集,顾名思义,训练集用来做训练,而测试集是最后用来测试评估我们的算法的。
在这个基础上,我们还需将训练集分为训练集和验证集,验证集是用来超参数调优。因为建议是测试集尽量不要动,它是留作最后来测试评估算法的,如果过早用测试集来调优,可能会导致在测试集上表现很好,而实际应用中表现很差,也就是对测试集过拟合。
如果数据集比较小,可以使用交叉验证的方式。将一份训练集分为几份(几折),将一份作为一个验证集,在其他四份数据集上进行训练,依次循环。
Nearest Neighbor分类器的优劣
首先可以知道优点是简单,执行起来很快,但这通常指训练起来快,而测试的时候是很慢的(因为要比较每一个图片),这不是我们希望的。实际需求通常希望训练过程多花时间,而测试过程尽可能快。
其次,在某些特定场合中,最邻近分类器不失为一种好方法。但通常我们要分类的图片是很复杂的(高维数据),那么仅比较像素的不同是没法很好的完成分类。下图所示,右边三张图与左一的L2距离都相等,但从视觉感官上它们是存在差异的(尽管这里都可以看作是人,但通常要比较的图片数量巨大,不能保证像素差相同的都是同一类)
线性分类器
我们已经知道Nearest Neighbor最邻近分类器 几乎不做训练,而测试时需要比对测试图片与所有训练集图片,这在实际应用中是非常不好的。所以要采用更好的办法来解决图像分类问题,这里讲到了线性分类器,它分为评分函数和损失函数。
这节先讲了评分函数
在CIFAR-10中,图片被分为10个不同的类别(狗,猫,汽车等)。所以这里最终得到10个类别的分数。
可以看到W对于分数的影响较大,它是从训练集中得来的,通常称为权重,它的每一行 实际上就是一个分类器。所以我们要在训练中得到比较好的W在测试时才能更准确。可以看到这里的W就很不好,因为它使这张猫的图片在狗的分类上得分更高。关于如何衡量W的好坏,这是损失函数的任务,先不提。
所以一个线性分类器到底在做什么?
1.看作模板匹配:
关于权重W的另一个解释是它的每一行对应着一个分类的模板(有时候也叫作原型)。一张图像对应不同分类的得分,是通过使用内积(也叫点积)来比较图像和模板,然后找到和哪个模板最相似。从这个角度来看,线性分类器就是在利用学习到的模板,针对图像做模板匹配。从另一个角度来看,可以认为还是在高效地使用k-NN,不同的是我们没有使用所有的训练集的图像来比较,而是每个类别只用了一张图片(这张图片是我们学习到的,而不是训练集中的某一张),而且我们会使用(负)内积来计算向量间的距离,而不是使用L1或者L2距离。
2.将图像看做高维度的点:
既然图像被伸展成为了一个高维度的列向量,那么我们可以把图像看做这个高维度空间中的一个点(即每张图像是3072维空间中的一个点)。整个数据集就是一个点的集合,每个点都带有1个分类标签。
既然定义每个分类类别的分值是权重和图像的矩阵乘,那么每个分类类别的分数就是这个空间中的一个线性函数的函数值。我们没办法可视化3072维空间中的线性函数,但假设把这些维度挤压到二维,那么就可以看看这些分类器在做什么了:
图像空间的示意图。其中每个图像是一个点,有3个分类器。以红色的汽车分类器为例,红线表示空间中汽车分类分数为0的点的集合,红色的箭头表示分值上升的方向。所有红线右边的点的分数值均为正,且线性升高。红线左边的点分值为负,且线性降低。从上面可以看到,W的每一行都是一个分类类别的分类器。对于这些数字的几何解释是:如果改变其中一行的数字,会看见分类器在空间中对应的直线开始向着不同方向旋转。而偏差b,则允许分类器对应的直线平移。
线性分类器的难点
很明显 对于上述非线性分布的分类问题,线性分类器是很难解决的 但可以通过一些途径将其变为线性问题,这在后面会说到。