1. 引入必要模块
import torchvision.models as models import torch.nn as nn
torchvision.models
:包含预定义的经典模型,如 AlexNet、ResNet 等。torch.nn
:用于构建神经网络的模块库,包括卷积层、全连接层等。
2. 加载预定义的 AlexNet 并打印结构
alexnet = models.alexnet() print(alexnet)
- 加载 PyTorch 提供的 AlexNet 预训练模型。
- 打印出模型结构,帮助理解其内部组成。
3. 定义自定义的 AlexNet
class MyAlexNet(nn.Module): def __init__(self): super(MyAlexNet, self).__init__() # 层的定义
- 创建一个自定义的 AlexNet 类,继承自
torch.nn.Module
。 super(MyAlexNet, self).__init__()
调用父类初始化函数。
3.1 定义卷积层和池化层
self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=11, stride=4, padding=2) self.pool1 = nn.MaxPool2d(3, stride=2) self.conv2 = nn.Conv2d(64, 192, 5, 1, 2) self.pool2 = nn.MaxPool2d(3, stride=2) self.conv3 = nn.Conv2d(192, 384, 3, 1, 1) self.conv4 = nn.Conv2d(384, 256, 3, 1, 1) self.conv5 = nn.Conv2d(256, 256, 3, 1, 1) self.pool3 = nn.MaxPool2d(3, stride=2) self.adapool = nn.AdaptiveAvgPool2d(output_size=6)
conv1
到conv5
:5 个卷积层,分别处理输入特征。包括:- 通道数:输入通道和输出通道。
- 卷积核大小:如 11×1111 \times 1111×11、5×55 \times 55×5 等。
- 步长(
stride
):决定每次卷积的移动步长。 - 填充(
padding
):用于保持输出特征图尺寸。
pool1
到pool3
:3 个最大池化层,用于下采样特征图,减小空间维度。adapool
:自适应平均池化层,将特征图调整为固定尺寸 6×66 \times 66×6,简化后续全连接层的设计。
3.2 定义全连接层
self.fc1 = nn.Linear(9216, 4096) self.fc2 = nn.Linear(4096, 4096) self.fc3 = nn.Linear(4096, 1000)
- 全连接层处理平坦化后的输入特征:
9216
是由 256×6×6256 \times 6 \times 6256×6×6 计算得来。1000
表示输出类别数量(ImageNet 数据集通常有 1000 类)。
- 这里的参数包括权重和偏置,将会参与训练。
4. 定义前向传播逻辑
def forward(self, x):
- 定义输入 xxx 如何经过各层传播并最终生成输出。
4.1 卷积和池化部分
x = self.conv1(x) x = self.relu(x) x = self.pool1(x) x = self.conv2(x) x = self.relu(x) x = self.pool2(x) x = self.conv3(x) x = self.relu(x) print(x.size()) x = self.conv4(x) x = self.relu(x) print(x.size()) x = self.conv5(x) x = self.relu(x) x = self.pool3(x) print(x.size())
- 每个卷积层后都使用
ReLU
激活函数,增强模型的非线性表示能力。 - 每个池化层后,