在深度学习领域,PyTorch 作为一款广受欢迎的开源框架,为开发者提供了便捷高效的工具。今天,我们就深入探讨一下 PyTorch 中的几个关键要点:torch.nn.Linear
、torch.nn.MSELoss
、model.train()
以及 model.eval()
,了解它们如何助力模型开发与评估。
一、torch.nn.Linear
:神经网络的基石 —
— 全连接层
全连接层是构建神经网络的基础组件之一,而 torch.nn.Linear
类在 PyTorch 中就是用于创建全连接层的关键工具。
从功能上看,它实现了对输入数据的线性变换。给定输入向量 x
,权重矩阵 W
和偏置向量 b
,通过公式 y = xW^T + b
得到输出向量 y
。这看似简单的操作,却是复杂神经网络架构中的核心步骤,能够将输入特征进行整合与转换。
使用起来也相当便捷,例如创建一个输入维度为 10
,输出维度为 5
的线性层:
import torch
import torch.nn as nn
linear_layer = nn.Linear(in_features=10, out_features=5)
input_tensor = torch.randn(3, 10)
output_tensor = linear_layer(input_tensor)
print("输入张量形状:", input_tensor.shape)
print("输出张量形状:", output_tensor.shape)
这里,我们定义了 linear_layer
,当输入形状为 (3, 10)
的张量时,它能按照设定的线性变换规则输出形状为 (3, 5)
的张量。
在参数方面,in_features
指明输入特征数量,要与输入张量最后一维匹配;out_features
设定输出特征数量;bias
默认为 True
,决定是否添加偏置项。
值得注意的是,权重和偏置会自动初始化,当然也能按需手动调整。并且输入张量的最后一维必须符合 in_features
要求,它还支持批量处理,只要最后一维正确,前面的维度可用于表示批量大小。
全连接层在多层感知机(MLP)、图像分类的 CNN 后续层以及自然语言处理的各类
模型中都有广泛应用,是实现复杂任务的重要基石。
二、torch.nn.MSELoss
:回归问题的 “裁判”
在处理回归任务时,我们需要一个标准来衡量模型预测值与真实值之间的偏差,torch.nn.MSELoss
就是这样一个常用的损失函数。
它基于均方误差(Mean Squared Error,MSE)概念,计算预测值与真实值误差平方的平均值。直观地说,MSE 值越小,模型预测就越接近真实值,反映出模型的拟合效果越好。
使用示例如下:
import torch
import torch.nn as nn
mse_loss = nn.MSELoss()
y_true = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32)
y_pred = torch.tensor([1.2, 1.8, 3.1], dtype=torch.float32)
loss = mse_loss(y_pred, y_true)
print("均方误差损失值:", loss.item())
构造函数中的 reduction
参数决定损失计算方式:'none'
不缩减,返回每个样本损失;'mean'
求平均值,是默认值;'sum'
则求和。
其数学原理依循经典的 MSE 计算公式,根据 reduction
取值不同有不同形式,在回归任务如房价预测、股票价格预测中广泛应用,同时也用于评估训练后模型在测试集上的性能。
使用时要确保输入的真实值和预测值张量数据类型一致,通常为 torch.float32
或 torch.float64
,且形状必须相同,否则会报错。
三、model.train()
:开启模型训练之旅
当我们着手训练模型时,model.train()
就是那个 “启动开关”。
它的核心作用是告知模型当前进入训练阶段,使得模型中的特定层能遵循训练规则运作。以 Dropout
层为例,在训练模式下,它会按照设定概率随机丢弃神经元,防止模型过拟合。假设设置 Dropout
概率为 0.5,每次前向传播都有一半神经元可能被暂时 “弃用”,迫使模型学习更具鲁棒性的特征。
Batch Normalization
层在训练时,会依据当前批次数据动态计算均值和方差,以此对输入归一化,加速收敛并缓解梯度问题。
以下是简单的训练示例:
import torch
import torch.nn as nn
import torch.optim as optim
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 20)
self.dropout = nn.Dropout(0.5)
self.fc2 = nn.Linear(20, 1)
def forward(self, x):
x = self.fc1(x)
x = self.dropout(x)
x = self.fc2(x)
return x
model = SimpleModel()
model.train()
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
inputs = torch.randn(32, 10)
labels = torch.randn(32, 1)
for epoch in range(10):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch {epoch + 1}, Loss: {loss.item()}')
在训练过程中,务必记得调用 model.train()
,它只会影响像 Dropout
和 Batch Normalization
这类在训练、评估行为有别的层,其他层如常运作。
四、model.eval()
:精准评估模型表现
模型训练完毕,进入评估环节,model.eval()
就派上用场了。
它的使命是将模型切换到评估模式,确保评估结果的准确性与稳定性。对于 Dropout
层,评估时不再随机丢弃神经元,而是让所有神经元参与计算,毕竟此时需要完整模型的输出。
Batch Normalization
层则使用训练过程中统计积累的全局均值和方差进行归一化,避免因批次不同带来的波动。
使用场景多为在验证集或测试集上预测,常结合 torch.no_grad()
一起使用,避免不必要的梯度计算,示例如下:
import torch
import torch.nn as nn
class SimpleModel(nn.Module):
def __init__(self):
super(SimpleModel, self).__init__()
self.fc1 = nn.Linear(10, 20)
self.bn = nn.BatchNorm1d(20)
self.dropout = nn.Dropout(0.5)
self.fc2 = nn.Linear(20, 1)
def forward(self, x):
x = self.fc1(x)
x = self.bn(x)
x = self.dropout(x)
x = self.fc2(x)
return x
model = SimpleModel()
model.eval()
input_data = torch.randn(1, 10)
with torch.no_grad():
output = model(input_data)
print(output)
与 model.train()
相对应,评估时务必调用 model.eval()
,否则可能导致评估结果偏差。它同样只作用于特定层,保障评估过程的精准。
综上,掌握 torch.nn.Linear
、torch.nn.MSELoss
、model.train()
和 model.eval()
这些要点,就如同握住了 PyTorch 模型开发与评估的关键钥匙,能帮助我们构建更强大、精准的深度学习模型,开启深度学习的探索之旅。