强化学习踩坑记录:从环境搭建到DQN实现

强化学习踩坑记录

之前做强化学习项目时,从环境搭建到算法实现走了不少弯路,这里记录一下过程。

机器学习基础环境搭建

CentOS环境TensorFlow安装

Python 3.8安装

在CentOS 7/8上使用yum从第三方仓库安装Python 3.8:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 注册SCL仓库
yum install -y centos-release-scl

# 安装Python 3.8
yum install -y rh-python38 which

# 创建软连接(方便调用)
ln -s /opt/rh/rh-python38/root/usr/bin/python3 /usr/bin/python3
ln -s /opt/rh/rh-python38/root/usr/bin/pip3 /usr/bin/pip3

# 验证安装
python3 -V
pip3 -V # 确保版本高于19.0

TensorFlow安装

1
pip install tensorflow

安装验证

1
2
3
4
5
6
7
8
import tensorflow as tf

# 基础运算测试
print(tf.add(1, 2).numpy()) # 输出: 3

# 字符串测试
hello = tf.constant('Hello, TensorFlow!')
print(hello.numpy()) # 输出: b'Hello, TensorFlow!'

Anaconda环境配置

Anaconda是Python数据科学环境的一站式解决方案。

下载安装

推荐从清华大学开源软件镜像站下载:

1
https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

环境变量配置

在Windows系统中,需要添加以下路径到系统环境变量:

1
2
3
F:\anaconda
F:\anaconda\Scripts
F:\anaconda\Library

配置方法:此电脑 - 右键属性 - 高级系统设置 - 环境变量 - 系统变量 - Path - 新建

验证安装

1
2
conda --version
conda list

Windows + PyCharm + Gym开发环境

完整环境搭建流程

Step 1: 安装Anaconda

按照前述步骤安装并配置Anaconda。

Step 2: 安装PyCharm

推荐使用PyCharm Community或Edu版本。

Step 3: 创建Conda虚拟环境

1
2
3
4
5
# 创建新环境(Python 3.9)
conda create -n gym_env python=3.9

# 激活环境
conda activate gym_env

Step 4: 安装依赖库

1
2
3
4
5
6
7
8
9
10
# 更新pandas
conda install pandas

# 安装TensorFlow
conda install tensorflow

# 使用清华镜像安装其他库
pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install gym -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple

Step 5: PyCharm中配置解释器

  1. File - Settings - Project: [项目名]
  2. Python Interpreter - Add Interpreter - Add Local Interpreter
  3. 左侧选择”Conda Environment”
  4. 选择已创建的gym_env环境

Gym框架测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import gym

# 创建CartPole环境
env = gym.make("CartPole-v1", render_mode="human", disable_env_checker=True)

# 重置环境
observation, info = env.reset(seed=42)

# 运行100000步
for _ in range(100000):
# 渲染游戏画面(训练时可注释以节省资源)
env.render()

# 随机采样动作
action = env.action_space.sample()

# 与环境交互
observation, reward, terminated, truncated, info = env.step(action)

# 回合结束则重置
if terminated or truncated:
observation, info = env.reset()

env.close()

关键参数说明:

  • render_mode="human":显示游戏画面
  • disable_env_checker=True:禁用环境检查器
  • env.step()返回5个参数:观察值、奖励、是否终止、是否截断、信息

强化学习基础

强化学习核心概念

强化学习(Reinforcement Learning)是机器学习的一个重要分支,其核心思想是让智能体通过与环境的交互来学习最优策略。

核心要素:

  • Agent(智能体):执行动作的决策者
  • Environment(环境):智能体所处的外部世界
  • State(状态):环境在某一时刻的描述
  • Action(动作):智能体可以执行的操作
  • Reward(奖励):环境对动作的反馈
  • Policy(策略):状态到动作的映射

更新方式对比

单步更新 (Temporal Difference)

1
2
3
特点:每一步都更新Q值
优点:学习更快,效率更高
缺点:某些步骤直到获得奖励前得不到更新

典型算法: Q-Learning、Sarsa

回合更新 (Monte Carlo)

1
2
3
特点:整个回合结束后才更新
优点:每一步都与最终奖励相关
缺点:必须等回合结束才能学习

典型算法: 蒙特卡洛方法

Q-Learning算法

Q-Learning核心思想

Q-Learning是一种离策略(Off-Policy)的强化学习算法,其核心是维护一个Q表来存储状态-动作值函数。

核心公式:

1
Q(s,a) = Q(s,a) + α[r + γ·maxQ(s',a') - Q(s,a)]

其中:

  • α:学习率,控制更新步长
  • γ:折扣因子,平衡当前和未来奖励
  • maxQ(s',a'):下一状态的最大Q值

Off-Policy特性

Q-Learning是”说到但不一定做到”的算法:

  • Off-Policy(离线学习):学习用的动作和实际执行的动作可以不同
  • 探索与利用:使用ε-贪婪策略平衡探索和开发
  • 勇敢型算法:因为有maxQ,总是选择最近的成功路径

Q-Learning实现要点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

class QLearningAgent:
def __init__(self, n_states, n_actions, learning_rate=0.1, gamma=0.9, epsilon=0.1):
self.q_table = np.zeros((n_states, n_actions))
self.lr = learning_rate
self.gamma = gamma
self.epsilon = epsilon

def choose_action(self, state):
# ε-贪婪策略
if np.random.uniform() < self.epsilon:
return np.random.randint(n_actions) # 探索
else:
return np.argmax(self.q_table[state]) # 利用

def learn(self, state, action, reward, next_state):
# Q-Learning更新公式
predict = self.q_table[state, action]
target = reward + self.gamma * np.max(self.q_table[next_state])
self.q_table[state, action] += self.lr * (target - predict)

Sarsa算法

Sarsa核心思想

Sarsa是一种在策略(On-Policy)的强化学习算法,与Q-Learning的关键区别在于更新方式。

核心公式:

1
Q(s,a) = Q(s,a) + α[r + γ·Q(s',a') - Q(s,a)]

与Q-Learning的区别:

  • Q-Learning使用maxQ(s’,a’)(下一状态的最大Q值)
  • Sarsa使用Q(s’,a’)(实际采取的下一动作的Q值)

On-Policy特性

Sarsa是”说到做到”的算法:

  • On-Policy(在线学习):学习的动作和实际执行的动作一致
  • 保守型算法:选择远离危险的路线,保命优先
  • 安全性高:适合危险环境中的应用

Q-Learning vs Sarsa对比

特性 Q-Learning Sarsa
策略类型 Off-Policy On-Policy
更新方式 maxQ(s’,a’) Q(s’,a’)
行为特点 勇敢,选择最短路径 保守,选择安全路径
适用场景 安全环境、追求效率 危险环境、安全第一
收敛速度 较快 较慢但更稳定

形象比喻:

  • Q-Learning像勇敢的探险家,总是选择最近的成功道路,不管多危险
  • Sarsa像谨慎的行者,保住小命最重要,拿宝藏是次要的

深度Q网络(DQN)

DQN核心创新

DeepMind团队通过DQN算法让计算机玩电动游戏超越人类水平,其核心创新是将神经网络与Q-Learning相结合。

核心思想:

1
2
传统Q-Learning:维护Q表,状态多时需要大量内存
DQN:使用神经网络近似Q函数,状态空间连续可扩展

神经网络替代Q表:

1
2
输入:状态s
输出:每个动作的Q值 [Q(s,a1), Q(s,a2), ..., Q(s,an)]

DQN两大核心技术

经验回放(Experience Replay)

1
2
3
4
机制:
1. 维护一个记忆库(Replay Buffer)存储经验(s, a, r, s')
2. 训练时从记忆库中随机采样批量经验
3. 打破数据相关性,提高样本利用率

优势:

  • 样本利用率提高
  • 打破时间相关性
  • 平滑数据分布

固定Q目标(Fixed Q-targets)

1
2
3
4
5
机制:
1. 使用两个结构相同但参数不同的神经网络
2. 行为网络(Behavior Network):选择动作,拥有最新参数
3. 目标网络(Target Network):计算目标Q值,使用旧参数
4. 定期同步目标网络参数

优势:

  • 减少训练过程中的震荡
  • 提高学习稳定性
  • 避免自举(Bootstrapping)问题

DQN算法流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class DQNAgent:
def __init__(self, state_dim, action_dim):
# 初始化两个网络
self.behavior_net = NeuralNetwork(state_dim, action_dim)
self.target_net = NeuralNetwork(state_dim, action_dim)
self.replay_buffer = ReplayBuffer(capacity=10000)
self.epsilon = 0.1

def choose_action(self, state):
if random.random() < self.epsilon:
return random.randint(0, action_dim - 1)
else:
with torch.no_grad():
q_values = self.behavior_net(state)
return q_values.argmax().item()

def store_transition(self, s, a, r, s_, done):
self.replay_buffer.push(s, a, r, s_, done)

def learn(self):
# 从记忆库采样
batch = self.replay_buffer.sample(batch_size=32)

# 计算当前Q值(行为网络)
current_q = self.behavior_net(batch.states).gather(1, batch.actions)

# 计算目标Q值(目标网络)
next_q = self.target_net(batch.next_states).max(1)[0].detach()
target_q = batch.rewards + gamma * next_q * (1 - batch.dones)

# 计算损失并更新
loss = F.mse_loss(current_q, target_q.unsqueeze(1))
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()

# 定期同步目标网络
if self.learn_step % target_replace_iter == 0:
self.target_net.load_state_dict(self.behavior_net.state_dict())

强化学习进阶概念

探索与利用平衡

ε-贪婪策略

1
2
3
4
5
def epsilon_greedy(q_values, epsilon):
if random.random() < epsilon:
return random.randint(0, len(q_values) - 1) # 探索
else:
return np.argmax(q_values) # 利用

衰减ε-贪婪

1
epsilon = max(min_epsilon, initial_epsilon * decay_rate ** episode)

奖励塑形(Reward Shaping)

通过修改奖励函数来引导智能体学习:

1
2
3
4
5
6
7
8
9
10
11
12
def shaped_reward(original_reward, state, action, next_state):
# 基础奖励
reward = original_reward

# 附加塑形奖励
if is_closer_to_goal(next_state, state):
reward += 0.1 # 靠近目标奖励

if is_safe_action(action):
reward += 0.05 # 安全动作奖励

return reward

实战应用案例

CartPole平衡问题

CartPole是强化学习的经典入门问题,目标是控制小车平衡倒立摆。

环境特性:

  • 状态空间:4维连续值(位置、速度、角度、角速度)
  • 动作空间:2个离散动作(左移、右移)
  • 奖励:每存活一帧+1
  • 终止条件:角度过大或位置超出范围

DQN解决方案要点:

  1. 神经网络输入4维状态
  2. 输出2个动作的Q值
  3. 使用经验回放和固定Q目标
  4. ε-贪婪策略平衡探索

Atari游戏

DeepMind使用DQN在Atari游戏上取得突破:

技术创新:

  • 原始像素作为输入
  • 卷积神经网络提取特征
  • 帧堆叠处理时序信息
  • 跳帧(Frame Skip)加速训练

学习资源推荐

在线教程

经典论文

  1. Playing Atari with Deep Reinforcement Learning (2013) - DQN开山之作
  2. Human-level control through deep reinforcement learning (2015) - Nature版DQN
  3. Double DQN (2015) - 解决过估计问题
  4. Dueling Network Architectures (2015) - 分离价值流和优势流
  5. Prioritized Experience Replay (2015) - 优先级经验回放

开源项目

总结

强化学习是一个很有趣的方向,从简单的Q-Learning到DQN,再到更高级的算法如DDPG、PPO等,每一步都需要动手实践才能真正理解。建议从简单的CartPole开始,逐步深入。


参考资源: