有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
U2NET显著性检测实战1
U2NET显著性检测实战2
U2NET显著性检测实战3
def _upsample_like(src,tar):
src = F.upsample(src,size=tar.shape[2:],mode='bilinear')
return src
使用双线性插值进行上采样操作
class REBNCONV(nn.Module):
def __init__(self,in_ch=3,out_ch=3,dirate=1):
super(REBNCONV,self).__init__()
self.conv_s1 = nn.Conv2d(in_ch,out_ch,3,padding=1*dirate,dilation=1*dirate)
self.bn_s1 = nn.BatchNorm2d(out_ch)
self.relu_s1 = nn.ReLU(inplace=True)
def forward(self,x):
hx = x
xout = self.relu_s1(self.bn_s1(self.conv_s1(hx)))
return xout
定义二维卷积、二维池化、Relu,然后进行对应的前向传播
在 U2-Net 中,RSU7
, RSU6
, RSU5
, RSU4
, 和 RSU4F
是用于构造网络不同层级的模块。它们共同构成了 U2-Net 的多层次特征提取体系
RSU7 (Residual U-Block 7):
RSU7
是最深层的模块,具有最大的感受野,用于网络的最初阶段,用于从输入图像中提取基础和全局特征。在 U2NET
架构中,RSU7
作为第一个阶段使用。RSU6, RSU5, RSU4:
RSU6
, RSU5
, RSU4
的主要区别在于它们的深度和感受野的大小。每个模块都比前一个模块浅一点,感受野也稍小。这些层用于提取越来越具体的特征,随着网络的深入,这些特征越来越侧重于局部细节。RSU4F (Residual U-Block 4-Full):
RSU4F
是一种特殊的 RSU 模块,它不使用最大池化层来减少特征图的尺寸,而是使用不同膨胀率的卷积来增大感受野(即空洞卷积),RSU4F
用于网络的深层,用于捕捉更细粒度的特征。在 U2-Net 的结构中,这些 RSU 模块按照从 RSU7
到 RSU4F
的顺序排列。
在编码器阶段,随着层级的增加,模块逐渐变得更浅,专注于更细节的特征提取。
在解码器阶段,这些模块的输出与对应编码器阶段的输出进行融合,通过上采样逐步恢复图像的空间维度,同时保持了特征的丰富性。
总结来说,RSU7
到 RSU4F
的不同主要在于它们的深度(层数)和膨胀率,这影响了它们的感受野大小和特征提取的具体性。
在前面的网络架构中,我们可以看到一共有d0到d6共7个输出,每一步都有一个对应的输出,每一步都可以计算损失,损失函数:
d0, d1, d2, d3, d4, d5, d6 = net(inputs_v)
loss2, loss = muti_bce_loss_fusion(d0, d1, d2, d3, d4, d5, d6, labels_v)
def muti_bce_loss_fusion(d0, d1, d2, d3, d4, d5, d6, labels_v):
loss0 = bce_loss(d0,labels_v)
loss1 = bce_loss(d1,labels_v)
loss2 = bce_loss(d2,labels_v)
loss3 = bce_loss(d3,labels_v)
loss4 = bce_loss(d4,labels_v)
loss5 = bce_loss(d5,labels_v)
loss6 = bce_loss(d6,labels_v)
loss = loss0 + loss1 + loss2 + loss3 + loss4 + loss5 + loss6
print("l0: %3f, l1: %3f, l2: %3f, l3: %3f, l4: %3f, l5: %3f, l6: %3f\n"%(loss0.item(),loss1.item(),loss2.item(),loss3.item(),loss4.item(),loss5.item(),loss6.item()))
return loss0, loss