1. 写在前面
从今天开始,我们将正式进入深度学习的领域。虽然机器学习只需要三行代码就能调用模型,但神经网络的灵活性更高,我们可以对模型结构、训练过程做非常多的定制。
在开始写代码之前,你需要先明确几个核心概念:
- 神经网络:它就像一个复杂的函数,输入数据,输出预测结果。
- 梯度下降:这是让模型"学习"的方法,通过不断调整参数来减少误差。
- PyTorch:这是目前最流行的深度学习框架之一,我们接下来的项目都会基于它来开发。
2. 环境配置与检查
深度学习通常需要独立的Python环境,以避免包版本冲突。
如果你不知道环境如何配置,这里推荐一个B站的教程:【2025年最新版】手把手教你安装PyTorch,用最简单的方式教你安装PyTorch_哔哩哔哩_bilibili
基本上很多环境配置的问题都可以得到解决。
创建环境
建议创建一个名为 DL (Deep Learning) 的新环境:
conda create -n DL python=3.8
conda activate DL
# 安装PyTorch(具体命令需参考PyTorch官网,根据你的显卡版本选择)
# pip install torch torchvision torchaudio ...
检查显卡 (CUDA)
深度学习主要是矩阵运算,GPU(显卡)的并行计算能力比CPU强得多。我们可以通过代码检查CUDA是否可用:
import torch
# 检查CUDA是否可用
if torch.cuda.is_available():
print("CUDA可用!")
# 查看设备数量
print(f"设备数量: {torch.cuda.device_count()}")
# 查看当前设备名称
print(f"显卡名称: {torch.cuda.get_device_name(0)}")
else:
print("CUDA不可用,将使用CPU训练")
如果是NVIDIA显卡且安装了正确的驱动,通常能看到显卡信息。如果没有显卡,用CPU也能跑今天的简单例子。
安装torch成功可以在终端输入以下命令验证,出现"True"就是成功了

3. 数据准备:从Numpy到Tensor
神经网络对输入数据比较挑剔,通常需要做两步处理:
-
归一化:将数据缩放到0-1之间,这样模型收敛更快。
-
转为Tensor:PyTorch无法直接处理Numpy数组,必须转换成张量(Tensor)。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import torch
import numpy as np1. 加载数据
iris = load_iris()
X = iris.data
y = iris.target2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
3. 数据归一化(非常重要)
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)4. 转换为PyTorch张量
特征转为FloatTensor(浮点型),标签转为LongTensor(长整型,分类任务要求)
X_train = torch.FloatTensor(X_train)
y_train = torch.LongTensor(y_train)
X_test = torch.FloatTensor(X_test)
y_test = torch.LongTensor(y_test)
4. 搭建神经网络模型
在PyTorch中定义模型主要有三个固定步骤:
-
继承
nn.Module父类。 -
在
__init__中定义层(如全连接层、激活函数)。 -
在
forward中定义前向传播的路径(数据怎么流)。import torch.nn as nn
class MLP(nn.Module):
def init(self):
super(MLP, self).init() # 必须调用父类初始化# 定义网络层 # 输入层到隐藏层:输入4个特征,输出10个神经元 self.fc1 = nn.Linear(4, 10) # 激活函数 self.relu = nn.ReLU() # 隐藏层到输出层:输入10个神经元,输出3个分类 self.fc2 = nn.Linear(10, 3) def forward(self, x): # 定义数据流向 out = self.fc1(x) out = self.relu(out) out = self.fc2(out) return out # 注意:输出层不需要加Softmax,因为后续的交叉熵损失函数自带了实例化模型
model = MLP()
5. 训练的"三件套"
在开始训练循环前,需要准备好工具:
-
损失函数 (Criterion):衡量模型预测得准不准。
-
优化器 (Optimizer):根据误差来更新模型参数。
import torch.optim as optim
分类任务常用交叉熵损失
criterion = nn.CrossEntropyLoss()
随机梯度下降优化器 (SGD)
lr是学习率,控制每次更新的步长
optimizer = optim.SGD(model.parameters(), lr=0.01)
6. 训练循环 (Training Loop)
这是深度学习代码中最核心的部分,逻辑非常固定,俗称"五步走":
num_epochs = 20000 # 训练轮数
losses = [] # 记录损失值用于画图
for epoch in range(num_epochs):
# 1. 前向传播:计算预测值
outputs = model(X_train)
# 2. 计算损失:预测值 vs 真实值
loss = criterion(outputs, y_train)
# 3. 梯度清零:清除上一步的残留梯度(必须做!)
optimizer.zero_grad()
# 4. 反向传播:计算新的梯度
loss.backward()
# 5. 更新参数:根据梯度调整权重
optimizer.step()
# 记录和打印
losses.append(loss.item())
if (epoch + 1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
新手易错点:
optimizer.zero_grad()千万别忘了,否则梯度会累积,导致模型训练失败。model(X_train)等价于model.forward(X_train),是Python的魔法方法调用。
7. 结果可视化
训练完成后,我们可以画出 Loss 的变化曲线。如果曲线一直在下降并趋于平稳,说明模型学到了东西。
import matplotlib.pyplot as plt
plt.plot(range(num_epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss over Epochs')
plt.show()