67、构建神经网络时损失函数和优化器的选择【用Python进行AI数据分析进阶教程】

用Python进行AI数据分析进阶教程67:

构建神经网络时损失函数和优化器的选择


关键词:均方误差损失、交叉熵损失、随机梯度下降、Adam优化器、损失函数选择

摘要:本文主要介绍了在构建神经网络时如何选择损失函数和优化器。对于损失函数,重点讲解了适用于回归问题的均方误差损失(MSE)和用于分类问题的交叉熵损失(Cross Entropy Loss),并给出了各自的使用场景与注意事项。针对优化器,分别介绍了随机梯度下降(SGD)和Adam优化器,强调了它们的优缺点及使用方法。文章通过PyTorch代码示例展示了如何定义和使用这些损失函数与优化器,并解释了关键语句的作用,帮助读者更好地理解和应用。

👉 欢迎订阅🔗
《用Python进行AI数据分析进阶教程》专栏
《AI大模型应用实践进阶教程》专栏
《Python编程知识集锦》专栏
《字节跳动旗下AI制作抖音视频》专栏
《智能辅助驾驶》专栏
《工具软件及IT技术集锦》专栏


在构建和训练神经网络时,损失函数和优化器的选择至关重要。损失函数用于衡量模型预测结果与真实标签之间的差异,而优化器则根据损失函数的梯度来更新模型的参数,以最小化损失。以下以 PyTorch 为例,详细讲解常见损失函数和优化器的选择。

一、损失函数

(一)均方误差损失(Mean Squared Error, MSE)

1、关键点

  • 常用于回归问题,计算预测值与真实值之间差值平方的平均值,能直观反映预测值与真实值的偏离程度。

2、注意点

  • 对异常值敏感,因为平方操作会放大误差。

3、示例代码

Python基本

import torch
import torch.nn as nn
from typing import Tuple


def calculate_mse_loss() -> torch.Tensor:
    """
    计算均方误差损失的示例。

    返回:
        torch.Tensor: 计算得到的 MSE 损失值。
    """
    # 定义预测值和真实值
    predictions = torch.tensor([2.5, 3.7, 4.1], 
                              dtype=torch.float32)
    targets = torch.tensor([2.0, 3.5, 4.0], 
                          dtype=torch.float32)

    # 验证输入维度是否匹配
    if predictions.shape != targets.shape:
        raise ValueError(
            f"预测值和真实值的形状不匹配: "
            f"{predictions.shape} vs {targets.shape}"
        )

    # 创建MSE损失函数实例
    mse_loss = nn.MSELoss()

    # 计算损失
    loss = mse_loss(predictions, targets)

    # 打印详细信息
    print(f"预测值: {predictions}")
    print(f"真实值: {targets}")
    print(f"MSE Loss: {loss.item():.6f}")

    # 手动验证计算结果
    manual_mse = torch.mean((predictions - targets) ** 2)
    print(f"手动计算的MSE: {manual_mse.item():.6f}")

    return loss


def calculate_mse_with_gradients() -> torch.Tensor:
    """
    演示带梯度的MSE计算。

    返回:
        torch.Tensor: 计算得到的 MSE 损失值。
    """
    # 需要计算梯度的张量
    predictions = torch.tensor([2.5, 3.7, 4.1], 
                              dtype=torch.float32, 
                              requires_grad=True)
    targets = torch.tensor([2.0, 3.5, 4.0], 
                          dtype=torch.float32)

    mse_loss = nn.MSELoss()
    loss = mse_loss(predictions, targets)

    print(f"\n带梯度计算:")
    print(f"MSE Loss: {loss.item():.6f}")

    # 反向传播计算梯度
    loss.backward()
    print(f"预测值的梯度: {predictions.grad}")

    return loss


def batch_mse_example() -> torch.Tensor:
    """
    批量数据的MSE计算示例。

    返回:
        torch.Tensor: 批量数据下的 MSE 损失值。
    """
    # 批量数据 (batch_size=2, features=3)
    predictions = torch.tensor(
        [[2.5, 3.7, 4.1], 
         [1.8, 2.9, 3.2]], 
        dtype=torch.float32
    )
    targets = torch.tensor(
        [[2.0, 3.5, 4.0], 
         [2.0, 3.0, 3.0]], 
        dtype=torch.float32
    )

    mse_loss = nn.MSELoss()
    loss = mse_loss(predictions, targets)

    print(f"\n批量数据示例:")
    print(f"预测值形状: {predictions.shape}")
    print(f"真实值形状: {targets.shape}")
    print(f"Batch MSE Loss: {loss.item():.6f}")

    return loss


if __name__ == "__main__":
    # 基本MSE计算
    calculate_mse_loss()

    # 带梯度的MSE计算
    calculate_mse_with_gradients()

    # 批量数据示例
    batch_mse_example()

运行结果将显示:

预测值: tensor([2.5000, 3.7000, 4.1000])

真实值: tensor([2.0000, 3.5000, 4.0000])

MSE Loss: 0.030000

手动计算的MSE: 0.030000

重点语句解读

  • mse_loss = nn.MSELoss():创建一个 MSE 损失函数的实例。
  • loss = mse_loss(predictions, targets):调用损失函数计算预测值和真实值之间的 MSE 损失。
  • loss.item():将损失值从张量转换为 Python 标量,方便打印输出。

(二)交叉熵损失(Cross Entropy Loss)

1、关键点

  • 常用于分类问题,尤其是多分类问题。它衡量预测概率分布与真实标签分布之间的差异。

2、注意点

  • 输入的预测值通常是未经过 Softmax 的原始分数,nn.CrossEntropyLoss 会自动进行 Softmax 操作;真实标签是类别索引。

3、示例代码

Python基本

import torch
import torch.nn as nn

# 定义预测值(未经过Softmax)
logits = torch.tensor(
    [[2.0, 1.0, 0.1], 
     [0.5, 2.5, 1.0]], 
    dtype=torch.float32
)

# 定义真实标签
targets = torch.tensor([0, 1], dtype=torch.long)

# 创建交叉熵损失函数实例
cross_entropy_loss = nn.CrossEntropyLoss()

# 计算损失
loss = cross_entropy_loss(logits, targets)

# 输出损失值
print(f"Cross Entropy Loss: {loss.item():.6f}")

# 额外的验证信息
print(f"Logits shape: {logits.shape}")
print(f"Targets shape: {targets.shape}")

重点语句解读

  • cross_entropy_loss = nn.CrossEntropyLoss():创建交叉熵损失函数实例。
  • logits:未经过 Softmax 的原始分数。
  • targets:真实标签为类别索引,类型为 torch.long
  • loss = cross_entropy_loss(logits, targets):计算交叉熵损失。

二、优化器

(一)随机梯度下降(Stochastic Gradient Descent, SGD)

1、关键点

  • 是最基础的优化算法,通过计算每个样本或小批量样本的梯度来更新模型参数。

2、注意点

  • 学习率的选择很关键,过大可能导致模型无法收敛,过小则会使收敛速度变慢。

3、示例代码

Python基本

import torch
import torch.nn as nn

# 定义一个简单的线性模型
model = nn.Linear(10, 1)

# 定义SGD优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

# 模拟输入数据和标签
inputs = torch.randn(32, 10)
labels = torch.randn(32, 1)

# 前向传播
outputs = model(inputs)

# 定义损失函数并计算损失
loss_fn = nn.MSELoss()
loss = loss_fn(outputs, labels)

# 反向传播
optimizer.zero_grad()  # 清零梯度
loss.backward()        # 计算梯度

# 更新参数
optimizer.step()

# 打印优化后的模型参数
print("Model parameters after one step of SGD:")
print("Weight:", model.weight.data)
print("Bias:", model.bias.data)

重点语句解读

  • optimizer = torch.optim.SGD(model.parameters(), lr=0.01):创建 SGD 优化器实例,传入模型的参数和学习率。
  • optimizer.zero_grad():在每次反向传播之前,将梯度清零,避免梯度累积。
  • loss.backward():计算损失函数关于模型参数的梯度。
  • optimizer.step():根据计算得到的梯度更新模型参数。

(二)Adam 优化器

1、关键点

  • 结合了 AdaGrad 和 RMSProp 的优点,自适应地调整每个参数的学习率,收敛速度通常较快。

2、注意点

  • 虽然 Adam 通常表现较好,但在某些情况下可能会出现过拟合问题,需要适当调整超参数。

3、示例代码

Python基本

import torch
import torch.nn as nn

# 定义一个简单的线性模型,输入维度为10,输出维度为1
model = nn.Linear(in_features=10, out_features=1)

# 定义Adam优化器,学习率设置为0.001
# Adam优化器通常比SGD具有更好的收敛性能
optimizer = torch.optim.Adam(
    params=model.parameters(), 
    lr=0.001
)

# 模拟输入数据和标签
# 生成32个样本,每个样本有10个特征
inputs = torch.randn(32, 10)
# 生成32个标签,每个标签为1维
labels = torch.randn(32, 1)

# 前向传播:计算模型输出
outputs = model(inputs)

# 定义均方误差损失函数
loss_fn = nn.MSELoss()
# 计算预测输出与真实标签之间的损失
loss = loss_fn(input=outputs, target=labels)

# 反向传播过程
optimizer.zero_grad()  # 清零梯度,避免梯度累积
loss.backward()        # 计算损失相对于参数的梯度

# 更新模型参数
optimizer.step()

# 打印优化后的模型参数
print("Model parameters after one step of Adam optimization:")
print("Weight tensor:", model.weight.data)
print("Bias value:", model.bias.data.item())

重点语句解读

  • optimizer = torch.optim.Adam(model.parameters(), lr=0.001):创建 Adam 优化器实例,传入模型参数和学习率。
  • 后续的 optimizer.zero_grad()loss.backward() 和 optimizer.step() 操作与 SGD 相同,分别用于梯度清零、反向传播和参数更新。

——The END——


🔗 欢迎订阅专栏

序号专栏名称说明
1用Python进行AI数据分析进阶教程《用Python进行AI数据分析进阶教程》专栏
2AI大模型应用实践进阶教程《AI大模型应用实践进阶教程》专栏
3Python编程知识集锦《Python编程知识集锦》专栏
4字节跳动旗下AI制作抖音视频《字节跳动旗下AI制作抖音视频》专栏
5智能辅助驾驶《智能辅助驾驶》专栏
6工具软件及IT技术集锦《工具软件及IT技术集锦》专栏

👉 关注我 @理工男大辉郎 获取实时更新

欢迎关注、收藏或转发。
敬请关注 我的
微信搜索公众号:cnFuJH
优快云博客:理工男大辉郎
抖音号:31580422589

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

理工男大辉郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值