<think>我们正在详细介绍PyTorch中的torch.nn模块,这是一个用于构建神经网络的核心模块。我们将按照以下结构进行讲解:1.torch.nn模块概述2.继承torch.nn.Module构建模型3.常用层介绍及示例4.模型参数管理5.损失函数6.一个完整的训练示例注意:所有行内数学表达式使用$...$,独立公式使用$$...$$。###1.torch.nn模块概述torch.nn是PyTorch中用于构建神经网络的模块,提供了构建神经网络所需的各种层(如线性层、卷积层、循环神经网络层等)、激活函数、损失函数以及容器(如Module,Sequential等)。该模块的设计基于面向对象的思想,用户通过继承`nn.Module`类并实现`forward`方法来定义自己的网络结构[^1]。###2.继承torch.nn.Module构建模型在PyTorch中,我们通过继承`torch.nn.Module`类来定义自己的神经网络模型。每个模型都是一个`Module`的子类,并且需要实现`forward`方法,该方法定义了前向传播的计算过程。####示例:定义一个简单的全连接神经网络```pythonimporttorchimporttorch.nnasnnclassSimpleNet(nn.Module):def__init__(self):super(SimpleNet,self).__init__()#定义两个全连接层self.fc1=nn.Linear(784,128)#输入特征784维,输出128维self.fc2=nn.Linear(128,10)#输入128维,输出10维(10分类问题)defforward(self,x):#输入x的形状:(batch_size,784)x=torch.relu(self.fc1(x))#经过第一层并应用ReLU激活函数x=self.fc2(x)#第二层,输出logitsreturnx```在这个例子中,我们定义了一个名为`SimpleNet`的类,它包含两个全连接层(`fc1`和`fc2`)。在`forward`方法中,我们定义了数据如何通过这些层。###3.常用层介绍及示例torch.nn提供了多种层,以下是一些常用的层:####线性层(nn.Linear)线性层执行一个线性变换:$y=xA^T+b$,其中$A$和$b$分别是可学习的权重和偏置。```python#创建一个线性层,输入特征数5,输出特征数3linear_layer=nn.Linear(5,3)input=torch.randn(2,5)#2个样本,每个样本5维特征output=linear_layer(input)```####卷积层(nn.Conv2d)卷积层用于处理图像数据,执行二维卷积操作。```python#输入通道数3(如RGB图像),输出通道数16,卷积核大小3x3conv_layer=nn.Conv2d(3,16,kernel_size=3,stride=1,padding=1)input=torch.randn(1,3,32,32)#1个样本,3通道,32x32图像output=conv_layer(input)#输出形状:(1,16,32,32)```####循环神经网络层(nn.RNN,nn.LSTM,nn.GRU)用于处理序列数据,如文本、时间序列等。```python#使用LSTM层,输入特征10,隐藏状态维度20,1层lstm_layer=nn.LSTM(input_size=10,hidden_size=20,num_layers=1)input_seq=torch.randn(5,3,10)#序列长度5,批量大小3,每个时间步特征10output,(hn,cn)=lstm_layer(input_seq)#output形状:(5,3,20)```###4.模型参数管理`nn.Module`会自动跟踪其内部的所有子模块(如层)及其参数。我们可以通过`parameters()`方法访问模型的所有参数。```pythonmodel=SimpleNet()forname,paraminmodel.named_parameters():print(f"{name}:{param.shape}")```输出示例:```fc1.weight:torch.Size([128,784])fc1.bias:torch.Size([128])fc2.weight:torch.Size([10,128])fc2.bias:torch.Size([10])```###5.损失函数torch.nn还提供了各种损失函数,如均方误差(MSE)、交叉熵损失(CrossEntropyLoss)等。```python#交叉熵损失函数(常用于多分类问题)criterion=nn.CrossEntropyLoss()outputs=model(inputs)#模型输出loss=criterion(outputs,labels)#计算损失```###6.一个完整的训练示例下面是一个使用简单全连接网络在MNIST数据集上进行训练的示例。```pythonimporttorchimporttorch.nnasnnimporttorch.optimasoptimfromtorchvisionimportdatasets,transforms#数据预处理transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))])#加载MNIST数据集train_dataset=datasets.MNIST('./data',train=True,download=True,transform=transform)train_loader=torch.utils.data.DataLoader(train_dataset,batch_size=64,shuffle=True)#初始化模型、损失函数和优化器model=SimpleNet()criterion=nn.CrossEntropyLoss()optimizer=optim.SGD(model.parameters(),lr=0.01)#训练循环num_epochs=5forepochinrange(num_epochs):forbatch_idx,(data,target)inenumerate(train_loader):data=data.view(data.size(0),-1)#将图像展平(64,784)optimizer.zero_grad()output=model(data)loss=criterion(output,target)loss.backward()optimizer.step()ifbatch_idx%100==0:print(f'Epoch:{epoch+1},Batch:{batch_idx},Loss:{loss.item():.6f}')```以上代码展示了如何使用torch.nn模块构建、训练一个神经网络模型。###总结torch.nn模块是PyTorch中构建神经网络的核心,它提供了构建网络所需的各种层、激活函数、损失函数等组件。通过继承`nn.Module`类并实现`forward`方法,我们可以灵活地定义自己的网络结构。同时,该模块还提供了方便的模型参数管理功能。§§相关问题§§1.torch.nn和torch.nn.functional有什么区别?2.如何在PyTorch中实现自定义层?3.如何保存和加载torch.nn模型?4.如何使用GPU训练torch.nn模型?5.在torch.nn中如何实现批量归一化(BatchNormalization)?</think>### PyTorch torch.nn 模块详解与使用教程
#### 一、torch.nn 模块概述
`torch.nn` 是 PyTorch 中用于构建神经网络的核心模块,提供:
1. **神经网络层**:预定义的层类型(如线性层、卷积层等)
2. **损失函数**:常见的损失计算方法
3. **容器类**:组织网络结构的工具(如 `Module`, `Sequential`)
4. **参数管理**:自动跟踪和管理可训练参数[^1]
数学上,神经网络层可表示为函数复合:
$$ f(x) = f_L(\cdots f_2(f_1(x; \theta_1); \theta_2)\cdots; \theta_L) $$
其中 $\theta_i$ 为第 $i$ 层参数[^3]
---
#### 二、核心组件详解
##### 1. 神经网络层类型
| 层类型 | 类名 | 数学表示 | 应用场景 |
|--------|------|----------|----------|
| 线性层 | `nn.Linear` | $y = xW^T + b$ | 全连接层 |
| 卷积层 | `nn.Conv2d` | $y_{i,j} = \sum_{k}W_{k} * x_{i+k,j+k} + b$ | 图像处理 |
| 循环层 | `nn.LSTM` | $h_t = \text{LSTM}(x_t, h_{t-1})$ | 序列数据 |
| 归一化层 | `nn.BatchNorm2d` | $\hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} \cdot \gamma + \beta$ | 加速训练 |
##### 2. 容器类
**nn.Module 基类**(所有网络必须继承):
```python
class MyNet(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = torch.relu(self.fc1(x))
return self.fc2(x)
```
关键特性:
- 自动跟踪所有子模块
- 通过 `parameters()` 获取所有可训练参数
- 内置 GPU 迁移方法 `.to(device)`[^3]
**nn.Sequential 顺序容器**:
```python
model = nn.Sequential(
nn.Linear(784, 128),
nn.ReLU(),
nn.Linear(128, 10)
)
```
---
#### 三、完整使用示例(MNIST分类)
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 1. 定义网络
class CNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3)
self.fc = nn.Linear(32*13*13, 10)
def forward(self, x):
x = torch.relu(self.conv1(x))
x = x.view(x.size(0), -1) # 展平
return self.fc(x)
# 2. 准备数据
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_data = datasets.MNIST('./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
# 3. 初始化模型
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = CNN().to(device)
optimizer = optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
# 4. 训练循环
for epoch in range(5):
for data, target in train_loader:
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
```
---
#### 四、最佳实践技巧
1. **参数初始化**:
```python
nn.init.xavier_uniform_(self.fc.weight) # Xavier初始化
nn.init.zeros_(self.fc.bias)
```
2. **自定义层**:
```python
class CustomLayer(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.weight = nn.Parameter(torch.randn(out_features, in_features))
def forward(self, x):
return x @ self.weight.t()
```
3. **模型保存/加载**:
```python
# 保存
torch.save(model.state_dict(), 'model.pth')
# 加载
model.load_state_dict(torch.load('model.pth'))
```
---
#### 五、与 torch.nn.functional 的区别
| 特性 | torch.nn | torch.nn.functional |
|------|----------|---------------------|
| 状态管理 | 自带可训练参数 | 无状态(需手动传参) |
| 使用方式 | 面向对象 | 函数式编程 |
| 适用场景 | 包含参数的层 | 无参数操作(如激活函数) |
示例对比:
```python
# nn 方式
self.conv = nn.Conv2d(3, 16, 3)
output = self.conv(input)
# functional 方式
output = F.conv2d(input, weight, bias) # 需手动传参
```