【问题标题】:Translating 3D CNN from Keras to Pytorch将 3D CNN 从 Keras 转换为 Pytorch
【发布时间】:2021-04-27 05:48:39
【问题描述】:

我正在尝试将以下 3D CNN 架构从 keras 转换为 pytorch。 3D 图像均具有以下尺寸:193 x 229 x 193。

Keras 中的网络架构:

def test_model(size):
    model = Sequential()
    model.add(Conv3D(filters=8,
                     kernel_size=(3, 3, 3),
                     activation='relu',
                     input_shape=size,
                     name="conv_1_1"))
    model.add(Conv3D(filters=8,
                     kernel_size=(3, 3, 3),
                     activation='relu',
                     name="conv_1_2"))
    model.add(MaxPooling3D(pool_size=(2, 2, 2),
                           strides=(2, 2, 2)))
    model.add(Conv3D(filters=16,
                     kernel_size=(3, 3, 3),
                     activation='relu',
                     input_shape=size,
                     name="conv_2_1"))
    model.add(Conv3D(filters=16,
                     kernel_size=(3, 3, 3),
                     activation='relu',
                     name="conv_2_2"))
    model.add(MaxPooling3D(pool_size=(2, 2, 2),
                           strides=(2, 2, 2)))
    model.add(Flatten())
    model.add(Dense(units=1,
                    name="d_2"))
    return model

我尝试将其转换为 Pytorch:

class Model(torch.nn.Module): 
    
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv3d(input_channel=1, output_channel=8, kernel_size=3)
        self.conv2 = nn.Conv3d(input_channel=8, output_channel=8, kernel_size=3)
        self.conv3 = nn.Conv3d(input_channel=8, output_channel=16, kernel_size=3)
        self.conv4 = nn.Conv3d(input_channel=16, output_channel=16, kernel_size=3)
        self.fc1 = nn.Linear( ???? , 1)

     def forward (self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(F.max_pool3d(self.conv2(x), kernel_size=2, stride=2))
        x = F.relu(self.conv3(x))
        x = F.relu(F.max_pool3d(self.conv4(x), kernel_size=2, stride=2))
        x = self.fc1

        return x
    
net = Model()

请您让我知道我在哪里犯了错误,并澄清如何确定 nn.Linear( ???? , 2) 层的输入?感谢您的帮助!

【问题讨论】:

    标签: keras pytorch conv-neural-network


    【解决方案1】:

    检查您最后一个nn.Conv3d 的输出,您的张量形状为(-1, 16, 45, 54, 45)。因此,您的密集层上总共需要16*45*54*45=1749600 个连接(这非常大!)。

    需要指出的其他一些事情:

    • input_channeloutput_channels 应分别为 in_channelsout_channels
    • 您可以使用torch.flatten(x, start_dim=1)nn.Flatten() 层(默认情况下,它将从axis=1 展平到axis=-1)。
    • 您放错了F.relu 激活,因为您的整体结构是[conv3d, relu, conv3d, relu, maxpool3d] + [conv3d, relu, conv3d, relu, maxpool3d] + [flatten, dense]

    结果代码:

    class Model(torch.nn.Module): 
        def __init__(self):
            super(Model, self).__init__()
            self.conv1 = nn.Conv3d(in_channels=1, out_channels=8, kernel_size=3)
            self.conv2 = nn.Conv3d(in_channels=8, out_channels=8, kernel_size=3)
            self.conv3 = nn.Conv3d(in_channels=8, out_channels=16, kernel_size=3)
            self.conv4 = nn.Conv3d(in_channels=16, out_channels=16, kernel_size=3)
            self.fc1 = nn.Linear(1749600, 1)
    
        def forward(self, x):
            x = F.relu(self.conv1(x))
            x = F.relu(self.conv2(x))
            x = F.max_pool3d(x, kernel_size=2, stride=2)
    
            x = F.relu(self.conv3(x))
            x = F.relu(self.conv4(x))
            x = F.max_pool3d(x, kernel_size=2, stride=2)
    
            x = torch.flatten(x, start_dim=1)
            x = self.fc1(x)
            return x
    

    【讨论】:

    • 谢谢@Ivan,这真的很有帮助。请问您如何计算 (-1, 16, 45, 54, 45) 的张量形状以及 -1 指的是什么?
    • 当然,我想您可以通过查看公式here 逐层计算输出形状。然而,最简单的方法是截断您的模型(删除 torch.flattenfc1 向前调用并查看输出的形状。不要担心 -1,它指的是批量大小,我可以只需将Bbatch_size 放在那里!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 2021-07-01
    • 2020-05-27
    • 2021-07-10
    • 1970-01-01
    • 2021-03-19
    • 2020-02-09
    相关资源
    最近更新 更多