我的AI贪吃蛇训练日记:调参踩坑、奖励函数设计与策略进化全记录
第一次打开训练日志时,屏幕上那条只会原地转圈的像素蛇让我哭笑不得。作为强化学习新手,我原本期待看到的是灵巧躲避、精准捕食的智能体,没想到收获的却是个"摆烂大师"。这段从零开始的AI贪吃蛇训练之旅,记录着无数个深夜调参的崩溃瞬间,也见证着那条笨拙小蛇逐渐蜕变为游戏高手的奇妙历程。
1. 环境搭建与初代"摆烂蛇"的诞生
安装PyGame和TensorFlow的过程比预想顺利,但当第一个训练周期启动后,问题接踵而至。初始版本采用最基础的DQN架构:
class DQNAgent: def __init__(self): self.model = self._build_model() # 3层全连接网络 self.memory = deque(maxlen=2000) # 经验回放缓冲区 self.gamma = 0.95 # 折扣因子首轮训练就暴露了三个典型问题:
- 转圈魔咒:蛇会持续顺时针/逆时针转圈
- 边界恐惧:接近边界时出现抽搐式抖动
- 食物无视:对屏幕上的食物完全视而不见
通过分析网络输出发现,转圈行为源于初始奖励函数的缺陷。原始设计只设置了:
- 吃到食物:+10
- 撞墙/撞身:-10
- 其他动作:-0.1
这种设计导致智能体发现:保持转圈既能避免碰撞惩罚,又比随机移动获得更高累积奖励。第一周的训练日志里写满了这样的记录:
2023-03-12 02:17
第37次训练迭代
平均步数:142步
典型死因:无限转圈耗尽步数
解决方案尝试:增加直线移动惩罚
2. 奖励函数设计的艺术与陷阱
第二代奖励系统引入了动态距离评估和路径多样性激励:
def get_reward(self): # 距离变化奖励 new_dist = distance_to_food() dist_reward = (self.last_dist - new_dist) * 0.5 # 方向变化惩罚 turn_penalty = -0.2 if direction_changed() else 0 # 生存奖励 survival_bonus = 0.01 * self.steps return dist_reward + turn_penalty + survival_bonus这个版本带来了新的挑战:
| 问题现象 | 根本原因 | 解决方案 |
|---|---|---|
| 蛇身缠绕 | 忽视身体碰撞预测 | 增加视野范围内障碍检测 |
| 局部最优 | 奖励稀疏导致探索不足 | 引入ε-greedy策略衰减 |
| 步数耗尽 | 长期规划能力不足 | 调整γ值至0.99 |
最有趣的发现来自第89次训练:当设置直线移动惩罚为-0.5时,AI竟然发展出"之字形"移动策略来规避惩罚,同时保持大体朝向食物的方向。这种 emergent behavior(涌现行为)让我意识到奖励函数的精妙之处——微小的数值调整就能引发策略级联变化。
3. 超参数调优的蝴蝶效应
第三周专注于超参数优化,建立了以下测试矩阵:
| 参数组 | 测试范围 | 最佳值 | 影响分析 |
|---|---|---|---|
| 学习率 | 1e-5~1e-3 | 3e-4 | 过高导致Q值震荡 |
| 批大小 | 32~256 | 128 | 增大提升训练稳定性 |
| γ值 | 0.9~0.999 | 0.99 | 增强长期规划能力 |
| ε衰减 | 0.995~0.999 | 0.997 | 平衡探索与利用 |
关键突破来自记忆回放机制的改进。原始实现存在两个缺陷:
- 均匀采样导致重要经验被稀释
- 新老经验混合影响收敛
改进后的优先经验回放(PER)实现:
class PrioritizedReplayBuffer: def __init__(self): self.tree = SumTree(capacity) # 基于和树的优先级采样 def add(self, error, experience): priority = (abs(error) + eps)**alpha self.tree.add(priority, experience) def sample(self): segment = self.tree.total() / batch_size return [self.tree.get(i*segment + random.uniform(0,segment)) for i in range(batch_size)]这个改进使训练效率提升约40%,特别是在处理"长蛇绕圈"场景时表现突出。某次凌晨三点的实验记录显示:
使用PER后第203代:
平均长度:15.7 → 22.3
最大长度:31 → 47
突破性表现:首次观察到主动绕开自身身体的策略
4. 策略进化可视化之旅
进入第四周,开始系统记录策略进化过程。通过t-SNE降维可视化策略空间,发现几个关键转折点:
随机探索期(0-50代):
- 动作熵值高
- 平均长度<5
- 典型策略:无规律移动
基础策略期(50-150代):
- 发展出趋食行为
- 出现简单避障
- 平均长度8-12
中级策略期(150-300代):
- 形成路径记忆
- 主动身体避让
- 平均长度15-20
高级策略期(300+代):
- 动态路径规划
- 预测性转向
- 平均长度25+
最令人振奋的是第427代出现的"J型绕行"策略:当食物出现在身体包围圈时,AI会主动沿反方向绕大圈接近,而不是直接冲撞。这种策略的出现验证了深度强化学习在复杂空间推理方面的潜力。
5. 实战中的经验结晶
经过两个月的迭代,总结出这些宝贵经验:
奖励函数设计原则
- 距离奖励应采用相对值而非绝对值
- 生存奖励需要随时间衰减
- 转向惩罚要区分有效/无效转向
- 碰撞惩罚应分级(预测碰撞>实际碰撞)
网络结构优化技巧
- 增加卷积层提升空间感知
- 使用Dueling DQN分离价值/优势估计
- 引入LSTM处理时序依赖
- 正交初始化提升训练稳定性
训练过程注意事项
- 定期保存模型快照
- 建立完整的评估指标
- 可视化关键神经元激活
- 监控优势估计方差
当看到那条曾经笨拙的像素蛇最终能在布满自身身体的迷宫中灵活穿梭,精准捕捉每一个食物时,所有调试的艰辛都化作了成就感。这或许就是强化学习最迷人的地方——你永远不知道下一次训练会诞生怎样令人惊喜的策略。