深度学习(4):torch.nn.Module

文章目录

  • 一、是什么
  • [二、`nn.Module` 的核心功能](#二、nn.Module 的核心功能)
  • [三、`nn.Module` 的基本用法](#三、nn.Module 的基本用法)
    • [1. 定义自定义模型](#1. 定义自定义模型)
    • [2. 初始化模型](#2. 初始化模型)
      • [3. 模型的使用](#3. 模型的使用)
  • [四、`nn.Module` 的关键特性](#四、nn.Module 的关键特性)
    • [1. 自动注册子模块和参数](#1. 自动注册子模块和参数)
    • [2. `forward` 方法](#2. forward 方法)
    • [3. 不需要定义反向传播](#3. 不需要定义反向传播)
  • 五、常用的内置模块
  • 六、示例:创建一个简单的神经网络
    • [1. 问题描述](#1. 问题描述)
    • [2. 模型定义](#2. 模型定义)
    • [3. 训练过程](#3. 训练过程)
  • [七、深入理解 `nn.Module` 的一些重要概念](#七、深入理解 nn.Module 的一些重要概念)
    • [1. 参数访问](#1. 参数访问)
    • [2. 模块访问](#2. 模块访问)
    • [3. 保存和加载模型](#3. 保存和加载模型)
    • [4. 自定义层和模块](#4. 自定义层和模块)
  • [八、`nn.Module` 的实践技巧](#八、nn.Module 的实践技巧)
    • [1. 使用 `Sequential` 快速构建模型](#1. 使用 Sequential 快速构建模型)
    • [2. 模型的嵌套](#2. 模型的嵌套)
  • 九、总结

一、是什么

torch.nn.Module 是 PyTorch 中所有神经网络模块的基类,是构建神经网络模型的核心组件。

二、nn.Module 的核心功能

  1. 参数管理 :自动管理模型的可训练参数(parameters),方便参数的访问和更新。

  2. 子模块管理:支持将模型分解为多个子模块,便于组织复杂的网络结构。

  3. 前向计算(forward):定义模型的前向传播逻辑。


三、nn.Module 的基本用法

1. 定义自定义模型

要创建自定义的神经网络模型,需要继承 nn.Module,并实现以下内容:

  • 构造函数 __init__:在这里定义网络的层和子模块。
  • 前向方法 forward:定义数据如何经过网络进行前向传播。
python 复制代码
import torch
import torch.nn as nn

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel, self).__init__()
        # 定义网络层
        self.layer1 = nn.Linear(10, 20)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(20, 1)
    
    def forward(self, x):
        # 定义前向传播过程
        out = self.layer1(x)
        out = self.relu(out)
        out = self.layer2(out)
        return out

2. 初始化模型

python 复制代码
model = MyModel()

3. 模型的使用

  • 前向传播

    python 复制代码
    output = model(input_data)
  • 获取模型参数

    python 复制代码
    for name, param in model.named_parameters():
        print(name, param.size())

四、nn.Module 的关键特性

1. 自动注册子模块和参数

__init__ 方法中,当你将 nn.Module 的实例(如 nn.Linearnn.Conv2d 等)赋值给模型的属性时,nn.Module 会自动将这些子模块注册到模型中。这意味着:

  • 参数管理 :模型的所有参数都会被自动收集,存储在 model.parameters() 中。
  • 子模块管理 :可以通过 model.children()model.modules() 访问子模块。
python 复制代码
class MyModule(nn.Module):
    def __init__(self):
        super(MyModule, self).__init__()
        self.fc = nn.Linear(10, 5)
        self.conv = nn.Conv2d(3, 16, kernel_size=3)

model = MyModule()
print(list(model.parameters()))  # 自动包含了 fc 和 conv 的参数

2. forward 方法

forward 方法定义了模型的前向传播逻辑。在调用模型实例时,会自动调用 forward 方法。

python 复制代码
output = model(input_data)  # 等价于 output = model.forward(input_data)

3. 不需要定义反向传播

在大多数情况下,不需要手动实现反向传播函数。PyTorch 的自动求导机制(autograd)会根据前向传播中的操作,自动计算梯度。

五、常用的内置模块

PyTorch 提供了大量的内置模块,继承自 nn.Module,可以直接使用:

  • 线性层nn.Linear
  • 卷积层nn.Conv1dnn.Conv2dnn.Conv3d
  • 循环神经网络nn.RNNnn.LSTMnn.GRU
  • 归一化层nn.BatchNorm1dnn.BatchNorm2d
  • 激活函数nn.ReLUnn.Sigmoidnn.Softmax
  • 损失函数nn.MSELossnn.CrossEntropyLoss

六、示例:创建一个简单的神经网络

1. 问题描述

创建一个多层感知机(MLP),用于对 MNIST 手写数字进行分类。

2. 模型定义

python 复制代码
class MNISTClassifier(nn.Module):
    def __init__(self):
        super(MNISTClassifier, self).__init__()
        self.flatten = nn.Flatten()  # 将输入展开为一维
        self.fc1 = nn.Linear(28 * 28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 64)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(64, 10)  # 输出10个类别的分数
    
    def forward(self, x):
        x = self.flatten(x)
        x = self.relu(self.fc1(x))
        x = self.relu2(self.fc2(x))
        x = self.fc3(x)
        return x

3. 训练过程

python 复制代码
import torch.optim as optim

# 初始化模型、损失函数和优化器
model = MNISTClassifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 假设有数据加载器 data_loader
for epoch in range(num_epochs):
    for images, labels in data_loader:
        # 前向传播
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

七、深入理解 nn.Module 的一些重要概念

1. 参数访问

  • parameters():返回一个生成器,包含模型所有可训练的参数。
  • named_parameters() :返回一个生成器,生成 (name, parameter) 对,方便查看参数名称和形状。
python 复制代码
for name, param in model.named_parameters():
    print(f'Parameter {name}: shape {param.shape}')

2. 模块访问

  • children():返回直接子模块的迭代器。
  • modules():返回自身及所有子模块的迭代器。
python 复制代码
for child in model.children():
    print(child)

for module in model.modules():
    print(module)

3. 保存和加载模型

  • 保存模型状态

    python 复制代码
    torch.save(model.state_dict(), 'model.pth')
  • 加载模型状态

    python 复制代码
    model = MNISTClassifier()
    model.load_state_dict(torch.load('model.pth'))

4. 自定义层和模块

通过继承 nn.Module,可以创建自定义的层或模块。

python 复制代码
class CustomLayer(nn.Module):
    def __init__(self, in_features, out_features):
        super(CustomLayer, self).__init__()
        self.weight = nn.Parameter(torch.randn(in_features, out_features))
        self.bias = nn.Parameter(torch.zeros(out_features))
    
    def forward(self, x):
        return torch.matmul(x, self.weight) + self.bias

八、nn.Module 的实践技巧

1. 使用 Sequential 快速构建模型

对于简单的模型,可以使用 nn.Sequential 将多个层按顺序组合。

python 复制代码
model = nn.Sequential(
    nn.Flatten(),
    nn.Linear(28 * 28, 128),
    nn.ReLU(),
    nn.Linear(128, 64),
    nn.ReLU(),
    nn.Linear(64, 10)
)

2. 模型的嵌套

可以将模块嵌套使用,构建复杂的网络结构。

python 复制代码
class ComplexModel(nn.Module):
    def __init__(self):
        super(ComplexModel, self).__init__()
        self.block1 = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3),
            nn.ReLU()
        )
        self.block2 = nn.Sequential(
            nn.Conv2d(32, 64, kernel_size=3),
            nn.ReLU()
        )
        self.fc = nn.Linear(64 * 24 * 24, 10)
    
    def forward(self, x):
        x = self.block1(x)
        x = self.block2(x)
        x = x.view(x.size(0), -1)  # 展平
        x = self.fc(x)
        return x

九、总结

  • nn.Module 是 PyTorch 构建神经网络的基础,提供了参数管理、子模块管理和前向传播等功能。
  • 通过继承 nn.Module,可以方便地创建自定义模型或层,满足各种复杂的需求。
  • 在使用 nn.Module 时,注意正确地定义 __init__forward 方法 ,并确保在 forward 方法中定义前向计算逻辑。
  • PyTorch 提供了大量的内置模块,可以直接使用或作为自定义模块的基石。
  • 善于利用 nn.Module 的特性和工具,可以大大提高模型开发的效率和代码的可读性。

十、参考示例:完整的训练脚本

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 定义超参数
batch_size = 64
learning_rate = 0.01
num_epochs = 5

# 数据集和数据加载器
train_dataset = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)

# 定义模型
class MNISTClassifier(nn.Module):
    def __init__(self):
        super(MNISTClassifier, self).__init__()
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(28 * 28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 64)
        self.relu2 = nn.ReLU()
        self.fc3 = nn.Linear(64, 10)
    
    def forward(self, x):
        x = self.flatten(x)
        x = self.relu(self.fc1(x))
        x = self.relu2(self.fc2(x))
        x = self.fc3(x)
        return x

# 初始化模型、损失函数和优化器
model = MNISTClassifier()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate)

# 训练模型
for epoch in range(num_epochs):
    for images, labels in train_loader:
        # 前向传播
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# 保存模型
torch.save(model.state_dict(), 'mnist_classifier.pth')
相关推荐
CV学术叫叫兽12 分钟前
快速图像识别:落叶植物叶片分类
人工智能·分类·数据挖掘
WeeJot嵌入式39 分钟前
卷积神经网络:深度学习中的图像识别利器
人工智能
糖豆豆今天也要努力鸭1 小时前
torch.__version__的torch版本和conda list的torch版本不一致
linux·pytorch·python·深度学习·conda·torch
脆皮泡泡1 小时前
Ultiverse 和web3新玩法?AI和GameFi的结合是怎样
人工智能·web3
机器人虎哥1 小时前
【8210A-TX2】Ubuntu18.04 + ROS_ Melodic + TM-16多线激光 雷达评测
人工智能·机器学习
码银1 小时前
冲破AI 浪潮冲击下的 迷茫与焦虑
人工智能
用户37791362947551 小时前
【循环神经网络】只会Python,也能让AI写出周杰伦风格的歌词
人工智能·算法
何大春1 小时前
【弱监督语义分割】Self-supervised Image-specific Prototype Exploration for WSSS 论文阅读
论文阅读·人工智能·python·深度学习·论文笔记·原型模式
uncle_ll1 小时前
PyTorch图像预处理:计算均值和方差以实现标准化
图像处理·人工智能·pytorch·均值算法·标准化
宋138102797201 小时前
Manus Xsens Metagloves虚拟现实手套
人工智能·机器人·vr·动作捕捉