DQN 代码实现:用 Tensorflow 2.0 征服强化学习
2024-01-04 19:51:14
在 DQN 算法的广袤世界中漫步:代码实现
简介
强化学习是一种计算机科学领域,它通过奖励和惩罚来训练智能体,让其在复杂环境中采取最佳行动。深度 Q 网络 (DQN) 算法是强化学习中的一颗璀璨明珠,它巧妙地将深度学习的神经网络与马尔可夫决策过程的理论基础相结合,赋予智能体应对复杂环境的能力。
DQN 算法的精髓
DQN 算法的核心是一个深度神经网络,它可以估计给定状态下采取每个动作的价值。通过反复训练,网络可以学习从长远来看哪种动作将带来最大的奖励。为了提高 DQN 的性能,采用了两种关键技术:
- 经验回放: 存储智能体经历过的状态和动作,允许智能体从过去的经验中学习。
- 固定目标值: 冻结目标网络的参数,防止网络在训练过程中相互竞争而产生不稳定性。
代码实现之旅
为了让 DQN 算法的魅力不再只停留在理论层面,我们决定亲自动手实现它。使用功能强大的 TensorFlow 2.0 框架,我们将踏上这段激动人心的编程之旅。
环境设置
首先,让我们定义我们希望智能体学习的环境。我们将使用经典的 CartPole 环境,这是一个平衡一根杆子的任务。
import gym
env = gym.make('CartPole-v1')
构建神经网络
现在,让我们构建神经网络,它将成为我们 DQN 智能体的核心。
import tensorflow as tf
from tensorflow.keras import layers, Model
def create_network():
inputs = layers.Input(shape=(env.observation_space.shape[0],))
x = layers.Dense(128, activation='relu')(inputs)
x = layers.Dense(env.action_space.n)(x)
model = Model(inputs=inputs, outputs=x)
return model
经验回放:保存历史
经验回放是一种关键技术,它允许智能体从过去的经验中学习。我们创建一个类来实现它:
class ReplayBuffer:
def __init__(self, max_size):
self.max_size = max_size
self.buffer = []
def add(self, experience):
self.buffer.append(experience)
if len(self.buffer) > self.max_size:
self.buffer.pop(0)
def sample(self, batch_size):
return np.random.choice(self.buffer, batch_size)
训练步骤:指引智能体
训练步骤是 DQN 算法的核心,它更新神经网络的参数。
def train_step(model, target_model, optimizer, replay_buffer, batch_size):
experiences = replay_buffer.sample(batch_size)
states, actions, rewards, next_states, dones = zip(*experiences)
target_values = target_model(next_states, training=False)
target_values = np.where(dones, rewards, rewards + 0.95 * np.max(target_values, axis=1))
with tf.GradientTape() as tape:
q_values = model(states, training=True)
q_action = tf.gather(q_values, tf.expand_dims(actions, -1), batch_dims=1)
loss = tf.keras.losses.mean_squared_error(target_values, q_action)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
主训练循环:不断精进
最后,我们定义主训练循环,这是智能体学习和提高技能的地方。
num_episodes = 500
max_steps_per_episode = 200
batch_size = 32
learning_rate = 0.001
# 创建网络和经验回放
model = create_network()
target_model = create_network()
target_model.set_weights(model.get_weights())
replay_buffer = ReplayBuffer(10000)
# 创建优化器
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
# 开始训练
for episode in range(num_episodes):
state = env.reset()
for step in range(max_steps_per_episode):
# 采取动作
action = np.argmax(model(np.expand_dims(state, 0), training=False))
# 执行动作
next_state, reward, done, _ = env.step(action)
# 存储经验
replay_buffer.add((state, action, reward, next_state, done))
# 训练模型
if len(replay_buffer) >= batch_size:
train_step(model, target_model, optimizer, replay_buffer, batch_size)
# 更新目标网络
if step % 100 == 0:
target_model.set_weights(model.get_weights())
# 判断是否结束
if done:
break
# 更新状态
state = next_state
应用训练好的模型:展现智能
训练完成后,我们可以使用训练好的 DQN 模型来控制智能体,让他在 CartPole 环境中大显身手。
state = env.reset()
while True:
# 采取动作
action = np.argmax(model(np.expand_dims(state, 0), training=False))
# 执行动作
next_state, reward, done, _ = env.step(action)
# 更新状态
state = next_state
# 判断是否结束
if done:
break
# 关闭环境
env.close()
结论:赋能智能体
通过这篇代码实现,我们深入了解了 DQN 算法的工作原理。它不仅可以让我们对强化学习有更深刻的理解,还可以为我们解决更复杂的问题提供一个强大的工具。随着 AI 技术的不断发展,DQN 算法将继续在各个领域发挥越来越重要的作用,赋能智能体应对现实世界的挑战。
常见问题解答
-
DQN 和其他强化学习算法有什么区别?
DQN 是一种基于价值的强化学习算法,它使用深度神经网络来估计状态的动作值。与其他算法不同,它特别适合于处理高维、连续的状态空间。 -
经验回放如何帮助 DQN?
经验回放允许智能体从过去的经验中学习,从而避免过拟合和提高训练稳定性。它存储了状态、动作和奖励的历史记录,允许算法在不同经验上进行采样和训练。 -
固定目标值如何影响 DQN?
固定目标值通过冻结目标网络的参数,防止训练不稳定。在标准 Q 学习中,目标网络不断变化,这可能会导致不稳定性和难以收敛。固定目标值技术通过创建稳定且一致的目标来缓解这个问题。 -
我可以使用 DQN 解决哪些类型的任务?
DQN 可以用于解决各种强化学习任务,包括视频游戏、机器人控制和金融交易。它特别适合于处理复杂、高维的状态空间,其中难以手动设计特征。 -
如何改善 DQN 的性能?
除了使用经验回放和固定目标值之外,还有其他技术可以改善 DQN 的性能,例如双 Q 网络、优先经验回放和目标网络更新延迟。通过调整这些参数和技术,可以进一步提高算法在复杂环境中的表现。