本文来自社区投稿与征集,来源:GDG Shanghai,作者:江岸青,早稻田大学博士生,机器学习领域研究人员讲师。
众所周知, 强化学习作为机器学习的一个重要的领域,在机器学习的发展史上具有举足轻重的地位。近年来,工程师与科学家将强化学习模型应用在了在游戏、自动驾驶、机器人以及优化领域等领域并取得了非常卓越的成果。
首先我们简单介绍一下强化学习,强化学习是一种利用环境反馈的学习机制(类似于人类在错误中总结,在失败中成长),类似的机制还有诸如博弈论,控制论,遗传算法等。
图 1 一些强化学习的应用实例
TF-AGENTS
今天我们在这里给大家介绍一款强化学习框架: TF-AGENTS (https://github.com/tensorflow/agents),作为一款优秀的强化学习框架 TF-AGENTS 可以让强化学习的工程师和科学家在设计、实现以及测试新的强化学习算法时更加的方便与快捷。同时,由于对代码结构的精心设计,在实际使用它时也有利于提高使用者的产品迭代速度。不仅仅如此,TF-AGENTS 还提供了基础的测试与基准测试部分帮助大家快速上手与构建“第一个强化学习”程序。
TF-AGENTS的工作模块
网络 (Network),在代理的网络中,用户可以使用 Keras 高层 API 快速的构建神经网络代替诸如 DQN 默认的 MLP 等以适应自己不同的环境需求。
图 2 TF-AGENTS 的工作流程
TF-AGENTS 的安装
目前 TF-AGENTS 仍然在高速迭代中,所以官方提供了 ’nightly’ 与 ’stable’ 两个版本大家使用与体验。其中 Stable 版本支持较为稳定的特性(截止到稿件发表日支持的版本为 0.3.0)。而 nightly 版本则会提供相对来说更加新颖的特性。
Stable 版本的安装方式:
pip install --user tf-agents
pip install --user tensorflow==2.0.0
# Or For TensorFlow 1.x
pip install --user tensorflow==1.15.0
# To get the matching examples and colabs
git clone https://github.com/tensorflow/agents.git
cd agents
git checkout v0.3.0
Nightly 版本的安装方式:
# Installing with the `--upgrade` flag ensures you'll get the latest version.
pip install --user --upgrade tf-agents-nightly # depends on tf-nightly
# `--force-reinstall helps guarantee the right version.
pip install --user --force-reinstall tf-nightly
pip install --user --force-reinstall tfp-nightly
初探 DQN
这里我们以 Gym 著名的平衡杆小游戏 ('CartPole-v0') 为例,带领大家从零构建一个简单的 DQN 小游戏。在这个小游戏中我们需要让我们的智能体控制黑色的小方块左右移动防止上面的木杆倒下,对于游戏成功与否的评价条件就是木杆站立的时间,时间越长则我们认为我们的智能体就是越成功的。
图 3 Gym 环境中的 CartPole-V3
1.导入环境:
在强化学习中,环境代表的是我们想要解决的任务或者问题,具体的可以为类似于平衡木杆的控制问题,也可以是类似参数搜索的优化问题,也可以是扑克或围棋所解决的博弈问题。要在 TF-AGENTS 中使用环境可以利用 tf_agents.environments 创建标准环境,并将 Gym,Atari,DM control 等环境加载入环境中。
加载 Gym 环境
env_name = 'CartPole-v0'
env = suite_gym.load(env_name)
将 Gym 环境导入 tf_agents.environments
agents_env = tf_py_environment.TFPyEnvironment(env)
2. 建立代理
在这里我们选择使用 DQN 作为我们的智能体代理,DQN 代理可用于任何具有离散动作空间的环境。DQN 的核心是一个 Q-Network,它是一个用以代替 Q-Table 的神经网络模型。在从环境中观测到回报后,可以用以学习或预测智能体所作操作的 Q-value(收益)。我们可以利用 tf_agents.networks.q_network 创建一个 Q-Network,并且定义网络的输入输出的形状与隐藏层神经元个数。
fc_layer_params = (100,)
q_net = q_network.QNetwork(
train_env.observation_spec(),
train_env.action_spec(),
fc_layer_params=fc_layer_params)
在创建完 Q-Network 后我们需要利用建立好的 Q-Network 生成一个完整的 DQN 代理,在这个代理里我们可以对环境的步进 (time_step_spec) 以及行动空间 (action_spec) 进行定义。同时对网络所使用的优化器,损失函数与步进计数器也都可以在上述的 DQN 代理中进行定义。在定义完成 DqnAgent 后不要忘记初始化这个代理。
optimizer = tf.compat.v1.train.AdamOptimizer(learning_rate=learning_rate)
train_step_counter = tf.Variable(0)
agent = dqn_agent.DqnAgent(
train_env.time_step_spec(),
train_env.action_spec(),
q_network=q_net,
optimizer=optimizer,
td_errors_loss_fn=common.element_wise_squared_loss,
train_step_counter=train_step_counter)
agent.initialize()
3. 执行策略 (policy)
Actor policy
我们以贪心策略为例(Greedy Policy),即每次都严格按照模型认为的最优动作(action)去执行动作。
greedy_policy = greedy_tf_policy.GreedyPolicy(train_env.time_step_spec(),
train_env.action_spec())
Info 信息 - 辅助数据,如操作的日志概率
4. 评价指标
在强化学习中,用于评估策略的最常用度量是平均回报率。回报是在一个环境中策略执行时获得的奖励的总和。当然是在实际的模型构建中回报函数的设计是非常重要的。首先我们需要将任务分解,明晰在不同状态下代理所收到的回报的正负值,同时也许规避贪婪、胆怯、鲁莽等一些常见的回报问题。
这里我们用一个简单的例子给大家展示一下如何构建一个回报函数:
def compute_avg_return(environment, policy, num_episodes=10):
total_return = 0.0
for _ in range(num_episodes):
time_step = environment.reset()
episode_return = 0.0
while not time_step.is_last():
action_step = policy.action(time_step)
time_step = environment.step(action_step.action)
episode_return += time_step.reward
total_return += episode_return
avg_return = total_return / num_episodes
return avg_return.numpy()[0]
在这里我们构建了一个简单的回报函数这个函数计算的是每次策略执行动作后所获得的平均回报。如果需要自定义回报函数的话则需要参考 (https://github.com/tensorflow/agents/tree/master/tf_agents/metrics) 网址中的标准回报函数模板进行自定义回报函数。
5. 回放缓存与数据收集
重播缓冲区跟踪从环境中收集的数据。这里使用了 tf_agents.replay_buffers.tf_uniform_replay_buffer.tfuniformormreplaybuffer,因为它是最常见的回放方式。回放数据可以帮助模型更加有效的利用执行出的一些数据。在有一些应用中,模拟环境往往会比较缓慢,这时候利用多个环境共同执行并放入同样的回放池中可以一定程度上加快强化学习的学习时间。
eplay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
data_spec=agent.collect_data_spec,
batch_size=train_env.batch_size,
max_length=replay_buffer_max_length)
在这里我们定义了一个 TFUniformReplayBuffer,他的输入参数由 data_spec,batch_size 与 max_length。
在定义完回放缓冲后我们需要定义一个数据收集的方式帮助回放缓冲记录数据:
def collect_step(environment, policy, buffer):
time_step = environment.current_time_step()
action_step = policy.action(time_step)
next_time_step = environment.step(action_step.action)
traj = trajectory.from_transition(time_step, action_step, next_time_step)
buffer.add_batch(traj)
def collect_data(env, policy, buffer, steps):
for _ in range(steps):
collect_step(env, policy, buffer)
这里我们定义了两个函数分别为记录单步数据与记录整体数据的 collect_step 与 collect_data 函数。在单步数据中我们可以记录一些我们需要利用到的数据例如步进 (step)、动作 (action)、轨迹 (trajectory) 等等。
同时代理需要访问重播缓冲区。这是通过创建 iterable tf.data.Dataset 管道提供的,该管道将向代理提供数据。重播缓冲区的每一行只存储一个观察步骤。但是,由于 DQN 代理需要当前和下一个观测值来计算损失,因此数据集管道将为批处理中的每个项采样两个相邻的行 (num_steps=2)。
dataset = replay_buffer.as_dataset(
num_parallel_calls=3,
sample_batch_size=batch_size,
num_steps=2).prefetch(3)
6. 训练代理
接下来就是训练的整体步骤,在执行每一步的时候都通过 collect data 将取得的结果进行收集,同时利用收集到的数据进行训练 DQN 代理的网络。同样在训练过程监控上我们可以简单的打印出或者记录下平均回报,损失函数等有助于帮助判断训练过程与进展的数据。
# (Optional) Optimize by wrapping some of the code in a graph using TF function.
agent.train = common.function(agent.train)
# Reset the train step
agent.train_step_counter.assign(0)
# Evaluate the agent's policy once before training.
avg_return = compute_avg_return(eval_env, agent.policy, num_eval_episodes)
returns = [avg_return]
for _ in range(num_iterations):
# Collect a few steps using collect_policy and save to the replay buffer.
for _ in range(collect_steps_per_iteration):
collect_step(train_env, agent.collect_policy, replay_buffer)
# Sample a batch of data from the buffer and update the agent's network.
experience, unused_info = next(iterator)
train_loss = agent.train(experience).loss
step = agent.train_step_counter.numpy()
if step % log_interval == 0:
print('step = {0}: loss = {1}'.format(step, train_loss))
if step % eval_interval == 0:
avg_return = compute_avg_return(eval_env, agent.policy, num_eval_episodes)
print('step = {0}: Average Return = {1}'.format(step, avg_return))
returns.append(avg_return)
至此我们已经完成了一个从零构建强化学习 DQN 的一个过程,有兴趣自己实现的小伙伴可以移步 codelab 或者是官方 github 仓库进行尝试。
codelab
https://colab.research.google.com/github/tensorflow/agents/blob/master/docs/tutorials/1_dqn_tutorial.ipynb
github 仓库
https://github.com/tensorflow/agents
了解更多请点击 “阅读原文” 访问官网教程。