pytorch api文档:nn.MSELoss()均方差损失

概念

nn.MSELoss() 是 Mean Squared Error Loss(均方误差损失)的缩写,它的核心作用是计算模型预测值和真实标签之间的平均平方差

详见 链接

公式

\text{MSE} = \frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2

其中:

  • y_i 是真实标签值

  • \hat{y}_i 是模型预测值

  • n 是样本数量

它主要用于回归任务(比如预测房价、温度、销量等连续值),而不是分类任务。

语法

torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean')

参数

nn.MSELoss() 有两个重要参数,决定了损失的计算方式:

参数 类型 默认值 作用
size_average bool True(已废弃) 是否对损失取平均
reduce bool True(已废弃) 是否聚合损失(平均/求和)
reduction str ‘mean’ 损失聚合方式:<br>- ‘mean’:取平均值(默认)<br>- ‘sum’:求和<br>- ‘none’:返回每个样本的损失

例子

import torch
import torch.nn as nn

# 1. 定义MSE损失函数实例
mse_loss = nn.MSELoss()

# 2. 模拟模型预测值和真实标签(注意:形状要匹配)
# 预测值(比如模型输出)
preds = torch.tensor([1.0, 2.0, 3.0, 4.0])
# 真实标签
targets = torch.tensor([1.5, 2.5, 3.5, 4.5])

# 3. 计算MSE损失
loss = mse_loss(preds, targets)

# 打印结果
print(f"预测值: {preds}")
print(f"真实值: {targets}")
print(f"MSE损失值: {loss.item()}")  # item() 取出张量中的数值
输出结果:
预测值: tensor([1., 2., 3., 4.])
真实值: tensor([1.5000, 2.5000, 3.5000, 4.5000])
MSE损失值: 0.25
手动验证计算过程:
(1-1.5)² + (2-2.5)² + (3-3.5)² + (4-4.5)² = 0.25 + 0.25 + 0.25 + 0.25 = 1.0
平均后:1.0 / 4 = 0.25 → 和代码计算结果一致

不同 reduction 参数的示例:

# 1. reduction='sum':求和(不平均)
mse_sum = nn.MSELoss(reduction='sum')
loss_sum = mse_sum(preds, targets)
print(f"\n求和模式损失值: {loss_sum.item()}")  # 输出 1.0

# 2. reduction='none':返回每个样本的损失
mse_none = nn.MSELoss(reduction='none')
loss_none = mse_none(preds, targets)
print(f"每个样本的损失值: {loss_none}")  # 输出 tensor([0.2500, 0.2500, 0.2500, 0.2500])

快捷连接神经网络中查看损失


import torch
import torch.nn as nn


class GELU(nn.Module):

    def __init__(self):
        super().__init__()

    def forward(self, x):
        return 0.5 * x * (1 + torch.tanh(
            torch.sqrt(torch.tensor(2.0 / torch.pi)) * (x + 0.044715 * torch.pow(x, 3))
        ))


class ExampleDeepNeuralNetwork(nn.Module):
    def __init__(self, layer_sizes, use_shortcut):
        super().__init__()
        self.use_shortcut = use_shortcut
        # 添加5个层
        self.layers = nn.ModuleList([
            nn.Sequential(nn.Linear(layer_sizes[0], layer_sizes[1]), GELU()),
            nn.Sequential(nn.Linear(layer_sizes[1], layer_sizes[2]), GELU()),
            nn.Sequential(nn.Linear(layer_sizes[2], layer_sizes[3]), GELU()),
            nn.Sequential(nn.Linear(layer_sizes[3], layer_sizes[4]), GELU()),
            nn.Sequential(nn.Linear(layer_sizes[4], layer_sizes[5]), GELU()),
        ])

    def forward(self, x):
        for layer in self.layers:
            # 计算当前层的输出
            layer_output = layer(x)
            # 检查是否可以使用快捷连接,如果use_shortcut为True就使用快捷连接
            if self.use_shortcut and x.shape == layer_output.shape:
                x = x+layer_output
            else:
                x = layer_output
        return x


"""
前4层为接受包含3个输入值的样本,并返回3个输出值。
最后1层会返回1个输出值:
"""
layer_sizes = [3, 3, 3, 3, 3, 1]
# 定义输入张量
sample_input = torch.tensor([[1., 0., -1.]])
# 指定随机种子,初始化权重,复现结果
torch.manual_seed(123)
# 初始化没有快捷连接的神经网络。
model_without_shortcut = ExampleDeepNeuralNetwork(layer_sizes, use_shortcut=False)


def print_gradients(model, x):
    """
    用于在模型的反向传播过程中计算梯度的函数
    :param model: 模型
    :param x: 输入张量
    :return:
    """
    # 前向传播
    output = model(x)
    # 用户指定目标,为简化处理,这里设为0。
    target = torch.tensor([[0.]])
    loss = nn.MSELoss()
    # 计算损失。计算模型输出与用户指定目标的接近程度
    loss = loss(output, target)
    # 反向传播,计算模型中每一层的损失梯度
    loss.backward()

    # 通过model.named_parameters()迭代权重参数
    for name, param in model.named_parameters():
        if 'weight' in name:
            # 打印梯度值的平均绝对值,以得到每一层的单一梯度值,更容易比较层与层之间的梯度
            print(f"{name} 平均梯度: {param.grad.abs().mean().item()}")


print("\n\n不包含跳跃连接的模型----------")
print_gradients(model_without_shortcut, sample_input)


# 实例化一个包含跳跃连接的模型
torch.manual_seed(123)
model_with_shortcut = ExampleDeepNeuralNetwork(
    layer_sizes, use_shortcut=True
)
print("\n\n包含跳跃连接的模型----------")
print_gradients(model_with_shortcut, sample_input)

在完整模型训练中的使用

下面是一个结合模型、优化器和 MSE 损失的完整训练示例(回归任务):

import torch.optim as optim

# 定义一个简单的回归模型
class RegressionModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(1, 1)  # 单输入单输出的线性回归

    def forward(self, x):
        return self.linear(x)

# 初始化模型、损失函数、优化器
model = RegressionModel()
criterion = nn.MSELoss()  # 损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 优化器

# 模拟训练数据(y = 2x + 1,加一点噪声)
x_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
y_train = torch.tensor([[3.1], [5.0], [7.2], [9.1]])  # 真实标签:2*1+1=3, 2*2+1=5 等

# 单步训练过程
for epoch in range(100):
    # 前向传播
    outputs = model(x_train)
    loss = criterion(outputs, y_train)

    # 反向传播 + 优化
    optimizer.zero_grad()  # 清空梯度
    loss.backward()        # 反向传播计算梯度
    optimizer.step()       # 更新参数

    # 每10轮打印一次损失
    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')

# 测试模型
x_test = torch.tensor([[5.0]])
y_pred = model(x_test)
print(f"\n测试输入 x=5.0,预测值: {y_pred.item():.2f}")  # 接近 11.0(2*5+1)

总结

  1. nn.MSELoss() 是计算均方误差的损失函数,核心用于回归任务,计算预测值与真实值的平均平方差;
  2. reduction 参数是核心:’mean’(默认,平均)、’sum’(求和)、’none’(保留每个样本损失);
  3. 使用时需保证预测值和真实标签的形状完全匹配,且在训练中要配合 optimizer.zero_grad()、loss.backward()、optimizer.step() 完成参数更新。

原文出处:/show_1GW2eh5RSApR.html