FCN论文详解
FCN算法Pytorch实现:https://github.com/codecat0/CV/tree/main/Semantic_Segmentation/FCN
1. 将全连接层替换为卷积层
语义分割的目的是对图像中每一个像素点进行分类,与普通的分类任务只输出图像某个类别不同,语义分割任务输出的是与输入图像大小相同的图像,输出图像的每个像素对应输入图像每个像素的类别,这也就是论文中提到的dense prediction
。
FCN全卷积网络是图像分割开山之作,其核心思想非常简单,用卷积层代替分类网络中的全连接层。
用于分类的神经网络由卷积层、池化层和最后连接的全连接层组成,经过最后的全连接层后,二维的图像信息被映射为具体的一维类别信息进行输出,得到分类标签。
对于语义分割问题,我们需要的不是具体的类别标签,而是一个二维的分割图,FCN方法丢弃全连接层,并将其换成卷积层,最后输出与原图相同大小的分割图
论文作者认为:全连接层让目标的位置信息消失了,只保留了语义信息,而将全连接层更换为卷积层可以同时保留位置信息和语义信息
2. 上采样
由于经过多次卷积之后图像的大小会缩小,需要通过上采样对其进行尺寸大小的恢复,使最后的分割图与原图尺寸一样
2.1 反卷积
下图为stride=1、paddding=0
的反卷积的工作过程
下图为stride=2、padding=1
的反卷积的工作过程
根据卷积的尺寸计算公式
o
=
i
−
k
+
2
⋅
p
s
+
1
o=\frac {i-k+2 \cdot p} {s} + 1
o=si−k+2⋅p+1
得反卷积的尺寸就算公式为:
i
=
(
o
−
1
)
⋅
s
+
k
−
2
⋅
p
i = (o-1) \cdot s + k - 2 \cdot p
i=(o−1)⋅s+k−2⋅p
Pytorch实现:nn.ConvTranspose2d
2.2 插值
2.2.1 最近邻插值
计算P与Q11、Q12、Q22、Q21的距离,可知P与Q11最近,所以P像素点的值与Q11像素点的值一样
2.2.2 双线性插值
双线性插值就是做两次线性变换,先在X轴上做一次线性变换,求出每一行的R点
R
1
=
x
2
−
x
x
2
−
x
1
Q
11
+
x
−
x
1
x
2
−
x
1
Q
21
R
2
=
x
2
−
x
x
2
−
x
1
Q
12
+
x
−
x
1
x
2
−
x
1
Q
22
R_1=\frac {x_2-x} {x_2-x_1} Q_{11} + \frac {x-x_1} {x_2-x_1}Q_{21} \\ R_2=\frac {x_2-x} {x_2-x_1} Q_{12} + \frac {x-x_1} {x_2-x_1} Q_{22}
R1=x2−x1x2−xQ11+x2−x1x−x1Q21R2=x2−x1x2−xQ12+x2−x1x−x1Q22
再在Y轴上做一次线性变换,求该区域的P点
P
=
y
2
−
y
y
2
−
y
1
R
1
+
y
−
y
1
y
2
−
y
1
R
2
P=\frac {y_2-y} {y_2-y_1}R_1 + \frac {y-y_1} {y_2-y_1}R_2
P=y2−y1y2−yR1+y2−y1y−y1R2
2.3 UpPooling
2.4 Upsample
3. 跳跃结构
如果直接用全卷积后的层进行上采样的话,得到的结果往往不够精细,所以本文中采取了跳级结构的方法,将更靠前的卷积层和经过上采样的层相结合,如下图所示:
采用这种方法,能够在保留全局特征的前提下,尽可能使得图像的划分更为精细