深度学习基础-1

0 前言

本文是公司组内分享的课程笔记,主要参考了北邮鲁鹏老师的《计算机视觉与深度学习》课程,课程视频链接在这里

这一讲还没有涉及到神经网络相关知识,是以图像分类任务为例,对除了神经网络之外的深度学习知识点概览。目的是讲清楚深度学习的总体流程,同时让读者对深度学习工作者的思考方式有一个了解。

下一讲:深度学习基础-2

1 图像分类简介

1.1 什么是图像分类

图像分类任务是计算机视觉中最基础也是最核心的一项任务,许多更加复杂的问题都可以转化为图像分类问题,如目标检测可以转化为对ROI(Region of interest)的分类问题,图像分割可以转化为对每个像素点的分类问题。

图像分类的核心是根据图像信息中所反映的不同特征,把不同类别的图像区分开来,即从已知的类别标签集合中为给定的输入图片选定一个类别标签。
图像分类任务

图1-1 图像分类任务

一般图像分类输出的是已知标签集合中各个标签的分数,也称为置信度,各类别置信度之和为1。一般会设置一个阈值,置信度最高且超过阈值的类别被认为是图像分类的结果。

1.2 图像分类任务的难点

计算机做图像分类和人对图像分类有挺大的区别,人认为很简单的问题,在计算机看来并不是如此,目前主要的难点包括以下几点:
(1)语义鸿沟
语义鸿沟

图1-2 语义鸿沟

(2)类别繁多
类别繁多

图1-3 类别繁多

(3)不同视角
不同视角

图1-4 不同视角

(4)不同光照
不同光照

图1-5 不同光照

(5)遮挡问题
遮挡问题

图1-6 遮挡问题

(6)不同形变
不同形变

图1-7 不同形变

(7)尺度问题
尺度问题

图1-8 尺度问题

(8)运动模糊
运动模糊

图1-9 运动模糊

1.3 分类任务的评价指标

分类任务的评价指标其实就是在一个叫做混淆矩阵(confusion matrix)的东西上做文章。

针对一个二分类问题,即将实例分成正类(positive)或负类(negative),在实际分类中会出现以下四种情况:

(1)若一个实例是正类,并且被预测为正类,即为真正类TP(True Positive )
(2)若一个实例是正类,但是被预测为负类,即为假负类FN(False Negative )
(3)若一个实例是负类,但是被预测为正类,即为假正类FP(False Positive )
(4)若一个实例是负类,并且被预测为负类,即为真负类TN(True Negative )

混淆矩阵的每一行是样本的预测分类,每一列是样本的真实分类(反过来也可以),其形式如下图1-10所示。

二分类混淆矩阵

图1-10 二分类混淆矩阵

对于多分类的问题,混淆矩阵的计算与二分类任务相似,只是类别数由之前的两个变成现在的多个,多分类混淆矩阵形式如下图1-11所示。

多分类混淆矩阵

图1-11 多分类混淆矩阵

每一个单元格第 i i i行,第 j j j列表示的是,预测值为 j j j,真实值为 i i i的个数。

为了更加直观地说明多分类的混淆矩阵,下面给出一个真实的例子,如图1-12所示。
多分类混淆矩阵实例

图1-12 多分类混淆矩阵实例

图1-4中共有6个类别,每个类别1000个样本,纵轴表示每个样本的真实标签,横轴表示每个样本的预测标签。对角线的值越大,说明模型的效果越好,比如sunflare这个类别模型的预测准确率是100%的,不会和其他任何一个类别混淆。又比如folds和part_remove就很容易混淆,folds有451个被误认为是part_remove,part_remove有277个被误认为是folds。

通过混淆矩阵,我们可以人为看出模型总体和细粒度的分类能力,不过还是需要有具体的数值指标,比如Accuracy,Precision和Recall。

还是以二分类为例,我们重新来看一下混淆矩阵,如下图1-13所示。多分类的时候,可以把其中一个类别当做正例,其他的类别当做反例,转化为二分类的混淆矩阵。
二分类混淆矩阵

图1-13 二分类混淆矩阵

1.3.1 Accuracy

Accuracy,即准确率,表示预测正确的样本数量占总量的百分比,具体的公式如下:
A c c u r a c y = T P + T N T P + F N + F P + T N (1-1) Accuracy = \frac{TP + TN}{TP + FN + FP + TN} \tag{1-1} Accuracy=TP+FN+FP+TNTP+TN(1-1)

更通俗一点说,就是所有测试样本里预测对了几个。

讲到这里,我们不妨停下来思考一下,准确率的局限性。这是一件对于深度学习工作者非常重要的事情,这个指标能告诉我什么,不能告诉我什么,以这个指标来评价模型能否达到我的目的。如果这个指标不行的话,就得要用其他的指标。有一个好的指标,我们才能评价两个模型之间的好坏,才能去不断迭代优化模型。

我们所有的评估都是基于测试样本的,不难理解,测试样本的分布情况对评估的结果有着很大的影响。

举个例子,假设我们有黑白两色两种球,白球10个,黑球2个,模型的预测结果如下图1-14所示。
模型预测结果示例

图1-14 模型预测结果示例

此时, a c c u r a c y = 1 + 10 1 + 1 + 0 + 10 = 0.92 accuracy = \frac{1+10}{1+1+0+10}=0.92 accuracy=1+1+0+101+10=0.92,从评价指标上看,模型能力还行,但是这可能是一个大概率输出白,小概率输出黑的随机模型。也可能是一个对白球预测能力极强,对黑球预测能力极弱的模型。

从这个例子中,我们总结出三点:

  • 测试样本需要尽可能类别平衡
  • 测试样本数据量要大
  • accuracy体现了模型在测试样本上的总体能力,没有更细粒度的类别指标

1.3.2 Precision和Recall

为了得到更细粒度的类别指标,就有了precision和recall。

Precision,即精确率,表示在预测为正例的结果中,有多少是正确的,具体公式如下:
P r e c i s i o n = T P T P + F P (1-2) Precision = \frac{TP}{TP + FP} \tag{1-2} Precision=TP+FPTP(1-2)

Recall,即召回率,表示在实际的正例中,有多少被预测出来了,具体公式如下:
R e c a l l = T P T P + F N (1-3) Recall = \frac{TP}{TP + FN} \tag{1-3} Recall=TP+FNTP(1-3)

这里要注意的是,正例是我们人为定义的,定义白球为正例,则有
P r e c i s i o n = 10 11 , R e c a l l = 10 10 = 1 Precision = \frac{10}{11}, Recall = \frac{10}{10} = 1 Precision=1110,Recall=1010=1

定义黑球为正例,则有
P r e c i s i o n = 1 1 = 1 , R e c a l l = 1 2 = 0.5 Precision = \frac{1}{1} = 1, Recall = \frac{1}{2} = 0.5 Precision=11=1,Recall=21=0.5

每个类别都有自己的precision和recall,细粒度的评价指标就有了。

这里我们再停下来思考一下:
(1)Accuracy和这两个指标的有什么联系吗?
答:每个类别的Recall,就是每个类别的Accuracy,当测试样本中,只有正例时,Recall就等于Accuracy。比如我们在说目标检测的Recall的时候,是没有负例的,我们只有“前景”这样一个正例,此时的Recall就是Accuracy。从公式上看,只有正例时, T N = F P = 0 TN=FP=0 TN=FP=0,Accuracy=Recall。换句话说,Accuracy是Recall的一种特殊情况。

对正例的定义,相当重要。

(2)Precision和Recall之间有什么联系?
分类时会设置一个置信度阈值,高于该阈值的被认为是正例,低于该阈值的被认为是负例,TP, FN, FP, TN随着置信度阈值的变化而变化。变化时,Precision和Recall是一个此消彼长的变化趋势,如下图1-15所示,该变化曲线包络的面积越大,证明模型的效果越好。面积比较难求,通常会看平衡点”(Break-Event Point,简称BEP)处的取值,这里不展开讲,感兴趣的可以看下参考资料3
Precision和Recall关系图

图1-15 Precision和Recall关系图

(3)置信度阈值确定时,每个类别两个指标,在一好一坏的情况下,很难评价两个模型的好坏,可以只用一个指标吗?
答:见下节的F1 Score。

1.3.3 F1 Score

通常使用精准率和召回率这两个指标,来评价二分类模型的分析效果。但当这两个指标发生冲突时,很难在模型之间进行比较。假如有两个模型,模型A精确率为80%,召回率为90%,模型B的精确率为90%,召回率为80%。如何来评价A和B哪一个的综合性能更优呢?

为了解决这个问题,人们提出了 F β F_β Fβ分数,意义就是将精准率和召回率这两个分值合并为一个分值,在合并过程中,召回率是精确率的 β β β倍。

F β = ( 1 + β 2 ) × P × R β 2 × P + R (1-4) F_\beta = \frac{(1+\beta_2) \times P \times R}{\beta^2 \times P + R} \tag{1-4} Fβ=β2×P+R(1+β2)×P×R(1-4)

F1分数认为召回率和精确率同样重要,相当于两者的调和平均数:

F 1 = 2 1 P + 1 R = 2 × P × R P + R (1-5) F1 = \frac{2}{\frac{1}{P} + \frac{1}{R}} =\frac{2 \times P \times R}{P + R} \tag{1-5} F1=P1+R12=P+R2×P×R(1-5)

除F1之外,F2分数和F0.5分数在统计学中也被大量应用。主要还是看对召回率和精确率哪一个指标需求更大一些,同时也能兼顾到另一个指标。

下面举两个例子来看看F1 Score和Accuracy的区别

假设好苹果为正例
示例1

图1-16 示例1

P = 1 P=1 P=1 R = 0.1 R=0.1 R=0.1,所以有 F 1 = 2 × 1 × 0.1 1 + 0.1 = 18.2 % F1 = \frac{2 \times 1 \times 0.1}{1 + 0.1} = 18.2\% F1=1+0.12×1×0.1=18.2% A c c u r a c y = 1 + 10 1 + 9 + 0 + 10 = 55 % Accuracy = \frac{1 + 10}{1 + 9 + 0 + 10} = 55\% Accuracy=1+9+0+101+10=55%

示例2

图1-17 示例2

P = 0.5 P=0.5 P=0.5 R = 1 R=1 R=1,所以有 F 1 = 2 × 0.5 × 1 0.5 + 1 = 66.7 % F1 = \frac{2 \times 0.5 \times 1}{0.5 + 1} = 66.7\% F1=0.5+12×0.5×1=66.7% A c c u r a c y = 10 + 0 10 + 0 + 10 + 9 = 50 % Accuracy = \frac{10 + 0}{10 + 0 + 10 + 9} = 50\% Accuracy=10+0+10+910+0=50%

从这两个例子从可以看出,Accuracy更关注的正反例整体的预测情况,而F1-score更关注正例中的预测情况。

可以看出,这些指标都是根据需求不断改进的,没有哪个指标更正确,完全看场景和需求。指标的设计在现在仍旧不够完善,比如图像生成任务的评价指标仍是研究热点。

对于图像分类的任务,实际情况下,还是以Accuracy为主。

1.4 分类图像模型总体框架

对分类任务有了一个大概了解之后,来看下深度学习中处理分类问题的总体框架,如下图1-10所示。接下来的章节会对标明序号的部分做详细的说明。
图像分类任务的总体框架图

图1-18 图像分类任务的总体框架图

2 线性分类器

2.1 图像的表示方法

图像的表示,也就是模型店输入。模型的输入可以有不同的形式,一个好的输入可以帮助模型屏蔽掉无用的信息,突出关键信息,是的模型更容易学习到关键特征。图像的表示方法可以总结为下图所示的几种,常用的还是像素值表示。
图像表示方法

图2-1 图像表示方法

2.2 Cifar10数据集介绍

本文中使用到的数据集为Cifar10数据集,它出自于规模更大的一个数据集TinyImages,它有八千万张小图片,Cifar10是它的一个子集。

Cifar10包含 10 个类别的 RGB 彩色图 片:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的尺寸为 32×32 ,数据集中一共有50000张训练图片和10000张测试图片。

Cifar10数据集示例图

图2-2 Cifar10数据集示例图

2.3 分类算法输入

大多数都分类算法都要求输入的是一个向量,本文将图片展开成一维的向量,这是一种最为简单粗暴的方式。
图像转向量

图2-3 图像转向量

一张RGB三通道的 32 × 32 32 \times 32 32×32的图片,展开称为向量后,其维度变为 1 × 3072 1 \times 3072 1×3072

2.4 线性分类器

本文不涉及神经网络,只是讲深度学习的总体流程,所以分类模型选择了线性分类器。

线性分类器是一种线性映射,将输入的图像特征映射为类别分数,其特点是

  • 形式简单、易于理解
  • 通过层级结构(神经网络)或者高维映射(支撑向量机)可以 形成功能强大的非线性模型

假设共有 c c c个类别,每个类别分别有一个线性分类器,第 i ∈ [ 1 , 2 , . . . , c ] i \in [1,2,...,c] i[1,2,...,c]个分类器的定义为

f i ( x , w i ) = w i T x + b i (2-1) f_i(x, w_i) = w_i^Tx + b_i \tag{2-1} fi(x,wi)=wiTx+bi(2-1)

预测时,图片会分别输入每个分类器当中,取得分最高的类别为预测类别。

举一个实际的例子,假设一张超级简单的单通道图片,只有四个像素点,如下图2-4所示。
输入示例

图2-4 输入示例

假设权重 w i w_i wi b i b_i bi已经全都学好,固定下来了,那么可以计算每个类别的得分,如下图2-5所示。

类别得分示例

图2-5 类别得分示例

整个过程就是这么简单。

这里会有一个疑问,这个学出来的权重到底是个什么?由于权重 w i w_i wi的维度和输入维度是一致的,我们将模型在 1 × 3072 1 \times 3072 1×3072输入上训练出来的权重还原回 32 × 32 × 3 32 \times 32 \times 3 32×32×3的图像,可以得到下图2-6所示的结果。
权重可视化

图2-6 权重可视化

不难看出,对应类别的权重有着该类别的物体形状和颜色。我们不妨这样来想,不考虑 b i b_i bi,线性分类器其实做了一个内积的操作,内积就是余弦距离,当两个向量之间的夹角越小,距离就越接近,内积就越大,分数也就越大。比如训练集只有一张图片,那么权重 w i w_i wi等于这样图片就会是我们训练出来的结果。现在的结果可以理解为每个类别所有图片的均值。

权值可以看作是一种模板,输入图像与评估模板的匹配程度越高,分类器输出的分数就越高。

不过这个分类器也有很多的弊端:
(1)不同光照的影响
内积包括了两个向量的模长,如果将图像的每个像素点除以2,得分也会减半,但图像的类别没有变化。

(2)不同视角,不同尺度的影响
将图像旋转180度或是缩小一倍,模板就匹配不上了,得分也会骤减,但图像的类别没有变化。

(3)背景的影响
当物体很小时图片大部分区域都是背景,如果输入图片的背景和模板很相似,而类别换成了其他的物体,背景的得分占优,类别会被误判。

这些都是图像分类时需要解决的问题,很显然,简单的线性分类器,天然无法解决这些问题。关于分类器的设计,本文不讲,会在下一章中介绍。

线性分类器也可以认为学了一个决策面,如下图2-7所示。
决策面

图2-7 决策面示意图

3 损失函数

3.1 损失函数的定义

训练模型需要定义损失函数,训练的过程就是使得损失值不断减小的过程。

损失函数的通用定义可以表示为

L = 1 N ∑ i L i ( f ( x i , W ) , y i ) (3-1) L = \frac{1}{N}\sum_{i}L_i(f(x_i, W), y_i) \tag{3-1} L=N1iLi(f(xi,W),yi)(3-1)

其中, x i x_i xi表示数据集中的第 i i i张图片; f ( x i , W ) f(x_i, W) f(xi,W)分类器对 x i x_i xi的预测结果; y i y_i yi为样本 i i i真实类别标签; L i L_i Li为第 i i i个样本点的损失; L L L为数据集的总损失,它是数据集中所有样本损失的平均。

3.2 多类支持向量机损失

回到线性分类器的例子,这里用到的损失函数为

L i = ∑ j ≠ y i { 0 , i f s i y i ≥ s i j + 1 s i j − s i y i + 1 o t h e r w i s e = ∑ j ≠ y i max ⁡ ( 0 , s i j − s i y i + 1 ) (3-2) \begin{aligned} L_i &= \sum_{j \neq y_i}\begin{cases} 0, &if s_{iy_i} \geq s_{ij} + 1 \\ s_{ij} - s_{iy_i} + 1 &otherwise \end{cases} \\ &= \sum_{j \neq y_i} \max (0, s_{ij} - s_{iy_i} + 1) \end{aligned} \tag{3-2} Li=j=yi{0,sijsiyi+1ifsiyisij+1otherwise=j=yimax(0,sijsiyi+1)(3-2)

其中, j j j表示类别标签,取值范围 [ 1 , 2 , 3 , … , c ] [1,2,3,\dots, c] [1,2,3,,c] s i j s_{ij} sij表示第 i i i个样本第 j j j个类别的预测分数; s i y i s_{iy_i} siyi表示第 i i i个样本第 y i y_i yi个类别的预测分数。

s i j = f i ( x i , w j , b j ) = w j T x i + b j (3-3) s_{ij} = f_i(x_i, w_j, b_j) = w_j^T x_i + b_j \tag{3-3} sij=fi(xi,wj,bj)=wjTxi+bj(3-3)

其中, w j w_j wj, b j b_j bj表示第 j j j个类别分类器的参数; x i x_i xi表示数据集中的第 i i i个样本。

这种 max ⁡ ( 0 , ⋅ ) \max(0, \cdot) max(0,)形式的损失也被称为折页损失(hinge loss)。
折页损失示意图

图3-1 折页损失示意图

也就是当 s i y i ≥ s i j + 1 s_{iy_i} \geq s_{ij} + 1 siyisij+1后,我们就认为模型已经学习的够了,不需要进行步学习了。不过这里为什么是1,而不是 s i y i ≥ s i j + 2 s_{iy_i} \geq s_{ij} + 2 siyisij+2,而不是 s i y i ≥ s i j + 10.6 s_{iy_i} \geq s_{ij} + 10.6 siyisij+10.6。理论上这些取值都是可以的,但不同的值会对结果有一定的影响,取1是因为在这个任务中设计为了1,如果取不同值,影响不大,也就无所谓了。这些都是深度学习工作者需要思考的问题。

这里同样举一个例子。假设有3个类别的训练样本各一张,分类器对三个类别的打分如下所示:
loss计算示例1

图3-2 loss计算示例1

根据结果计算多类支持向量机损失,比如bird这一类的计算过程为

L i = ∑ j ≠ y i max ⁡ ( 0 , s i j − s i y i + 1 ) = max ⁡ ( 0 , − 2.3 − 0.6 + 1 ) + max ⁡ ( 0 , 1.9 − 0.6 + 1 ) = 2.3 (3-4) \begin{aligned} L_i &=\sum_{j \neq y_i} \max (0, s_{ij} - s_{iy_i} + 1) \\ &= \max(0, -2.3-0.6+1) + \max(0, 1.9-0.6+1) \\ &= 2.3 \end{aligned} \tag{3-4} Li=j=yimax(0,sijsiyi+1)=max(0,2.30.6+1)+max(0,1.90.6+1)=2.3(3-4)

所有结果如下图3-3所示。

loss计算示例2

图3-3 loss计算示例2

又到了思考的环节。对模型的改进,其实就是在不断质疑设计中的每一个细节的过程中产生的。

(1) L i L_i Li的最大值和最小值是多少?
答:最大值是无穷大,最小值为0。Loss的设计必须满足有最小值,不然模型会无止尽地训练下去。

(2)初始化时, w w w b b b都为0,总损失 L L L会是多少?
答: w w w b b b都为0时,所有输出均为0, L = c − 1 L=c-1 L=c1。这其实可以用来检验代码有没有编写正确,如果 w w w b b b设置为0,输出不是 L = c − 1 L=c-1 L=c1,那代码就有问题了。

(3)考虑所有类别(包括 j = y i j=y_i j=yi),损失会有什么变化?
答: L i L_i Li会比原来大1,仅此而已。也就是 ∑ j ≠ y i \sum_{j \neq y_i} j=yi可以改为 ∑ j \sum_{j} j,效果上不会有影响,只是计算更加方便。

(4)在计算总损失时,用求和代替平均会有什么影响?
答:总损失会放大N倍,效果上不会有影响。

(5)多标签的情况下,该损失是否适用?
答:不能直接适用,需要将Loss稍作修改,下式 ( 3 − 5 ) (3-5) (35)是一种修改方式。预测错误的标签数量越多,损失越大。但是标签数量不同的标签之间,损失会不平衡。怎样是更好的Loss,留给读者思考。
L i = ∑ y i ∈ Y ∑ j ∉ Y max ⁡ ( 0 , s i j − s i y i + 1 ) (3-5) L_i = \sum_{y_i \in Y}\sum_{j \notin Y} \max (0, s_{ij} - s_{iy_i} + 1) \tag{3-5} Li=yiYj/Ymax(0,sijsiyi+1)(3-5)

(6)假设存在一个 W W W使损失函数 L = 0 L=0 L=0,这个 W W W是唯一的吗?
答:不唯一。

举个例子,假设两个线性分类器 f 1 ( x , W 1 ) = W 1 x f_1(x, W_1)=W_1x f1(x,W1)=W1x f 2 ( x , W 2 ) = W 2 x f_2(x, W_2)=W_2x f2(x,W2)=W2x,其中 W 2 = 2 W 1 W_2=2W_1 W2=2W1。对于下面图像,分类器1和分类器2的打分结果分别为

分类器打分结果

图3-4 分类器打分结果

可见两个不同的权重下, L L L都等于0。那么新的问题来了,如何在这两个权重中做选择呢?

这个时候,就该正则项出场了。

3.3 正则项

正则项的通用表示为 R ( W ) R(W) R(W),有了正则项的损失函数变为了

L ( W ) = 1 N ∑ i L i ( f ( x i , W ) , y i ) + λ R ( W ) (3-6) L(W) = \frac{1}{N}\sum_{i} L_i (f(x_i, W), y_i) + \lambda R(W) \tag{3-6} L(W)=N1iLi(f(xi,W),yi)+λR(W)(3-6)

其中, R ( W ) R(W) R(W)为超参数,控制着正则损失在总损失当中的比重。

这里顺便说一下超参数的定义。超参数指的是在开始学习过程之前设置的参数,不是通过学习得到的。当然,现在也有许多学习超参数的方法,比如元学习,这里不展开讲。超参数对模型的性能有着重要的影响。

这里以式 ( 3 − 6 ) (3-6) (36)中的 λ \lambda λ为例,当 λ = 0 \lambda=0 λ=0时,优化结果仅与数据损失相关;当 λ = + ∞ \lambda=+\infty λ=+时,优化结果与数据损失无关,仅考虑权重损失,此时系统最优解为 W = 0 W=0 W=0

再举一个正则项的具体例子,L2正则项。
R ( W ) = ∑ k ∑ l w k , l 2 (3-7) R(W) = \sum_{k} \sum_{l} w^{2}_{k, l} \tag{3-7} R(W)=klwk,l2(3-7)

其中 k k k表示类别序号, l l l表示 k k k类别对应的第 l l l个权重。

L2正则损失对大数值权值进行惩罚,喜欢分散权值,鼓励分类器将所有维度的特征都用起来,而不是强烈的依赖其中少数几维特征。
L2损失示例

图3-5 L2损失示例

4 优化算法

4.1 优化算法目标

优化算法的作用时更新模型中的参数,也就是学习的过程。学习需要有目标,而损失函数就是我们的目标函数

L ( W ) = 1 N ∑ i L i ( f ( x i , W ) , y i ) + λ R ( W ) (4-1) L(W) = \frac{1}{N}\sum_{i} L_i (f(x_i, W), y_i) + \lambda R(W) \tag{4-1} L(W)=N1iLi(f(xi,W),yi)+λR(W)(4-1)

我们的目标是求解使得 L ( W ) L(W) L(W)最小的那组 W W W

直接求解,令 ∂ L ∂ W = 0 \frac{\partial L}{\partial W} = 0 WL=0的做法通常不太现实,因为 L ( W ) L(W) L(W)会是一个相当复杂的的复合函数。

通常通过梯度下降的方法,步步逼近最小值。

4.2 梯度下降算法

梯度下降涉及到两个问题,一个是往哪儿走?另一个是走多远?

梯度下降示意图

图4-1 梯度下降示意图

先来看往哪儿走的问题。我们希望每走一步,损失函数的值可以减小一点,而且我们希望走同样的步长,沿着我们选择的方向走,损失值可以减小的更快,也就是通常说的下降得更快。

这个问题的答案是负梯度方向,我们来看下为什么。

借助于泰勒公式我们有

f ( x + δ ) − f ( x ) ≈ f ’ ( x ) ⋅ δ (4-2) f(x + δ) − f(x) ≈ f’(x) \cdot δ \tag{4-2} f(x+δ)f(x)f(x)δ(4-2)

由于 f ’ ( x ) f’(x) f(x) δ δ δ都是向量,根据内积的定义有

f ’ ( x ) ⋅ δ = ∣ f ’ ( x ) ∣ ⋅ ∣ δ ∣ c o s θ (4-3) f’(x) \cdot δ = |f’(x)| \cdot |δ| cos\theta \tag{4-3} f(x)δ=f(x)δcosθ(4-3)

目的是使得 f ( x + δ ) f(x + δ) f(x+δ)尽可能比 f ( x ) f(x) f(x)小,故要使得 f ’ ( x ) ⋅ δ f’(x) \cdot δ f(x)δ负的最小,也就是 θ = π θ=π θ=π的时候。此时 f ’ ( x ) f’(x) f(x) δ δ δ方向相反,也就是负梯度方向。

至于另一个走多远的问题,答案就是由步长来决定。

在梯度下降时,是利用所有样本计算损失并更新梯度的。学习率可以控制步长。

梯度更新示意图

图4-2 梯度更新示意图

4.3 梯度计算

计算梯度的方法主要分为两种,数值法和解析法。

(1)数值法
数值法对应于离散的求法,也就是参数发生小的变化,根据值发生对应的变化来计算梯度。其特点是计算量大,不精确。

举个例子,假设损失函数 L ( w ) = w 2 L(w)=w^2 L(w)=w2,求 w = 1 w=1 w=1点处的梯度。

d L ( w ) d w = l i m h → 0 L ( w + h ) − L ( w ) h ≈ L ( 1 + 0.0001 ) − L ( 1 ) 0.0001 = 2.0001 (4-4) \frac{dL(w)}{dw}=lim_{h→0}\frac{L(w+ℎ) − L(w)}{h} ≈ \frac{L(1 + 0.0001) − L(1)}{0.0001}=2.0001 \tag{4-4} dwdL(w)=limh0hL(w+h)L(w)0.0001L(1+0.0001)L(1)=2.0001(4-4)

(2)解析法
解析法就是直接求导数的表达式,并代进去求解。其特点是精确,速度快,但导数函数推导易错。

还是以 L ( w ) = w 2 L(w)=w^2 L(w)=w2,求 w = 1 w=1 w=1点处的梯度为例。

∇ L ( w ) = 2 w , ∇ w = 1 L ( w ) = 2 (4-5) \nabla L(w) = 2w, \nabla_{w=1} L(w) = 2 \tag{4-5} L(w)=2w,w=1L(w)=2(4-5)

实际求梯度时一般使用解析梯度,而数值梯度主要用于解析梯度的正确性校验(梯度检查)。

4.4 多类支持向量机损失函数梯度

回顾一下多类支持向量机损失函数为

L i = ∑ j ≠ y i max ⁡ ( 0 , ( w j T x i + b j ) − ( w y i T + b y i ) + 1 ) (4-6) L_i = \sum_{j \neq y_i} \max(0, (w_j^Tx_i + b_j) - (w_{y_i}^T + b_{y_i}) + 1) \tag{4-6} Li=j=yimax(0,(wjTxi+bj)(wyiT+byi)+1)(4-6)

对该式的 w j w_j wj b j b_j bj求偏导有
∂ L i ∂ w j = { 0 , w j T x i + b j ) − ( w y i T + b y i ) + 1 ≤ 0 x i , w j T x i + b j ) − ( w y i T + b y i ) + 1 > 0 ∂ L i ∂ b j = { 0 , w j T x i + b j ) − ( w y i T + b y i ) + 1 ≤ 0 1 , w j T x i + b j ) − ( w y i T + b y i ) + 1 > 0 (4-7) \begin{aligned} &\frac{\partial L_i}{\partial w_j} = \begin{cases} 0, &w_j^Tx_i + b_j) - (w_{y_i}^T + b_{y_i}) + 1 \leq 0 \\ x_i, &w_j^Tx_i + b_j) - (w_{y_i}^T + b_{y_i}) + 1 \gt 0 \end{cases}\\ &\frac{\partial L_i}{\partial b_j} = \begin{cases} 0, &w_j^Tx_i + b_j) - (w_{y_i}^T + b_{y_i}) + 1 \leq 0 \\ 1, &w_j^Tx_i + b_j) - (w_{y_i}^T + b_{y_i}) + 1 \gt 0 \end{cases} \end{aligned} \tag{4-7} wjLi={0,xi,wjTxi+bj)(wyiT+byi)+10wjTxi+bj)(wyiT+byi)+1>0bjLi={0,1,wjTxi+bj)(wyiT+byi)+10wjTxi+bj)(wyiT+byi)+1>0(4-7)

4.5 随机梯度下降

在利用梯度下降的时候,每次都需要对所有样本求一次损失,复杂度是 O ( n ) O(n) O(n)的。这样计算的开销太大。为了减小计算开销,我们可以放弃一点对方向的精度,于是就有了随机梯度下降法。

随机梯度下降的每次迭代中,我们随机平均采样一个样本索引 i ∈ 1 , … , n i∈{1,…,n} i1,,n,并计算梯度 ∇ f i ( x ) ∇f_i(x) fi(x)来迭代 x x x
x ← x − η ∇ f i ( x ) (4-8) x←x−η∇f_i(x) \tag{4-8} xxηfi(x)(4-8)
η η η为学习率。可以看到每次迭代的计算开销从梯度下降的 O ( n ) O(n) O(n)降到了常数 O ( 1 ) O(1) O(1)

讲到这里,也许会有疑问。这么算不对啊,梯度下降的复杂度是 O ( n ) O(n) O(n)是因为它把所有的样本都看了一遍,如果随机梯度下降也把所有样本都看一遍的话,复杂度也是 O ( n ) O(n) O(n)。这两者有什么区别吗?

有!大有区别!别忘了,梯度下降虽然方向准确,但是步长是不知道,为了不走过头,每次都只往正确的方向上走一小步,然后下次迭代时就又要重新计算了。随机梯度下降虽然方向不准确,但是每走一步都在修正方向,歪歪扭扭地,最终也能走到极小值点。同样是看一遍所有的数据,梯度下降只能走一步,随机梯度下降可以走 n n n步。正是因为步长需要试探,使得随机梯度下降占了很大的优势。

5 数据处理

5.1 数据集的划分

我们通常将数据集 D D D划分为两个互斥的集合,其中一个集合作为训练集 S S S,另一个作为测试集 T T T,即 D = S ∪ T D=S∪T D=ST S ∩ T = ∅ S∩T=∅ ST=。在 S S S上训练出模型后,用 T T T来评估其效果。

数据划分示意图-1

图5-1 数据划分示意图-1

但是,这样会有一个问题。训练多个epochs,模型会输出多个权重,如何挑选权重?直接的想法是,对比模型在不同权重下的测试集效果。这种做法可行吗?不可行!因为这样其实测试集已经被利用了,这种情况下,无法真实评估出模型的泛化能力。

解决方案是,使用验证集。

训练集用于分类器参数的学习。验证集用于选择最佳权重。测试集评估泛化能力。

数据划分示意图-2

图5-2 数据划分示意图-2

问题又来了,如果数据很少,那么验证集包含的样本就太少,从而无法在统计上代表数据,怎么办?

一种方式叫做K折交叉验证。

K折交叉验证将除测试集外的所有样本 D D D划分为 k k k个大小相似的互斥子集,即 D = D 1 ∪ D 2 ∪ ⋯ ∪ , D i ∩ D j = ∅ ( i ≠ j ) D=D1∪D2∪⋯∪,Di∩Dj=∅(i≠j) D=D1D2DiDj=i=j。每个子集都要尽可能保持数据分布的一致性,即从 D D D中通过分层采样得到。然后用 ( k − 1 ) (k−1) (k1)个子集的并集作为训练集,余下的子集作为验证集。这样就可以获得 k k k组训练/验证集,从而可以进行 k k k次训练和验证,最终返回的是 k k k个验证结果的均值,根据该值来选择合适的模型。交叉验证法评估结果的稳定性和保真性在很大程度上取决于 k k k的取值。3折交叉验证如下图5-3所示。

3折交叉验证

图5-3 3折交叉验证示意图

选出的模型最后可以通过以下两种方式得到最终模型:
(1)合并训练集和验证集,一并训练后,在测试集上测试其泛化能力。
(2)使用K折验证训练时分类器参数的均值,然后在测试集上测试器泛化能力。

为了避免随机性带来的影响,还有打乱数据的重复 k k k折交叉验证。
打乱数据的重复k折交叉验证

图5-4 打乱数据的重复k折交叉验证示意图

带有打乱数据的重复 k k k折交叉验证就是多次使用 k k k折验证,在每次将数据划分为 k k k个分区前,先将数据打乱。最终分数是多次 k k k折验证分数的平均值。

5.2 数据的预处理

假设 x = [ x 1 , x 2 ] T x=[x_1, x_2]^T x=[x1,x2]T x 1 x_1 x1 x 2 x_2 x2分别是输入的两个特征, x 1 = [ 1 , 2 , 3 , … . ] x_1=[1,2,3,….] x1=[1,2,3,.] x 2 = [ 100 , 200 , 300 , … ] x_2=[100,200,300,…] x2=[100,200,300,],对于模型 y ^ = ∑ i w i x i + b i \hat{y}=\sum_i w_i x_i+b_i y^=iwixi+bi L ( w , b ) = ∑ i ∣ y i − y ^ i ∣ L(w, b) = \sum_i |y_i - \hat{y}_i| L(w,b)=iyiy^i。显然,由于 x 1 x_1 x1的取值小,引起 y y y的变化小,进而对 L L L的影响也小,因此 w 1 w_1 w1方向的梯度就小。同理 w 2 w_2 w2方向的梯度就大。从而模型会更偏向 w 2 w_2 w2梯度的方向更新参数。

不同特征尺度示意图

图5-5 不同特征尺度示意图

通过这个分析,我们发现要使 w 1 w_1 w1 w 2 w_2 w2方向上的梯度相近,就应该使其相应的输入的取值在一个范围内。相应的方法就是特征归一化。

图像预处理中最常用的归一化是最大最小归一化(Min-Max Normalization),使结果值映射到 [ 0 , 1 ] [0,1] [0,1]之间,转换函数如下:
x ′ = x − m i n ( x ) m a x ( x ) − m i n ( x ) (5-1) x' = \frac{x - min(x)}{max(x) - min(x)} \tag{5-1} x=max(x)min(x)xmin(x)(5-1)

最大最小归一化之所以适用于图像预处理,是因为最大最小值是固定的255和0,数值比较集中。
归一化结果示意图

图5-6 归一化结果示意图

5.3 数据增广

数据增广是深度学习中常用的技巧之一,主要用于增加训练数据集,不仅可以让数据集尽可能的多样化,而且随机改变训练样本可以降低模型对于某些属性的依赖,从而提升模型的泛化能力。例如,可以对图像进行随机的平移,使感兴趣的物体出现在不同位置以减轻模型对出现位置的依赖项。也可以对图像进行随机裁剪,使得模型不依赖于对象的完整特征,从而通过局部特征也可以识别出物体。一个比较经典的数据增广库就是albumentations

目前数据增广主要包括:

  • 水平/垂直翻转
  • 旋转
  • 缩放
  • 裁剪
  • 平移
  • 对比度
  • 色彩抖动
  • 噪声

数据增广示意图

图5-7 数据增广示意图

6 参考资料

[1] 计算机视觉与深度学习 北京邮电大学 鲁鹏 清晰版合集(完整版)
[2] 动手学深度学习-pytorch
[3] https://zhuanlan.zhihu.com/p/110015537

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七元权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值