深度强化学习已经在许多领域取得了瞩目的成就,并且仍是各大领域受热捧的方向之一。本文深入浅出的介绍了如何利用tensorforce框架快速搭建深度强化学习模型。
深度强化学习(deep reinforcement learning, drl)是目前最热门的方向之一,从视频游戏、围棋、蛋白质结构预测到机器人、计算机视觉、推荐系统等领域已经取得了很多令人瞩目的成就且仍在蓬勃发展中。
alphago第一作者davild silver就认为通用人工智能需要强化学习结合深度学习来实现,即agi=dl+rl。
框架
为了便于研究人员快速搭建出强化学习模型,很多机构发布了强化学习基准算法或框架,其中较早的有openai baselines [1]、伯克利的rllab [2],最新的有18年谷歌发布的dopamine [3]、facebook发布的horizon [4]。具体见下表:
本文介绍的是tensorforce并非由这些大机构发布,而是由几个剑桥大学的博士生开发、维护的。
当时选择tensorforcce是因为需要在ros框架下开发,而如上表列出的,它完全支持python2,且包含很多主流的强化学习算法、支持openai gym、deepmind lab等常用于强化学习算法测试的基准环境。
tensorforce是架构在tensorflow上的强化学习api,最早在17年就开源了,并发布了博客[5]介绍其背后的设计思想及基本应用。
这里简单介绍一下tensorforce的设计思想。
框架设计的难点在于如何解耦出其它层面的内容,尽可能将共用的部分抽象出来。拿强化学习来说,智能体与环境不断通过交互试错来学习,如果由我们从头自己编程实现某个rl任务,为了方便智能体与环境很自然地会写在一起。但作为框架却不行,需要将智能体从环境中解耦出来。
tensorforce包括了下面四个层面的概念:
environment runner agent model
agent在训练前可以加载model,训练后保存model,运行时接收state,(预处理后)作为model的输入,返回action。模型会根据算法及配置自动更新。runner将agent和environment之间的交互抽象出来作为函数。environment根据应用场景的不同需要自己写接口,后文会提供一个机器人导航环境的接口案例。如果是学习或者算法测试,可以使用现成的基准环境,tensorforce提供了openai gym、openai universe和deepmind lab的接口。
第一行代码
下面通过使用近端策略优化(proximal policy optimization, ppo)算法训练openai gym中倒立摆来初识tensorforce的简洁和强大。
from tensorforce.agents import ppoagentfrom tensorforce.execution import runnerfrom tensorforce.contrib.openai_gym import openaigym# create an openaigym environment.environment=openaigym('cartpole-v0',visualize=true)network_spec=[dict(type='dense',size=32,activation='relu'),dict(type='dense',size=32,activation='relu')]agent = ppoagent(states=environment.states,actions=environment.actions,network=network_spec,step_optimizer=dict(type='adam',learning_rate=1e-3),saver=dict(directory='./saver/',basename='ppo_model.ckpt',load=false,seconds=600),summarizer=dict(directory='./record/',labels=[losses,entropy],seconds=600),)# create the runnerrunner=runner(agent=agent,environment=environment)# start learningrunner.run(episodes=600, max_episode_timesteps=200)runner.close()
很快,倒立摆能够平衡:
使用tensorboard查看训练过程(左图是loss,右图是entropy):
上面我们只用了30行代码实现了ppo算法训练倒立摆,代码首先定义了环境和网络(两层32个节点的全连接网络,激活函数为relu),然后定义了agent,agent的参数中states, actions, network三个参数是必填的,step_optimizer定义了优化器,saver和summarizer分别保存模型和训练过程。最后通过runner来实现agent和environment的交互,总共跑了600个episodes,每个episode的最大步长是200。
runner解耦出了交互过程,实际上是是下面过程的循环:
# query the agent for its action decisionaction = agent.act(state)# execute the decision and retrieve the current informationobservation, terminal, reward = gazebomaze.execute(action)# pass feedback about performance (and termination) to the agentagent.observe(terminal=terminal, reward=reward)
在上述过程中,agent会储存相关信息来更新模型,比如dqnagent会存储(state, action, reward, next_state)。
视频游戏
tensorforce提供了丰富的observation预处理功能,视频游戏是drl最先取得突破的方向,以flappy bird为例,需要进行四个步骤的预处理:
转化为灰度图,去除不必要的颜色信息;
缩小输入的游戏截屏,resize为80*80;
堆叠连续的四帧,推导出运行信息;
归一化处理,以便于训练。
使用tensorforce可以很方便地进行预处理:
states = dict(shape=(3264, 18723, 3), type='float')states_preprocessing_spec = [dict( type='image_resize', width=80, height=80), dict( type='grayscale'),dict( type='normalize')dict( type='sequence', length=4)]agent = dqnagent( states=states, actions=actions, network=network_spec, states_preprocessing=states_preprocessing_spec)
环境搭建
如果要在具体的应用场景中使用tensorforce就需要根据应用场景手动搭建环境,环境的模板为environment.py [7],其中最重要的函数是execute,该函数接收agent产生的action,并在环境中执行该action,然后返回next_state,reward,terminal。这里我以搭建的gazebo中的机器人导航环境为例,进行介绍。
首先搭建仿真环境如下图:
设计环境的接口及其与agent交互的过程:
仿真开始,init函数打开gazebo并加载对应的导航环境,reset函数初始化机器人,execute函数接收到action后通过ros发送对应的速度命令,gazebo中的机器人接收到速度命令后执行对应的速度,机器人传感器返回相应的信息,计算对应的reward,读取视觉传感器的rgb图像作为next_state,判断是否到达目标点或者碰撞,如果是terminal为true,该episode结束。完整的代码见 [8]。
复杂网络
drl网络和算法是智能体最重要的两部分,一个确定模型结构、一个决定模型更新。上面只介绍了简单的模型,对于有些复杂网络需要层叠的方式来定义,如下如:
该网络的输入为64*48*3的rgb图像,由卷积层提取特征后与2维的速度信息和运动信息共同输入全连接层进行决策。首先定义state:
states=dict(image=dict(shape=(48,64,3),type='float'),#observationprevious_act=dict(shape=(2,),type='float'),#velocityrelative_pos=dict(shape=(2,),type='float')#target)
然后定义action即velocity,这里为机器人的线速度(限制在[0,1])和角速度(限制在[-1,1]):
dict(linear_vel=dict(shape=(),type='float',min_value=0.0,max_value=1.0),angular_vel=dict(shape=(),type='float',min_value=-1.0,max_value=1.0))
然后通过层叠的方式来定义网络结构:
network_spec=[[dict(type='input',names=['image']),dict(type='conv2d',size=32,window=(8,6),stride=4,activation='relu',padding='same'),dict(type='conv2d',size=64,window=(4,3),stride=2,activation='relu',padding='same'),dict(type='pool2d',pooling_type='max',window=2,stride=2,padding='same'),dict(type='conv2d',size=64,window=2,stride=2,activation='relu',padding='same'),dict(type='flatten'),dict(type='output',name='image_output')],[dict(type='input',names=['image_output','previous_act','relative_pos'],aggregation_type='concat'),dict(type='dense',size=512,activation='relu'),dict(type='dense',size=512,activation='relu'),]]
完整代码见[8]
其它
1. agent会有actions_exploration参数来定义exploration,默认值为'none',但这并不代表不探索,以ppo为例,模型在输出的时候不输出直接的确定性动作(只有dpg才会输出确定性动作),而是分布,输出在分布上采样输出,这可以看作是一种exploration。
2. 网络的输出层是根据action自动添加的,在network中定义输入层和隐藏层即可
3. 如果不再需要exploration而只是exploitation,则运行:
agent.act(action,deterministic=true)
此时agent执行greedy策略。而如果模型训练完成,不再训练则:
agent.act(action,independent=true)
此时函数只执行act不执行observe来更新模型
4. ppo算法相比于dqn,不仅性能好,并且对超参数更鲁棒,建议优先选择ppo
科通技术携手伙伴为中寰卫星智能座舱项目提供科技支撑
三相电机控制电路的工作原理、功能特点和接线方法
未来的合成生物学“黑客”:他们用声音窃取DNA合成信息
卡莱特取得多项LED芯片相关专利
高通欲收购以色列Cellwize,目前处于谈判阶段
如何利用TensorForce框架快速搭建深度强化学习模型
离散制造业MOM工业软件的发展难点和趋势
小型功率放大器设计及仿真实验
又多一部骁龙835,魅族Pro7如果真有你会入手吗?
三星正在研发一款新的无线耳塞和一款专注于体育运动的智能手表
量子计算机将能够解决一些今天计算机需要数百万年才能计算的问题
永磁同步电机控制系列的数学模型(4)simulink仿真搭建案例
电力电子器件的换流方式有哪些
乐华MES工位机在实际应用中可能遇到的问题
电子誊写烫腊器电路图
什么是焦耳小偷?LaserSaber的焦耳小偷照明电路
国产降噪耳机哪些值得买?最值得入手的国产降噪耳机推荐
什么是相机标定?视觉机械臂自主抓取全流程
索尼的PS VR,让《头号玩家》中的游戏世界实现不是梦
真正的全球手机 三星Galaxy Ace Duos上市