使用ChainerRL,在Minecraft中进行深度强化学习的实践

注意

    現在はこちらの方法の方がより簡単に環境構築できます ChainerRL + Minecraftで深層強化学習 ハンズオン [MineRL version]

我的世界

大家好,你们都知道Minecraft。我之前并不知道,但原来Minecraft可以简称为”マイクラ”。作为官方的宣传视频,也有下面这样的内容。

请用中文给以下链接进行释义:https://t.co/gITUej4Tmb— Keisuke Umezawa (Chainer Evangelist) (@kmechann) 2018年12月12日

此外,在Minecraft Japan Wiki上有以下的解释。

Minecraftは、2009年5月10日にNotch氏(本名:Markus Persson)が開発を始めた、サンドボックス型のものづくりゲームです。
レトロゲーを想起させるドットテイストのブロックが溢れる世界で、プレイヤーは建物やその他のものを自由に創造することが出来ます。
未開の土地を探索したり、洞窟を探検したり、モンスターと戦ったり、植物を育てたり、新しいブロックを手に入れ配置することで、様々なものを作ることができます。
創造(想像)力次第で小さな家から、ドット絵、地下基地、巨大な城まで何でも作ることができます。

マルチプレイでは、協力して巨大な建築物を作ったり、Player VS Player(PvP)で他プレイヤーと戦うことも出来ます。

根据这个说明,有一些适合当前强化学习的关键词。

    • 建物やその他のものを自由に作ることできる

 

    • 色々なゲームができる

 

    マルチプレイできる

我认为正因为Minecraft具有这些特性,所以才产生了在Minecraft进行强化学习的动机。

马洛项目

在这个工作坊中,我们将使用Minecraft作为模拟环境进行深度强化学习。目前,有一个名为MARLO的深度强化学习竞赛正在使用Minecraft进行。这次我们将使用一个名为marLo的OpenAI’s Gym兼容的Minecraft环境来参加这个竞赛。由于兼容OpenAI’s Gym,我们可以轻松地使用强化学习框架如ChainerRL(虽然并不完全,比如不能使用保存视频的包装器)。

在MarLo中,已经提供了以下环境,例如可以使用深度强化学习来创建一个能够在熔岩上走的AI。本次我们将使用MarLo-FindTheGoal-v0进行说明,然后请大家挑战新的任务。

ハンズオンの内容

※ このハンズオンは、https://github.com/keisuke-umezawa/marlo-handson を元に作成しています。

需求

截至2018年12月14日,需要以下内容。

    • Python 3.5+ environment with

Chainer v5.0.0
CuPy v5.0.0
ChainerRL v0.4.0
marlo v0.0.1.dev23

使用Azure进行环境设置。

为了按照以下步骤进行操作,需要一个Azure订阅。
请参考其他环境建设方法的文章。

1. 安装Azure CLI

请根据环境选择以下选项。

Windowsの場合

Install Azure CLI on Windows

Homebrew(macOS)の場合

$ brew update && brew install azure-cli

pythonを使用する場合

$ pip install azure-cli

2. 登录 Azure

$ az login

3. 订阅选择

以下のコマンドで、あなたがお持ちのsubscriptionをリストアップできます。

$ az account list --all

让我们在您的账户中设置所选的订阅。当然,[A SUBSCRIPTION ID]请替换为您的订阅ID。

$ az account set --subscription [A SUBSCRIPTION ID]

4. 启动GPU虚拟机

接下来,使用以下命令创建数据科学VM。参数–generate-ssh-keys会自动创建用于连接VM的密钥,并将私钥保存在~/.ssh/目录下的id_rsa文件中,将公钥保存在id_rsa.pub文件中。

$ AZ_USER=[好きなuser名 e.g. kumezawa]
$ AZ_LOCATION=[resource-groupを作ったlocation e.g. eastus]
$ AZ_RESOURCE_GROUP=[resource-groupを作ったlocation e.g. marmo]
$ az vm create \
--location ${AZ_LOCATION} \
--resource-group ${AZ_RESOURCE_GROUP} \
--name ${AZ_USER}-vm \
--admin-username ${AZ_USER} \
--public-ip-address-dns-name ${AZ_USER} \
--image microsoft-ads:linux-data-science-vm-ubuntu:linuxdsvmubuntu:latest \
--size Standard_NC6 \
--generate-ssh-keys

如果顺利的话,应该会出现以下类似的消息。

{
  "fqdns": "[YOUR USERNAME].eastus.cloudapp.azure.com",
  "id": "/subscriptions/[YOUR SUBSCRIPTION ID]/resourceGroups/marLo-handson/providers/Microsoft.Compute/virtualMachines/vm",
  "location": "eastus",
  "macAddress": "AA-BB-CC-DD-EE-FF",
  "powerState": "VM running",
  "privateIpAddress": "10.0.0.4",
  "publicIpAddress": "123.456.78.910",
  "resourceGroup": "marLo-handson",
  "zones": ""
}

请记住以下步骤,以便使用公共IP地址。

注意

如果在~/.ssh/目录下存在私钥id_rsa和公钥id_rsa.pub,则上述命令将引发错误。
在这种情况下,您可以自己创建密钥并指定其创建方式。

$ az vm create \
--location ${AZ_LOCATION} \
--resource-group ${AZ_RESOURCE_GROUP} \
--name ${AZ_USER}-vm \
--admin-username ${AZ_USERER} \
--public-ip-address-dns-name ${AZ_USER} \
--image microsoft-ads:linux-data-science-vm-ubuntu:linuxdsvmubuntu:latest \
--size Standard_NC6 \
--ssh-key-value [公開鍵のpath e.g. ~/.ssh/id_rsa.pub]

注意

如果您希望在CPU实例而不是GPU上启动,可以使用例如–size Standard_D2s_v3的选项。如果您想要了解其他可用的虚拟机大小,可以通过以下方式进行查询。

az vm list-sizes --location eastus --output table

需要打开的端口以访问。

$ az vm open-port --resource-group ${AZ_RESOURCE_GROUP} --name ${AZ_USER}-VM --port 8000 --priority 1010 \
&& az vm open-port --resource-group ${AZ_RESOURCE_GROUP} --name ${AZ_USER}-VM --port 8001 --priority 1020 \
&& az vm open-port --resource-group ${AZ_RESOURCE_GROUP} --name ${AZ_USER}-VM --port 6080 --priority 1030

6. SSH连接到虚拟机

$ AZ_IP=[あなたのvmのIPアドレス e.g. "40.121.36.99"]
$ ssh ${AZ_USER}@${AZ_IP} -i ~/.ssh/id_rsa

为MarLo创建一个Conda环境。

请在VM环境中执行以下命令。

$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list \
&& sudo apt-get update \
&& sudo apt-get install -y libopenal-dev
$ conda config --set always_yes yes \
&& conda create python=3.6 --name marlo \
&& conda config --add channels conda-forge \
&& conda activate marlo \
&& conda install -c crowdai malmo matplotlib ipython numpy scipy opencv \
&& pip install git+https://github.com/crowdAI/marLo.git

根据当前安装的CUDA版本,安装相应的CuPy和Chainer。例如,对于CUDA 9.0,安装CuPy-cuda90。

$ nvcc --version
$ pip install chainer==5.1.0 cupy-cuda90==5.1.0 chainerrl==0.5.0

8. 通过Docker启动Minecraft客户端。

$ sudo docker pull ikeyasu/marlo:latest
$ VNC_PW=[適当なpassword]
$ sudo docker run -it --net host --rm --name robo6082 -d -p 6080:6080 -p 10000:10000 -e VNC_PW=${VNC_PW} ikeyasu/marlo:latest

请访问您VM的IP地址:6080,并尝试输入您自己设置的密码${VNC_PW}。

通过VNC连接可以连接到远程环境,并在其中启动Minecraft,您应该可以确认这一点!

image.png

让我们开始动手实践吧

0. 确认是否激活了Conda环境。

$ conda info -e
# conda environments:
#
base                     /anaconda
marlo                 *  /anaconda/envs/marlo
py35                     /anaconda/envs/py35
py36                     /anaconda/envs/py36

如果之前创建的marlo尚未被激活,请执行下面的命令。

$ conda activate marlo

1. 亲自操作,克隆代码库。

$ git clone https://github.com/keisuke-umezawa/marlo-handson.git
$ cd marlo-handson

2. 运行malro测试脚本

$ python test_malmo.py

稍等一下,接下来应该会显示以下画面。

スクリーンショット 2018-12-13 21.20.41.png

我将执行以下的Python脚本。

测试_malmo.py

import marlo


def make_env(env_seed=0):
    join_tokens = marlo.make(
        "MarLo-FindTheGoal-v0",
        params=dict(
            allowContinuousMovement=["move", "turn"],
            videoResolution=[336, 336],
            kill_clients_after_num_rounds=500
        ))
    env = marlo.init(join_tokens[0])

    obs = env.reset()
    action = env.action_space.sample()
    obs, r, done, info = env.step(action)
    env.seed(int(env_seed))
    return env


env = make_env()
obs = env.reset()


for i in range(10):
    action = env.action_space.sample()
    obs, r, done, info = env.step(action)
    print(r, done, info)

“MarLo-FindTheGoal-v0″を変更すると環境を変更できます

obsはnumpy形式の画像データです。

rは前回の行動に対する報酬です

doneはゲームが終了したか真偽値です。

infoはその他情報が入っています。

课题1:请确认并对上述内容进行修改,并尝试玩耍。

3. 运行使用ChainerRL进行DQN训练的脚本。

请先执行以下命令。这样,您就可以从零开始使用ChainerRL训练DQN强化学习模型了。

$ python train_DQN.py

请在适当的时候按下CTRL+C,停止脚本。这样就应该创建了以下目录:xxxx_except,其中保存了我们迄今为止学习的模型。

$ ls results/
3765_except  scores.txt

Note

如果您只想使用CPU运行,请尝试添加以下选项并运行。

$ python train_DQN.py --gpu -1

3. 验证保存的模型是否正常运行。

以下のコマンドで、学習したモデルのロードと、その動作確認ができます。

$ python train_DQN.py --load results/3765_except --demo

请问怎么样呢?我并没有让它进行过很多学习,所以应该不能正常运行。

从保存的模型开始训练。

只需要一个选项,对以下命令进行汉语的同义转述:
通过使用以下命令,您可以从之前保存的模型中恢复学习。

$ python train_DQN.py --load results/3765_except

また、こちらである程度訓練したモデルを用意したので、そこから学習を開始することもできます。ただし、単にpython train_DQN.pyを実行して作成されたモデルですので、コードに変更を加えたり、環境を変更したりした場合動かないことがあります。

$ wget https://github.com/keisuke-umezawa/marlo-handson/releases/download/v0.2/157850_except.tar.gz
$ tar -xvzf 157850_except.tar.gz
$ python train_DQN.py --load 157850_except

实现以下paraphrase:

题目2:让我们来阅读train_DQN.py的代码。

这个脚本本身如下所示。

训练_DQN.py


# ...省略...

def main():
    parser = argparse.ArgumentParser()

    # ...省略...

    # Set a random seed used in ChainerRL.
    misc.set_random_seed(args.seed, gpus=(args.gpu,))

    if not os.path.exists(args.out_dir):
        os.makedirs(args.out_dir)

    experiments.set_log_base_dir(args.out_dir)
    print('Output files are saved in {}'.format(args.out_dir))

    env = make_env(env_seed=args.seed)

    n_actions = env.action_space.n

    q_func = links.Sequence(
        links.NatureDQNHead(n_input_channels=3),
        L.Linear(512, n_actions),
        DiscreteActionValue
    )

    # Use the same hyper parameters as the Nature paper's
    opt = optimizers.RMSpropGraves(
        lr=args.lr, alpha=0.95, momentum=0.0, eps=1e-2)

    opt.setup(q_func)

    rbuf = replay_buffer.ReplayBuffer(10 ** 6)

    explorer = explorers.LinearDecayEpsilonGreedy(
        1.0, args.final_epsilon,
        args.final_exploration_frames,
        lambda: np.random.randint(n_actions))

    def phi(x):
        # Feature extractor
        x = x.transpose(2, 0, 1)
        return np.asarray(x, dtype=np.float32) / 255

    agent = agents.DQN(
        q_func,
        opt,
        rbuf,
        gpu=args.gpu,
        gamma=0.99,
        explorer=explorer,
        replay_start_size=args.replay_start_size,
        target_update_interval=args.target_update_interval,
        update_interval=args.update_interval,
        batch_accumulator='sum',
        phi=phi
    )

    if args.load:
        agent.load(args.load)

    if args.demo:
        eval_stats = experiments.eval_performance(
            env=env,
            agent=agent,
            n_runs=args.eval_n_runs)
        print('n_runs: {} mean: {} median: {} stdev {}'.format(
            args.eval_n_runs, eval_stats['mean'], eval_stats['median'],
            eval_stats['stdev']))
    else:
        experiments.train_agent_with_evaluation(
            agent=agent,
            env=env,
            steps=args.steps,
            eval_n_runs=args.eval_n_runs,
            eval_interval=args.eval_interval,
            outdir=args.out_dir,
            save_best_so_far_agent=False,
            max_episode_len=args.max_episode_len,
            eval_env=env,
        )


if __name__ == '__main__':
    main()
    • 参考リンク

NatureDQNHead
DiscreteActionValue
ReplayBuffer
LinearDecayEpsilonGreedy
DQN

问题3:提高性能

要改进强化学习性能,有以下方式可供选择。

    • モデルの変更

 

    • ReplayBufferの変更

 

    そのたパラメータの変更

另外,还有一篇名为《Rainbow:结合深度强化学习的改进方法来评估性能提升》的论文,尝试了各种强化学习方法,并评估了它们在性能上的提升。根据该论文,可以尝试以下方式来提高性能。

    • PrioritizedReplayBufferの使用

 

    • DDQNの使用

 

    etc
广告
将在 10 秒后关闭
bannerAds