CHAPTER 04

控制流:条件判断与循环

让程序根据情况做不同的事,或重复执行某些操作。AI 训练循环的本质就是 for 循环加上条件判断。

if / elif / else —— 条件判断

if 让程序做决策:"如果...就做...,否则做..."。Python 用缩进表示代码块,冒号 : 后面的缩进内容属于这个 if 块。

核心语法

if / elif / else 结构

if 是"如果",elif 是"否则如果"(else if 的缩写),else 是"以上都不是时"。elif 和 else 都是可选的,可以有多个 elif。

PYTHON · 条件判断基础
accuracy = 0.85

# 基本 if-elif-else
if accuracy >= 0.95:
    print("优秀!可以部署")
elif accuracy >= 0.85:
    print("良好,继续调优")     # ← 这行会执行
elif accuracy >= 0.70:
    print("一般,需要改进")
else:
    print("较差,重新设计模型")

# 组合条件(and、or、not)
loss = 0.3
epoch = 50

if accuracy >= 0.9 and loss < 0.2:
    print("模型达标")

if epoch > 100 or loss < 0.01:
    print("停止训练")

# 三元表达式(简洁写法)
status = "通过" if accuracy > 0.8 else "不通过"
print(status)  # 通过
PYTHON · AI 训练中的条件判断
# Early Stopping(早停):常见的 AI 训练策略
best_val_loss = float('inf')  # 初始设为无穷大
patience = 5               # 允许连续 5 轮没提升
wait = 0
current_val_loss = 0.35

if current_val_loss < best_val_loss:
    best_val_loss = current_val_loss
    wait = 0
    print("验证损失改善,保存模型")
else:
    wait += 1
    if wait >= patience:
        print("早停触发,停止训练!")

# 选择设备(GPU 还是 CPU)
import torch
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"使用设备: {device}")

for 循环 —— 遍历迭代

for 循环用于遍历一个序列(列表、字典、范围等),对每个元素执行相同的操作。AI 训练的核心就是 for 循环:每轮(epoch)遍历一次训练集。

核心概念

可迭代对象(Iterable)

凡是可以用 for 循环遍历的对象都是"可迭代对象":列表、字典、字符串、range()、文件对象等都是可迭代的。理解这个概念后,你就明白为什么 for 循环可以用在这么多地方了。

PYTHON · for 循环基础
# 遍历列表
models = ["GPT-4o", "Claude", "Gemini"]
for model in models:
    print(f"评估模型: {model}")

# range() 生成数字范围
# range(start, stop, step) - stop 不包含在内
for epoch in range(1, 6):  # 1, 2, 3, 4, 5
    print(f"Epoch {epoch}/5")

# enumerate() - 同时获得索引和值
losses = [2.5, 1.8, 1.2, 0.9]
for i, loss in enumerate(losses):
    print(f"Epoch {i+1}: loss = {loss}")

# zip() - 同时遍历两个列表
train_losses = [2.5, 1.8, 1.2]
val_losses = [2.8, 2.0, 1.4]
for t_loss, v_loss in zip(train_losses, val_losses):
    print(f"训练: {t_loss:.2f}, 验证: {v_loss:.2f}")

# 遍历字典
config = {"lr": 0.001, "batch": 32, "epochs": 100}
for key, value in config.items():
    print(f"{key} = {value}")

break 和 continue

PYTHON · break 和 continue
# break:立即退出循环
losses = [2.5, 1.8, 1.2, 0.05, 0.8]  # 第4个达标
for i, loss in enumerate(losses):
    print(f"Epoch {i}: {loss}")
    if loss < 0.1:
        print("达到目标!停止训练")
        break  # 退出循环,不再继续

# continue:跳过当前这一次,继续下一次
data = [1.0, None, 3.0, None, 5.0]  # 含有空值的数据
for x in data:
    if x is None:
        continue  # 跳过 None,继续下一个
    print(x ** 2)  # 1.0, 9.0, 25.0

while 循环 —— 条件循环

while 循环在条件为 True 时一直重复,直到条件变 False。与 for 循环的区别:for 循环知道要循环多少次,while 循环不知道,只要条件满足就继续。

PYTHON · while 循环
# 训练直到 loss 足够小
loss = 10.0
epoch = 0
target_loss = 0.5

while loss > target_loss:
    # 模拟损失下降(实际是模型训练)
    loss = loss * 0.7
    epoch += 1
    print(f"Epoch {epoch}: loss = {loss:.4f}")

print(f"训练完成,共 {epoch} 轮")

# 输出:
# Epoch 1: loss = 7.0000
# Epoch 2: loss = 4.9000
# ...最终达到目标

# 防死循环:加一个最大迭代次数限制
max_epochs = 1000
epoch = 0
while loss > 0.01 and epoch < max_epochs:
    epoch += 1
    # ... 训练逻辑
⚠️

小心无限循环

while 循环如果条件永远为 True,程序就会卡死(无限循环)。一定要确保循环内部有能使条件变 False 的逻辑,或者设置最大迭代次数。

综合示例:AI 训练循环

把本章学的所有控制流组合起来,看一个模拟的完整 AI 训练循环:

PYTHON · 模拟 AI 训练循环
import random

# 训练配置
config = {
    "epochs": 20,
    "target_loss": 0.3,
    "patience": 3  # 早停等待轮数
}

best_loss = float('inf')
wait = 0
loss_history = []

# 训练循环(核心是 for + if)
for epoch in range(1, config["epochs"] + 1):

    # 模拟损失(真实代码是跑一遍训练集)
    loss = 2.0 / epoch + random.uniform(-0.05, 0.05)
    loss_history.append(loss)

    # 每5轮打印一次
    if epoch % 5 == 0:
        print(f"[Epoch {epoch:02d}] loss: {loss:.4f}")

    # 检查是否改善(早停逻辑)
    if loss < best_loss:
        best_loss = loss
        wait = 0
    else:
        wait += 1

    # 早停:连续 patience 轮没改善就停止
    if wait >= config["patience"]:
        print(f"早停触发(Epoch {epoch})")
        break

    # 目标达成
    if loss < config["target_loss"]:
        print(f"✅ 目标达成!Epoch {epoch}, loss = {loss:.4f}")
        break

print(f"最低损失: {best_loss:.4f}")
print(f"损失曲线: {[round(l,2) for l in loss_history[:5]]}...")
🤖

这就是 AI 训练的骨架

真实的 PyTorch 训练循环和上面这段代码结构几乎完全一样,只是把"模拟损失"替换成了真正的前向传播、反向传播和参数更新。掌握这个结构,你就理解了 AI 训练的核心逻辑。