神经网络搭建小实战&Sequential的使用
一级目录
二级目录
三级目录
神经网络搭建小实战&Sequential的使用
1. 搭建网络
所要搭建的网络结构(利用数据集CIFAR10)
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv1 = Conv2d(3,32,5, padding=2, stride=1)
self.pool1 = MaxPool2d(2)
self.conv2 = Conv2d(32,32,5, padding=2, stride=1)
self.pool2 = MaxPool2d(2)
self.conv3 = Conv2d(32,64,5, padding=2, stride=1)
self.pool3 = MaxPool2d(2)
self.flatten = Flatten()
self.linear1 = Linear(1024,64)
self.linear2 = Linear(64,10)
def forward(self, x):
x = self.conv1(x)
x = self.pool1(x)
x = self.conv2(x)
x = self.pool2(x)
x = self.conv3(x)
x = self.pool3(x)
x = self.flatten(x)
x = self.linear1(x)
x = self.linear2(x)
return x
test = Test()
print(test)
运行结果为
2. 检查网络的正确性
我们创建一个模拟输入张量,将其传入名为test的模型,来验证模型的输入输出格式是否符合预期,是模型开发和调试中的常见操作
# 检测网络结构
input = torch.ones((64,3,32,32))
output = test(input)
print(output.shape)
其中
input = torch.ones((64,3,32,32))
- torch.ones():创建一个全为 1 的张量
- (64, 3, 32, 32):指定张量的形状(shape),各维度含义:
- 64:批量大小(Batch Size),即一次处理 64 张图像
- 3:通道数(Channels),对应 RGB 三通道彩色图像
- 32x32:图像的高度和宽度(Height & Width),单位为像素
- 数据类型:默认是torch.float32
用途:模拟 64 张 32×32 像素的彩色图像输入
运行结果为
此时如果修改网络结构
则会报错,进一步验证了我们搭建的网络的正确性
3. Sequential的使用
在PyTorch中,torch.nn.Sequential
是一个非常有用的顺序容器,用于按顺序组合一系列神经网络模块,方便构建神经网络模型。以下是对其用法的详细讲解:
nn.Sequential
可以将多个神经网络层(如卷积层 Conv2d
、全连接层 Linear
、激活函数层 ReLU
等)按顺序封装起来,形成一个新的模块。在正向传播时,输入数据会按照添加层的顺序依次通过这些层。
3.1 两种常见使用方式
3.1.1 直接传入模块
通过在构造函数中直接传入一系列模块来创建 Sequential
容器,示例如下:
import torch
from torch import nn
# 创建一个包含卷积层、ReLU激活函数层、再一个卷积层、ReLU激活函数层的Sequential模型
model = nn.Sequential(
nn.Conv2d(1, 20, 5), # 输入通道为1,输出通道为20,卷积核大小为5
nn.ReLU(), # ReLU激活函数
nn.Conv2d(20, 64, 5), # 输入通道为20,输出通道为64,卷积核大小为5
nn.ReLU() # ReLU激活函数
)
这里,输入数据首先会进入第一个 Conv2d
层进行卷积操作,然后经过 ReLU
激活函数处理,接着进入第二个 Conv2d
层,最后再经过一次 ReLU
激活函数处理,得到最终输出。
3.1.2. 使用OrderedDict传入模块
当需要为每个模块指定名称时,可以使用 OrderedDict
来传入模块,示例如下:
from collections import OrderedDict
model = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(1, 20, 5)), # 模块名称为'conv1'
('relu1', nn.ReLU()), # 模块名称为'relu1'
('conv2', nn.Conv2d(20, 64, 5)), # 模块名称为'conv2'
('relu2', nn.ReLU()) # 模块名称为'relu2'
]))
这种方式的好处是可以方便地通过名称来访问和操作特定的模块,比如后续可能需要获取某一层的权重、修改某一层的参数等。
应用场景
- 快速搭建简单模型:对于一些结构相对简单、层与层之间按顺序连接的神经网络,如小型的卷积神经网络用于图像分类任务的基础结构、简单的多层感知机(全连接神经网络)等,使用
nn.Sequential
可以快速搭建起来,减少代码量。 - 模型模块化:在构建大型复杂模型时,可以将模型的不同部分(如特征提取部分、分类部分等)分别用
nn.Sequential
封装,使代码结构更加清晰,便于管理和维护。
总之,torch.nn.Sequential
是PyTorch中构建神经网络模型时常用的工具,能帮助开发者高效、简洁地组织神经网络层。
3.2 有关代码
import torch
from torch import nn
from torch.nn import Conv2d, MaxPool2d, Flatten, Linear, Sequential
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
# self.conv1 = Conv2d(3,32,5, padding=2, stride=1)
# self.pool1 = MaxPool2d(2)
# self.conv2 = Conv2d(32,32,5, padding=2, stride=1)
# self.pool2 = MaxPool2d(2)
# self.conv3 = Conv2d(32,64,5, padding=2, stride=1)
# self.pool3 = MaxPool2d(2)
# self.flatten = Flatten()
# self.linear1 = Linear(1024,64)
# self.linear2 = Linear(64,10)
self.model1 = Sequential(
Conv2d(3, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 32, 5, padding=2, stride=1),
MaxPool2d(2),
Conv2d(32, 64, 5, padding=2, stride=1),
MaxPool2d(2),
Flatten(),
Linear(1024, 64),
Linear(64, 10)
)
def forward(self, x):
# x = self.conv1(x)
# # x = self.pool1(x)
# # x = self.conv2(x)
# # x = self.pool2(x)
# # x = self.conv3(x)
# # x = self.pool3(x)
# # x = self.flatten(x)
# # x = self.linear1(x)
# # x = self.linear2(x)
x = self.model1(x)
return x
test = Test()
print(test)
# 检测网络结构
input = torch.ones((64, 3, 32, 32))
output = test(input)
print(output.shape)
运行结果
3.2 利用tensorboard来查看结果
writer = SummaryWriter("logs_seq")
writer.add_graph(test, input)
writer.close()