摘要:在本案例中,我们将展示如何基于A2C算法,训练一个LunarLander小游戏。

本文分享自华为云社区《使用A2C算法控制登月器着陆》,作者:HWCloudAI 。

LunarLander是一款控制类的小游戏,也是强化学习中常用的例子。游戏任务为控制登月器着陆,玩家通过操作登月器的主引擎和副引擎,控制登月器降落。登月器平稳着陆会得到相应的奖励积分,如果精准降落在着陆平台上会有额外的奖励积分;相反地如果登月器坠毁会扣除积分。

A2C全称为Advantage Actor-Critic,在本案例中,我们将展示如何基于A2C算法,训练一个LunarLander小游戏。

整体流程:基于gym创建LunarLander环境->构建A2C算法->训练->推理->可视化效果

A2C算法的基本结构

A2C是openAI在实现baseline过程中提出的,是一种结合了Value-based (比如 Q learning) 和 Policy-based (比如 Policy Gradients) 的强化学习算法。

Actor目的是学习策略函数π(θ)以得到尽量高的回报。 Critic目的是对当前策略的值函数进行估计,来评价。

  • Policy Gradients

Policy Gradient算法的整个过程可以看作先通过策略π(θ)让agent与环境进行互动,计算每一步所能得到的奖励,并以此得到一局游戏的奖励作为累积奖励G,然后通过调整策略π,使得G最大化。所以使用了梯度提升的方法来更新网络参数θ,利用更新后的策略再采集数据,再更新,如此循环,达到优化策略的目的。

  • Actor Critic

agent在于环境互动过程中产生的G值本身是一个随机变量,可以通过Q函数去估计G的期望值,来增加稳定性。即Actor-Critic算法在PG策略的更新过程中使用Q函数来代替了G,同时构建了Critic网络来计算Q函数,此时Actor相关参数的梯度为:

而Critic的损失函数使用Q估计和Q实际值差的平方损失来表示:

  • A2C算法

A2C在AC算法的基础上使用状态价值函数给Q值增加了基线V,使反馈可以为正或者为负,因此Actor的策略梯变为:

同时Critic网络的损失函数使用实际状态价值和估计状态价值的平方损失来表示:

LunarLander-v2游戏环境简介

LunarLander-v2,是基于gym和box2d提供的游戏环境。游戏任务为玩家通过操作登月器的喷气主引擎和副引擎来控制登月器降落。

gym:开源强化学习python库,提供了算法和环境交互的标准API,以及符合该API的标准环境集。

box2d:gym提供的一种环境集合

注意事项

  1. 本案例运行环境为 TensorFlow-1.13.1,且需使用 GPU 运行,请查看《ModelAtrs JupyterLab 硬件规格使用指南》了解切换硬件规格的方法;
  2. 如果您是第一次使用 JupyterLab,请查看《ModelAtrs JupyterLab使用指导》了解使用方法;
  3. 如果您在使用 JupyterLab 过程中碰到报错,请参考《ModelAtrs JupyterLab常见问题解决办法》尝试解决问题。

实验步骤

1. 程序初始化

第1步:安装基础依赖

要确保所有依赖都安装成功后,再执行之后的代码。如果某些模块因为网络原因导致安装失败,直接重试一次即可。

!pip install gym
!conda install swig -y
!pip install box2d-py
!pip install gym[box2d]

第2步:导入相关的库

import os
import gym
import numpy as np
import tensorflow as tf
import pandas as pd

2. 参数设置¶

本案例设置的 游戏最大局数 MAX_EPISODE = 100,保存模型的局数 SAVE_EPISODES = 20,以便快速跑通代码。

你也可以调大 MAX_EPISODE 和 SAVE_EPISODES 的值,如1000和100,可以达到较好的训练效果,训练耗时约20分钟。

MAX_EPISODE = 100 # 游戏最大局数
DISPLAY_REWARD_THRESHOLD = 100 # 开启可视化的reward阈值
SAVE_REWARD_THRESHOLD = 100 # 保存模型的reward阈值
MAX_EP_STEPS = 2000 # 每局最大步长
TEST_EPISODE = 10 # 测试局
RENDER = False # 是否启用可视化(耗时)
GAMMA = 0.9 # TD error中reward衰减系数
RUNNING_REWARD_DECAY=0.95 # running reward 衰减系数
LR_A = 0.001 # Actor网络的学习率
LR_C = 0.01 # Critic网络学习率
NUM_UNITS = 20 # FC层神经元个数
SEED = 1 # 种子数,减小随机性
SAVE_EPISODES = 20 # 保存模型的局数
model_dir = './models' # 模型保存路径

3. 游戏环境创建

def create_env():env = gym.make('LunarLander-v2')# 减少随机性env.seed(SEED)env = env.unwrappednum_features = env.observation_space.shape[0]num_actions = env.action_space.nreturn env, num_features, num_actions

4. Actor-Critic网络构建¶

class Actor:"""Actor网络Parameters----------sess : tensorflow.Session()n_features : int特征维度n_actions : int动作空间大小lr : float学习率大小"""def __init__(self, sess, n_features, n_actions, lr=0.001):self.sess = sess# 状态空间self.s = tf.placeholder(tf.float32, [1, n_features], "state")# 动作空间self.a = tf.placeholder(tf.int32, None, "action")# TD_errorself.td_error = tf.placeholder(tf.float32, None, "td_error")# actor网络为两层全连接层,输出为动作概率with tf.variable_scope('Actor'):l1 = tf.layers.dense(inputs=self.s,units=NUM_UNITS,activation=tf.nn.relu,kernel_initializer=tf.random_normal_initializer(0., .1),bias_initializer=tf.constant_initializer(0.1),name='l1')self.acts_prob = tf.layers.dense(inputs=l1,units=n_actions,activation=tf.nn.softmax,kernel_initializer=tf.random_normal_initializer(0., .1),bias_initializer=tf.constant_initializer(0.1),name='acts_prob')with tf.variable_scope('exp_v'):log_prob = tf.log(self.acts_prob[0, self.a])# 损失函数self.exp_v = tf.reduce_mean(log_prob * self.td_error)with tf.variable_scope('train'):# minimize(-exp_v) = maximize(exp_v)self.train_op = tf.train.AdamOptimizer(lr).minimize(-self.exp_v)def learn(self, s, a, td):s = s[np.newaxis, :]feed_dict = {self.s: s, self.a: a, self.td_error: td}_, exp_v = self.sess.run([self.train_op, self.exp_v], feed_dict)return exp_v# 生成动作def choose_action(self, s):s = s[np.newaxis, :]probs = self.sess.run(self.acts_prob, {self.s: s}) return np.random.choice(np.arange(probs.shape[1]), p=probs.ravel())
class Critic:"""Critic网络Parameters----------sess : tensorflow.Session()n_features : int特征维度lr : float学习率大小"""def __init__(self, sess, n_features, lr=0.01):self.sess = sess# 状态空间self.s = tf.placeholder(tf.float32, [1, n_features], "state")# value值 self.v_ = tf.placeholder(tf.float32, [1, 1], "v_next")# 奖励 self.r = tf.placeholder(tf.float32, None, 'r')# critic网络为两层全连接层,输出为value值with tf.variable_scope('Critic'):l1 = tf.layers.dense(inputs=self.s,# number of hidden unitsunits=NUM_UNITS,activation=tf.nn.relu, kernel_initializer=tf.random_normal_initializer(0., .1), bias_initializer=tf.constant_initializer(0.1), name='l1')self.v = tf.layers.dense(inputs=l1,# output unitsunits=1,activation=None,kernel_initializer=tf.random_normal_initializer(0., .1), bias_initializer=tf.constant_initializer(0.1), name='V')with tf.variable_scope('squared_TD_error'):self.td_error = self.r + GAMMA * self.v_ - self.v# TD_error = (r+gamma*V_next) - V_evalself.loss = tf.square(self.td_error)with tf.variable_scope('train'):self.train_op = tf.train.AdamOptimizer(lr).minimize(self.loss)def learn(self, s, r, s_):s, s_ = s[np.newaxis, :], s_[np.newaxis, :]v_ = self.sess.run(self.v, {self.s: s_})td_error, _ = self.sess.run([self.td_error, self.train_op],{self.s: s, self.v_: v_, self.r: r})return td_error

5. 创建训练函数

def model_train():env, num_features, num_actions = create_env()render = RENDERsess = tf.Session()actor = Actor(sess, n_features=num_features, n_actions=num_actions, lr=LR_A)critic = Critic(sess, n_features=num_features, lr=LR_C)sess.run(tf.global_variables_initializer())saver = tf.train.Saver()for i_episode in range(MAX_EPISODE+1):cur_state = env.reset()cur_step = 0track_r = []while True:# notebook暂不支持该游戏的可视化# if RENDER:# env.render()action = actor.choose_action(cur_state)next_state, reward, done, info = env.step(action)track_r.append(reward)# gradient = grad[reward + gamma * V(next_state) - V(cur_state)]td_error = critic.learn(cur_state, reward,next_state)# true_gradient = grad[logPi(cur_state,action) * td_error]actor.learn(cur_state, action, td_error) cur_state = next_statecur_step += 1if done or cur_step >= MAX_EP_STEPS:ep_rs_sum = sum(track_r)if 'running_reward' not in locals():running_reward = ep_rs_sumelse:running_reward = running_reward * RUNNING_REWARD_DECAY + ep_rs_sum * (1-RUNNING_REWARD_DECAY)# 判断是否达到可视化阈值# if running_reward > DISPLAY_REWARD_THRESHOLD:#     render = Trueprint("episode:", i_episode, "  reward:", int(running_reward), "  steps:", cur_step)breakif i_episode > 0 and i_episode % SAVE_EPISODES == 0:if not os.path.exists(model_dir):os.mkdir(model_dir)ckpt_path = os.path.join(model_dir, '{}_model.ckpt'.format(i_episode))saver.save(sess, ckpt_path)

6. 开始训练

训练一个episode大约需1.2秒

print('MAX_EPISODE:', MAX_EPISODE)
model_train()
# reset graph
tf.reset_default_graph()

7.使用模型推理

由于本游戏内核可视化依赖于OpenGL,需要桌面化操作系统的窗口显示,但当前环境暂不支持弹窗,因此无法可视化,您可将代码下载到本地,取消 env.render() 这行代码的注释,查看可视化效果。

def model_test():env, num_features, num_actions = create_env()sess = tf.Session()actor = Actor(sess, n_features=num_features, n_actions=num_actions, lr=LR_A)sess.run(tf.global_variables_initializer())saver = tf.train.Saver()saver.restore(sess, tf.train.latest_checkpoint(model_dir))for i_episode in range(TEST_EPISODE):cur_state = env.reset()cur_step = 0track_r = []while True:# 可视化# env.render()action = actor.choose_action(cur_state)next_state, reward, done, info = env.step(action)track_r.append(reward)cur_state = next_statecur_step += 1if done or cur_step >= MAX_EP_STEPS:ep_rs_sum = sum(track_r)print("episode:", i_episode, "  reward:", int(ep_rs_sum), "  steps:", cur_step)break
model_test()
episode: 0   reward: -31   steps: 196
episode: 1   reward: -99   steps: 308
episode: 2   reward: -273   steps: 533
episode: 3   reward: -5   steps: 232
episode: 4   reward: -178   steps: 353
episode: 5   reward: -174   steps: 222
episode: 6   reward: -309   steps: 377
episode: 7   reward: 24   steps: 293
episode: 8   reward: -121   steps: 423
episode: 9   reward: -194   steps: 286

8.可视化效果

下面的视频为训练1000 episode模型的推理效果,该视频演示了在三个不同的地形情况下,登月器都可以安全着陆

https://modelarts-labs-bj4-v2.obs.cn-north-4.myhuaweicloud.com/course/modelarts/reinforcement_learning/a2c_lunarlander/A2C_lunarlander.mp4

点击关注,第一时间了解华为云新鲜技术~

动手实践丨基于ModelAtrs使用A2C算法制作登月器着陆小游戏相关推荐

  1. C++毕业设计——基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现(毕业论文+程序源码)——五子棋游戏

    基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C+++EasyX+剪枝算法的能人机对弈的五子棋游戏设计与实现,文章末尾附有本毕业设 ...

  2. 基于stm32、0.96寸OLED实现的俄罗斯方块小游戏(详细源码注释)

    概述:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的俄罗斯方块小游戏.项目源码地址:点击下载. 硬件要求: 普通摇杆,两个电位器和一个开关组成,左右摇动控制一个电 ...

  3. 基于cocoCreator版本2.4.5整理一款2D小游戏快速开发的游戏框架

    前言:基于cocoCreator版本2.4.5整理一款2D小游戏快速开发的游戏框架. 一.cocosCreator的UI框架. 中心思想, 将所有的UI窗体分为3类管理(1级窗体, 2级窗体, 3级窗 ...

  4. 基于Arduino Uno开发板制作音乐播放器

    基于Arduino Uno开发板制作音乐播放器 本文将基于Arduino开发板实现一个音乐播放器. 利用Arduino Uno读取sd卡模块中内存卡的音乐,传输信号到扬声器进行播放. 一.项目软硬件简 ...

  5. 推荐系统实践(五)----基于图的推荐算法

      基于图的模型(graph−basedmodelgraph-based modelgraph−basedmodel)是推荐系统中的重要内容.在研究基于图的模型之前,首先需要将用户行为数据表示成图的形 ...

  6. 基于声网 Flat 实现“成语解谜”的 Web 小游戏

    前言 本文作者赵杭天.他参加了"2022 RTE(Real-time Engagement,实时互动) 编程挑战赛"--"赛道二 场景化白板插件应用开发" , ...

  7. 借助实时数据推送快速制作在线对战五子棋小游戏丨实战

    1 项目概述 游戏开发,尤其是微信小游戏开发,是最近几年比较热门的话题. 本次「云开发」公开课,将通过实战「在线对战五子棋」,一步步带领大家,在不借助后端的情况下,利用「小程序 ✖ 云开发」,独立完成 ...

  8. 基于Ubuntu+Bochs模拟器实现的操作系统图形化的小游戏(2048、flappybird、)

    目录 操作系统课程设计文档 1 项目设计与功能说明文档 1 一. 项目描述 2 项目目的 2 开发环境 2 项目完成指标 3 一. 功能说明 3 图形化界面 3 开机动画 4 图片显示 4 进程管理 ...

  9. 女神节你也能自己动手制作一个漂亮的微信小游戏

    嗨!大家好,我是小蚂蚁. 这是我之前制作的一个非常漂亮的微信小游戏,你可以给予它进行改编,然后自己制作一个小游戏送给你想送的人. 我发现这篇文章每年至少可以发四次,情人节一次,女神节一次,520一次, ...

最新文章

  1. 自动检索、修复Python代码bug,微软推出DeepDebug
  2. 【caffe解读】 caffe从数学公式到代码实现4-认识caffe自带的7大loss
  3. bzoj 3572 [Hnoi2014]世界树——虚树
  4. ONOS系统架构演进,实现高可用性解决方案
  5. 史上最简单的隐马尔可夫模型讲解
  6. oracle optimizermode,Oracle OPTIMIZER_MODE参数
  7. 【C++】双边滤波器(bilateral filter)
  8. wampserver修改默认根目录
  9. MTK手机平台充电原理
  10. ubuntu虚拟显示器远程连接桌面方案
  11. 远程桌面连接计算机下拉记录清除,Win7怎么删除远程桌面连接记录
  12. mybatis 大小写 字符串_Mybatis查询时,区分大小写操作
  13. Kaplan-Meier plot cutoff选择
  14. OGG FOR BIGDATA 安装(修正)
  15. 【LeetCode系列】数的奥秘之幂数与完全平方数
  16. 玩转华为数据中心交换机系列 | 配置STP功能示例
  17. 《Learn python3 the hard way》ex42到ex43总结
  18. 流星汇聚:跨境电商几大主流电商平台势均力敌,卖家如何选择?
  19. 【原创】互联网行业数据分析通识(中)
  20. 不锈钢无缝钢管重量计算公式

热门文章

  1. 线程池(java.util.concurrent.ThreadPoolExecutor)的使用
  2. Android 操作权限大全(已归纳分类)
  3. 休闲游戏,益智游戏,游戏美术开发介绍
  4. 20个设计网站 素材
  5. mysql主从有关参数_MySQL 主从复制相关参数
  6. 机器学习之LR算法理论和实战(实战篇)
  7. M1 安装 pyaudio
  8. AD中off grid pin问题解决
  9. 信安周报-第02周:SQL基础
  10. 带你全面掌握高级知识点!毕业一年萌新的Android大厂面经,论程序员成长的正确姿势