以图片为目标的视觉强化学习 -- 代码解析上篇(rlkit安装及部分代码及函数的解析和使用)

Luna
Written by Luna on

    之前有讲过一篇论文,今天来讲讲它的代码:

论文解析的链接是:以图片为目标的视觉强化学习

    这篇研究以及这篇研究的后续研究,源代码都有公开,我们的目标是把这个库都解析一遍,感兴趣的话,关注吧。下面是相关源代码的链接:

https://github.com/rail-berkeley/rlkit

现在要说的这个工作我们称呼它RIG,RIG适用的rlkit版本和最新的两个工作适用的rlkit版本不一样,我们先看RIG适用的rlkit。

    论文开发者直接开发了一个工具,里面有众多强化学习的算法,方便做相关研究的渣渣们,比如我,直接拿来用,但前提你得看得懂。那么看懂就交给我了。

    我们先来安装和解析一下这个工具,首先看安装指引:

cp rlkit/launchers/config_template.py rlkit/launchers/config.py

    然后我们看看config.py里面都做了些什么:

import os
from os.path import join
import rlkit
# 设定项目目录

rlkit_project_dir = join(os.path.dirname(rlkit.__file__), os.pardir)
LOCAL_LOG_DIR = join(rlkit_project_dir, 'data')


# 接下来设定大部分与远程服务器相关


# 代码目录,可能不止一个,不止一个就添加在后面
CODE_DIRS_TO_MOUNT = [
    rlkit_project_dir,
    # '/home/user/python/module/one', Add more paths as needed
]
# 工作需要用到mujoco模拟器,如果你mujoco安装的位置特殊,这里可能要改
DIR_AND_MOUNT_POINT_MAPPINGS = [
    dict(
        local_dir=join(os.getenv('HOME'), '.mujoco/'),
        mount_point='/root/.mujoco',
    ),
]
# 跑程序的代码地址
RUN_DOODAD_EXPERIMENT_SCRIPT_PATH = (
    join(rlkit_project_dir, 'scripts', 'run_experiment_from_doodad.py')
    # '/home/user/path/to/rlkit/scripts/run_experiment_from_doodad.py'
)


# 接下来是AWS,SLURM,和GCP的一些设定,
# 我目前都没用到,暂时不提,用到的小伙伴可以看一下

关于config.py文件,不用doodad的话,要把下面两行改一下,不然之后跑程序会报错:

# If not set, default will be chosen by doodad
#AWS_S3_PATH = 's3://bucket/directory

改为(其实就是把注释去掉,再补个冒号),我的环境里它不会被用到,只是调试起来方便一些:

# If not set, default will be chosen by doodad
AWS_S3_PATH = 's3://bucket/directory'

接下来创建一个虚拟代码环境,他提供了三个虚拟环境配置文件:linux-cpu-env.yml,linux-gpu-env.yml,mac-env.yml。一般是linux-gpu:

conda env create -f environment/linux-gpu-env.yml

在跑之前我们看里面写了点啥,name是虚拟环境的名称,channels是虚拟环境安装软件的源,下面的dependencies是虚拟环境依赖的软件,这里就不列全了:   

name: rlkit
channels:
- kne  # for pybox2d
- pytorch
- anaconda  # for mkl
dependencies:
- cython
- ipython  # technically unnecessary

我自己不习惯用别人写好的脚本建立环境,喜欢一边看代码一边解决依赖问题。

首先我们要解决最重要的一个依赖,MuJoCo,强化学习的环境模拟常用的软件,以前是个付费软件,现在免费了,可能是有大佬买了,现在似乎属于DeepMind,DeepMind属于Google:

https://mujoco.org/

代码里用的MuJoCo版本是1.5,我喜欢用最新的,我们试试2.1,不行再回来换1.5,MuJoCo安装起来还是挺费劲的,遇到问题耐心些,多搜一搜:

mkdir -p ~/.mujoco
cd ~/.mujoco
# 到mujoco官网->download页面->选2.1.0版本->下载linux版
wget https://github.com/deepmind/mujoco/releases/download/2.1.0/mujoco210-linux-x86_64.tar.gz
tar -xvf mujoco210-linux-x86_64.tar.gz
echo 'export LD_LIBRARY_PATH=$HOME/.mujoco/mujoco210/bin:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
# 以上mujoco就下载安置好了
# 接下来安装mujoco-py
git clone https://github.com/openai/mujoco-py.git
cd mujoco-py
pip3 install -r requirements.txt
pip3 install -r requirements.dev.txt
python3 setup.py install
#----------------------------------------
# 接下来是一些你可能import mujoco_py失败,甚至上面就没装成功,而需要进行的步骤
# 按错误提示选择性执行
sudo apt-get install gcc
sudo apt install libosmesa6-dev
sudo apt-get install python3-devel
sudo apt-get update -y
sudo apt-get install -y patchelf
sudo apt-get install libglew-dev
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/nvidia' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.local/bin' >> ~/.bashrc
echo 'export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libGLEW.so' >> ~/.bashrc
source ~/.bashrc

如果可以import mujoco_py执行成功,且可以跑一些示例代码,就表示安装成功了。

    再回过头看rlkit,他除了提供虚拟环境的方案,还提供了Docker文件,Docker我不喜欢用,当然,主要是因为没下功夫,用不好,所以只能不喜欢,对这些比较擅长的可以试着用Docker。

    rlkit调用GPU的方式:

import rlkit.torch.pytorch_util as ptu
ptu.set_gpu_mode(True)

     如果用doodad来执行方法,则直接用下面的方式调用gpu,然而我测试发现,不用doodad,下面这种方式也可以成功调用gpu:

run_experiment(..., use_gpu=True)

    他们会建议用doodad来执行python程序,这里我们更想偏向于原理性代码的讨论,doodad部分的代码就不涉及了。

    接下来我们看RIG的代码,在examples/rig/目录下,有两个目录,四个文件,我们一个一个开始,首先看examples/rig/pointmass/rig.py:

from multiworld.envs.pygame.point2d import Point2DWallEnv
from rlkit.launchers.launcher_util import run_experiment
from rlkit.launchers.rig_experiments import grill_her_td3_full_experiment

要安装一下multiworld,这个工具也是该团队开发的:

git clone https://github.com/vitchyr/multiworld.git
cd multiworld
python setup.py install
pip install gym
pip install pygame
pip install boto3
pip install gtimer
pip install sk-video
pip install gitpython

关于安装rlkit,rlkit依赖版本较低的python和tensorflow,再加上跑不同程序要用到的rlkit版本还不太一样,我们反正要解析源代码,这里就不安装rlkit了,直接把rlkit的源码包放在主程序的目录下。如果想安装rlkit,可以按照他们给的方法操作,之后直接pip install rlkit就行。亲测不安装是可以的。

    接着看main函数,先定义了一个字典,里面都是参数,字典里还嵌套字典,层层叠叠,难怪AI工程师会被调侃调参大师,这里暂时不一一看,之后用到了会提:

    variant = dict(
        imsize=84,
        .......
        algorithm='RIG',
    )

    配置完参数之后,就是跑训练代码了:

    run_experiment(
        grill_her_td3_full_experiment, #rig算法实验的函数,以variant为参数
        exp_prefix='rlkit-pointmass-rig-example', #实验名称
        # 实验方式:默认是local,我们这里没装doodad。
        # 单机用here_no_doodad可以跑,也可以调用GPU
        # 其他方式暂时不研究了,有兴趣的可以研究
        # “local”,
        # “docker_local”,
        # “ec2”,
        # 'here_no_doodad', 
        mode='here_no_doodad', 
        variant=variant, # 参数
        use_gpu=True,  # 要用GPU跑就打开
    )

    在这样的配置下,我们看代码是怎么跑的(会略过不太重要的代码),下面是run_experiment里比较重要的代码:

    run_experiment_kwargs = dict(
        # 实验名称,默认会带上时间
        exp_prefix=exp_prefix,
        # 参数
        variant=variant,
        # 实验ID
        exp_id=exp_id,
        # 随机种子,不设定就随机产生
        seed=seed,
        use_gpu=use_gpu,
        # 默认是‘last’,作用之后说
        snapshot_mode=snapshot_mode,
        # 默认是1,作用之后说
        snapshot_gap=snapshot_gap,
        # 没装git就是None,暂时就None吧
        git_infos=git_infos,
        #这里应该是rig.py 
        script_name=main.__file__,
    )
    if mode == 'here_no_doodad':
        run_experiment_kwargs['base_log_dir'] = base_log_dir
        return run_experiment_here(
            method_call,
            **run_experiment_kwargs
        )

接下来是run_experiment_here函数,依然是只看重要一点的代码:

    # 这个函数里只有一行代码:
    # logger.reset()
    # logger也是他们自己开发的,reset就是回归初始状态
    reset_execution_environment()
    # 这里做的事情包括:创建log目录,将variant参数记录下来,
    # 以及添加各式各样的路径和参数
    actual_log_dir = setup_logger(
        exp_prefix=exp_prefix,
        variant=variant,
        exp_id=exp_id,
        seed=seed,
        snapshot_mode=snapshot_mode,
        snapshot_gap=snapshot_gap,
        base_log_dir=base_log_dir,
        log_dir=log_dir,
        git_infos=git_infos,
        script_name=script_name,
        **setup_logger_kwargs
    )
    # 启用seed
    set_seed(seed)
    # 启用GPU,默认用id为0的GPU
    # 如果想选择用其他gpu,可以set_gpu_mode(use_gpu,gpu_id)
    set_gpu_mode(use_gpu)
    
    run_experiment_here_kwargs = dict(
        variant=variant,
        exp_id=exp_id,
        seed=seed,
        use_gpu=use_gpu,
        exp_prefix=exp_prefix,
        snapshot_mode=snapshot_mode,
        snapshot_gap=snapshot_gap,
        git_infos=git_infos,
        script_name=script_name,
        base_log_dir=base_log_dir,
        **setup_logger_kwargs
    )
    # 把参数信息存成actual_log_dir下面的experiment.pkl文件
    save_experiment_data(
        dict(
            run_experiment_here_kwargs=run_experiment_here_kwargs
        ),
        actual_log_dir
    )
    # 好了,终于到我们的算法函数了。
    # 其实是这样的 grill_her_td3_full_experiment(variant)
    return experiment_function(variant)

接下来到这里:‍

def grill_her_td3_full_experiment(variant):
    # 看名字就知道功能了,预处理
    full_experiment_variant_preprocess(variant)
    # 训练vae,一边训练还会一边自己调参哦
    train_vae_and_update_variant(variant)
    # 这个看了再说。
    grill_her_td3_experiment(variant['grill_variant'])

这篇先到这里吧,我累了。下篇会讲具体模型算法还有训练测试代码,希望一个下篇就解决,不需要再分个中下

感兴趣的小伙伴们就关注吧。觉得有用右下角帮忙点个赞哦。

Comments

comments powered by Disqus