6.1 torch.nn.Module介绍
torch.nn.Module是 PyTorch 中构建神经网络的基础类,所有的神经网络模块都应该继承这个类。它提供了一种便捷的方式来组织和管理网络中的各个组件,包括层、参数等,同时还内置了许多用于模型训练和推理的功能。
官网:torch.nn — PyTorch 1.8.1 documentation
核心功能:
(1)、网络构建:通过继承torch.nn.Module类,我们可以自定义自己的神经网络结构。在__init__方法中定义网络的各个层,在forward方法中定义数据的前向传播过程。
(2)、参数管理:torch.nn.Module会自动跟踪和管理网络中的参数(如权重和偏置)。我们可以通过parameters()方法获取网络的所有参数,方便进行优化器的配置和参数的更新。
(3)、设备转换:可以使用to()方法将模型转移到指定的设备(如 CPU 或 GPU)上,以利用不同设备的计算能力。
(4)、状态切换:提供了train()和eval()方法来切换模型的训练和评估状态。在训练状态下,一些具有随机性的层(如 Dropout、BatchNorm)会正常工作;在评估状态下,这些层会采用确定性的行为。
6.2 torch.nn.Module常用方法
__init__(self):构造函数,用于初始化网络的各个层和参数。在自定义网络时,需要在该方法中调用super().__init__()来初始化父类。
forward(self, x):前向传播方法,定义了数据在网络中的流动过程。当对模型进行调用时(如model(x)),实际上是调用了该方法。
parameters(self):返回一个迭代器,包含网络中的所有可学习参数。
named_parameters(self):返回一个迭代器,包含网络中参数的名称和对应的参数值。
to(self, device):将模型转移到指定的设备上。例如,model.to('cuda')将模型转移到 GPU 上。
train(self, mode=True):将模型设置为训练模式。
eval(self):将模型设置为评估模式,相当于train(mode=False)。
save_state_dict(self, path):保存模型的参数状态字典到指定路径。
load_state_dict(self, state_dict):从参数状态字典中加载模型的参数。
6.3 程序演示
6.3.1 官网提供的例子
import torch.nn as nn
import torch.nn.functional as Fclass Model(nn.Module): #搭建的神经网络 Model继承了 Module类(父类)def __init__(self): #初始化函数super(Model, self).__init__() #必须要这一步,调用父类的初始化函数self.conv1 = nn.Conv2d(1, 20, 5)self.conv2 = nn.Conv2d(20, 20, 5)def forward(self, x): #前向传播(为输入和输出中间的处理过程),x为输入x = F.relu(self.conv1(x)) #conv为卷积,relu为非线性处理return F.relu(self.conv2(x))
注意:前向传播 forward(在所有子类中进行重写)
6.3.2 自定义Model
import torch
from torch import nn# 定义一个自定义模型类Custom_Model,继承自nn.Module
# 所有的神经网络模型都应该继承nn.Module,以利用其提供的参数管理、设备转换等功能
class Custom_Model(nn.Module):# 构造函数,用于初始化模型的层和参数def __init__(self):# 调用父类nn.Module的构造函数,确保模型能够正确初始化super().__init__()# 前向传播方法,定义数据在模型中的流动和计算过程# 当对模型实例传入输入数据时,会自动调用该方法def forward(self, input):# 定义模型的计算逻辑:输入数据加1output = input + 1# 返回计算结果return outputCustom_Model = Custom_Model()
# 创建一个张量x,值为1.0,作为模型的输入数据
x = torch.tensor(1.0)
# 将输入数据x传入模型,模型会自动调用forward方法进行计算,得到输出结果
output = Custom_Model(x)
# 打印输出结果,此时输出应为2.0(1.0 + 1)
print(output)
6.4 torch.nn.functional.conv2d介绍
torch.nn.functional.conv2d是 PyTorch 中用于执行二维卷积操作的函数,在卷积神经网络(CNN)中扮演着至关重要的角色,用于提取图像等二维数据的特征。以下是对它的详细介绍:
参数说明:
- input (Tensor):输入张量,形状为(N, C_in, H_in, W_in)。其中,N是批量大小(batch size),表示一次处理的样本数量;C_in是输入通道数,例如对于灰度图像C_in=1,对于彩色图像(RGB 格式)C_in=3;H_in和W_in分别是输入特征图的高度和宽度。
- weight (Tensor):卷积核(过滤器)张量,形状为(C_out, C_in, H_k, W_k) 。C_out是输出通道数,决定了经过卷积操作后生成的特征图数量;C_in必须与输入张量的通道数一致;H_k和W_k分别是卷积核的高度和宽度。
- bias (Tensor,可选):偏置张量,形状为(C_out) ,为每个输出通道添加一个可学习的偏置值,默认值为None。
- stride (int或tuple,默认值:1 ):卷积核在输入特征图上滑动的步长。如果是一个整数,表示在高度和宽度方向上的步长相同;如果是一个元组(stride_h, stride_w),则分别指定高度和宽度方向上的步长。
- padding (int或tuple,默认值:0 ):在输入特征图的边缘添加填充(padding)像素。同样,整数表示在高度和宽度方向上添加相同数量的填充;元组(padding_h, padding_w)分别指定高度和宽度方向上的填充数量。填充可以用来控制输出特征图的大小,使其与输入大小相同或满足特定的尺寸要求。
- dilation (int或tuple,默认值:1 ):卷积核元素之间的间距。dilation=1表示正常的卷积核;dilation=2时,卷积核元素之间会间隔一个位置,相当于扩大了卷积核的感受野。
- groups (int,默认值:1 ):分组卷积的组数。当groups=1时,就是普通的卷积操作;当groups > 1时,输入通道会被分成groups组,卷积核也会相应分组,每组卷积核只与对应的一组输入通道进行卷积操作,常用于减少计算量或实现特定的网络结构,比如 AlexNet 中的分组卷积。
应用场景:
torch.nn.functional.conv2d广泛应用于各类基于卷积神经网络的任务,如:
- 图像分类:从输入图像中提取各种层次的特征,用于判断图像所属的类别。
- 目标检测:提取图像特征来定位和识别目标物体。
- 语义分割:对图像中的每个像素进行分类,以实现对图像内容的精细分割。
总的来说,torch.nn.functional.conv2d是构建深度学习视觉模型的基础组件之一,通过合理设置其参数,可以灵活地调整卷积操作,以适应不同的任务需求。
6.4.1 卷积操作原理
6.4.2 实战演示
import torch
import torch.nn.functional as F
# 将二维矩阵转化为tensor数据类型
input = torch.tensor([[1, 2, 0, 3, 1],[0, 1, 2, 3, 1],[1, 2, 1, 0, 0],[5, 2, 3, 1, 1],[2, 1, 0, 1, 1]])
# 卷积核
kernel = torch.tensor([[1, 2, 1],[0, 1, 0],[2, 1, 0]])
# 尺寸只有高宽,不符合要求
print(input.shape) # 5*5
print(kernel.shape) # 3*#
input = torch.reshape(input, (1, 1, 5, 5))
kernel = torch.reshape(kernel, (1, 1, 3, 3))
print(input.shape)
print(kernel.shape)output = F.conv2d(input, kernel, stride=1)
print(output)
运行结果:
参数修改:
(1)、将stride修改
stride (int或tuple,默认值:1 ):卷积核在输入特征图上滑动的步长。如果是一个整数,表示在高度和宽度方向上的步长相同;如果是一个元组(stride_h, stride_w),则分别指定高度和宽度方向上的步长。
output = F.conv2d(input, kernel, stride=2)
(2)、修改Padding
padding (int或tuple,默认值:0 ):在输入特征图的边缘添加填充(padding)像素。同样,整数表示在高度和宽度方向上添加相同数量的填充;元组(padding_h, padding_w)分别指定高度和宽度方向上的填充数量。填充可以用来控制输出特征图的大小,使其与输入大小相同或满足特定的尺寸要求。
padding=1:将输入图像左右上下两边都拓展一个像素,空的地方默认为0
output = F.conv2d(input, kernel, stride=1, padding=1)
运行结果: