torch.nn

一、torch.nn 概述与设计哲学

torch.nn 是 PyTorch 提供的一个模块化工具集,专为构建和训练神经网络设计。其核心设计理念包括:

模块化:通过 nn.Module 基类,用户可以像搭积木一样组合各种层、激活函数和损失函数,构建复杂模型。
动态计算图:PyTorch 的动态计算图(eager execution)允许在运行时定义和修改网络结构,适合研究和快速原型开发。
灵活性与控制力:用户可以轻松自定义层、损失函数或前向传播逻辑,同时保留对底层张量操作的访问权限。
易用性:预定义的层和工具(如卷积、BatchNorm、优化器)简化了开发流程,适合初学者和专家。

torch.nn 的核心组件包括:

层(Layers):如 nn.Linearnn.Conv2d 等。
激活函数:如 nn.ReLUnn.Softmax 等。
损失函数:如 nn.MSELossnn.CrossEntropyLoss 等。
容器:如 nn.Sequentialnn.ModuleList 等。
正则化工具:如 nn.Dropoutnn.BatchNorm2d 等。

接下来,将逐一深入讲解这些组件,辅以数学公式、代码示例和实际应用。


二、nn.Module:神经网络的核心基类

1. 原理与功能

nn.Module 是所有神经网络模块的基类,无论是简单的全连接层还是复杂的 Transformer 模型,都继承自它。其核心功能包括:

参数管理:自动跟踪模型中的 torch.nn.Parameter(如权重和偏置),并通过 parameters()named_parameters() 方法访问。
层次结构:支持嵌套模块,允许构建复杂的网络结构。
前向传播:通过定义 forward 方法实现数据流。
设备管理:通过 .to(device) 将模型和参数移动到指定设备(如 GPU)。
训练/评估模式:通过 .train().eval() 切换模式,影响 Dropout 和 BatchNorm 的行为。

数学背景

一个神经网络层通常表示为 y = f ( W x + b ) y = f(Wx + b) y=f(Wx+b),其中 W W W 和 b b b 是可学习的参数, f f f 是激活函数。
nn.Module 负责管理 W W W 和 b b b,并在反向传播时计算梯度 ∂ L ∂ W frac{partial L}{partial W} ∂W∂L​ 和 ∂ L ∂ b frac{partial L}{partial b} ∂b∂L​。

2. 实现细节

当定义一个继承 nn.Module 的类时,PyTorch 会:

自动注册所有子模块(如 nn.Linear)和参数(如 nn.Parameter)。
在调用 model.parameters() 时,递归收集所有可学习的参数。
在调用 model(x) 时,自动执行 forward 方法。

代码示例:实现一个简单的两层神经网络

import torch
import torch.nn as nn

class TwoLayerNet(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(TwoLayerNet, self).__init__()
        self.layer1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(hidden_size, output_size)
    
    def forward(self, x):
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        return x

# 实例化模型
model = TwoLayerNet(input_size=10, hidden_size=20, output_size=2)
x = torch.randn(32, 10)  # 批次大小32,输入10维
output = model(x)        # 输出形状为 (32, 2)
print(model)

输出

TwoLayerNet(
  (layer1): Linear(in_features=10, out_features=20, bias=True)
  (relu): ReLU()
  (layer2): Linear(in_features=20, out_features=2, bias=True)
)

3. 参数管理

nn.Module 自动管理参数。例如,nn.Linear 的权重和偏置是 nn.Parameter 类型的张量,PyTorch 会跟踪它们并在优化时更新。

查看参数

for name, param in model.named_parameters():
    print(f"Parameter: {
              name}, Shape: {
              param.shape}")

输出

Parameter: layer1.weight, Shape: torch.Size([20, 10])
Parameter: layer1.bias, Shape: torch.Size([20])
Parameter: layer2.weight, Shape: torch.Size([2, 20])
Parameter: layer2.bias, Shape: torch.Size([2])

4. 自定义模块

通过继承 nn.Module,可以实现自定义逻辑。例如,添加一个残差连接:

class ResidualBlock(nn.Module):
    def __init__(self, dim):
        super(ResidualBlock, self).__init__()
        self.fc1 = nn.Linear(dim, dim)
        self.fc2 = nn.Linear(dim, dim)
        self.relu = nn.ReLU()
    
    def forward(self, x):
        residual = x
        out = self.fc1(x)
        out = self.relu(out)
        out = self.fc2(out)
        out += residual  # 残差连接
        return out

三、常用神经网络层

以下是 torch.nn 中常见的层,包含数学原理、参数说明、代码示例和应用场景。

1. 全连接层:nn.Linear

数学原理

实现线性变换: y = W x + b y = Wx + b y=Wx+b
W ∈ R o u t _ f e a t u r e s × i n _ f e a t u r e s W in mathbb{R}^{out\_features imes in\_features} W∈Rout_features×in_features, b ∈ R o u t _ f e a t u r e s b in mathbb{R}^{out\_features} b∈Rout_features
输入 x ∈ R b a t c h _ s i z e × i n _ f e a t u r e s x in mathbb{R}^{batch\_size imes in\_features} x∈Rbatch_size×in_features,输出 y ∈ R b a t c h _ s i z e × o u t _ f e a t u r e s y in mathbb{R}^{batch\_size imes out\_features} y∈Rbatch_size×out_features

参数

in_features:输入维度。
out_features:输出维度。
bias:是否包含偏置(默认 True)。

代码示例

linear = nn.Linear(10, 5)
x = torch.randn(32, 10)  # 批次大小32
y = linear(x)            # 输出形状 (32, 5)
print(y.shape)

应用场景

多层感知机(MLP)的核心层。
分类任务的最后一层(如 logits 输出)。

注意事项

输入张量的最后一维必须匹配 in_features
权重和偏置会自动初始化(通常为均匀分布或 Kaiming 初始化)。

2. 卷积层:nn.Conv2d

数学原理

对输入特征图进行二维卷积操作:
y [ i , j ] = ∑ c = 0 C − 1 ∑ m = 0 K h − 1 ∑ n = 0 K w − 1 x [ c , i + m , j + n ] ⋅ w [ c , m , n ] + b y[i,j] = sum_{c=0}^{C-1} sum_{m=0}^{K_h-1} sum_{n=0}^{K_w-1} x[c, i+m, j+n] cdot w[c, m, n] + b y[i,j]=∑c=0C−1​∑m=0Kh​−1​∑n=0Kw​−1​x[c,i+m,j+n]⋅w[c,m,n]+b
C C C:输入通道数, K h , K w K_h, K_w Kh​,Kw​:卷积核高度和宽度。

参数

in_channels:输入通道数。
out_channels:输出通道数。
kernel_size:卷积核大小(如 3 或 (3,3))。
stride:步幅(默认 1)。
padding:填充(默认 0)。
dilation:膨胀系数(用于空洞卷积)。

代码示例

conv = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)
x = torch.randn(32, 3, 28, 28)  # 批次大小32,3通道,28x28图像
y = conv(x)                     # 输出形状 (32, 16, 28, 28)
print(y.shape)

输出形状计算
H o u t = ⌊ H i n + 2 ⋅ p a d d i n g − k e r n e l _ s i z e s t r i d e ⌋ + 1 H_{out} = leftlfloor frac{H_{in} + 2 cdot padding – kernel\_size}{stride}
ight
floor + 1 Hout​=⌊strideHin​+2⋅padding−kernel_size​⌋+1
对于上述示例, H o u t = ⌊ 28 + 2 ⋅ 1 − 3 1 ⌋ + 1 = 28 H_{out} = lfloor frac{28 + 2 cdot 1 – 3}{1}
floor + 1 = 28 Hout​=⌊128+2⋅1−3​⌋+1=28。

应用场景

图像分类(CNN,如 ResNet)。
目标检测(YOLO)、图像分割(U-Net)。

注意事项

输入形状为 (batch_size, in_channels, height, width)
确保输入通道数与 in_channels 匹配。

3. 池化层:nn.MaxPool2d, nn.AvgPool2d

数学原理

最大池化:取窗口内的最大值。
平均池化:取窗口内的平均值。
输出尺寸计算与卷积类似。

参数

kernel_size:池化窗口大小。
stride:步幅(默认等于 kernel_size)。
padding:填充(默认 0)。

代码示例

pool = nn.MaxPool2d(kernel_size=2, stride=2)
x = torch.randn(32, 16, 28, 28)
y = pool(x)  # 输出形状 (32, 16, 14, 14)
print(y.shape)

应用场景

降低特征图分辨率,减少计算量。
增强特征的平移不变性。

4. 循环神经网络层:nn.RNN, nn.LSTM, nn.GRU

数学原理(以 RNN 为例):

对于时间步 t t t,隐藏状态更新:
h t = tanh ⁡ ( W i h x t + W h h h t − 1 + b ) h_t = anh(W_{ih}x_t + W_{hh}h_{t-1} + b) ht​=tanh(Wih​xt​+Whh​ht−1​+b)
LSTM 和 GRU 引入门机制(如遗忘门、输入门)以解决长依赖问题。

参数

input_size:输入特征维度。
hidden_size:隐藏状态维度。
num_layers:层数。
batch_first:是否将批次维度放在第一维(默认 False)。

代码示例

rnn = nn.RNN(input_size=10, hidden_size=20, num_layers=2, batch_first=True)
x = torch.randn(32, 5, 10)  # 批次大小32,序列长度5,特征维度10
h0 = torch.randn(2, 32, 20) # 初始隐藏状态
output, hn = rnn(x, h0)     # output: (32, 5, 20), hn: (2, 32, 20)
print(output.shape, hn.shape)

应用场景

自然语言处理(文本分类、机器翻译)。
时间序列预测。

注意事项

输入形状为 (seq_len, batch_size, input_size)(batch_size, seq_len, input_size)(若 batch_first=True)。
初始化隐藏状态 h 0 h_0 h0​ 的形状必须正确。

5. 正则化层:nn.BatchNorm2d, nn.Dropout

(1)nn.BatchNorm2d

数学原理

对每个通道的特征进行归一化:
y = x − μ σ 2 + ϵ ⋅ γ + β y = frac{x – mu}{sqrt{sigma^2 + epsilon}} cdot gamma + eta y=σ2+ϵ
​x−μ​⋅γ+β
μ , σ 2 mu, sigma^2 μ,σ2:批次均值和方差, γ , β gamma, eta γ,β:可学习参数。

参数

num_features:输入通道数。
eps:防止除零的小值(默认 1e-5)。
momentum:用于更新运行均值和方差。

代码示例

bn = nn.BatchNorm2d(16)
x = torch.randn(32, 16, 28, 28)
y = bn(x)

应用场景

加速训练,稳定梯度。
常用于深层 CNN。

(2)nn.Dropout

数学原理

在训练时,以概率 p p p 随机将输入置零:
y = x ⋅ Bernoulli ( 1 − p ) 1 − p y = frac{x cdot ext{Bernoulli}(1-p)}{1-p} y=1−px⋅Bernoulli(1−p)​
测试时不应用 Dropout。

参数

p:丢弃概率(默认 0.5)。

代码示例

dropout = nn.Dropout(p=0.5)
x = torch.randn(32, 10)
y = dropout(x)

应用场景

防止过拟合。
常用于全连接层或深层网络。


四、激活函数

激活函数为神经网络引入非线性,torch.nn 提供了多种激活函数:

ReLU: f ( x ) = max ⁡ ( 0 , x ) f(x) = max(0, x) f(x)=max(0,x)

nn.ReLU()
优点:简单、计算快,缓解梯度消失。
缺点:可能导致“神经元死亡”(负值区域梯度为 0)。
变体:nn.LeakyReLU, nn.PReLU

Sigmoid: f ( x ) = 1 1 + e − x f(x) = frac{1}{1 + e^{-x}} f(x)=1+e−x1​

nn.Sigmoid()
输出范围 (0, 1),适合二分类。
缺点:梯度消失,输出非零中心。

Tanh: f ( x ) = tanh ⁡ ( x ) f(x) = anh(x) f(x)=tanh(x)

输出范围 (-1, 1),零中心化。
常用于 RNN 的隐藏状态。

Softmax: f ( x i ) = e x i ∑ j e x j f(x_i) = frac{e^{x_i}}{sum_j e^{x_j}} f(xi​)=∑j​exj​exi​​

nn.Softmax(dim=-1)
用于多分类,输出概率分布。
通常与 nn.CrossEntropyLoss 配合使用(后者内部包含 Softmax)。
为什么需要 dim
在 PyTorch 中,输入张量通常是多维的(例如,批次数据 [batch_size, num_classes] 或更高维张量)。
dim 参数指定了 Softmax 归一化的维度。例如:
如果 dim=1,Softmax 会在张量的第二个维度(通常是类别维度)上计算概率分布。
如果 dim=0,Softmax 会在第一个维度(例如批次维度)上计算,但这在分类任务中较少见。
不指定 dim 会导致 PyTorch 无法确定归一化的维度,尤其在输入张量维度大于 1 时。

特别说明:如果 dim=-1
含义:设置 dim=-1 告诉 PyTorch 在张量的最后一个维度上执行 Softmax 归一化。-1 是 Python 中常用的索引方式,表示倒数第一个维度。
为什么常用 dim=-1
语义匹配:在许多深度学习任务中,最后一个维度通常是需要归一化的维度,例如:
分类任务的 logits:[batch_size, num_classes],最后一个维度是 num_classes。
Transformer 注意力分数:[batch_size, num_heads, seq_len, seq_len],最后一个维度是注意力分数的归一化维度。
通用性:dim=-1 使代码对张量维度的数量更鲁棒。例如,无论是 2D 张量 [batch_size, num_classes] 还是 3D 张量 [batch_size, channels, num_classes],dim=-1 始终作用于最后一个维度(通常是类别维度)。
社区惯例:PyTorch 生态(例如 torchvision、Hugging Face 的 Transformer 模型)常使用 dim=-1,因为它直观且适用于大多数分类和概率归一化任务。

代码示例

relu = nn.ReLU()
sigmoid = nn.Sigmoid()
x = torch.tensor([-1.0, 0.0, 1.0])
print(relu(x))    # tensor([0.0, 0.0, 1.0])
print(sigmoid(x)) # tensor([0.2689, 0.5000, 0.7311])

五、损失函数

损失函数衡量模型预测与真实标签的差距,torch.nn 提供多种损失函数:

均方误差:nn.MSELoss

L = 1 N ∑ ( y − y ^ ) 2 L = frac{1}{N} sum (y – hat{y})^2 L=N1​∑(y−y^​)2
适用于回归任务。

交叉熵损失:nn.CrossEntropyLoss

结合 LogSoftmax 和负对数似然:
L = − ∑ i = 1 C y i log ⁡ ( y ^ i ) L = -sum_{i=1}^C y_i log(hat{y}_i) L=−∑i=1C​yi​log(y^​i​)
适用于多分类任务,输入为 logits(不需要显式 Softmax)。
为什么不需要显式 Softmax?

nn.CrossEntropyLoss 内部集成了 Softmax 和负对数似然(NLL)损失的计算。输入的 logits(未归一化的原始分数)会先经过 Softmax 函数转换为概率分布,再计算负对数似然损失。这种设计提高了数值稳定性和计算效率。
具体来说,Softmax 函数将 logits 转换为概率:
y ^ i = exp ⁡ ( z i ) ∑ j = 1 C exp ⁡ ( z j ) hat{y}_i = frac{exp(z_i)}{sum_{j=1}^C exp(z_j)} y^​i​=∑j=1C​exp(zj​)exp(zi​)​
其中 z i z_i zi​ 是第 i i i 类的 logit。
随后,负对数似然损失取目标类的对数概率的负值。如果直接在模型输出后手动应用 Softmax,会导致重复计算,且可能引入数值不稳定问题(例如,指数运算可能导致溢出)。因此,nn.CrossEntropyLoss 要求输入未经 Softmax 的 logits,由其内部完成归一化和损失计算。
这种方式还避免了在反向传播中重复计算 Softmax 的梯度,优化了计算图的效率。

二元交叉熵:nn.BCELoss, nn.BCEWithLogitsLoss

适用于二分类任务,nn.BCEWithLogitsLoss 结合 Sigmoid。

代码示例

criterion = nn.CrossEntropyLoss()
outputs = torch.randn(32, 10)  # 批次大小32,10个类别
labels = torch.randint(0, 10, (32,))
loss = criterion(outputs, labels)
print(loss.item())

注意事项

确保输入和标签的形状匹配。
对于分类任务,标签通常是整数(nn.CrossEntropyLoss)或浮点数(nn.BCELoss)。


六、容器

torch.nn 提供几种容器,用于组织网络结构:

nn.Sequential

按顺序堆叠层,前向传播自动按序执行。
适合简单的线性网络。

代码示例

model = nn.Sequential(
    nn.Linear(10, 20),
    nn.ReLU(),
    nn.Linear(20, 2)
)
x = torch.randn(32, 10)
y = model(x)  # 输出形状 (32, 2)

nn.ModuleList

存储模块列表,适合动态或循环结构。
不会自动定义 forward 方法。

代码示例

class MyNet(nn.Module):
    def __init__(self, dims):
        super(MyNet, self).__init__()
        self.layers = nn.ModuleList([nn.Linear(dims[i], dims[i+1]) for i in range(len(dims)-1)])
        self.relu = nn.ReLU()
    
    def forward(self, x):
        for layer in self.layers:
            x = self.relu(layer(x))
        return x

model = MyNet([10, 20, 5])

nn.ModuleDict

存储模块字典,适合按名称访问。

代码示例

class MyNet(nn.Module):
    def __init__(self):
        super(MyNet, self).__init__()
        self.layers = nn.ModuleDict({
            
            'fc1': nn.Linear(10, 20),
            'fc2': nn.Linear(20, 5)
        })
    
    def forward(self, x):
        x = self.layers['fc1'](x)
        x = self.layers['fc2'](x)
        return x

七、构建与训练神经网络的完整流程

以下是一个完整的示例,展示如何使用 torch.nn 构建、训练和评估一个 CNN,用于 MNIST 手写数字分类。

1. 准备数据

使用 torchvision 加载 MNIST 数据集。

import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

# 数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
])

# 加载数据集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

2. 定义模型

class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, 10)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(0.5)
    
    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))  # 输出: (batch, 32, 14, 14)
        x = self.pool(self.relu(self.conv2(x)))  # 输出: (batch, 64, 7, 7)
        x = x.view(-1, 64 * 7 * 7)              # 展平
        x = self.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.fc2(x)
        return x

model = ConvNet()

3. 设置损失函数和优化器

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

4. 训练模型

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
num_epochs = 5

for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for images, labels in train_loader:
        images, labels = images.to(device), labels.to(device)
        
        # 前向传播
        outputs = model(images)
        loss = criterion(outputs, labels)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        total_loss += loss.item()
    
    print(f"Epoch [{
              epoch+1}/{
              num_epochs}], Loss: {
              total_loss/len(train_loader):.4f}")

5. 评估模型

model.eval()
correct = 0
total = 0
with torch.no_grad():
    for images, labels in test_loader:
        images, labels = images.to(device), labels.to(device)
        outputs = model(images)
        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f"Test Accuracy: {
              100 * correct / total:.2f}%")

预期结果

训练 5 个 epoch 后,测试准确率通常可达 98% 以上。


八、进阶主题

1. 参数初始化

参数初始化对模型收敛至关重要。torch.nn.init 提供多种初始化方法:

Xavier 初始化(适合 Sigmoid/Tanh):
W ∼ Uniform ( − 6 n i n + n o u t , 6 n i n + n o u t ) W sim ext{Uniform}(-sqrt{frac{6}{n_{in} + n_{out}}}, sqrt{frac{6}{n_{in} + n_{out}}}) W∼Uniform(−nin​+nout​6​
​,nin​+nout​6​
​)

Kaiming 初始化(适合 ReLU):
W ∼ Normal ( 0 , 2 n i n ) W sim ext{Normal}(0, sqrt{frac{2}{n_{in}}}) W∼Normal(0,nin​2​
​)

代码示例

def init_weights(m):
    if isinstance(m, nn.Linear) or isinstance(m, nn.Conv2d):
        nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
        if m.bias is not None:
            nn.init.zeros_(m.bias)

model.apply(init_weights)

2. 自定义损失函数

通过继承 nn.Module,可以定义自定义损失函数。例如,带 L2 正则化的损失:

class CustomLoss(nn.Module):
    def __init__(self, l2_weight=0.01):
        super(CustomLoss, self).__init__()
        self.l2_weight = l2_weight
        self.ce_loss = nn.CrossEntropyLoss()
    
    def forward(self, outputs, labels, model):
        ce = self.ce_loss(outputs, labels)
        l2 = sum(p.pow(2.0).sum() for p in model.parameters())
        return ce + self.l2_weight * l2

criterion = CustomLoss(l2_weight=0.01)

3. 动态网络结构

PyTorch 的动态计算图允许在 forward 中根据输入调整网络结构。例如,动态层数:

class DynamicNet(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(DynamicNet, self).__init__()
        self.fc = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
    
    def forward(self, x, num_layers=1):
        for _ in range(num_layers):
            x = self.fc(x)
            x = self.relu(x)
        return x

4. 模型保存与加载

保存整个模型

torch.save(model, "model.pt")
model = torch.load("model.pt")

仅保存参数(推荐):

torch.save(model.state_dict(), "model_state.pth")
model.load_state_dict(torch.load("model_state.pth"))

5. 调试技巧

检查形状

print(x.shape)  # 在 forward 中打印张量形状

检查梯度

for name, param in model.named_parameters():
    print(f"{
                name}.grad: {
                param.grad.norm()}")

模型结构
使用 torchsummary 查看模型:

from torchsummary import summary
summary(model, input_size=(1, 28, 28))  # 对于 ConvNet

九、常见问题与解决方案

维度不匹配

问题:RuntimeError: size mismatch
解决:检查每一层的输入输出形状,确保匹配。例如,nn.Linear 的输入维度必须与上一层输出一致。

梯度消失/爆炸

解决:使用适当的初始化(如 Kaiming)、BatchNorm 或梯度裁剪:

torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)

过拟合

解决:增加 Dropout、L2 正则化(optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4))或数据增强。

训练/评估模式混淆

问题:Dropout 在测试时生效。
解决:确保测试时调用 model.eval(),训练时调用 model.train()


十、学习建议与资源

实践项目

实现经典模型:LeNet、VGG、ResNet。
参与 Kaggle 比赛:MNIST、CIFAR-10、NLP 任务。
使用 torchvision.models 加载预训练模型,尝试迁移学习。

阅读资料

PyTorch 官方文档:https://pytorch.org/docs/stable/nn.html
《Deep Learning with PyTorch》:全面介绍 PyTorch 的书籍。
GitHub 上的 PyTorch 示例:https://github.com/pytorch/examples

调试工具

torchinfo:比 torchsummary 更强大的模型结构可视化工具。
TensorBoard:可视化损失和准确率:

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
writer.add_scalar("Loss/train", loss.item(), epoch)

社区与论坛

PyTorch 论坛:https://discuss.pytorch.org/


十一、总结

torch.nn 是 PyTorch 构建神经网络的核心模块,提供了从基本层到复杂模型的全面支持。通过深入理解 nn.Module 的机制、掌握常用层(如 nn.Linearnn.Conv2d)、激活函数、损失函数和容器,可以灵活构建各种深度学习模型。结合数学原理、代码实践和调试技巧,能够应对从简单 MLP 到复杂 CNN/RNN 的开发任务。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容