赞
踩
早期的相机
从动物到人类,从柱状表示到面部识别
再到最后的基于特征的识别系统,加入了不同环境下的变化
一个重点:图像分类
一般都建立与一些为了图片分类的工具上,然后我们讨论一下其他问题,比如目标检测与图像摘要生成
在目标检测中,我们对于猫狗一些物品的画像要画出边界框,说明这里有一只猫,一只狗。。。。标记出这些东西。
还有一些很多。。。
当做图像分类时,分类系统接收一些输入图像,并且系统已经清楚了一些已经确定了分类或者标签的集合,标签可能是猫、狗、汽车以及一些固定的类别标签集合等等;计算机的工作就是观察图片并且给它分配其中一些固定的分类标签。对于人来说这是非常简单的事情,但对计算机来说,却是非常困难的事情。
计算机呈现图片的方式是一大堆数字,图像可能就像下图所示的800*600的像素:
所以,对计算机来说,这就是一个巨大的数字阵列**,很难从中提取出猫咪的特征**,我们把这个问题称为“语义鸿沟”。对于猫咪的概念或者它的标签,是我们赋予图像的一个语义标签,而猫咪的语义标签和计算机实际看到的像素值之间有很大的差距。
对于同一只猫,从不同的角度拍出来的图像,它的数字阵列是不同,所有要同时让算法对这些变化能够做出调整;其实不仅只有角度的问题,还有光照条件等其他情况,算法都应该具有很好的鲁棒性(系统在异常情况下的正常工作的能力)。
所以算法在处理这些情况的时候是非常有挑战性的,相比人的大脑能够轻易的识别出来,如果让计算机来处理这些事情都会是很难的挑战。
如果使用python写一个图像分类器,定义一个方法,接受图片作为输入参数,经过一系列的操作,最终返回到图片上进行标记是猫还是狗等等。
对于猫来说,它有耳朵、眼睛、鼻子、嘴巴,而通过上一章中Hubel和Wiesel的研究,我们了解到**边缘对于视觉识别是十分重要的,**所以尝试计算出图像的边缘,然后把边、角各种形状分类好,可以写一些规则来识别这些猫。
但是如果想识别比如卡车、其他动物等,又需要重新从头再来一遍,所以这不是一种可推演的方法,我们需要的是一种识别算法可以拓展到识别世界上各种对象,由此我们想到了一种数据驱动的方法。
我们并不需要具体的分类规则来识别一只猫或鱼等其他的对象,取而代之的方法是:
(1)首先收集不同类别图片的示例图,制作成带有标签的图像数据集;
(2)然后用机器学习的方法来训练一个分类器;
(3)最后用这个分类器来识别新的图片,看是否能够识别。
所以,如果写一个方法,可以定义两个函数,一个是训练函数,用来接收图片和标签,然后输出模型;另一个数预测函数,接收一个模型,对图片种类进行预测。
import numpy as np class NearestNeighbor: def __init__(self): pass def train(self,X,y): """X是N*D ,y是一维的size是N""" self.Xtr=X self.ytr=y def predict(self,X): num_test=X.shape[0] y_pred=np.zeros(num_test,dtype=self.ystr.dtype) for i in range(num_test): distances=np.sum(np.abs(self.Xstr-X[i,:]),axis=1) min_index=np.argmin(distances) y_pred[i]=self.ytr[min_index] return y_pred
Q:
1.如果我们在训练集中有N个实例,训练和测试的过程可以有多快?
训练函数:只需要储存所以O(1)
预测函数:需要将实际图片n个与训练进行比较O(N)
2.由上述可知:邻算法是很慢的一个过程 ,那么,邻算法到底表现如何?
训练集:平面里的点
不同的类别(或者类标签):平面中的点的不同的颜色
3.邻算法是根据最近的点来切割空间进行着色
这个图片还有呈现出一些问题:
图像中集中了很多绿点中心却有一个黄色,因为我们只计算最近的点,所以在绿色区域的中间,我们黄色被分割了一块。而且绿色部分和别的颜色混合在一起,这个点可能是噪点或者失真信号,so,产生了k-近邻算法,他不只是寻找最近的点我们根据距离度量,找到k个邻近你的点,然后在这些邻近的点中进行投票,根据票数多的得出预测结果,在使用时,我们通常要求k的值尽可能大。
问题:上图中白色区域代表什么?
白色区域表示这个区域没有获得K-最近邻的投票,可以做大胆的假设,把它划分为一个不同的类别。
所以使用最近邻分类器时,总会给K赋一个比较大的值,这会是决策边界变得更加平滑,从而得到更好的结果。
KNN(K-最近邻算法),用红色和绿色分别标注了图像分类的正确与否:
取决于它的近邻值,可以看到KNN的表现效果不是很好,但如果可以使用一个更大的K值,那么投票操作的结果就可能会达到很好的分类效果。
当我们使用K-最近邻算法时,确定应该如何比较相对近邻数据距离值。比如,已经讨论过的L1距离,它是像素之间绝对值的总和;另一种常见的选择是L2距离,也就是欧式距离(平方和的平方根)。
这两种方式,L1取决于你选择的坐标系统,所以如果转动坐标轴,将会改变点之间的L1距离;而改变坐标轴对L2距离无影响。
问题:什么情况下L1距离比L2距离表现的更好?
主要和解决的问题相关,很难说哪一种更好,但是如果向量中的各个元素有着实际意义,那么L1可能更加好一点。
通过使用不同的距离度量,可以将K-最近邻分类器泛化到许多不同的数据类型上,而不仅仅是向量和图像。例如,假设想对文本进行分类,那么要做的就是对KNN指定一个距离函数,这个函数可以测量两段、两句话之间的距离。
因此,通过指定不同的距离度量,就可以很好地应用这个算法在基本上任何数据类型的数据上。
,讨论过的选择K的不同值,选择不同的距离度量,该如何根据问题和数据来选择这些超参数,K值和距离度量称之为超参数,它们不一定能从训练数据中学到。
那么尝试不同的超参数看看哪种更合适该如何去做呢?
错误的策略:
(1)选择能对训练集给出最高的准确率、表现最佳的超参数;
不要这么做,在机器学习中,不是要尽可能拟合训练集,而是要让分类器在训练集以外的未知数据上表现更好。
(2)所有的数据分成两部分:一部分是训练集,另一部分是测试集,然后在训练集上使用不同的超参数来训练算法,将训练好的分类器用在测试集上,再选择一组在测试集上表现最好的超参数;
同样不要这么做,机器学习系统的目的是让我们了解算法表现究竟如何,所以测试集的目的是给我们一种预估方法,如果采用这种方法,只能让我们算法在这组测试集上表现良好,但它无法代表在未见过的数据上的表现。
正确的策略:
(3)所有数据分成三部分:训练集、验证集和测试集,通常所做的是在训练集上用不同的超参数来训练算法,在验证集上进行评估,然后用一组超参选择在验证集上表现最好的,再把这组验证集上表现最好的分类器拿出来在测试集上运行,这才是正确的方法。(必须分割测试集和验证集)
(4)交叉验证:取出测试集数据,保留部分数据作为最后的测试集,剩余的数据不是分成训练集和验证集,而是将训练数据分成很多份,然后轮流将每一份都当成验证集。
问题:训练集和验证集的区别是什么?
算法可以看到训练集中的各个标签,但是在验证集中,只是用验证集中的标签来检查算法的表现
那么经过交叉验证可能会得到这样的一张图:
这里用了5折交叉验证,对每个K值,都对算法进行了5次不同的测试来了解这个算法表现如何;所以当训练一个机器学习的模型时,最后要画这样一张图,从中可以看出算法的表现以及各个超参数之间的关系,最终可以选出在验证集上最好的模型以及相应的超参数。
KNN在图像分类中很少用到:
(1)它的测试时间非常慢;
(2)像欧式距离或者L1距离这样的衡量标准用在比较图像上不太合适;
(3)维度灾难:KNN有点像把样本空间分成几块,意味着如果希望分类器有好的效果,需要训练数据密集的分布在空间中;而问题在于,想要密集的分布在样本空间中,需要指数倍的训练数据,然而不可能拿到这样高维空间中的像素。
线性分类是参数模型中最简单的例子,以下图为例:
通常把输入数据设为x,权重设为w,现在写一些函数包含了输入参数x和参数w,然后就会有10个数字描述的输出,即在CIFAR-10中对应的10个类别所对应的分数。
在深度学习中,整个描述都是关于函数F正确的结构,可以来编写不同的函数形式用不同的、复杂的方式组合权重和数据,这些对应于不同的神经网络体系结构,将他们相乘是最简单的组合方式,这就是一个线性分类器,。
发现:线性分类器,每个类别只能学习一个模板,如果这种模型出现变体。那么他将尝试求取所有不同的变体。并且只能识别一个单独的模板,来识别其中的每一个分类
线性分类器的另一个观点是回归到图像,作为点和高维空间的概念,可以想像每一张图像都是类似高维空间中的一个点,现在线性分类器尝试在线性决策边界上画一个线性分类面来划分一个类别和剩余其他类别,如下图所示:
图像分类就是输入一个元素为像素值的数组,然后给它分配一个分类标签
图像分类流程,如下:
输入:输入是包含N个图像的集合,每个图像的标签是K种分类标签中的一种。这个集合称为训练集。
学习:这一步的任务是使用训练集来学习每个类到底长什么样。一般该步骤叫做训练分类器或者学习一个模型。
评价:让分类器来预测它未曾见过的图像的分类标签,并以此来评价分类器的质量。我们会把分类器预测的标签和图像真正的分类标签对比。毫无疑问,分类器预测的分类标签和图像真正的分类标签如果一致,那就是好事,这样的情况越多越好。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。