百度飞桨PaddlePaddle-21天零基础实践深度学习-卷积神经网络基础
计算机视觉
主要任务
识别图片物体
检测物体所在的位置
目标物体跟踪
理解并描述图像里场景和故事
基本子任务:
<1> 图像分类 (类别)
<2> 目标检测 (类别 + 位置)
<3> 图像语义分割 (类别 + 同类物体用同一颜色标识)
<4> 实例分割 (类别 + 位置 + 轮廓)
应用场景
停车场出入口的车牌识别一 目标检测+文字识别
小区安防监控一行为识别
道路交通违章抓拍—行为识别
写字楼入口处的人脸闸机一人脸识别
手机上的刷脸支付一人脸识别
自动票据识别一文字识别
工业产品缺陷检测一目标检测、 图像分割
医疗影像检测一目标检测、 图像分割
…
飞桨为计算机视觉任务提供了丰富的API,并通过底层优化和加速保证API的性能。同时,飞桨还提供了丰富的模型库,覆盖图像分类、检测、分割、文字识别和视频理解等多个领域。
发展历程
<早期> 全局的视觉底层特性统计量表示图像 (特征向量:颜色、形状、纹理…)
<中期> 局部特征转化为视觉关键词,图片表示为视觉词袋 (局部检测算子、局部描述算子)
<传统方法> 人工特征提取+分类器 (专家经验+耗时长)
<深度学习> 原始信号——低级抽象——高级抽象迭代
<后来> 大数据的涌现 + 硬件性能提升 → 计算机视觉的丰富发展
卷积神经网络
卷积神经网络(CNN)是计算机视觉技术最经典的模型结构。接下来主要介绍卷积神经网络的常用模块,包括:卷积、池化、激活函数、批归一化、Dropout等。
手写数字识别任务,全连接层的特征提取,即将一张图片上的所有像素点展开成一个1维向量输入网络,存在问题:
1. 输入数据的空间信息被丢失。
2. 模型参数过多,容易发生过拟合。
为了解决上述问题,我们引入卷积神经网络进行特征提取,既能提取到相邻像素点之间的特征模式,又能保证参数的个数不随图片尺寸变化。
卷积
卷积计算
互相关运算作为卷积的定义
卷积核(kernel)也被叫做滤波器(filter),假设卷积核的高和宽分别为
k
h
k_{h}
kh和
k
w
k_{w}
kw,则称为
k
h
×
k
w
k_{h}\times k_{w}
kh×kw卷积。
卷积核的计算过程可以用下面的数学公式表示,其中 a 代表输入图片, b 代表输出特征图,w 是卷积核参数,它们都是二维数组,
∑
u
,
v
\sum u,v
∑u,v 表示对卷积核参数进行遍历并求和。
b
[
i
,
j
]
=
∑
u
,
v
a
[
i
+
u
,
j
+
v
]
⋅
w
[
u
,
v
]
b[i,j]=\sum_{u,v}a[i+u,j+v]\cdot w[u,v]
b[i,j]=u,v∑a[i+u,j+v]⋅w[u,v]
卷积计算过程:
填充(padding)
卷积输出特征图的尺寸计算方法
H o u t = H − k h + 1 H_{out}=H-k_{h}+1 Hout=H−kh+1 W o u t = W − k w + 1 W_{out}=W-k_{w}+1 Wout=W−kw+1
当卷积核尺寸大于1时,输出特征图的尺寸会小于输入图片尺寸。说明经过多次卷积之后尺寸会不断减小。为了避免卷积之后图片尺寸变小,通常会在图片的外围进行填充(padding)。
在卷积计算过程中,通常会在高度或者宽度的两侧采取等量填充
H o u t = H + 2 p h − k h + 1 H_{out}=H+2p_{h}-k_{h}+1 Hout=H+2ph−kh+1 W o u t = W + 2 p h − k w + 1 W_{out}=W+2p_{h}-k_{w}+1 Wout=W+2ph−kw+1
卷积核大小通常使用1,3,5,7这样的奇数,如果使用的填充大小为 p h = ( k h − 1 ) / 2 p_{h}=(k_{h}-1)/2 ph=(kh−1)/2 , p w = ( k h − 1 ) / 2 p_{w}=(k_{h}-1)/2 pw=(kh−1)/2,则卷积之后图像尺寸不变。
步幅(stride)
步幅为 m m m的卷积过程,卷积核在图片上移动时,每次移动大小为 m m m个像素点。
当宽和高方向的步幅分别为 s h s_{h} sh和 s w s_{w} sw 时,输出特征图尺寸的计算公式:
H o u t = H + 2 p h − k h s h + 1 H_{out}=\frac{H+2p_{h}-k_{h}}{s_{h}}+1 Hout=shH+2ph−kh+1 W o u t = W + 2 p w − k w s w + 1 W_{out}=\frac{W+2p_{w}-k_{w}}{s_{w}}+1 Wout=swW+2pw−kw+1
感受野(Receptive Field)
输出特征图上每个点的数值,是由输入图片上大小为 k h × k w k_{h}\times k_{w} kh×kw的区域的元素与卷积核每个元素相乘再相加得到的,所以输入图像上 k h × k w k_{h}\times k_{w} kh×kw 区域内每个元素数值的改变,都会影响输出点的像素值。我们将这个区域叫做输出特征图上对应点的感受野。感受野内每个元素数值的变动,都会影响输出点的数值变化。
多输入通道、多输出通道和批量操作
多输入通道场景
一张图片往往含有RGB三个通道,假设输入图片的通道数为
C
i
n
C_{in}
Cin,输入数据的形状是
C
i
n
×
H
i
n
×
W
i
n
C_{in}\times H_{in}\times W_{in}
Cin×Hin×Win。
多输入通道计算过程:
1.对每个通道分别设计一个2维数组作为卷积核,卷积核数组的形状是
C
i
n
×
k
h
×
k
w
C_{in}\times k_{h}\times k_{w}
Cin×kh×kw
2.对任一通道
c
i
n
∈
[
0
,
C
i
n
)
c_{in}∈[0,C_{in})
cin∈[0,Cin) ,分别用大小为
k
h
×
k
w
k_{h}\times k_{w}
kh×kw 的卷积核在大小为
H
i
n
×
W
i
n
H_{in}\times W_{in}
Hin×Win的二维数组上做卷积
3.将这
C
i
n
C_{in}
Cin个通道的计算结果相加,得到的是一个形状为
H
o
u
t
×
W
o
u
t
H_{out}×W_{out}
Hout×Wout 的二维数组
多输出通道场景
一般来说,卷积操作的输出特征图也会具有多个通道
C
o
u
t
C_{out}
Cout,这时需要设计
C
o
u
t
C_{out}
Cout个维度为
C
i
n
×
k
h
×
k
w
C_{in}\times k_{h}\times k_{w}
Cin×kh×kw的卷积核,卷积核数组的维度是
C
o
u
t
×
C
i
n
×
k
h
×
k
w
C_{out}\times C_{in}\times k_{h}\times k_{w}
Cout×Cin×kh×kw
多输出通道计算过程:
1.对任一通道
c
o
u
t
∈
[
0
,
C
o
u
t
)
c_{out}∈[0,C_{out})
cout∈[0,Cout) ,分别使用上面描述的形状为
C
i
n
×
k
h
×
k
w
C_{in}\times k_{h}\times k_{w}
Cin×kh×kw 的卷积核对输入图片做卷积。
2.将这
C
o
u
t
C_{out}
Cout个形状为
H
o
u
t
×
W
o
u
t
H_{out}\times W_{out}
Hout×Wout的二维数组拼接在一起,形成维度为
C
o
u
t
×
H
o
u
t
×
W
o
u
t
C_{out}×H_{out}×W_{out}
Cout×Hout×Wout
批量操作
在卷积神经网络的计算中,通常将多个样本放在一起形成一个mini-batch进行批量操作,即输入数据的维度是
N
×
C
i
n
×
H
i
n
×
W
i
n
N\times C_{in} \times H_{in} \times W_{in}
N×Cin×Hin×Win。
批量操作计算过程:
由于会对每张图片使用同样的卷积核进行卷积操作,卷积核的维度与上面多输出通道的情况一样,仍然是 输出特征图的维度是 C o u t × C i n × k h × k w C_{out}×C_{in}×k_{h}×k_{w} Cout×Cin×kh×kw,输出特征图的维度是 N × C o u t × H o u t × W o u t N\times C_{out}\times H_{out}\times W_{out} N×Cout×Hout×Wout
池化
平均池化 : 池化窗口覆盖区域内的像素取平均值,得到相应的输出特征图的像素值。
最大池化 : 对池化窗口覆盖区域内的像素取最大值,得到输出特征图的像素值。
在卷积神经网络中,通常使用
2
×
2
2×2
2×2大小的池化窗口,步幅也使用2,填充为0,则输出特征图的尺寸为:
H
o
u
t
=
H
2
H_{out}=\frac {H}{2}
Hout=2H
W
o
u
t
=
W
2
W_{out}=\frac {W}{2}
Wout=2W
通过这种方式的池化,输出特征图的高和宽都减半,但通道数不会改变。
激活函数
Sigmoid激活函数
y
=
1
1
+
e
−
x
y=\frac {1}{1+e^{-x}}
y=1+e−x1
Sigmoid函数在反向传播过程中,容易造成梯度的衰减。
如果有多层网络使用了Sigmoid激活函数,则比较靠后的那些层梯度将衰减到非常小的值,导致梯度消失。
ReLU激活函数
y
=
{
0
x
<
0
x
x
⩾
0
y=\left\{\begin{matrix} 0 &x<0 \\ x & x\geqslant 0 \end{matrix}\right.
y={0xx<0x⩾0
目前用的较多的激活函数是ReLU
批归一化(BatchNorm)
目的 : 对神经网络中间层的输出进行标准化处理,使得中间层的输出更加稳定。
优点:
使学习快速进行(能够使用较大的学习率)
降低模型对初始值的敏感性
从一定程度上抑制过拟合
主要思路:在训练时按mini-batch为单位,对神经元的数值进行归一化,使数据的分布满足均值为0,方差为1
计算过程
1.计算mini-batch内样本的均值
μ
B
←
1
m
∑
i
=
1
m
x
(
i
)
\mu _{B}\leftarrow\frac{1}{m}\sum_{i=1}^{m}x^{(i)}
μB←m1i=1∑mx(i)
2.计算mini-batch内样本的方差
σ
B
2
←
1
m
∑
i
=
1
m
(
x
(
i
)
−
μ
B
)
2
\sigma _{B}^{2}\leftarrow \frac{1}{m}\sum_{i=1}^{m}(x^{(i)-\mu _{B}})^{2}
σB2←m1i=1∑m(x(i)−μB)2
3. 计算标准化之后的输出
x
^
(
i
)
←
x
(
i
)
−
u
B
(
σ
B
2
+
ϵ
)
\hat{x}^{(i)}\leftarrow \frac{x^{(i)}-u_{B}}{\sqrt{(\sigma _{B}^{2}+\epsilon )}}
x^(i)←(σB2+ϵ)x(i)−uB
在BatchNorm的具体实现中,训练时会计算均值和方差的移动平均值。在飞桨中,默认计算:
Dropout
深度学习中一种常用的抑制过拟合的方法,其做法是在神经网络学习过程中,随机删除一部分神经元。通常Dropout=0.5
downgrade_in_infer
训练时以比例 r r r随机丢弃一部分神经元,不向后传递它们的信号;预测时向后传递所有神经元的信号,但是将每个神经元上的数值乘以 ( 1 − r ) (1−r) (1−r)。
upscale_in_train
训练时以比例 r r r随机丢弃一部分神经元,不向后传递它们的信号,但是将那些被保留的神经元上的数值除以 ( 1 − r ) (1−r) (1−r);预测时向后传递所有神经元的信号,不做任何处理。