yaoppeng / U-Net_v2

211 stars 18 forks source link

模型问题 #16

Open sorryandbyebye opened 7 months ago

sorryandbyebye commented 7 months ago

您好!我有几个问题想提问~ 1、为什么您的跳跃连接是用add操作,而不是用cat呢?

2、我在ISIC2018数据集上测试,使用pvt encoder的unet(姑且称为pvt-Unet)结果似乎不如unet,但是pvt-Unet结合SDI模块(也就是您文章中提出的Unet_v2)的结果远远好于unet这是什么原因呢?

3、我在ISIC2018数据集上测试,使用Unet结合SDI模块的结果似乎不如unet,但是pvt-Unet结合SDI模块(也就是您文章中提出的Unet_v2)的结果远远好于unet这是什么原因呢?

不知您是否做过这两个消融实验?能否向您要份相关代码?

下面是我的结果,实验设置是adam(0.5,0.999),lr=0.001,lr每10回合衰减为原来的0.1倍

1707723251(1)

希望能得到您的指导和回复~

这是我用来实验的pvt-Unet代码 ` class transEncoderUNet(nn.Module): """ use SpatialAtt + ChannelAtt """ def init(self, channel=32, n_classes=1, deep_supervision=True, pretrained_path=None): super(transEncoderUNet,self).init() self.deep_supervision = deep_supervision

    self.encoder = Encoder(pretrained_path)
    self.down4 = down(512, 512)

    self.up1 = up(1024, 320)
    self.up2 = up(640, 128)
    self.up3 = up(256, 64)
    self.up4 = up(128, 64)
    self.outc = outconv(64, 1)

def forward(self, x):
    seg_outs = []
    f1, f2, f3, f4 = self.encoder(x)

    f5 = self.down4(f4)
    #
    y = self.up1(f5, f4)
    seg_outs.append(y)
    y = self.up2(y, f3)
    seg_outs.append(y)
    y = self.up3(y, f2)
    seg_outs.append(y)
    y = self.up4(y, f1)
    y = self.outc(y)
    seg_outs.append(y)

    for i, o in enumerate(seg_outs):
        seg_outs[i] = F.interpolate(o, scale_factor=4, mode='bilinear')

    if self.deep_supervision:
        return seg_outs[::-1]
    else:
        return seg_outs[-1]

`

这是我用来实验的Unet+SDI代码

` class SDIUnet(nn.Module): def init(self, n_channels=3, n_classes=1): super(SDIUnet, self).init()

    self.inc = inconv(n_channels, 64)
    self.down1 = down(64, 128)
    self.down2 = down(128, 256)
    self.down3 = down(256, 512)
    self.down4 = down(512, 512)

    self.ca_1 = ChannelAttention(64)
    self.sa_1 = SpatialAttention()

    self.ca_2 = ChannelAttention(128)
    self.sa_2 = SpatialAttention()

    self.ca_3 = ChannelAttention(256)
    self.sa_3 = SpatialAttention()

    self.ca_4 = ChannelAttention(512)
    self.sa_4 = SpatialAttention()

    self.Translayer_1 = BasicConv2d(64, 32, 1)
    self.Translayer_2 = BasicConv2d(128, 32, 1)
    self.Translayer_3 = BasicConv2d(256, 32, 1)
    self.Translayer_4 = BasicConv2d(512, 32, 1)

    self.sdi_1 = SDI(32)
    self.sdi_2 = SDI(32)
    self.sdi_3 = SDI(32)
    self.sdi_4 = SDI(32)

    self.up1 = up(544, 32)
    self.up2 = up(64, 32)
    self.up3 = up(64, 32)
    self.up4 = up(64, 32)
    self.outc = outconv(32, n_classes)

def forward(self, x):
    x = x.float()
    x1 = self.inc(x)
    x2 = self.down1(x1)
    x3 = self.down2(x2)
    x4 = self.down3(x3)
    x5 = self.down4(x4)

    f1 = self.ca_1(x1) * x1
    f1 = self.sa_1(f1) * f1
    f1 = self.Translayer_1(f1)

    f2 = self.ca_2(x2) * x2
    f2 = self.sa_2(f2) * f2
    f2 = self.Translayer_2(f2)

    f3 = self.ca_3(x3) * x3
    f3 = self.sa_3(f3) * f3
    f3 = self.Translayer_3(f3)

    f4 = self.ca_4(x4) * x4
    f4 = self.sa_4(f4) * f4
    f4 = self.Translayer_4(f4)

    f41 = self.sdi_4([f1, f2, f3, f4], f4)
    f31 = self.sdi_3([f1, f2, f3, f4], f3)
    f21 = self.sdi_2([f1, f2, f3, f4], f2)
    f11 = self.sdi_1([f1, f2, f3, f4], f1)

    x = self.up1(x5, f41)
    x = self.up2(x, f31)
    x = self.up3(x, f21)
    x = self.up4(x, f11)

    x = self.outc(x)

    return x

`

yaoppeng commented 7 months ago
  1. AddCat都可以。如果用Cat则需要Cat完了之后使用Conv进行降维操作,也会增加参数量和计算量。我为了简单使用了Add操作。

  2. 请问你这个分数是IoU还是DSC?DSC我的实验数据能到90左右。我做过相关实验(可能并非全部),结果是更好的,而且差距没有你这个这么大。你在做消融实验时应该保证Backbone一致(包括网络层数,输出通道数)。U-Net其实是简化版的VGG作为backbone。你可以试试ISIC segmentation的相关训练步骤。

By the way, 你这个81的score,无论是DSC和IoU都偏低了, 我记得我当时的实验没有到过这个数据。

由于最近一段时间在外面忙于其他事物, 我会抽时间检查repo看相关的代码是否已经上传。谢谢。

sorryandbyebye commented 7 months ago

十分感谢您的回复 我的分数是DSC,可能是我训练设置(学习率等)的原因,我感觉我训练的所有模型分数普遍偏低。我会重新训练这些分数很低的模型。

可以问一下您Unet加上SDI模块的代码嘛?

yaoppeng commented 7 months ago

我再check一下repo里看看有没有相关代码。