11本系列文章配套代码获取有以下两种途径:
-
通过百度网盘获取:
链接:https://pan.baidu.com/s/1XuxKa9_G00NznvSK0cr5qw?pwd=mnsj
提取码:mnsj
-
前往GitHub获取:
https://github.com/returu/PyTorch
在Pytorch中搭建神经网络有几种不同的方式,每种方式都有其特点和适用场景。选择哪种方式取决于具体的项目需求、个人习惯以及团队规范。在实际开发中,应当根据情况灵活选择合适的网络搭建方法,以达到效率和可维护性的平衡。
下面使用不同的方式搭建具有相同网络结构的卷积神经网络。
继承nn.Module类:
class CompleteConvNet(nn.Module):
def __init__(self,num_classes=10):
super().__init__()
# 第一个卷积层
self.conv1 = nn.Conv2d(3, 32, kernel_size=3)
self.bn1 = nn.BatchNorm2d(32)
self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
# 第二个卷积层
self.conv2 = nn.Conv2d(32, 64, kernel_size=3)
self.bn2 = nn.BatchNorm2d(64)
self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
# 第三个卷积层
self.conv3 = nn.Conv2d(64, 128, kernel_size=3)
self.bn3 = nn.BatchNorm2d(128)
# 全连接层
self.fc1 = nn.Linear(128 * 4 * 4, 512)
self.fc2 = nn.Linear(512,num_classes)
def forward(self, x):
# 第一个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
x = F.relu(self.bn1(self.conv1(x)))
x = self.pool1(x)
# 第二个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
x = F.relu(self.bn2(self.conv2(x)))
x = self.pool2(x)
# 第三个卷积层(卷积 -> 标准化 -> 激活)
x = F.relu(self.bn3(self.conv3(x)))
# 将特征图展平
x = x.view(x.size(0), -1)
# 全连接层
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
使用nn.Sequential:
-
1、直接使用nn.Sequential():
# 假设有10个类别
num_classes = 10
net_2 = nn.Sequential(
# 第一个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
nn.Conv2d(3, 32, kernel_size=3),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# 第二个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
nn.Conv2d(32, 64, kernel_size=3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# 第三个卷积层(卷积 -> 标准化 -> 激活)
nn.Conv2d(64, 128, kernel_size=3) ,
nn.BatchNorm2d(128),
nn.ReLU(),
# 展平层,将多维的特征图展平为一维张量
nn.Flatten(),
# 全连接层
nn.Linear(128 * 4 * 4, 512),
nn.ReLU(),
nn.Linear(512,num_classes))
# 获取子module
net_2[0]
-
2、nn.Sequential()搭配add_module():
# 假设有10个类别
num_classes = 10
net_3 = nn.Sequential()
# 第一个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
net_3.add_module("Conv_1" , nn.Conv2d(3, 32, kernel_size=3))
net_3.add_module("BatchNorm_1" , nn.BatchNorm2d(32))
net_3.add_module("ReLU_1" , nn.ReLU())
net_3.add_module("MaxPool_1" , nn.MaxPool2d(kernel_size=2, stride=2))
# 第二个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
net_3.add_module("Conv_2" , nn.Conv2d(32, 64, kernel_size=3))
net_3.add_module("BatchNorm_2" , nn.BatchNorm2d(64))
net_3.add_module("ReLU_2" , nn.ReLU())
net_3.add_module("MaxPool_2" , nn.MaxPool2d(kernel_size=2, stride=2))
# 第三个卷积层(卷积 -> 标准化 -> 激活)
net_3.add_module("Conv_3" , nn.Conv2d(64, 128, kernel_size=3) )
net_3.add_module("BatchNorm_3" , nn.BatchNorm2d(128))
net_3.add_module("ReLU_3" , nn.ReLU())
# 展平层,将多维的特征图展平为一维张量
net_3.add_module("Flatten_layer" , nn.Flatten())
# 全连接层
net_3.add_module("Linear_1" , nn.Linear(128 * 4 * 4, 512))
net_3.add_module("ReLU_4" , nn.ReLU())
net_3.add_module("Linear_2" , nn.Linear(512,num_classes))
# 获取子module
net_3[0] , net_3.Conv_1
-
3、nn.Sequential()搭配collections.OrderedDict():
from collections import OrderedDict
# 假设有10个类别
num_classes = 10
net_4 = nn.Sequential(OrderedDict([
# 第一个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
("Conv_1" , nn.Conv2d(3, 32, kernel_size=3)),
("BatchNorm_1" , nn.BatchNorm2d(32)),
("ReLU_1" , nn.ReLU()),
("MaxPool_1" , nn.MaxPool2d(kernel_size=2, stride=2)),
# 第二个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
("Conv_2" , nn.Conv2d(32, 64, kernel_size=3)),
("BatchNorm_2" , nn.BatchNorm2d(64)),
("ReLU_2" , nn.ReLU()),
("MaxPool_2" , nn.MaxPool2d(kernel_size=2, stride=2)),
# 第三个卷积层(卷积 -> 标准化 -> 激活)
("Conv_3" , nn.Conv2d(64, 128, kernel_size=3) ),
("BatchNorm_3" , nn.BatchNorm2d(128)),
("ReLU_3" , nn.ReLU()),
# 展平层,将多维的特征图展平为一维张量
("Flatten_layer" , nn.Flatten()),
# 全连接层
("Linear_1" , nn.Linear(128 * 4 * 4, 512)),
("ReLU_4" , nn.ReLU()),
("Linear_2" , nn.Linear(512,num_classes))
]))
# 获取子module
net_4[0] , net_4.Conv_1
-
4、nn.Sequential()嵌套nn.Sequential():
# 假设有10个类别
num_classes = 10
# 定义各个卷积块
conv_block1 = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
conv_block2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2)
)
conv_block3 = nn.Sequential(
nn.Conv2d(64, 128, kernel_size=3),
nn.BatchNorm2d(128),
nn.ReLU()
)
# 定义展平层部分
flatten_layer = nn.Flatten()
# 定义全连接层部分
fc_layers = nn.Sequential(
nn.Linear(128 * 4 * 4, 512), # 根据实际情况,可能需要修改为128 * 4 * 4
nn.ReLU(),
nn.Linear(512, num_classes)
)
# 使用nn.Sequential嵌套构建整个网络
net_5 = nn.Sequential(
conv_block1,
conv_block2,
conv_block3,
flatten_layer,
fc_layers)
使用nn.ModuleList:
class ConvNetList(nn.Module):
def __init__(self,num_classes=10):
super().__init__()
# 创建一个ModuleList,用于存储网络中的各个层
# 这些层将按照它们在列表中的顺序在前向传播中被依次应用
self.module_list = nn.ModuleList([
# 第一个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
nn.Conv2d(3, 32, kernel_size=3),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# 第二个卷积层(卷积 -> 标准化 -> 激活 -> 池化)
nn.Conv2d(32, 64, kernel_size=3),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2),
# 第三个卷积层(卷积 -> 标准化 -> 激活)
nn.Conv2d(64, 128, kernel_size=3) ,
nn.BatchNorm2d(128),
nn.ReLU(),
# 展平层,将多维的特征图展平为一维张量
nn.Flatten(),
# 全连接层
nn.Linear(128 * 4 * 4, 512),
nn.ReLU(),
nn.Linear(512,num_classes)
])
def forward(self, x):
# 遍历self.module_list中的每一个模块(层),并将输入数据x依次传递给这些模块
# 每个模块接的输出结果,将被作为下一个模块的输入
for module in self.module_list:
x = module(x)
return x
更多内容可以前往官网查看:
https://pytorch.org/
本篇文章来源于微信公众号: 码农设计师