给定组=1,权重大小为[8,3,3,3],预期输入[1,1000,28,28]有3个通道,但得到了1000个通道

问题描述 投票:0回答:1

我尝试实现残差连接神经网络并重新创建 Lenet-5,但无法设置架构 这是剩余连接块

class ResidualBlock(torch.nn.Module): 

    def __init__(  
        self,
        input_c,  # Число каналов на входе
        output_c,  # Число каналов на выходе
        kernel_size,  # Размер ядра
        activation=torch.nn.ReLU,  # Класс функции активации
    ):
        super().__init__()
        # Функция активации для нелинейности
        self.activation = activation()

        # Паддинг подбираем такой, чтобы размеры h и w изображения не менялись
        #  (считаем что размер ядра всегда нечётный)
        padding_size = (kernel_size - 1) // 2

        # Операция свёртки
        self.conv = torch.nn.Conv2d(
            in_channels=input_c,
            out_channels=output_c,
            kernel_size=kernel_size,
            padding=padding_size,
            padding_mode="zeros",
        )

        # Если число каналов у входа и выхода различаются, то будем делать свёртку с
        #  ядром размера 1
        if input_c != output_c:
            self.correct_channels = torch.nn.Conv2d(
                in_channels=input_c,
                out_channels=output_c,
                kernel_size=1,
            )
        else:
            self.correct_channels = torch.nn.Identity()

这是架构

class MyModel(torch.nn.Module):
    def __init__(self):
      super().__init__()
      
      self.conv1 = ResidualBlock(input_c=1, output_c=6, kernel_size=5,)
      self.maxpool1 = torch.nn.MaxPool2d(kernel_size=2)
      self.conv2 = ResidualBlock(input_c=6, output_c=16, kernel_size=5)
      self.maxpool2 = torch.nn.MaxPool2d(kernel_size=2)
      self.conv3 = ResidualBlock(input_c=16, output_c=120, kernel_size=5)

      self.lin1 = torch.nn.Linear(in_features=120, out_features=84)
      self.relu1 = torch.nn.ReLU()
      self.lin2 = torch.nn.Linear(in_features=84, out_features=10)
      self.softmax = torch.nn.Softmax()

    def forward(self, x):
      x = self.activation(self.conv(x) + self.correct_channels(x))
      x = self.maxpool1(x)
      x = self.activation(self.conv(x) + self.correct_channels(x))
      x = self.maxpool2(x)
      x = self.activation(self.conv(x) + self.correct_channels(x))

      x = self.lin1(x)
      x = self.relu1(x)
      x = self.lin2(x)
      x = self.softmax(x)

      return x
model = MyModel()

我尝试更改输入和输出通道的大小,但没有任何效果

machine-learning pytorch conv-neural-network deep-residual-networks
1个回答
0
投票

我对您的代码做了一些修改:

class ResidualBlock(torch.nn.Module): 
    def __init__(  
        self,
        input_c,  # Число каналов на входе
        output_c,  # Число каналов на выходе
        kernel_size,  # Размер ядра
        activation=torch.nn.ReLU,  # Класс функции активации
    ):
        super().__init__()
        # Функция активации для нелинейности
        self.activation = activation()
        # Паддинг подбираем такой, чтобы размеры h и w изображения не менялись
        #  (считаем что размер ядра всегда нечётный)
        padding_size = (kernel_size - 1) // 2
        # Операция свёртки
        self.conv = torch.nn.Conv2d(
            in_channels=input_c,
            out_channels=output_c,
            kernel_size=kernel_size,
            padding=padding_size,
            padding_mode="zeros",
        )
        # Если число каналов у входа и выхода различаются, то будем делать свёртку с
        #  ядром размера 1
        if input_c != output_c:
            self.correct_channels = torch.nn.Conv2d(
                in_channels=input_c,
                out_channels=output_c,
                kernel_size=1,
            )
        else:
            self.correct_channels = torch.nn.Identity()
    def forward(self,x):
      return self.activation(self.conv(x) + self.correct_channels(x))

class MyModel(torch.nn.Module):
    def __init__(self):
      super().__init__()
      self.conv1 = ResidualBlock(input_c=1, output_c=6, kernel_size=5,)
      self.maxpool1 = torch.nn.MaxPool2d(kernel_size=2)
      self.conv2 = ResidualBlock(input_c=6, output_c=16, kernel_size=5)
      self.maxpool2 = torch.nn.MaxPool2d(kernel_size=2)
      self.conv3 = ResidualBlock(input_c=16, output_c=120, kernel_size=5)
      self.lin1 = torch.nn.Linear(in_features=120*64*64, out_features=84)
      self.relu1 = torch.nn.ReLU()
      self.lin2 = torch.nn.Linear(in_features=84, out_features=10)
      self.softmax = torch.nn.Softmax()

    def forward(self, x):
      x = self.conv1(x)
      x = self.maxpool1(x)
      x = self.conv2(x)
      x = self.maxpool2(x)
      x = self.conv3(x)
      x = x.view(x.shape[0], -1)
      x = self.lin1(x)
      x = self.relu1(x)
      x = self.lin2(x)
      x = self.softmax(x)
      return x
model = MyModel()
  1. 为了清晰起见,将

    self.activation(self.conv(x) + self.correct_channels(x))
    行移至
    ResidualBlock
    类。

  2. 添加

    x = x.view(x.shape[0], -1)
    以展平提取的卷积特征。

  3. self.lin1
    的大小取决于输入张量的大小。在提供的代码中,我假设输入大小为
    [8, 1, 256, 256]
    。由于您在模型中使用了
    torch.nn.MaxPool2d
    两次,因此经过
    [8, 120, 64, 64]
    后,张量大小将为
    self.conv3
    。因此,经过
    [8, 491520]
    后,张量大小会变为
    x.view(x.shape[0], -1)
    (120 * 64 * 64 = 491520),因此需要将
    self.lin1
    调整为
    torch.nn.Linear(in_features=120*64*64, out_features=84)
    。同样,如果您的输入张量形状不同,例如
    [8, 1, 1000, 1000]
    ,您应该将
    self.lin1
    设置为
    torch.nn.Linear(in_features=120*250*250, out_features=84)

  4. 有关LeNet-5的更多信息,您可以参考此存储库:https://github.com/ChawDoe/LeNet5-MNIST-PyTorch/blob/master/model.py

© www.soinside.com 2019 - 2024. All rights reserved.