《动手学深度学习》笔记——计算机视觉(目标检测、语义分割、样式迁移)
深度学习基础笔记 (1) :预备知识(张量、梯度、概率…)
深度学习基础笔记 (2) :深度神经网络 DNN
深度学习基础笔记 (3) :优化算法(梯度下降、冲量法、Adam…)
深度学习基础笔记 (4) :卷积神经网络 CNN
深度学习基础笔记 (5) :计算机视觉(目标检测、语义分割、样式迁移)
深度学习基础笔记 (6) :注意力机制、Transformer
深度学习PyTorch代码模板
文章目录
1 改进模型泛化的方法
1.1 图像增强
图像增强对训练图像进行一系列的随机变化,生成相似但不同的训练样本,增强训练集的多样性,从而提高模型的泛化能力。
常用的图像增强方法
- 翻转:翻转图像。不总是可行。
# 左右翻转 torchvision.transforms.RandomHorizontalFlip() # 上下翻转 torchvision.transforms.RandomVerticalFlip()
- 切割:从图片中切割一块,然后变形到固定形状
# 随机高宽比、大小、位置 torchvision.transforms.RandomResizedCrop((200, 200), scale=(0.1, 1), ratio=(0.5, 2))
- 变色:改变亮度、对比度、饱和度和色调
# 随机亮度、对比度、饱和度和色调 torchvision.transforms.ColorJitter(brightness=0.5, contrast=0, saturation=0, hue=0)
- ……
1.2 微调
一个神经网络一般可以分成两块:特征抽取(将原始像素变成容易线性分割的特征)、线性分类器(用来做分类)。
微调(Fine-tuning)通过使用在大数据上得到的预训练好的模型来初始化模型权重来完成提升精度。步骤如下:
- 在源数据集(例如ImageNet数据集)上预训练神经网络模型,即源模型。
- 创建一个新的神经网络模型,即目标模型,将源模型上的所有模型设计及其参数(输出层除外)复制至其中。
- 向目标模型添加输出层,其输出数是目标数据集中的类别数。然后随机初始化该层的模型参数。
- 在目标数据集(如椅子数据集)上训练目标模型。输出层将从头开始进行训练,而所有其他层的参数将根据源模型的参数进行微调。
预训练模型质量很重要。微调通常速度更快、精度更高。
2 目标检测
目标检测(Object Detection)或目标识别(Object Recognition)比图像分类更加复杂,需要进行多个物体的识别,还要找出每个物体的位置。目标检测的应用场景也更多。
2.1 边界框
边界框(Bounding Box)用来描述对象的空间位置
- 通过矩形左上角的以及右下角的坐标决定: ( x 左上 , y 左上 , x 左下 , y 左下 ) (x_\text{左上},y_\text{左上},x_\text{左下},y_\text{左下}) (x左上,y左上,x左下,y左下)
- 通过边界框中心的坐标以及框的宽度和高度决定: ( x 中心 , y 中心 , w , h ) (x_\text{中心},y_\text{中心},w,h) (x中心,y中心,w,h)
目标检测算法通常会在输入图像中采样大量的区域,然后判断这些区域中是否包含我们感兴趣的目标,并调整区域边界从而更准确地预测目标的真实边界框(Ground-truth Bounding Box)。
2.2 锚框
预测真实边界框其中一种方法为:以每个像素为中心,生成多个缩放比(Scale) s s s 和宽高比(Aspect Ratio) r r r 不同的边界框, 这些边界框称为锚框(Anchor Box)。
2.2.1 生成锚框
以图像的每个像素为中心生成不同形状的锚框:设输入图像的高度为 h h h 、宽度为 w w w ,缩放比 s ∈ ( 0 , 1 ] s\in (0,1] s∈(0,1] ,宽高比 r > 0 r>0 r>0 ,则锚框的宽度和高度分别为 h s r hs\sqrt{r} hsr 和 h s r \frac{hs}r rhs。 注意当中心位置给定时,已知宽和高的锚框是确定的。
要生成多个不同形状的锚框,需设置许多缩放比 s 1 , ⋯ , s n s_1,\cdots,s_n s1,⋯,sn 和许多宽高比 r 1 , ⋯ , r m r_1,\cdots,r_m r1,⋯,rm 。 当使用这些比例和长宽比的所有组合以每个像素为中心时,输入图像将共有 w h n m whnm whnm 个锚框。 在实践中常只考虑包含 s 1 s_1 s1 或 r 1 r_1 r1 的组合,即 ( s 1 , r 1 ) , ( s 1 , r 2 ) , ⋯ , ( s 1 , r m ) , ( s 2 , r 1 ) , ( s 3 , r 1 ) , ⋯ , ( s n , r 1 ) (s_1,r_1),(s_1,r_2),\cdots,(s_1,r_m),(s_2,r_1),(s_3,r_1),\cdots,(s_n,r_1) (s1,r1),(s1,r2),⋯,(s1,rm),(s2,r1),(s3,r1),⋯,(sn,r1)此时以同一像素为中心的锚框的数量为 n + m − 1 n+m-1 n+m−1 ,整个输入图像将共生成 w h ( n + m − 1 ) wh(n+m-1) wh(n+m−1) 个锚框。
2.2.2 交并比(IoU)
杰卡德系数(Jaccard)可以衡量两组之间的相似性。 给定集合 A \mathcal{A} A 和 B \mathcal{B} B ,其杰卡德系数为他们交集的大小除以他们并集的大小,即 J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ J(\mathcal{A},\mathcal{B})=\frac{|\mathcal{A} \cap \mathcal{B}|}{|\mathcal{A} \cup \mathcal{B}|} J(A,B)=∣A∪B∣∣A∩B∣可以将任何边界框的像素区域视为一组像素,两个像素区域集合的杰卡德系数称之为交并比(Intersection over Union,IoU)。易知交并比的取值范围为 [ 0 , 1 ] [0,1] [0,1] ,其中0表示无重叠,1表示重合。
2.2.3 赋予锚框标号
在训练集中将每个锚框视为一个训练样本,为了训练目标检测模型,需要每个锚框的类别(Class)和偏移量(Offset)标签,其中前者是与锚框相关的对象的类别,后者是真实边界框相对于锚框的偏移量。
(1) 将真实边界框分配给锚框
给定图像,设锚框 A 1 , A 2 , ⋯ , A n a A_1,A_2,\cdots,A_{n_a} A1,A2,⋯,Ana,真实边界框 B 1 , B 2 , ⋯ , B n b B_1,B_2,\cdots,B_{n_b} B1,B2,⋯,Bnb,其中 n a ≥ n b n_a≥n_b na≥nb 。定义矩阵 X ∈ R n a × n b \mathbf{X}\in \mathbb{R}^{n_a\times n_b} X∈Rna×nb ,其第 i i i 行第 j j j 列的元素 x i j x_{ij} xij 是锚框 A I A_I AI 和真实边界框 B j B_j Bj 的IoU。将真实边界框分配给锚框的算法步骤如下
- 在矩阵
X
\mathbf{X}
X 中找最大的元素,其行、列索引分别为
i
i
i 和
j
j
j 。将真实边界框
B
j
B_{j}
Bj分配给锚框
A
i
A_{i}
Ai,然后丢弃第
i
i
i 行和第
j
j
j列中所有元素。
因为这对是所有锚框和真实边界框配对中最相近的
- 重复上一步操作,直至丢光 n b n_b nb 列中的所有元素,此时已经为 n b n_b nb 个锚框各分配了一个真实边界框。
- 遍历剩下的 n a − n b n_a-n_b na−nb 个锚框:对于锚框 A i A_i Ai,在矩阵 X \mathbf{X} X 第 i i i 行中找到与 A i A_i Ai 的IoU最大的真实边界框 B j B_j Bj ,只有当此IoU大于预定义的阈值时才将 B j B_j Bj 分配给 A i A_i Ai。
(2) 标记类别和偏移量
设锚框 A A A 被分配了真实边界框 B B B 。 A A A 的类别应与 B B B 相同; A A A 的偏移量将根据 A A A 和 B B B 中心坐标的相对位置以及这两个框的相对大小进行标记,设 A A A 和 B B B 的中心坐标分别为 ( x a , y a ) , ( x b , y b ) (x_a,y_a),(x_b,y_b) (xa,ya),(xb,yb) ,宽度分别为 w a , w b w_a,w_b wa,wb ,高度分别为 h a , h b h_a,h_b ha,hb ,则 A A A 的偏移量标记为 ( x b − x a w a − μ x σ x , y b − y a h a − μ y σ y , log w b w a − μ w σ w , log h b h a − μ h σ h ) (\frac{\frac{x_b-x_a}{w_a}-\mu_x}{\sigma_x},\frac{\frac{y_b-y_a}{h_a}-\mu_y}{\sigma_y},\frac{\log\frac{w_b}{w_a}-\mu_w}{\sigma_w},\frac{\log\frac{h_b}{h_a}-\mu_h}{\sigma_h}) (σxwaxb−xa−μx,σyhayb−ya−μy,σwlogwawb−μw,σhloghahb−μh)其中常量的默认值为 μ x = μ y = μ w = μ h = 0 , σ x = σ y = 0.1 , σ w = σ h = 0.2 \mu_x=\mu_y=\mu_w=\mu_h=0,\sigma_x=\sigma_y=0.1,\sigma_w=\sigma_h=0.2 μx=μy=μw=μh=0,σx=σy=0.1,σw=σh=0.2
2.2.4 使用 非极大值抑制 预测边界框
当有许多锚框时,可能会输出许多相似的具有明显重叠的预测边界框,都围绕着同一目标。
非极大值抑制(Non-maximum Suppression,NMS):合并属于同一目标的类似的预测边界框,从而简化输出。
对于一个预测边界框 B B B,目标检测模型会计算每个类别的预测概率,则最大预测概率 p p p 所指的类别即为 B B B 的类别,称 p p p 为预测边界框 B B B 的置信度(Confidence)。在同一张图像中,所有预测的非背景边界框都按置信度降序排序生成列表 L L L 。通过以下步骤操作对列表 L L L 进行排序:
- 从
L
L
L 中选取置信度最高的预测边界框
B
B
B 作为基准,将所有与
B
B
B 的IoU超过预定阈值
ϵ
\epsilon
ϵ 的非基准预测边界框从
L
L
L 中移除。
此时 L L L 保留了置信度最高的预测边界框,去除了与其太过相似的其他预测边界框,即那些具有非极大值置信度的边界框被抑制了。
- 重复上一步操作,直到
L
L
L 中的所有预测边界框都曾被用作基准。
此时 L L L 中任意一对预测边界框的IoU都小于预定阈值 ϵ \epsilon ϵ ,因此没有一对边界框过于相似。
- 输出列表
L
L
L 中的所有预测边界框。
变化如下两图所示
对于多尺度目标检测,可以利用深层神经网络在多个层次上对图像进行分层表示来实现,参见SSD。
2.3 区域卷积神经网络(R-CNN)系列
区域卷积神经网络(Region-based CNN 或 Regions with CNN features,R-CNN) 是将深度模型应用于目标检测的开创性工作之一。
2.3.1 R-CNN
原始的R-CNN首先从输入图像中选取若干锚框,并标注它们的类别和边界框(如偏移量),然后用卷积神经网络对每个提议区域进行前向传播以抽取其特征。之后用每个提议区域的特征来预测类别和边界框。具体包含以下4步骤:
- 使用选择性搜索(启发式搜索)算法来选择锚框。
- 使用预训练CNN模型来对每个锚框抽取特征。
- 将每个提议区域的特征连同其标注的类别作为一个样本,训练一个SVM(支持向量机)来对类别分类。
- 将每个提议区域的特征连同其标注的边界框作为一个样本,训练一个线性回归模型来预测边界框偏移。
尽管R-CNN模型通过预训练的卷积神经网络有效地抽取了图像特征,但它的速度很慢。庞大的计算量使得R-CNN在现实世界中难以被广泛应用。
2.3.2 Fast R-CNN
R-CNN需要对每个锚框进行CNN运算,这些特征抽取计算有重复,并且锚框数量大,特征抽取的计算量也大。
快速的R-CNN(Fast R-CNN)对R-CNN的主要改进之一,是仅在整张图象上执行卷积神经网络的前向传播。
兴趣区域池化层(Rol Pooling):使每个锚框都可以变成想要的形状。
- 给定一个锚框,均匀分割成 n × m n\times m n×m 块,输出每块里的最大值
- 不管锚框多大,总是输出 n m nm nm 个值
Fast R-CNN使用CNN对整张图片抽取特征(快的关键),再对每个锚框使用Rol Pooling(将在原图片中搜索到的锚框,映射到CNN得到的结果上)生成固定长度的特征。
2.3.3 Faster R-CNN
为了较精确地检测目标结果,Fast R-CNN模型通常需要在选择性搜索中生成大量的提议区域。
更快的R-CNN(Faster R-CNN)提出将选择性搜索替换为区域提议网络(Region Proposal Network)来获得更好的锚框。
Faster R-CNN将CNN结果输入到卷积层,然后生成许多锚框,这些锚框有好有坏。随后进行预测:
- 二元类别预测:预测这个锚框的好坏,即有没有有效的圈住物体
- 边界框预测:对锚框进行一些改进,最后用NMS(非极大值抑制)对锚框进行合并。
2.3.4 Mask R-CNN
掩码R-CNN(Mask R-CNN)引入了一个全卷积网络(FCN),能够有效地利用在训练集中标注的每个目标在图像上的像素级位置进一步提升目标检测的精度。
Mask R-CNN将兴趣区域池化层替换为了兴趣区域对齐层,使用双线性插值(Bilinear Interpolation)来保留特征图上的空间信息,从而更适于像素级预测。
如图,Faster RCNN精度高但是速度慢
2.4 单发多框检测(SSD)
单发多框检测(SSD)是一种多尺度目标检测模型。基于基础网络块和各个多尺度特征块,SSD生成不同数量和不同大小的锚框,并通过预测这些锚框的类别和偏移量检测不同大小的目标。
- 通过单个基础网络从输入图像中提取特征,常用VGG、ResNet等卷积神经网络。
- 其后的几个多尺度特征块将上一层提供的特征图的高和宽缩小(如减半)。
- 底部段来拟合小物体,顶部段来拟合大物体。
- 以每个像素为中心产生多个锚框,对每个锚框预测类别和边缘框。
如图,SSD模型速度快但精度不高
2.5 YOLO
SSD中锚框大量重叠,因此浪费了很多计算。
YOLO(You Only Look Once)将图片均匀分成
S
×
S
S\times S
S×S 个锚框,每个锚框预测
B
B
B 个边缘框。后续版本(V2、V3、V4、……)有持续改进。
如图,相同精度下YOLO比SSD速度快
3 语义分割
语义分割(Semantic Segmentation)将图像分割成属于不同语义类别的区域,其语义区域的标注和预测是像素级的。
计算机视觉领域中2个与语义分割相似的重要问题:
- 图像分割(Image Segmentation):将图像划分若干组成区域,这类问题的方法通常利用图像中像素之间的相关性。
- 实例分割/同时检测并分割(Simultaneous Detection and Segmentation)研究如何识别图像中各个目标实例的像素级区域。
语义分割的一个重要的数据集叫做Pascal VOC2012。
由于语义分割的输入图像和标签在像素上一一对应,输入图像会被随机裁剪为固定尺寸而不是缩放。
3.1 转置卷积
卷积不会增大输入的高宽,通常要么不变、要么减半。
转置卷积(Transposed Convolution)可以用来增大输入高宽。
3.1.1 基本操作
单通道的转置卷积基本操作可以表示为 Y [ i : i + h , j : j + w ] ← + X [ i , j ] ⋅ K Y[i:i+h,j:j+w] \xleftarrow{+} X[i,j]\cdot K Y[i:i+h,j:j+w]+X[i,j]⋅K
- 为何称之为“转置”?
- 对于卷积 Y = X ∗ W Y=X*W Y=X∗W,可以对 W W W 构造一个 V V V,使得卷积等价于矩阵乘法 Y ′ = V X ′ Y'=VX' Y′=VX′ ,其中 Y ′ , X ′ Y',X' Y′,X′ 是 Y , X Y,X Y,X 对应的向量版本。
- 转置卷积则等价于 Y ′ = V T X ′ Y'=V^\text{T}X' Y′=VTX′ 。
- 转置卷积不是反卷积!
- 数学上的反卷积(Deconvolution)是指卷积的逆运算:如果 Y = conv ( X , K ) Y=\text{conv}(X,K) Y=conv(X,K) ,则 X = deconv ( Y , K ) X=\text{deconv}(Y,K) X=deconv(Y,K)
- 反卷积很少用在深度学习中,所谓的反卷积神经网络指用了转置卷积的神经网络。
常规卷积将填充应用于输入,而转置卷积将填充应用于的输出。
3.1.2 重新排列输入和核
转置卷积是一种卷积,它将输入和核进行了重新排列。同卷积一般是做下采样不同,它通常用作上采样。若卷积将输入从 ( h , w ) (h,w) (h,w) 变成了 ( h ′ , w ′ ) (h',w') (h′,w′) ,则同样超参数的转置卷积为从 ( h ′ , w ′ ) (h',w') (h′,w′) 变成 ( h , w ) (h,w) (h,w) 。
- 当填充为
0
0
0 、步幅为
1
1
1 时:
- 将输入填充 k − 1 k-1 k−1( k k k 为核窗口)
- 将核矩阵上下、左右翻转
- 然后做正常卷积(填充
0
0
0 、步幅
1
1
1)
- 当填充
p
p
p 、步幅为
1
1
1 时:
- 将输入填充 k − p − 1 k-p-1 k−p−1( k k k 为核窗口)
- 将核矩阵上下、左右翻转
- 然后做正常卷积(填充
0
0
0 、步幅
1
1
1)
- 当填充为
p
p
p 、步幅为
s
s
s 时:
- 在行和列之间插入 s − 1 s-1 s−1 行或列
- 将输入填充 k − p − 1 k-p-1 k−p−1( k k k 为核窗口)
- 将核矩阵上下、左右翻转
- 然后做正常卷积(填充
0
0
0 、步幅
1
1
1)
3.1.3 形状换算
设输入高、宽为 n n n ,核窗口为 k k k ,填充为 p p p ,步幅为 s s s ,则
- 转置卷积: n ′ = s n + k − 2 p − s n'=sn+k-2p-s n′=sn+k−2p−s
- 卷积: n ′ = ⌊ n − k − 2 p + s s ⌋ ⇒ n ≥ s n ′ + k − 2 p − s n'=\lfloor \frac{n-k-2p+s}{s} \rfloor \Rightarrow n ≥ sn'+k-2p-s n′=⌊sn−k−2p+s⌋⇒n≥sn′+k−2p−s
若让高宽成倍增加,则 k = 2 p + s k=2p+s k=2p+s
3.2 全连接卷积神经网络(FCN)
全连接卷积神经网络(Fully Convolutional Network,FCN)是用深度神经网络来做语义分割的奠基性工作,它用转置卷积层来替换CNN最后的全连接层或全局池化层,从而可以实现每个像素的预测。
FCN先使用CNN抽取图像特征,然后通过
1
×
1
1\times 1
1×1 卷积层将通道数变换为类别个数,最后通过转置卷积层将特征图的高和宽变换为输入图像的尺寸。模型如下图所示
在全卷积网络中,可以将转置卷积层初始化为双线性插值的上采样。
4 样式迁移
样式迁移(Style Transfer)使用卷积神经网络,自动将一个图像(样式图像)中的样式应用在另一图像(内容图像)之上。
基于卷积神经网络的样式迁移方法如下图所示
样式迁移常用的损失函数由3部分组成:
- 内容损失:使合成图像与内容图像在内容特征上接近。
- 样式损失:令合成图像与样式图像在样式特征上接近。
- 全变分损失:有助于减少合成图像中的噪点。
可以通过预训练的卷积神经网络来抽取图像的特征,并通过最小化损失函数来不断更新合成图像来作为模型参数。