DL-FWI内训Day4
今日内训主要研习理解FCNVMB,一种基于FCN(fully convolutional networks)的VMB(velocity-model build)方法。
FCNVMB
FCN指的是全卷积网络,其具体定义可参考StackExchange的解释。与传统CNN有所不同的是,FCN的所有操作均为卷积计算,而前者的全连接层中并不包含卷积操作。该网络在图像语义分割中有着广泛应用。
虽然这篇文章的作者强调该算法属于FCN引导的VMB,但在代码层面上该算法更类似于UNet结构——一种FCN改进后的变体。
网络分析
如前文所提,FCNVMB可以理解为UNet网络架构下的FWI。与UNet相同,FCNVMB会分别经历图像下采样(编码器)和上采样(解码器)两个步骤。
下采样主要用于提取图像的深层特征;而上采样过程中,通过与对应的浅层特征图像拼接,更好地融合了图像的浅层特征和深层特征两个方面。其中,浅层特征图像更倾向于表达例如点、线、边缘轮廓等基本特征单元,蕴含的空间信息更多;而深层特征图更倾向于表达图像的语义信息,蕴含的空间信息更少,语义特征更多。
编码器
下采样过程中,每一轮都会经历两轮红色箭头操作,不改变图像尺寸;并在最后经历一次紫色箭头操作,使得图像尺寸缩小为原来的一半。
红色箭头包括了三样操作:kernal size = 3 * 3的卷积计算、批归一化操作BN以及ReLU激活函数。
紫色箭头是一次size = 2 * 2的最大池化操作,用于缩小图像尺寸,挖掘图像深层语义信息。
解码器
红色箭头同上所述,不改变特征图像尺寸的同时,对特征进行重整合。
黄色箭头为kernel size = 2 * 2的反卷积操作,使得图像尺寸扩大为原本的两倍。
在每次黄色箭头操作后,都需要将图像对应的浅层特征图像拼接到深层特征图像后,融合特征信息,增加图像的通道数。
代码实现
函数封装
分析了FCNVMB的算法原理后,我们可将图像处理过程封装为3个函数:
-
卷积组合操作(红箭头):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33class unetConv2(nn.Module):
def __init__(self, in_size, out_size, is_batchnorm): # in/out_size分别为输入输出的通道数
'''
Convolution with two basic operations
[Affiliated with FCNVMB]
:param in_size: Number of channels of input
:param out_size: Number of channels of output
:param is_batchnorm: Whether to use BN
'''
super(unetConv2, self).__init__()
if is_batchnorm:
self.conv1 = nn.Sequential(nn.Conv2d(in_size, out_size, 3, 1, 1),
nn.BatchNorm2d(out_size),
nn.ReLU(inplace=True), )
self.conv2 = nn.Sequential(nn.Conv2d(out_size, out_size, 3, 1, 1),
nn.BatchNorm2d(out_size),
nn.ReLU(inplace=True), )
else:
self.conv1 = nn.Sequential(nn.Conv2d(in_size, out_size, 3, 1, 1),
nn.ReLU(inplace=True), )
self.conv2 = nn.Sequential(nn.Conv2d(out_size, out_size, 3, 1, 1),
nn.ReLU(inplace=True), )
def forward(self, inputs):
'''
:param inputs: Input Image
:return:
'''
outputs = self.conv1(inputs)
outputs = self.conv2(outputs)
return outputs -
下采样操作(红箭头+紫箭头):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class unetDown(nn.Module):
def __init__(self, in_size, out_size, is_batchnorm):
'''
Downsampling Unit
[Affiliated with FCNVMB]
:param in_size: Number of channels of input
:param out_size: Number of channels of output
:param is_batchnorm: Whether to use BN
'''
super(unetDown, self).__init__()
self.conv = unetConv2(in_size, out_size, is_batchnorm)
self.down = nn.MaxPool2d(2, 2, ceil_mode=True)
def forward(self, inputs):
'''
:param inputs: Input Image
:return:
'''
outputs = self.conv(inputs)
outputs = self.down(outputs)
return outputs -
上采样操作(黄箭头+红箭头):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33class unetUp(nn.Module):
def __init__(self, in_size, out_size, is_deconv):
'''
Upsampling Unit
[Affiliated with FCNVMB]
:param in_size: Number of channels of input
:param out_size: Number of channels of output
:param is_deconv: Whether to use deconvolution
'''
super(unetUp, self).__init__()
self.conv = unetConv2(in_size, out_size, True)
# Transposed convolution
if is_deconv:
self.up = nn.ConvTranspose2d(in_size, out_size, kernel_size=2, stride=2)
else:
self.up = nn.UpsamplingBilinear2d(scale_factor=2)
def forward(self, inputs1, inputs2):
'''
:param inputs1: Layer of the selected coding area via skip connection
:param inputs2: Current network layer based on network flows
:return:
'''
outputs2 = self.up(inputs2)
offset1 = (outputs2.size()[2] - inputs1.size()[2])
offset2 = (outputs2.size()[3] - inputs1.size()[3])
padding = [offset2 // 2, (offset2 + 1) // 2, offset1 // 2, (offset1 + 1) // 2]
# Skip and concatenate
outputs1 = F.pad(inputs1, padding)
return self.conv(torch.cat([outputs1, outputs2], 1))
匹配尺寸
上述的封装函数unetUp
中,在拼接浅层特征和深层特征图像时两者的尺寸并不一致,而是相差一倍。为此,需要对inputs1
(浅层特征图像)进行pad
操作进行图像尺寸匹配。
网络类
经过函数封装后,FCNVMB
类可以简写如下:
1 | class FCNVMB(nn.Module): |
异同比较
主要对比Day 3介绍的InversionNet。
相同点
- 无论是FCNVMB还是InversionNet,它们都是单一的端到端深度网络并没有利用更多的物理含义。
- 都采用了编码器-解码器的架构。
- 都是利用叠前多炮数据的不同炮集直接投入训练,并未处理。
不同点
- InversionNet在编码的过程中最终将图像压缩为完全的一维向量,抛弃了空间关联性;而FCNVMB在压缩后仍保留了25 * 19的空间尺寸关联。
- FCNVMB面向SEG数据,InversionNet面向部分OpenFWI的数据。因为OpenFWI数据的特点,InversionNet有非常明显的高度降维部分。
- FCNVMB使用了迁移学习的训练手段,后者InversionNet是单一的训练思想。
- FCNVMB采用了包含skip connection的UNet的架构,而InversionNet是单一的CNN架构。