我尝试实现残差连接神经网络并重新创建 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()
我尝试更改输入和输出通道的大小,但没有任何效果
我对您的代码做了一些修改:
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()
为了清晰起见,将
self.activation(self.conv(x) + self.correct_channels(x))
行移至 ResidualBlock
类。
添加
x = x.view(x.shape[0], -1)
以展平提取的卷积特征。
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)
。
有关LeNet-5的更多信息,您可以参考此存储库:https://github.com/ChawDoe/LeNet5-MNIST-PyTorch/blob/master/model.py