RLLAB 中 TRPO 算法

Neil Zhu,简书ID Not_GOD,University AI 创始人 & Chief Scientist,致力于推进世界人工智能化进程。制定并实施 UAI 中长期增长战略和目标,带领团队快速成长为人工智能领域最专业的力量。
作为行业领导者,他和UAI一起在2014年创建了TASA(中国最早的人工智能社团), DL Center(深度学习知识中心全球价值网络),AI growth(行业智库培训)等,为中国的人工智能人才建设输送了大量的血液和养分。此外,他还参与或者举办过各类国际性的人工智能峰会和活动,产生了巨大的影响力,书写了60万字的人工智能精品技术内容,生产翻译了全球第一本深度学习入门书《神经网络与深度学习》,生产的内容被大量的专业垂直公众号和媒体转载与连载。曾经受邀为国内顶尖大学制定人工智能学习规划和教授人工智能前沿课程,均受学生和老师好评。

执行实验

我们对不同的实验模块使用面向对象抽象。进行实验,可以为环境、算法等等构造对应的对象,然后调用合适的训练方法。简单示例如examples/trpo_cartpole.py。代码如下:

from rllab.algos.trpo import TRPO
from rllab.baselines.linear_feature_baseline import LinearFeatureBaseline
from rllab.envs.box2d.cartpole_env import CartpoleEnv
from rllab.envs.normalized_env import normalize
from rllab.policies.gaussian_mlp_policy import GaussianMLPPolicy

env = normalize(CartpoleEnv())

policy = GaussianMLPPolicy(
    env_spec=env.spec,
    # The neural network policy should have two hidden layers, each with 32 hidden units.
    hidden_sizes=(32, 32)
)

baseline = LinearFeatureBaseline(env_spec=env.spec)

algo = TRPO(
    env=env,
    policy=policy,
    baseline=baseline,
    batch_size=4000,
    whole_paths=True,
    max_path_length=100,
    n_itr=40,
    discount=0.99,
    step_size=0.01,
)
algo.train()

执行第一次需要初始化 Theano 并且编译计算图,可能需要登上几分钟。后续执行会非常快,因为编译已经被缓存了。你可以看到下面的后续信息:

using seed 1
instantiating rllab.envs.box2d.cartpole_env.CartpoleEnv
instantiating rllab.policy.mean_std_nn_policy.MeanStdNNPolicy
using argument hidden_sizes with value [32, 32]
instantiating rllab.baseline.linear_feature_baseline.LinearFeatureBaseline
instantiating rllab.algo.trpo.TRPO
using argument batch_size with value 4000
using argument whole_paths with value True
using argument n_itr with value 40
using argument step_size with value 0.01
using argument discount with value 0.99
using argument max_path_length with value 100
using seed 0
0%                          100%
[##############################] | ETA: 00:00:00
Total time elapsed: 00:00:02
2016-02-14 14:30:56.631891 PST | [trpo_cartpole] itr #0 | fitting baseline...
2016-02-14 14:30:56.677086 PST | [trpo_cartpole] itr #0 | fitted
2016-02-14 14:30:56.682712 PST | [trpo_cartpole] itr #0 | optimizing policy
2016-02-14 14:30:56.686587 PST | [trpo_cartpole] itr #0 | computing loss before
2016-02-14 14:30:56.698566 PST | [trpo_cartpole] itr #0 | performing update
2016-02-14 14:30:56.698676 PST | [trpo_cartpole] itr #0 | computing descent direction
2016-02-14 14:31:26.241657 PST | [trpo_cartpole] itr #0 | descent direction computed
2016-02-14 14:31:26.241828 PST | [trpo_cartpole] itr #0 | performing backtracking
2016-02-14 14:31:29.906126 PST | [trpo_cartpole] itr #0 | backtracking finished
2016-02-14 14:31:29.906335 PST | [trpo_cartpole] itr #0 | computing loss after
2016-02-14 14:31:29.912287 PST | [trpo_cartpole] itr #0 | optimization finished
2016-02-14 14:31:29.912483 PST | [trpo_cartpole] itr #0 | saving snapshot...
2016-02-14 14:31:29.914311 PST | [trpo_cartpole] itr #0 | saved
2016-02-14 14:31:29.915302 PST | -----------------------  -------------
2016-02-14 14:31:29.915365 PST | Iteration                   0
2016-02-14 14:31:29.915410 PST | Entropy                     1.41894
2016-02-14 14:31:29.915452 PST | Perplexity                  4.13273
2016-02-14 14:31:29.915492 PST | AverageReturn              68.3242
2016-02-14 14:31:29.915533 PST | StdReturn                  42.6061
2016-02-14 14:31:29.915573 PST | MaxReturn                 369.864
2016-02-14 14:31:29.915612 PST | MinReturn                  19.9874
2016-02-14 14:31:29.915651 PST | AverageDiscountedReturn    65.5314
2016-02-14 14:31:29.915691 PST | NumTrajs                 1278
2016-02-14 14:31:29.915730 PST | ExplainedVariance           0
2016-02-14 14:31:29.915768 PST | AveragePolicyStd            1
2016-02-14 14:31:29.921911 PST | BacktrackItr                2
2016-02-14 14:31:29.922008 PST | MeanKL                      0.00305741
2016-02-14 14:31:29.922054 PST | MaxKL                       0.0360272
2016-02-14 14:31:29.922096 PST | LossBefore                 -0.0292939
2016-02-14 14:31:29.922146 PST | LossAfter                  -0.0510883
2016-02-14 14:31:29.922186 PST | -----------------------  -------------

桩模式实验

rllab 同样提供一种“桩”模式来执行实验,这样能够支持更多的配置,例如记录日志和并行化。简单的脚本可在 examples/trpo_cartpole_stub.py 中看到。内容如下:

from rllab.algos.trpo import TRPO
from rllab.baselines.linear_feature_baseline import LinearFeatureBaseline
from rllab.envs.box2d.cartpole_env import CartpoleEnv
from rllab.envs.normalized_env import normalize
from rllab.misc.instrument import stub, run_experiment_lite
from rllab.policies.gaussian_mlp_policy import GaussianMLPPolicy

stub(globals())

env = normalize(CartpoleEnv())

policy = GaussianMLPPolicy(
    env_spec=env.spec,
    # The neural network policy should have two hidden layers, each with 32 hidden units.
    hidden_sizes=(32, 32)
)

baseline = LinearFeatureBaseline(env_spec=env.spec)

algo = TRPO(
    env=env,
    policy=policy,
    baseline=baseline,
    batch_size=4000,
    whole_paths=True,
    max_path_length=100,
    n_itr=40,
    discount=0.99,
    step_size=0.01,
)

run_experiment_lite(
    algo.train(),
    # Number of parallel workers for sampling
    n_parallel=1,
    # Only keep the snapshot parameters for the last iteration
    snapshot_mode="last",
    # Specifies the seed for the experiment. If this is not provided, a random seed
    # will be used
    seed=1,
    # plot=True,
)

第一个需要注意的差异是代码的所有 import 语句后的这一行:stub(globals()),这个可以将所有已经导入的类的构造器用桩式方法替代。在这个调用后,类构造器如 TRPO() 将会返回一个序列化的桩对象,所有方法 invocation 和 属性获取方法同样会变成序列化的桩式调用和桩式属性。接着,run_experiment_lite 调用序列化最终的桩式方法调用,并启动一个脚本实际运行试验。

按照这样的方式启动试验的好处是,我们将试验参数的配置和试验的实际执行分割开来。run_experiment_lite 支持多种执行方式,本地式,在一个 docker 容器本地式,或者在 ec2 远程。按照这样的抽象,不同超参数的多个试验可以被快速构造并在多个 ec2 的机器上同时执行。
另一个微妙的地方是我们使用 Theano 来实现算法,这对混合 GPU 及 CPU 使用支持较弱。当主进程对批量优化使用 GPU 而多个 worker 进行想要使用 GPU 产生轨迹 rollout 的时候非常麻烦。所以分割实验让 worker 进程可以合适地进行 CPU 下的 Theano 的初始化。

run_experiment_lite 的另外参数:

  • exp_name:如果该参数设置了,实验数据会被存放在 data/local/{exp_name} 中。默认来说,该文件夹名被设置为 experiment_{timestamp}
  • exp_prefix:如果该参数设置了,并且 exp_name 没有指定,实验文件夹名将会被设置为 {exp_prefix}_{timestamp}

实现新的环境

本节我们会介绍如何通过框架实现一个点机器人环境。

每个环境必须实现定义在文件 rllab/envs/base.py 中的方法、属性:

class Env(object):
    def step(self, action):
        """
        Run one timestep of the environment's dynamics. When end of episode
        is reached, reset() should be called to reset the environment's internal state. 执行环境转移动态的一个时间步,当回合的结尾到达,reset() 必须调用重置环境内部状态
        Input
        -----
        action : an action provided by the environment
        Outputs
        -------
        (observation, reward, done, info)
        observation : agent's observation of the current environment
        reward [Float] : amount of reward due to the previous action
        done : a boolean, indicating whether the episode has ended
        info : a dictionary containing other diagnostic information from the previous action
        """
        raise NotImplementedError

    def reset(self):
        """
        Resets the state of the environment, returning an initial observation. 重置环境状态,返回初始观察状态
        Outputs
        -------
        observation : the initial observation of the space. (Initial reward is assumed to be 0.) 初始状态,初始回报为 0
        """
        raise NotImplementedError

    @property
    def action_space(self):
        """
        Returns a Space object 返回一个行动空间对象
        """
        raise NotImplementedError

    @property
    def observation_space(self):
        """
        Returns a Space object 返回一个状态空间对象
        """
        raise NotImplementedError

我们会实现一个简单的 2D 状态和 2D 行动的环境。其目标是控制点机器人在 2D 中移动到源点。我们接受在 2D 平面 (x,y)∈ℝ2 点机器人的位置。行动是他的速度 (x˙,y˙)∈ℝ2,满足 |x˙|≤0.1 和 |y˙|≤0.1。我们通过定义奖励为负的到原点的距离鼓来励机器人往源点移动。r(x,y)=−sqrt(x2+y2)。

我们现在来创建环境的文件,假设被放在 example/point_env.py 中。首先,声明一个继承自基环境的类,加入一些 import 内容:

from rllab.envs.base import Env
from rllab.envs.base import Step
from rllab.spaces import Box
import numpy as np


class PointEnv(Env):

    # ...

对每个环境,我们需要指定合法状态集合和合法行动集合。这个是通过下面的属性方法实现:

class PointEnv(Env):

    # ...

    @property
    def observation_space(self):
        return Box(low=-np.inf, high=np.inf, shape=(2,))

    @property
    def action_space(self):
        return Box(low=-0.1, high=0.1, shape=(2,))

现在已经做到了!然后通过下面给诊断脚本来模拟环境:

python scripts/sim_env.py examples.point_env --mode random

随机行动模拟下,从均匀分布中采样。

也可以使用一个神经网络策略来解决这个问题,当然是远远胜任了。可以创建下面的代码的脚本:

from rllab.algos.trpo import TRPO
from rllab.baselines.linear_feature_baseline import LinearFeatureBaseline
from examples.point_env import PointEnv
from rllab.envs.normalized_env import normalize
from rllab.policies.gaussian_mlp_policy import GaussianMLPPolicy

env = normalize(PointEnv())
policy = GaussianMLPPolicy(
    env_spec=env.spec,
)
baseline = LinearFeatureBaseline(env_spec=env.spec)
algo = TRPO(
    env=env,
    policy=policy,
    baseline=baseline,
)
algo.train()

假设这个文件是 examples/trpo_point.py。你可以运行下面的脚本:

python examples/trpo_point.py
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容

  • 本系列文章面向深度学习研发者,希望通过Image Caption Generation,一个有意思的具体任务,深入...
    imGeek阅读 1,795评论 0 8
  • 一道拯救人生的菜肴 片子的一开始就是一个盛装打扮的老太婆 叫了份酒蒸蛤蜊还要了一瓶酒 感觉真的很“酒鬼” …… 中...
    金澜爱写作阅读 623评论 0 1
  • 前几天看了部电影《分裂》,讲述的是三个少女被一个患有多重人格分裂症的变态狂魔绑架囚禁在地下室,歹徒的心理医生和女主...
    我的春夏秋冬阅读 179评论 2 2
  • 之前一位朋友推荐给我一部电影《当幸福来敲门》,也曾在其他各个网站看见过关于这部电影的描述,最近两天不是很忙,昨...
    六个核桃GL阅读 576评论 0 2
  • 枫叶掉落了多少情节 血红的一片沉淀了谁的对错 枫的神色被风猜透 再把谁的泪在挽留 你深深的侧着你倔强的脸 半边发丝...
    李译阅读 348评论 0 4