Lecture 2:Image Classification pipeline
1.Image Classification(图片分类):a core task in Computer Vision(计算机视觉中的核心部分)
图像分类的基本任务就是比如将狗、猫和飞机等区分开来,在这之前我们先要将图片转换为一张巨大的数字表单,然后从所有种类中,给这个表单选定一个标签。图片分类是计算机视觉中的最基本的一部分,比如计算机视觉中的物体检测就是在这个基础上进行细小的改动,所以学会图片分类,其他工作就是小菜一碟了。
比如一张图片,它在计算机看来就是一张巨大的数字表单,可以大致由一个300*100*3的三位数组表示,这里的3来自于图片红绿蓝三色道,所以图片的全部数字都是处于0~255之间的,这些数字反映的是亮度以及每个单点三基色的权值,所以难度在于,当你想要处理这表单中数以百万计的数字,并对其分类,如猫类,这个问题是相当复杂的。此外,通过调整相机旋转、调亮度、光线等操作,还有图片对象的形变(Deformation,比如猫的不同姿势),对象被遮掩(Occlusion,只可以看到10%),同类演变(Intraclass variation)等相当多的干扰,一个物体可以完全不同,但是要在姿势改变时候,依旧识别出这些猫来,就是我们的算法可以解决这些所有问题。
An image classifier(图片分类器)是什么样子的呢?我们构建一个三维空间,将x轴上的值定位种类标签值,但是没有一种显示的方式来实现识别猫或者其他类别的算法代码,在数据结构中的简单算法比如冒泡排序(bubble sort)等算法的变体中,并没有哪种可以用来检测猫。我们要做的是检测并勾画出图片的边界,按照边界形状与连接方式进行分类,这会让你学习到这类东西的“样本集合”,我们可以尽量找到他们的各种形态,比如我们看到任何像猫的耳朵,我们便认为检测到猫,或者如果我们检测到猫的某些结构特征,一定程度上,我们可以认为检测到猫了,你也可以设定一些别的规则,但是问题在于,如果我现在要识别船或者人,就得回到画板去想“船和人的边界和明显特征是什么”,显然这是不可扩展的分类方法。
我们在机器学习的框架中经常采用的数据驱动的方法效果更好。我们有一个训练集,开始训练一个模型,这个模型是一个类,然后可以使用这个模型去对测试数据进行分类,因此当得到一张新的图片的时候,我可以参考我的训练数据,然后做一些基于模式匹配和统计的工作,这是一个利用此框架来工作的简单例子。
2.Nearest Neighbor Classifier(近邻算法分类器)
1)Remember all training images and their labels ;
2)Predict the label of the most similar training image
对测试图像和之前看过的每一张训练集中的图像,进行一一比对,然后传送相应的标签。因此我只需要浏览所有图片,我们在处理具体的案例时会经理这些过程,测试集的图片是32*32的小缩略图。
那我们如何做距离的度量呢,如何来做比较呢?
最简单的方式可能就是曼哈顿距离算法(L1距离算法),我们需要做的是逐元素比较,所有的像素值,形成绝对值的差,将差值全部相加。也就是说,只要观察每一个像素的位置,得到同一个空间位置的像素差,将其全部相加,就得到了相似性,找到距离最近的标签,得到较为相似的图片。此外,当训练集的规模增大的时候,则该算法需要独立地比较每一个训练样本,所以效率会线性地减慢。不管训练集有多大,我们对于每一张测试实例进行分类的计算量都将是恒定的。
使近邻算法分类器速度加快的方法,这就是近似近邻算法(Approximate Nearest Neighbor Classifier)。
另一个人们喜欢在实践中使用的度量叫做欧式距离(L2距离)。欧式距离不是计算绝对值差的和,而是计算这些图像间差值的平方和。
3.k-Nearest Neighbor(KNN最邻近分类算法)
Q1.What is the best distance to use?
Q2.What is the best value of k to use?
Q3.How do we set the hyperparameters(超参数)?
A.Very problem-dependent.Must try them all out and see what works best.(必须要各个情况都尝试,看哪个效果最好)。有一个思路就是我们对大量不同的参数进行试验,比如1,2,3,4,5,6,。。。。。。2000,所以我们使用训练数据,然后试验,即采用不同的测量标准,效果最好的便是我所需要的,使用线段表示不是一个好的选择。所以测试集是一个泛化程度的代表,但是你不应该只相信测试集,事实上,你应该忘记你测试过的数据,将测试的数据放在一边假装没有这些数据,这将会使你得知你的算法对于其他数据的泛化程度。你有时候会看到你的算法在训练过程中表现得非常好,但是在测试过程中表现得不是很好,这就是说明你的算法分类能力不是很好,说明你的分类器已经过拟合了(因为拟合程度的选择将会影响到分类器的泛化能力,测试数据集是非常有节制的使用)。
我们应该做的是将我们的训练集分成“折”,有时候会用到一个“5折验证”,这时候,安全的把训练数据分成5等份,也就是说我们会使用训练数据中的20%来作为想象中的验证集来调整超参数,从而对不同超参数的学习效果进行测试;将在另外4折中进行训练,取不同数量的近邻值做多数投票,通过比对不同k值下验证集的平均正确率,来得出究竟取多少个近邻值才能得出最准确的结果;如果对训练结果不太满意,有时可以使用交叉验证法,在使用交叉验证法的过程中,这些选择中反复选择测试验证折,首先使用1折到4折来做训练,用5折做测试,然后在5个折中循环选择作为验证集,然后,在所有可能的测试折中的选择中选出效果最好的,从所有可能的方案中采用效果最好的方案。将其做成折线图,横轴是交叉验证法中最近邻分类器的k值,纵轴表示的是准确率,我们对不同值的k进行试验,这就是k在5种折的选择中变化的情况。可以用交叉验证法来确定最好的参数。
不同的数据集需要不同的选择去判断,不同的方法会有不同的泛化边界。
在实际应用中,很少会用到KNN算法,首先是因为其效率低,其次,这是在图像上的一些小测验,这些图片是高维度的物体,它们看上去不够自然和直观,但是KNN无法将这些设定的不同分辨出来(distance metrics on level of whole images can be very unintuitive),这种情况下,当你想通过距离来进行高维度物体的判断上,就会有不直观的情况发生。
4.线性分类器(Linear Classification)
卷积神经网络可以识别图片,并描述图片,不只是图像领域,还可以应用于语音等多种领域。
5.损失函数(loss function)
损失函数是一种能够定量的测量每一个W,在我们的数据集上表现得有多差的方法。这个函数可以定量的测定分类器工作的好坏,即得出一个数学表达式来确切的告诉我们这个分类器的好坏。一旦能找到一个W(find a W that minimizes the loss),使得你损失的值非常低,这说明能接近正确的分类你所有的图片。
主要是能找到能够分清楚所有图片的W分类器。通过观察损失函数的梯度,可以确定在哪个方向上损失函数的数值会减少,然后通过调整参数(权值W)使得函数值向这个方向一点点运动从而达到降低损失值的目的。