用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数据分析进阶教程》专栏 |
2 | AI大模型应用实践进阶教程 | 《AI大模型应用实践进阶教程》专栏 |
3 | Python编程知识集锦 | 《Python编程知识集锦》专栏 |
4 | 字节跳动旗下AI制作抖音视频 | 《字节跳动旗下AI制作抖音视频》专栏 |
5 | 智能辅助驾驶 | 《智能辅助驾驶》专栏 |
6 | 工具软件及IT技术集锦 | 《工具软件及IT技术集锦》专栏 |
👉 关注我 @理工男大辉郎 获取实时更新
欢迎关注、收藏或转发。
敬请关注 我的
微信搜索公众号:cnFuJH
优快云博客:理工男大辉郎
抖音号:31580422589