一周前我就已经在看CS231n的网课了,但是当时并没有很好的总结知识点,所以内容不免遗忘许多,开始review啦,一边复习前面的知识点,一边学习后面的知识点。人类的视觉系统是很强大的,尽管这些年在计算机视觉领域我们取得了巨大的进步,但是我们仍有很长的路需要走。
在课程的最开始,我们了解计算机视觉及其发展历史和关于本课程的描述,接下来我们需要深入了解这些算法,学习这些算法在实践中到底是如何工作的。
本课程的第一个重点是图像分类问题。
在图像分类中,让你的算法接收一张图作为输入,从固定的类别集合中选出该图像所属的类别,从而对图像分类。
当你在做图像分类的时候,系统接收一些输入图像,比如说可爱的猫咪,并且系统已经清楚一些确定了分类或标签的集合,这些标签可能是一只狗狗或者一只猫咪,也有可能是一辆卡车,亦或是一架飞机,还有一些固定的类别标签集合,那计算机的工作就是看图片并且给它分配其中一些固定的分类标签。
仔细思考,计算机看一张图片时看到的是什么,它肯定没有一只猫咪的整体概念,和我们所看的图片当然是不同的,计算机呈现图片的方式其实就是一大堆数字。所以图像可能就是一些像800乘以600的像素,每一个像素由三个数字表示,给出像素红、绿、蓝三个值,所以,对于计算机来说,这是一个巨大的数字阵列,这很难从中提取猫咪的特性,我们把这个问题定义为语义鸿沟。对于猫咪的概念或者它的标签是我们赋给图像的一个语义标签,一只猫咪的语义概念和计算机实际看到的像素值之间有着很大的差距。对这些图片做简单的改变,比如视角、光照、遮挡、目标图像的变形等,数字矩阵中的每一个像素值都会不同,而我们算法对于这些情况应该都是兼容的。
我们想发明的是一些识别算法,可以拓展到识别世界上各种对象,所以基于此,我们想到用数据驱动的方法,我们不写具体的分类规则来识别一只猫或者鱼,取而代之的是,我们从网上抓取大量猫的图片数据集,或者抓取大量飞机 的图像数据集,抓取大量小鹿的图片数据集等等诸如此类,比如用谷歌图片搜索、引擎之类的工具收集到大量的不同类别图片的示例图,这种收集图片数据集的方法,实际上也挺花时间的,但是好在已经有很多很高质量可用的图片数据集,一旦有了数据集,我们训练机器来分类这些图片,机器会收集所有数据,用某种方式总结,然后生成一个模型,总结出识别出这些不同类对象的核心知识要素,然后我们用这些模型来识别新的图片来看能不能识别猫狗等等,所以我们的接口变成这样,写一个函数,不仅仅是输入一张图片,然后识别它是一只猫,我们会有两个函数,一个是训练函数,这些函数接收图片和标签然后输出模型,另一种是预测函数,接收一个模型,对图片种类进行预测正是用了这种方法。
这种数据驱动类的算法是比深度学习更广义的一种理念,对于一个简单的分类器,我们称为最近邻,在训练机器的过程中,我们什么也不做,我们只是单纯记录所有的训练数据,在图片预测的步骤中,我们去拿一些新的图片,去在训练数据中,寻找与新图片最相似的,然后基于此,来给出一个标签,是非常简单的算法,但是这些很多用到的属性,都是数据驱动的。具体来说,比如一个叫做CIFAR-10的数据集,这是在机器学习中很常用的一个测试数据集,在作业中我们也会用到这个数据集,数据集CIFAR-10会给出10个不同的类别,飞机、汽车、猫等等。每个类别会给出5万张训练数据图,大体平均分布在这10个种类中,还会有1万张额外的测试图片来测你的算法。所以当我们将最近邻算法用于这些图片,我们就能在训练集中找到最接近的示例(样本),因为他们来自训练集,因此我们知道这些最接近示例的标签,这时我们就可以说出这幅测试图片是什么。
如果给我们两张图片,我们该怎么比较它们,因为如果我们要将测试图片与所有的训练图片进行比较,我们将有很多不同的选择来确定需要什么样的比较函数,这里就要提到的是L1距离,我们也称之为曼哈顿距离,我们只是对这些图片中的单个像素点进行比较,假设我们的图片是4×4的小图片,我们只取测试图像左上角的像素,用它减去训练图像对应像素的值,然后取绝对值,得到这两幅图像这个像素的差别,将图像中所有像素的这个差值相加,这也是一种比较两幅图片的具体方法。
这里也有最近邻分类器的完整Python代码,它非常简明,因为我们使用了NumPy提供的向量运算,我们可以看到之前提到过的这个训练函数,将它运用于最近邻算法非常简单,你不需要做太多,只需要存储训练数据,在测试的时候,我们将输入图像,然后使用L1距离函数,将我们的测试图片与训练实例进行比较,然后在训练集中找到最相似的实例。
一些关于简单分类器的问题:
第一,如果我们在训练集中由N个实例,训练和测试的过程可以有多快?
当然,训练是连续的过程,因为我们不需要做任何事,我们只需要存储数据,但在测试时,我们需要停下来,我们要将数据集中N个训练实例与我们测试的图像进行比较,这是一个很慢的过程。在实际应用中,我们希望训练过程很慢,而测试过程很快,因为你可以想象,训练过程是在数据中心完成的,它可以负担起非常大的运算量,从而训练出一个优秀的分类器,然而,当你在测试过程部署分类器的时候,你希望它运行在手机、或者浏览器、或者其他低功耗设备,但你又希望分类器能够快速地运行,由此看来,最近邻算法有点落后了,卷积神经网络和其他参数模型则正好相反,他们会花很多时间在训练上,而测试过程则非常快,那么问题来了,在实际应用中,最近邻算法到底表现如何?所以我们画了这个图形,我们叫它最近邻分类器的决策区域,我们的训练集包含二维平面中的这些点,点的颜色代表不同的类别或不同的类标签,所以我们看到这里有五个类别,上面角落里有蓝色的点,紫色的点
在右上角,对整幅图像的每个点来说,我们将计算这些训练数据中最近的实例,然后在这些点的背景上着色标示出它的类标签,你可以发现最近邻分类器是根据相邻的点来切割空间并进行着色,但这个分类器并非是个好的选择,看看这张图片,你会发现最近邻分类器的一些问题,其中一个就是,图像的中部集中了大多数的绿点,但在中心却有一个黄点,因此我们只计算最近的点,所以在绿色区域的中间,这个黄色被分割成了独立的一块,这其实并不太好,也许那些点事实上应该是绿色,还有相似的情况,由于一个绿点,绿色区域像一根手指一样插入了蓝色区域,而这个点可能是噪声或者失真信号(当然啦,这里用的图片和我的描述可能并不相符,但是意思是相同的),由这个动机出发,产生了K-最近邻算法,它不只是寻找最近的点,我们会做一些特殊的操作,根据我们的距离度量,找到最近的K个点,然后在这些相邻点中进行投票,然后这些票数多的近邻点预测出结果,这是完成这个任务最简单的算法,这里我们用同样的数据集,使用不同K值的最近邻分类器,所以我们总会给K选一个较大的值,这样会使决策边界更加平滑从而得到更好的结果。
第二,这些白色区域表示的是什么呢?
白色区域表示这些点周围没有投票,也可以大胆归为另外一种类别。
来源:oschina
链接:https://my.oschina.net/u/4280959/blog/4438674