网站首页 > 文章精选 正文
学习目标
- 理解损失函数:学习什么是损失函数,为什么需要它,以及常见类型(如 MSE 和 CrossEntropy)。
- 理解优化器:了解优化器如何帮助模型学习,以及 SGD 和 Adam 的基本原理。
- 实践任务:为 Day 7 的 MLP 添加 MSE 损失函数和 SGD 优化器,训练 10 轮,观察模型如何改进预测。
术语解释
1. 损失函数 (Loss Function)
- 是什么:损失函数是衡量模型预测结果与真实答案之间差距的指标。模型的目标是让这个“差距”尽可能小。
- 类比:想象你在玩飞镖,目标是击中靶心(真实答案)。你的飞镖落在哪里(模型预测)与靶心的距离就是“损失”。损失越小,说明你越接近目标。
- 常见类型: MSE (Mean Squared Error, 均方误差):用于回归任务(预测连续值,如房价、温度)。它计算预测值与真实值差的平方平均值。 公式:MSE = (1/n) * Σ(预测值 - 真实值)^2 例子:预测房价是 100 万,真实是 120 万,差 20 万,平方后加权平均。 CrossEntropy (交叉熵损失):用于分类任务(预测类别,如猫狗分类)。它衡量预测概率分布与真实标签分布的差异。 例子:预测一张图片是猫的概率是 0.8,真实是猫,损失小;如果预测是狗,损失大。
- 作用:告诉模型“错在哪里,错多少”,为优化提供方向。
2. 优化器 (Optimizer)
- 是什么:优化器是调整模型参数(权重和偏置)的算法,让损失函数的值变小,模型预测更准确。
- 类比:模型像一个在山谷里找最低点(最小损失)的人。优化器是“导航员”,告诉它每次走哪一步(调整参数)。
- 常见类型: SGD (Stochastic Gradient Descent, 随机梯度下降): 原理:根据损失函数的梯度(斜率),小步调整参数,朝损失下降的方向走。 类比:像下山时看脚下的坡度,慢慢走。 特点:简单,但可能需要较多步数,容易卡在“局部低点”。 Adam: 原理:结合动量法和自适应学习率,比 SGD 更“聪明”,能更快找到最低点。 类比:像个有经验的登山者,知道哪里陡、哪里平,步伐大小自动调整。 特点:收敛更快,适合复杂模型,但参数多。
- 作用:通过反复调整模型参数,降低损失,让模型学到数据的规律。
示例:MLP + MSE + SGD
场景
假设你有一个简单的数据集:输入是 2 个数字(x1, x2),输出是它们的和(y = x1 + x2)。我们用一个 MLP 模型预测这个和,MSE 衡量预测误差,SGD 优化模型。
数据示例
- 输入:[1.0, 2.0],真实输出:3.0
- 输入:[0.5, 1.5],真实输出:2.0
- 目标:模型学会预测任意输入的和。
代码
以下是完整的 PyTorch 代码,包含注释,帮助新手理解每一步。
python
Bash
import torch
import torch.nn as nn
import torch.optim as optim
# 定义 MLP 模型(Day 7 的假设结构)
class MLP(nn.Module):
# 继承 PyTorch 的 Module 类
def __init__(self, input_size=2, hidden_size=10, output_size=1):
super(MLP, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size) # 第一层:输入到隐藏层
self.relu = nn.ReLU() # 激活函数,让模型学非线性关系
self.fc2 = nn.Linear(hidden_size, output_size) # 第二层:隐藏层到输出
def forward(self, x): # 前向传播
x = self.fc1(x)
x = self.relu(x)
x = self.fc2(x)
return x
# 设置超参数
input_size = 2 # 输入是 2 个数字
hidden_size = 10 # 隐藏层有 10 个神经元
output_size = 1 # 输出是 1 个数字(和)
learning_rate = 0.01 # 学习率,控制优化器步伐
epochs = 10 # 训练 10 轮
batch_size = 32 # 每批处理 32 个样本
# 生成示例数据
torch.manual_seed(42) # 固定随机种子,结果可重复
X = torch.randn(100, input_size) # 100 个样本,每个有 2 个特征
y = X.sum(dim=1, keepdim=True) + 0.1 * torch.randn(100, 1) # 目标:特征和 + 噪声
# 初始化模型、损失函数、优化器
model = MLP(input_size, hidden_size, output_size) # 创建模型
criterion = nn.MSELoss() # MSE 损失函数
optimizer = optim.SGD(model.parameters(), lr=learning_rate) # SGD 优化器
# 训练循环
model.train() # 设置模型为训练模式
for epoch in range(epochs):
total_loss = 0
# 小批量训练
for i in range(0, len(X), batch_size):
# 取一批数据
inputs = X[i:i+batch_size]
targets = y[i:i+batch_size]
# 前向传播
outputs = model(inputs) # 模型预测
loss = criterion(outputs, targets) # 计算 MSE 损失
# 反向传播与优化
optimizer.zero_grad() # 清空上一步的梯度
loss.backward() # 计算当前梯度
optimizer.step() # 根据梯度更新参数
total_loss += loss.item() # 累加损失
# 打印每轮平均损失
avg_loss = total_loss / (len(X) // batch_size)
print(f'Epoch [{epoch+1}/{epochs}], Loss: {avg_loss:.4f}')
# 测试模型
model.eval() # 设置模型为评估模式
with torch.no_grad(): # 禁用梯度计算
test_input = torch.tensor([[1.0, 2.0]]) # 测试输入
prediction = model(test_input) # 预测
print(f'Test input: {test_input.tolist()}, Prediction: {prediction.tolist()}')
代码逐行解释
- 模型定义: MLP 类定义了一个两层神经网络:输入(2 个特征)→ 隐藏层(10 个神经元)→ 输出(1 个值)。 ReLU 激活函数让模型学到非线性关系(比如复杂的曲线)。 forward 方法描述数据如何通过网络。
- 数据生成: 创建 100 个随机样本,输入是 2 维(X),输出是输入的和加一点噪声(y)。 噪声模拟现实中的不完美数据。
- 损失函数: nn.MSELoss() 计算预测值和真实值的均方误差。 比如,预测 2.8,真实 3.0,误差是 (2.8 - 3.0)^2 = 0.04。
- 优化器: optim.SGD 使用梯度下降更新模型参数。 lr=0.01 控制每次调整的大小,太大可能跳过最低点,太小收敛慢。
- 训练过程: 每轮(epoch)遍历所有数据,分批(batch)处理。 前向传播:输入通过模型得到预测,计算损失。 反向传播:根据损失计算梯度(告诉参数怎么调整)。 优化:SGD 用梯度更新参数,减小损失。 打印平均损失,观察是否下降。
- 测试: 用 [1.0, 2.0] 测试,理想预测接近 3.0。 model.eval() 和 no_grad() 确保不计算梯度,节省内存。
预期输出
运行后,你会看到类似:
Bash
Epoch [1/10], Loss: 0.1234
Epoch [2/10], Loss: 0.0987
...
Epoch [10/10], Loss: 0.0123
Test input: [[1.0, 2.0]], Prediction: [[2.9876]]
- 损失逐渐下降,说明模型在学习。
- 预测值接近 3.0,说明模型学会了“求和”。
新手常见问题
- 为什么损失不下降? 学习率可能太高或太低,试试 0.001 或 0.1。 数据可能有问题,检查输入和目标是否匹配。 模型结构可能太简单,增加隐藏层或神经元。
- MSE 和 CrossEntropy 怎么选? 用 MSE 预测连续值(如温度、房价)。 用 CrossEntropy 预测类别(如猫、狗)。
- SGD 和 Adam 哪个好? SGD 简单,适合小数据集,但慢。 Adam 更快,适合复杂模型,但可能过拟合。
- 什么是梯度? 梯度是损失函数对参数的“斜率”,告诉优化器参数该往哪调(增大还是减小)。
资源建议
- PyTorch 文档: MSELoss SGD
- 视频教程: PyTorch 官方 YouTube 频道(如 Intro to PyTorch)。 Aladdin Persson 的 PyTorch 教程(YouTube)。
- 实践: 试试用 CrossEntropy 做分类任务。 调整学习率、隐藏层大小,观察损失变化。
下一步
- 试试 Adam 优化器:替换 optim.SGD 为 optim.Adam(model.parameters(), lr=0.001),比较收敛速度。
- 加载真实数据集:如果有 CSV 或图像数据,我可以帮你写加载代码。
- 可视化:用 Matplotlib 画损失曲线或预测结果。
猜你喜欢
- 2025-05-28 如何提高PyTorch“炼丹”速度?这位小哥总结了17种方法
- 2025-05-28 显存告急?微调资源优化的三大法宝
- 2025-05-28 大模型训练成本降低近一半!新加坡国立大学最新优化器已投入使用
- 2025-05-28 Pytorch 入门-day13: 调试与可视化
- 2025-05-28 基于昇腾用PyTorch实现CTR模型DIN(Deep interest Netwok)网络
- 2025-05-28 神经网络训练全解析:从理论到实战的开发者指南及超参数优化法则
- 2025-05-28 BattProDeep——深度学习赋能电池老化概率精准预测
- 2025-05-28 让AI自己调整超参数,谷歌大脑新优化器火了,自适应多种不同任务
- 2025-05-28 神经辐射场(NeRF)实战指南:基于PyTorch的端到端实现
- 2025-05-28 Pytorch入门-Day 14:实践与优化
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)