nn.Module的使用
torch.nn的核心数据结构是Module,它是一个抽象的概念,既可以表示神经网络中的某个层(layer),也可以表示一个包含很多层的神经网络。在实际使用中,最常见的做法是继承nn.Module,撰写自己的网络/层。以下是其主要用法和功能:
1、构建自定义模型:
继承‘nn.Module’类是构建自定义神经网络模型的第一步。通过创建一个新的类,并将其继承自‘nn.Module’,可以利用PyTorch提供的丰富的神经网络构建块来定义自己的模型。
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super().__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, output_size)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
forword函数:
2、管理模型参数:
‘ nn.Module’会自动追踪并管理模型中的所有参数。在上述示例中,‘nn.Linear'层的权重和偏置就是模型的参数。通过调用'model.parameters()'方法,你可以获取模型中所有参数的迭代器,方便优化和保存。
model = MyModel(input_size=10, hidden_size=20, output_size=5)
parameters = list(model.parameters())
3、管理子模块:
'nn.Module'还允许将子模块嵌套在模型中,这使得模型的层次结构更加清晰,并允许在模型中嵌套复杂的子模块。
class ComplexModel(nn.Module):
def __init__(self):
super(ComplexModel, self).__init__()
self.layer1 = MyModel(input_size=10, hidden_size=20, output_size=5)
self.layer2 = MyModel(input_size=5, hidden_size=10, output_size=3)
def forward(self, x):
x = self.layer1(x)
x = self.layer2(x)
return x
4、定义前向计算:
在'nn.Module'中,需要实现一个'forward'方法,该方法定义了模型的前向计算逻辑。通过这个方法,PyTorch可以了解模型的结构,并在调用'model.forward()'时执行前向计算。
class MyModel(nn.Module):
# ... (前面的定义)
def forward(self, x):
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
5、模型的保存和加载:
由于'nn.Module'跟踪模型的结构和参数,因此可以轻松的保存整个模型或仅保存模型的参数,并在需要时加载他们。
torch.save(model.state_dict(), 'model.pth') # 保存模型参数
loaded_model = MyModel(input_size=10, hidden_size=20, output_size=5)
loaded_model.load_state_dict(torch.load('model.pth')) # 加载模型参数
神经网络—卷积层
卷积层是构成卷积神经网络的核心组件之一。卷积神经网络是一类专门用于处理网络结构数据(如图像)的神经网络,卷积层用于提取输入数据的局部特征,并通过卷积操作实现对输入数据的空间层次表示。
卷积神经网络通常由多个卷积层、池化层和全连接层等组成。其中,卷积层通过使用卷积操作对输入数据进行处理,通过学习卷积核的权重来捕获输入数据的特征。卷积层在处理图像等数据时能够有效地保留空间结构信息,使得网络能够学习到具有平移不变性的特征。
以二维卷积为例:
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)
其中:
1、in_channels('int'):描述输入数据的通道数(输入特征图的深度)。例如,如果输入是RGB图像,则通道数为3。
2、out_channels('int'):描述输出数据的通道数,即卷积层的滤波器数量。每个滤波器在输出上产生一个通道。这决定了卷积层的输出特征图深度。
3、kernel_size:卷积核的大小可以是单个整数表示方形核的边长,也可以是元组'(height,width)'表示矩形核的高度和宽度。
4、stride:卷积核的滑动步幅,控制卷积核在输入上的移动步长。可以是单个整数(默认为1)或元组,表示水平和垂直方向上的步幅。
5、padding:在输入的每一侧添加零值填充的数量。可以是单个整数或元组,表示水平和垂直方向上的填充数。
6、dilation:卷积核元素之间的间距,也称为膨胀因子。用于控制卷积核中元素的采样间隔。
7、groups:控制输入通道和输出通道之间的连接方式。当 groups大于1时(默认为1),表示使用分组卷积。
8、bias:决定是否使用偏置项。如果设置为False(默认为True),则卷积层不包含可学习的偏置项。
9、padding_mode:控制填充的模式,可以是字符串 {‘zeros’, ‘reflect’, ‘replicate’, ‘circular’} 中的一个(默认为'zeros')。
10、device:用于指定卷积层的计算设备(CPU或GPU)。
11、dtype:用于指定卷积层的数据类型。
import torch
import torchvision.datasets
from torch import nn
from torch.utils.data import DataLoader
dataset=torchvision.datasets.CIFAR10("../data",train=False,transform=torchvision.transforms.ToTensor(),download=True)
dataloader=DataLoader(dataset,batch_size=64)
class Mymodel(nn.Module):
def __init__(self):
super().__init__()
self.conv1=Conv2d(in_channels=3,out_chaanels=3,kernel_size=3,stride=1,padding=0)
def forward(self,x):
x=self.conv1(x)
return x
mymodel=Mymodel()
for data in dataloader:
imags,targets=data
output=mymodel(imags)
卷积前后的尺寸关系(N为batch_size):
神经网络—最大池化的使用
池化层是卷积神经网络中的一种用于降采样的层,主要用于减小输入数据的空间尺寸、减少计算量,并提取输入数据的主要特征。池化层在整个网络中通常与卷积层交替使用,帮助网络更好地学习和捕捉图像的特征。
池化操作是在输入数据的局部区域内进行的降采样操作。通常采用最大池化或平均池化。最大池化取局部区域的最大值,而平均池化取局部区域的平均值。
以最大池化为例:
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
其中:
1、kernel_size:池化窗口的大小,可以是单个整数表示方形窗口的边长,也可以是元组 (height, width)
表示矩形窗口的高度和宽度。
2、stride:池化窗口的滑动步幅,控制池化窗口在输入上的移动步长。可以是单个整数或元组,表示水平和垂直方向上的步幅。
3、padding:在输入的每一侧添加零值填充的数量。可以是单个整数或元组,表示水平和垂直方向上的填充数。
4、dilation:池化窗口元素之间的间距,也称为膨胀因子。用于控制池化窗口中元素的采样间隔。
5、return_indices:如果设置为 True(默认为 False),将返回每个最大值的索引
6、ceil_mode:如果设置为 True(默认为 False),将使用上取整而不是下取整来计算输出形状。这在某些情况下可以避免计算误差。
import torch
import torch.nn as nn
# 创建一个最大池化层实例
maxpool_layer = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
# 假设输入数据为 4x4 的张量
input_data = torch.randn(1, 1, 4, 4)
# 使用最大池化层进行池化
output_data = maxpool_layer(input_data)
在这个例子中,kernel_size=2,stride=2,所以输入数据经过最大池化后,输出数据的空间尺寸被减半。
尺寸关系: