使用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,您应该可以确认这一点!
让我们开始动手实践吧
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
稍等一下,接下来应该会显示以下画面。
我将执行以下的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