- 作者:韩信子 @ShowMeAI
- 教程地址:http://www.showmeai.tech/tutorials/37
- 本文地址:http://www.showmeai.tech/article-detail/261
- 申明:版权所有,转载请分割平台与作者并注明出处
- 珍藏 ShowMeAI 查看更多精彩内容
本系列为 斯坦福 CS231n《深度学习与计算机视觉 (Deep Learning for Computer Vision)》的全套学习笔记,对应的课程视频能够在 这里 查看。更多材料获取形式见文末。
引言
图像分类 是计算机视觉的外围工作,计算机视觉畛域中很多问题(比方 指标检测 和 语义宰割 ),都能够关联到图像分类问题。 图像分类 问题,就是已有固定的分类标签汇合,而后对于输出的图像,从分类标签汇合中找出一个分类标签,最初把分类标签调配给该输出图像。在本篇内容汇总,ShowMeAI 将给大家解说数据驱动的模型算法,包含简略的 KNN 模型 和 线性分类模型。
本篇重点
- 数据驱动办法
- KNN 算法
- 线性分类
1. 图像分类的挑战
对于计算机而言,图像等同于一个像素矩阵;而对人类,图像是蕴含丰盛语义信息的多媒体出现,对应不同的物体类别,所以对计算机而言存在微小的语义鸿沟。
比方,给计算机输出如下小猫的图片,计算机图像分类模型会读取该图片,并计算该图片属于汇合 \({猫, 狗, 帽子, 杯子}\) 中各个标签的概率。但读取的输出图像数据是一个由数字组成的微小的 \(3\) 维数组。
在下图中,猫的图像大小高 \(600\) 像素,宽 \(800\) 像素,有 \(3\) 个色彩通道(红、绿和蓝,简称 RGB),因而它蕴含了 \(600 \times 800 \times 3=1440000\) 个数字,每个数字都是在范畴 \(0 \sim 255\) 之间的整型,其中 \(0\) 示意全黑,\(255\) 示意全白。
咱们的工作就是把这些数字变成一个简略的标签,比方「猫」。
![图像分类; 图像分类的挑战; 计算机 [眼] 中的图像; 2-1](https://img-blog.csdnimg.cn/i…)
图像分类算法要足够强壮(鲁棒,robust),咱们心愿它可能适应下述变动及组合:
- 视角变动(Viewpoint variation):同一个物体,摄像机能够从多个角度来展示。
- 大小变动(Scale variation):物体可视的大小通常是会变动的(不仅是在图片中,在真实世界中大小也是变动的)。
- 形变(Deformation):很多货色的形态并非变化无穷,会有很大变动。
- 遮挡(Occlusion):指标物体可能被挡住。有时候只有物体的一小部分(能够小到几个像素)是可见的。
- 光照条件(Illumination conditions):在像素层面上,光照的影响十分大。
- 背景烦扰(Background clutter):物体可能混入背景之中,使之难以被识别。
- 类内差别(Intra-class variation):一类物体的个体之间的形状差别很大,比方椅子。这一类物体有许多不同的对象,每个都有本人的形状。
如下图所示是一些变动和图像识别的挑战:
2. 数据驱动的形式
一种实现形式是「硬编码 」:先获取猫图像的边缘失去一些线条,而后定义规定比方 三条线穿插是耳朵之类。然而这种形式的辨认成果不好,并且不能辨认新的物体。
咱们会采纳 数据驱动算法 :不具体写出辨认每个物体对应的规定,而是 针对每一类物体,找到大量样例图片,灌给计算机进行机器学习,演绎模式法则,生成一个分类器模型,总结出辨别不同类物体的外围常识因素,而后用训练好的模型,辨认新的图像。
数据驱动算法 过程如下:
- 输出:输出是蕴含 \(N\) 个图像的汇合,每个图像的标签是 \(K\) 种分类标签中的一种。这个汇合称为训练集。
- 学习:这一步的工作是应用训练集来学习每个类的模式法则。个别该步骤叫做分类器训练或者模型学习。
- 评估:让分类器对它未曾见过的图像进行分类,把分类器预测的标签和图像真正的分类标签(根本事实) 比照,并以此来评估分类器的品质。
2.1 最邻近算法
本局部内容也能够参考 ShowMeAI 的 图解机器学习教程 中的文章详解 KNN 算法及其利用
咱们这里介绍第 1 个分类器算法:最近邻算法。训练过程只是简略的记住图像数据和标签,预测的时候和训练数据中图片比拟找出最靠近的输入标签。这个分类器和卷积神经网络没有任何关系,理论中也极少应用,但通过实现它,能够对解决图像分类问题的办法有个根本意识。
1) 图像分类数据集:CIFAR-10
CIFAR-10 是一个十分风行的图像分类数据集。这个数据集蕴含 10 种分类标签,60000 张 \(32 \times 32\) 的小图像,每张图片含有一个标签。这 60000 张图像被分为蕴含 50000 张(每种分类 5000 张)图像的训练集和蕴含 10000 张图像的测试集。
假如当初咱们用这 50000 张图片作为训练集,将余下的 10000 作为测试集并打上标签,Nearest Neighbor 算法将会拿着测试图片和训练集中每一张图片去比拟,而后将它认为最类似的那个训练集图片的标签赋给这张测试图片。
后果如下图所示,成果并不是特地好。
- 右边:CIFAR-10 数据库的样本图像;
- 左边:第一列是测试图像,前面是应用 Nearest Neighbor 算法,依据像素差别,从训练集中选出的 10 张最相似的图片
那么具体 如何比拟两张图片呢?咱们有一些间隔度量计算方法,上面开展介绍一下。
2) L1 间隔(曼哈顿间隔)
间隔度量的数学知识也能够参考 ShowMeAI 的系列教程 图解 AI 数学根底 中的文章 线性代数与矩阵论 对各种间隔度量的开展解说
在本例中,就是比拟 \(32 \times 32 \times 3\) 的像素块。最简略的办法就是一一像素比拟,最初将差别值全副加起来。行将两张图片先转化为两个向量 \(I_{1}\) 和 \(I_{2}\),而后计算他们的 L1 间隔:
$$
d_{1} (I_{1} ,I_{2} )=\sum_{p}\vert I_{1}^p -I_{2}^p \vert
$$
- 其中 \(p\) 为像素点,\(I^p\) 示意第 \(p\) 个像素点的值。
- 两张图片应用 L1 间隔来进行比拟,即一一像素求差值,而后将所有差值加起来失去一个数值。如果两张图片截然不同,那么 L1 间隔为 \(0\);然而如果两张图片很是不同,那 L1 值将会十分大。
下图是仅一个 RGB 通道的 \(4 \times 4\) 图片计算 L1 间隔。
上面看具体 编程如何实现:
① 首先,咱们将 CIFAR-10 的数据加载到内存中,并分成 4 个数组:训练数据和标签,测试数据和标签。
Xtr, Ytr, Xte, Yte = load_CIFAR10('data/cifar10/') # 这个函数能够加载 CIFAR10 的数据
# Xtr 是一个 50000x32x32x3 的数组,一共 50000 个数据,# 每条数据都是 32 行 32 列的数组,数组每个元素都是一个三维数组,示意 RGB。# Xte 是一个 10000x32x32x3 的数组;# Ytr 是一个长度为 50000 的一维数组,Yte 是一个长度为 10000 的一维数组。Xtr_rows = Xtr.reshape(Xtr.shape[0], 32 * 32 * 3)
# Xtr_rows 是 50000x3072 的数组,按每个像素点排列,每个像素点有三个值。Xte_rows = Xte.reshape(Xte.shape[0], 32 * 32 * 3)
# Xte_rows 是 10000x3072 的数组
''' shape 会返回数组的行和列数元组:(行数,列数),shape[0]示意行数,
Xtr.shape[0]会返回 50000;Xtr.shape 会返回(50000,32,32,3)Xtr.reshape(50000,3072)会将 Xtr 重形成 50000x3072 数组,等于 np.reshape(Xtr, (50000,3072))'''
- Xtr(大小是 50000x32x32x3)存有训练集中所有的图像
- Xte(大小是 10000×3072)存有测试集中所有的图像
- Ytr 是对应的长度为 50000 的 1 维数组,存有图像对应的分类标签(从 0 到 9)
- Yte 对应长度为 10000 的 1 维数组
当初咱们失去所有的图像数据,每张图片对应一个长度为 3072 的行向量。
② 接下来训练一个分类器并评估成果。咱们经常应用准确率作为评估规范,它形容了咱们预测正确的得分。
本例中 OK,很多其余利用中准确率并不一定是最佳的评估准则,能够参考 ShowMeAI 的 图解机器学习教程 中的文章详解 模型评估办法与准则
nn = NearestNeighbor() # 创立一个最邻近分类器对象
nn.train(Xtr_rows, Ytr) # 用训练图片数据和标签训练分类器
Yte_predict = nn.predict(Xte_rows) # 预测测试图片的标签
# 并输入预测准确率,是一个平均值
print 'accuracy: %f' % (np.mean(Yte_predict == Yte) )
- 请留神当前咱们实现的所有分类器都须要有这个接口函数(API):
train(X, y)
函数。该函数应用训练集的数据和标签来进行训练。 - 从其外部来看,类应该实现一些对于标签和标签如何被预测的模型。这里还有个
predict(X)
函数,它的作用是预测输出的新数据的分类标签。
上面就是应用 L1 间隔的 Nearest Neighbor 分类器的实现:
import numpy as np
class NearestNeighbor(object):
def __init__(self):
pass
def train(self, X, y):
""" X 是 NxD 维的数组,每一行都是一个样本,比方一张图片,D 是样本的数据维度;Y 是长度为 N 的一维数组。"""
# 最邻近分类器只是简略的记住所有的训练数据
self.Xtr = X
self.ytr = y
def predict(self, X):
"""X 是 NxD 维的数组,每一行都是一个心愿预测其标签的样本"""
num_test = X.shape[0]
# 确保输入的标签数据类型和输出的标签格局统一,长度是测试样本数
Ypred = np.zeros(num_test, dtype = self.ytr.dtype)
# 循环所有测试样本数,即测试数组的行数
for i in range(num_test):
# 为第 i 张测试图片找到最靠近的训练图片
# 应用 L1 间隔 (差值的绝对值求和)
'''self.Xtr - X[i,:] 利用流传机制,求测试集第 i 张图片对应的行向量和
训练集所有图片行向量的差值,失去一个一个 50000x3072 的差值矩阵;abs(self.Xtr - X[i,:] )会将矩阵所有元素求绝对值;而后 axis = 1 会对差值矩阵按行求和,最终失去一个长度为 50000 的一维
数组,寄存第 i 张图片和训练集所有 50000 张图片的 L1 间隔。'''
distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)
min_index = np.argmin(distances) # 获取间隔最小的训练集图片索引
Ypred[i] = self.ytr[min_index] # 预测第 i 张测试集图片的标签时与其最靠近的训练集图片索引
return Ypred
这段代码的训练工夫复杂度为 \(O(1)\),因为只是简略的存储数据,不论数据多大,都是一个绝对固定的工夫;如果训练集有 \(N\) 个样本,则预测工夫复杂度为 \(O(N)\),因为测试图片要和训练集每张图片进行比拟。
这是一个不太好的分类器,理论对分类器的要求是,咱们心愿它预测的时候要快,训练的时候能够慢。
这段代码跑 CIFAR-10,准确率能达到 \(38.6\%\)。这比随机猜想的 \(10\%\) 要好,然而比人类辨认的程度和卷积神经网络能达到的 \(95\%\) 还是差很多。
3) L2 间隔(欧式间隔)
间隔度量的数学知识也能够参考 ShowMeAI 的系列教程 图解 AI 数学根底 中的文章 线性代数与矩阵论 对各种间隔度量的开展解说
另一个罕用的办法是 L2 间隔,从几何学的角度,能够了解为它在计算两个向量间的欧式间隔。L2 间隔的公式如下:
$$
d_{2} (I_{1},I_{2})=\sqrt{\sum_{p}(I_{1}^p – I_{2}^p )^2 }
$$
- 仍旧是在计算像素间的差值,只是先求差值的平方,而后把这些平方全副加起来,最初对这个和开方。
此时的代码只需改变计算间隔差别的一行:
distances = np.sqrt(np.sum(np.square(self.Xtr - X[i,:]), axis = 1))
'''np.square(self.Xtr - X[i,:]) 会对差值矩阵的每一个元素求平方'''
留神在这里应用了 np.sqrt
,然而在理论中可能不必。因为对不同间隔的绝对值求平方根尽管扭转了数值大小,但仍然放弃了不同间隔大小的程序。这个模型,正确率是 \(35.4\%\),比方才低了一点。
4) L1 和 L2 比拟
在 L1 间隔更依赖于坐标轴的选定,坐标轴抉择不同 L1 间隔也会跟着变动,断定的数据归类的边界会更趋向于贴近坐标系的轴来宰割所属区域,而 L2 的话相对来说与坐标系的关联度没那么大,会造成一个圆,不追随坐标轴变动。
在面对两个向量之间的差别时,L2 比 L1 更加不能容忍这些差别。也就是说,绝对于 1 个微小的差别,L2 间隔更偏向于承受多个中等水平的差别(因为会把差值平方)。
L1 和 L2 都是在 p-norm 罕用的非凡模式。
当图像中有特地在意的特色时能够抉择 L1 间隔;当对图像中所有元素未知时,L2 间隔会更天然一些。最好的形式是两种间隔都尝试,而后找出最好的那一个。
2.2 k 最近邻分类器
本局部内容也能够参考 ShowMeAI 的 图解机器学习教程 中的文章详解KNN 算法及其利用
只用最类似的 1 张图片的标签来作为测试图像的标签,有时候会因为参照不够多而成果不好,咱们能够应用 k-Nearest Neighbor 分类器。KNN 的思维是:找最类似的 \(k\) 个图片的标签,\(k\) 中数量最多的标签作为对测试图片的预测。
当 \(k=1\) 的时候,k-Nearest Neighbor 分类器就是下面所说的最邻近分类器。
如下图所示,例子应用了 2 维的点来示意图片,分成 3 类(红、绿、蓝)。不同色彩区域代表的是应用 L2 间隔的分类器的决策边界。
下面示例展现了 NN 分类器和 KNN(\(k=5\))分类器的区别。从直观感触上就能够看到,更高的 \(k\) 值能够让分类的成果更平滑,使得分类器对于异样值更有抵抗力。
- 在 \(k=1\) 时,异样的数据点(比方:在蓝色区域中的绿点)制作出一个不正确预测的孤岛。
-
在 \(k=5\) 时分类器将这些不规则都平滑了,使得它针对测试数据的 泛化(generalization)能力更好。
- 留神,5-NN 中也存在一些红色区域,这些区域是因为 5 个近邻标签中的最高数雷同导致的分类含糊(即图像与两个以上的分类标签绑定)。
- 比方:2 个街坊是红色,2 个街坊是蓝色,还有 1 个是绿色,所以无奈断定是红色还是蓝色。
1) 超参数调优
模型调优,超参数的试验抉择办法也能够参考 ShowMeAI 的文章 图解机器学习 | 模型评估办法与准则 和 深度学习教程 | 网络优化:超参数调优、正则化、批归一化和程序框架
- KNN 分类器须要设定 \(k\) 值,如何抉择 \(k\) 值最合适?
- L1 间隔和 L2 间隔选哪个比拟好(还是应用其余的间隔度量准则例如点积)?
所有这些抉择,被称为 超参数(hyperparameter)。在基于数据进行学习的机器学习算法设计中,超参数是很常见的。
超参数是须要提前设置的,设置实现后模型才能够训练学习,具体的设置办法通常要借助于试验,尝试不同的值,依据成果体现进行抉择。
特地留神:不能应用测试集来进行调优。
- 如果应用测试集来调优,而且算法看起来成果不错,真正的危险在于:算法理论部署后,性能可能会远低于预期。这种状况,称之为算法对测试集过拟合。
- 大家能够了解为,如果应用测试集来调优,实际上就是把测试集当做训练集,由测试集训练进去的算法再预测测试集,性能天然会看起来很好,但理论部署起来成果就会差很多。
- 最终测试的时候再应用测试集,能够很好地近似度量分类器的泛化性能。
测试数据集只能应用一次,而且是在训练实现后评估最终模型时应用,不可用来调优!
办法 1:设置验证集
从训练集中取出一部分数据用来调优,称之为 验证集(validation set)。以 CIFAR-10 为例,能够用 49000 个图像作为训练集,用 1000 个图像作为验证集。验证集其实就是作为假的测试集来调优。
代码如下:
# 假如 Xtr_rows, Ytr, Xte_rows, Yte 还是和之前一样
# Xtr_rows 是 50,000 x 3072 的矩阵
Xval_rows = Xtr_rows[:1000, :] # 取前 1000 个训练集样本作为验证集
Yval = Ytr[:1000]
Xtr_rows = Xtr_rows[1000:, :] # 剩下的 49,000 个作为训练集
Ytr = Ytr[1000:]
# 找出在验证集体现最好的超参数 k
validation_accuracies = []
for k in [1, 3, 5, 10, 20, 50, 100]:
# 应用一个明确的 k 值评估验证集
nn = NearestNeighbor()
nn.train(Xtr_rows, Ytr)
# 这里假如一个修改过的 NearestNeighbor 类,能够把 k 值作为参数输出
Yval_predict = nn.predict(Xval_rows, k = k)
acc = np.mean(Yval_predict == Yval)
print 'accuracy: %f' % (acc,)
# 把每个 k 值和相应的准确率保存起来
validation_accuracies.append((k, acc))
程序完结后,作图剖析出哪个 \(k\) 值体现最好,而后用这个 \(k\) 值来跑真正的测试集,并作出对算法的评估。
办法 2:穿插验证
训练集数量较小(因而验证集的数量更小)时,能够应用 穿插验证 的办法。还是用方才的例子,如果是穿插验证集,咱们就不是取 1000 个图像,而是将训练集均匀分成 5 份,每份 10000 张图片,其中 4 份用来训练,1 份用来验证。而后咱们循环着取其中 4 份来训练,其中 1 份来验证,最初取所有 5 次验证后果的平均值作为算法验证后果。
上面是 5 份穿插验证对 \(k\) 值调优的例子。针对每个 \(k\) 值,失去 5 次验证的准确率后果,取其平均值,而后对不同 \(k\) 值的均匀体现画线连贯。
上图能够看出,本例中,当 \(k=7\) 的时算法体现最好(对应图中的准确率峰值)。如果咱们将训练集分成更多份数,直线个别会更加平滑(乐音更少)。
理论状况下,深度学习不会应用穿插验证,次要是因为它会消耗较多的计算资源。个别间接把训练集依照 \(50\% \sim 90\%\) 的比例分成训练集和验证集。然而训练集数量不多时能够应用穿插验证,个别都是分成 3、5 和 10 份。
2) KNN 分类器长处
① 易于了解,实现简略。
② 算法的训练不须要花工夫,因为其训练过程只是将训练集数据存储起来。
3) KNN 分类器毛病
① 测试要花费大量工夫
- 因为每个测试图像须要和所有存储的训练图像进行比拟在理论利用中,关注测试效率远远高于训练效率;
② 应用像素差别来比拟图像是不够的,图片间 L2 间隔小,更多的是被背景主导而不是图片语义内容自身主导,往往背景类似图片的 L2 间隔就会小。
- 也就是说,在高维度数据上,基于像素的类似和基于感官上的类似十分不同。感官上不同的两张图片,可能有雷同的 L2 间隔。
③ 维度劫难
- KNN 有点像训练数据把样本空间分成几块,咱们须要训练数据密集的散布在样本空间里,否则测试图片的最邻近点可能理论间隔会十分远,导致和最靠近的训练集样本实际上齐全不同。然而如果使训练数据密集散布,须要的训练集数量指数倍减少,是数据维度的平方。
4) 理论利用 KNN
上面是一些对于理论利用 KNN 算法的倡议
① 预处理数据
- 对数据中的特色进行 归一化(normalize),让其具备零均值(zero mean)和单位方差(unit variance)。本大节不探讨,是因为图像中的像素都是同质的,不会体现出较大的差别散布,不须要标准化解决。
② 降维
- 如果数据是高维数据,思考应用降维办法,比方 PCA 或者随机投影。
③ 将数据随机分入训练集和验证集
- 个别法则,\(70\% \sim 90\%\) 数据作为训练集。这个比例依据算法中有多少超参数,以及这些超参数对于算法的预期影响来决定。
- 如果须要预测的超参数很多,那么就应该应用更大的验证集来无效地预计它们;如果放心验证集数量不够,那么就尝试穿插验证办法;如果计算资源足够,应用穿插验证更好(份数越多,成果越好,也更消耗计算资源)。
④ 在验证集上调优
- 尝试足够多的 \(k\) 值,尝试 L1 和 L2 两种范数计算形式。
⑤ 减速分类器
- 如果分类器跑得太慢,尝试应用 ANN 库(比方 FLANN 来减速这个过程,其代价是升高一些准确率。
⑥ 对最优的超参数做记录
- 记录最优参数后,不要应用最优参数的算法在残缺的训练集上运行并再次训练,这样做会毁坏对于最优参数的预计。
- 间接应用测试集来测试用最优参数设置好的最优模型,失去测试集数据的分类准确率,并以此作为你的 KNN 分类器在该数据上的性能体现。
3. 线性分类:评分函数
3.1 线性分类概述
KNN 模型中训练过程中没有应用任何参数,只是单纯的把训练数据存储起来(参数 k 是在预测中应用的,找出 \(k\) 个靠近的图片,而后找出标签最多的,并且 \(k\) 是超参数,是人为设定的)。
与之绝对的是 参数模型,参数模型往往会在训练实现后失去一组参数,之后就能够齐全扔掉训练数据,预测的时候只需和这组参数做某种运算,即可依据运算后果做出判断。线性分类器是参数模型里最简略的一种,但却是神经网络里很重要的根底模块。
线性分类的办法由两局部组成:
① 评分函数(score function)
- 它是原始图像数据到类别分值的映射。
② 损失函数(loss function)
- 它用来量化评分函数计算的分数与实在标签之间的一致性。该办法可转化为一个最优化问题,在最优化过程中,通过更新评分函数的参数来最小化损失函数值。
3.2 评分函数
评分函数将图像的像素值映射为各个分类类别的得分,得分高下代表图像属于该类别的可能性高下。下面的所有阐明都比拟形象,上面以具体的例子阐明。
从新回到 KNN 应用的 CIFAR-10 图像分类数据集。
假如咱们的训练集有 \(N\) 个样本,这里 \(N=50000\),每个样本 \(x_{i}b \in R^D\),其中 \(i = 1,2,\cdots,N\),\(D=3072\);每个 \(x_{i}\) 对应着一个标签 \(y_{i}\),\(y_{i}\) 在 \([1, K]\) 上取值,\(K\) 示意总分类数,这里 \(K=10\)。当初能够定义评分函数:\(f:R^D \rightarrow R^K\),即把一个 \(D\) 维的图像映射为 \(K\) 个类别的分数。
最简略的模型是线性模型:参数和输出数据相乘。即:
$$
f(x_{i},W,b)=Wx_{i}+b
$$
- 上式中参数 \(W\) 被称为 权重 ,\(b\) 被称为 偏置项
- 在下面的公式中,假如每个图像数据都被拉长为一个长度为 \(D\) 的列向量,大小为 \([D \times 1]\)。其中大小为 \([K \times D]\) 的矩阵 \(W\) 和大小为 \([K \times 1]\) 的列向量 \(b\) 为该函数的 参数(parameters)。
还是以 CIFAR-10 为例,\(x_{i}\) 就蕴含了第 \(i\) 个图像的所有像素信息,这些信息被拉成为一个 \([3072 \times 1]\) 的列向量,\(W\) 大小为 \([10 \times 3072]\),\(b\) 的大小为 \([10 \times 1]\)。因而,输出 \(3072\) 个数字(原始像素数值),函数输入 \(10\) 个数字(不同分类失去的分值),是一个 \(3072\) 维到 \(10\) 维的映射。
留神:
- 经常混用 权重 (weights)和 参数(parameters)这两个术语,实际上数据和参数相乘,就相当于数据占的比重,这个权重就是参数值;
- 该办法的一个劣势是训练数据是用来学习参数 \(W\) 和 \(b\) 的,一旦训练实现,训练数据就能够抛弃,留下学习到的参数即可。当测试图像时能够简略地把图像数据输出给函数,函数计算出的分类分值来进行分类;
- 输出数据 \((x_{i},y_{i})\) 是给定且不可扭转的,但参数 \(W\) 和 \(b\) 是可扭转的。指标就是通过扭转这些参数,使得计算出来的分类分值状况和训练集中图像数据的实在类别标签相符;
- 只需一个矩阵乘法和一个矩阵加法就能对一个测试数据分类,这比 KNN 中将测试图像和所有训练数据做比拟的办法要高效很多。
3.3 了解线性分类器
1) 了解一:W 是所有分类器的组合
如上图所示,将小猫的图像像素数据拉伸成一个列向量 \(x_i\),这里为不便阐明,假如图像只有 4 个像素(都是黑白像素,不思考 RGB 通道),即 \(D=4\);有 \(3\) 个分类(红色代表猫,绿色代表狗,蓝色代表船,色彩仅代表不同类别,和 RGB 通道没有关系),即 \(K=3\)。\(W\) 矩阵乘列向量 \(x_i\),失去各个分类的分值。
实际上,咱们能够看到,参数矩阵 \(W\) 相当于是三个分类器的组合,\(W\) 的每一行都是一个分类器,别离对应猫、狗、船。在线性模型中每个分类器的参数个数与输出图像的维度相当,每个像素和对应的参数相乘,就示意该像素在该分类器中应占的比重。
须要留神的是,这个 \(W\) 一点也不好:猫分类的分值非常低。从上图来看,算法倒是感觉这个图像是一只狗。
咱们能够这样了解,线性分类器会计算图像中 3 个色彩通道中所有像素的值与权重矩阵的乘积,进而失去每个类别分值。依据咱们对权重设置的值,对于图像中的某些地位的某些色彩,函数体现出爱好或者讨厌(依据每个权重的符号而定)。
举例:能够设想「船」分类就是被大量的蓝色所突围(对应的就是水)。那么「船」分类器在蓝色通道上的权重就有很多的正权重(它们的呈现进步了「船」分类的分值),而在绿色和红色通道上的权重为负的就比拟多(它们的呈现升高了「船」分类的分值)。
联合下面的小猫示例,猫分类器对第二个地位的像素比拟「讨厌」,而恰好输出的小猫图像第二个地位像素值很大,最终计算失去一个很低的分数(当然,这个分类器是谬误的)。
2) 了解二:将线性分类器看做模板匹配
把权重 \(W\) 的每一行看作一个分类的模板,一张图像对应不同分类的得分,是通过应用内积(也叫点积)来比拟图像和模板,而后找到和哪个模板最类似。
这种了解角度下,线性分类器在利用学习到的模板,和输出图像做模板匹配。咱们设置能够把其视作一种高效的 KNN,不同的是不再应用所有的训练集的图像来比拟,而是每个类别只用了一张图片来表征(这张图片是咱们学习到的模板,而不存在训练集中),而且咱们会更换度量规范,应用(负)内积来计算向量间的间隔,而不是应用 L1 或者 L2 间隔。
上图是以 CIFAR-10 为训练集,学习完结后的权重的例子。能够看到:
- 马的模板看起来仿佛是两个头的马,这是因为训练集中的马的图像中马头朝向各有左右造成的。线性分类器将这两种状况交融到一起了;
- 汽车的模板看起来也是将几个不同的模型交融到了一个模板中,这个模板上的车是红色的,是因为 CIFAR-10 中训练集的车大多是红色的。线性分类器对于不同色彩的车的分类能力是很弱的,然而前面能够看到神经网络是能够实现这一工作的;
- 船的模板如冀望的那样有很多蓝色像素。如果图像是一艘船行驶在大海上,那么这个模板利用内积计算图像将给出很高的分数。
3) 了解三:将图像看做高维空间的点
既然定义每个分类类别的分值是权重和图像的矩阵乘积,那么每个分类类别的分数就是这个空间中的一个线性函数的函数值。咱们没方法可视化 \(3072\) 维空间中的线性函数,但假如把这些维度挤压到二维,那么就能够看看这些分类器在做什么了:
在上图中,每张输出图片是一个点,不同色彩的线代表 3 个不同的分类器。以红色的汽车分类器为例,红线示意空间中汽车分类分数为 \(0\) 的点的汇合,红色的箭头示意分值回升的方向。所有红线左边的点的分数值均为正,且线性升高。红线右边的点分值为负,且线性升高。
从下面能够看到,\(W\) 的每一行都是一个分类类别的分类器。对于这些数字的几何解释是:
- 如果扭转 \(W\) 一行的数字取值,会看见分类器在空间中对应的直线开始向着不同方向旋转。而偏置项 \(b\),则容许分类器对应的直线平移。
- 须要留神的是,如果没有偏置项,无论权重如何,在 \(x_{i}=0\) 时分类分值始终为 \(0\)。这样所有分类器的线都不得不穿过原点。
3.4 偏置项和权重合并
下面的推导过程大家能够看到:理论咱们有权重参数 \(W\) 和偏置项参数 \(b\)两个参数,离开解决比拟冗余,罕用的优化办法是把两个参数放到同一个矩阵中,同时列向量 \(x_{i}\) 就要减少一个维度,这个维度的数值是常量 \(1\),这就是默认的 偏置项维度。
如下图所示,新的公式就简化成如下模式:
$$
f(x_{i},W,b)=Wx_{i}
$$
还是以 CIFAR-10 为例,那么 \(x_{i}\) 的大小就变成 \([3073 \times 1]\),而不是 \([3072 \times 1]\) 了,多出了蕴含常量 1 的 1 个维度;\(W\) 大小就是 \([10 \times 3073]\) 了,\(W\) 中多进去的这一列对应的就是偏差值 \(b\):
通过这样的解决,最终只需学习一个权重矩阵,无需学习两个别离装着权重和偏差的矩阵。
3.5 图像数据预处理
在下面的例子中,所有图像都是应用的原始像素值(\(0 \sim 255\))。在机器学习中,咱们常常会对输出的特色做 归一化(normalization)解决,对应到图像分类的例子中,图像上的每个像素能够看做一个特色。
在实践中,咱们会有对每个特色减去平均值来中心化数据这样一个步骤。
在这些图片的例子中,该步骤是依据训练集中所有的图像计算出一个均匀图像值,而后每个图像都减去这个平均值,这样图像的像素值就大概散布在 \([-127, 127]\) 之间了。
后续能够操作的步骤包含归一化,即让所有数值散布的区间变为 \([-1, 1]\)。
3.6 线性分类器生效的情景
线性分类器的分类能力理论是无限的,例如上图中的这三种情景都无奈找到适合的直线辨别开。其中第 1 个 case 是奇偶分类,第 3 个 case 是有多个模型。
4. 拓展学习
能够点击 B 站 查看视频的【双语字幕】版本
- 【课程学习指南】斯坦福 CS231n | 深度学习与计算机视觉
- 【字幕 + 材料下载】斯坦福 CS231n | 深度学习与计算机视觉 (2017·全 16 讲)
- 【CS231n 进阶课】密歇根 EECS498 | 深度学习与计算机视觉
- 【深度学习教程】吴恩达专项课程 · 全套笔记解读
- 【Stanford 官网】CS231n: Deep Learning for Computer Vision
5. 要点总结
- 图像分类中的艰难与挑战
- 数据驱动办法、最邻近算法、L1 和 L2 间隔
- KNN 分类器、超参数调优、KNN 的优缺点与理论利用
- 线性分类的概念、评分函数的了解、参数合并、数据预处理、线性分类器局限性
斯坦福 CS231n 全套解读
- 深度学习与 CV 教程(1) | CV 引言与根底
- 深度学习与 CV 教程(2) | 图像分类与机器学习根底
- 深度学习与 CV 教程(3) | 损失函数与最优化
- 深度学习与 CV 教程(4) | 神经网络与反向流传
- 深度学习与 CV 教程(5) | 卷积神经网络
- 深度学习与 CV 教程(6) | 神经网络训练技巧 (上)
- 深度学习与 CV 教程(7) | 神经网络训练技巧 (下)
- 深度学习与 CV 教程(8) | 常见深度学习框架介绍
- 深度学习与 CV 教程(9) | 典型 CNN 架构 (Alexnet, VGG, Googlenet, Restnet 等)
- 深度学习与 CV 教程(10) | 轻量化 CNN 架构 (SqueezeNet, ShuffleNet, MobileNet 等)
- 深度学习与 CV 教程(11) | 循环神经网络及视觉利用
- 深度学习与 CV 教程(12) | 指标检测 (两阶段, R-CNN 系列)
- 深度学习与 CV 教程(13) | 指标检测 (SSD, YOLO 系列)
- 深度学习与 CV 教程(14) | 图像宰割 (FCN, SegNet, U-Net, PSPNet, DeepLab, RefineNet)
- 深度学习与 CV 教程(15) | 视觉模型可视化与可解释性
- 深度学习与 CV 教程(16) | 生成模型 (PixelRNN, PixelCNN, VAE, GAN)
- 深度学习与 CV 教程(17) | 深度强化学习 (马尔可夫决策过程, Q-Learning, DQN)
- 深度学习与 CV 教程(18) | 深度强化学习 (梯度策略, Actor-Critic, DDPG, A3C)
ShowMeAI 系列教程举荐
- 大厂技术实现:举荐与广告计算解决方案
- 大厂技术实现:计算机视觉解决方案
- 大厂技术实现:自然语言解决行业解决方案
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学习算法:从入门到精通系列教程
- 机器学习实战:手把手教你玩转机器学习系列
- 深度学习教程:吴恩达专项课程 · 全套笔记解读
- 自然语言解决教程:斯坦福 CS224n 课程 · 课程带学与全套笔记解读
- 深度学习与计算机视觉教程:斯坦福 CS231n · 全套笔记解读