使用方法について

はじめに

強化学習においてニューラルネットワーク を用いる場合、入力関数を多変数とし、出力を行動とするエージェントして学習させます。しかし、問題によって、何を環境変数として捉えるか、出力のタイプはどのようなものを求めるかが異なるため、エージェントの構造のみならず、エージェントに入る情報、報酬、リセットの条件等の環境情報を設定する必要があります。

ReNom RLの特徴として、DQN、A3C等の複雑なアルゴリズムが既に実装されているところにあります。強化学習を実装する上において、主にユーザーに実施していただく操作として以下の3つがあります。

  1. 環境の準備

  2. モデルの準備

  3. 強化学習の実装

1-環境の準備

簡易的に学習するために、環境モデルをBaseEnvに合わせた構造にしなければなりません。ここでは既存のモデルを使った方法と、0から実装する方法を紹介します。

既存のモデルを使った方法

Open AIを使った環境モデルを一つの関数として用意しております。例えばBreakoutのモデルを利用する場合は、以下のように呼び出すこともできます。

from renom_rl.environ.openai import Breakout
env = Breakout()

0から実装する方法

オリジナルの環境を作成する場合は、オブジェクトを継承し、以下の変数および関数を書き換える必要があります。

  • action_shape: actionの形状

  • state_shape: stateの形状

  • reset(): リセット時の初期stateを指定

  • sample(): action のサンプル手段を指定

  • step(): action 取った時のstate, reward, terminal を指定

例えば CustomEnv() というオブジェクトを新たに作るとしたら、CustomEnv の概略は以下のようになります。

import gym
from renom_rl.environ import BaseEnv

env = gym.make('BreakoutNoFrameskip-v4')

class CustomEnv(BaseEnv):

    def __init__(self, env):
        self.env = env
        self.action_shape = 4
        self.state_shape = (4, 84, 84)
        self.previous_frames = []
        self._reset_flag = True
        self._last_live = 5
        super(CustomEnv, self).__init__()

    def reset(self):
        if self._reset_flag:
            self._reset_flag = False
            self.env.reset()
        n_step = np.random.randint(4, 32+1)
        for _ in range(n_step):
            state, _, _ = self.step(self.env.action_space.sample())
        return state

    def sample(self):
        return self.env.action_space.sample()

    def render(self):
        self.env.render()

    def _preprocess(self, state):
        resized_image = Image.fromarray(state).resize((84, 110)).convert('L')
        image_array = np.asarray(resized_image)/255.
        final_image = image_array[26:110]
        # Confirm that the image is processed correctly.
        # Image.fromarray(np.clip(final_image.reshape(84, 84)*255, 0, 255).astype(np.uint8)).save("test.png")
        return final_image

    def step(self, action):
        state_list = []
        reward_list = []
        terminal = False
        for _ in range(4):
            # Use last frame. Other frames will be skipped.
            s, r, t, info = self.env.step(action)
            state = self._preprocess(s)
            reward_list.append(r)
            if self._last_live > info["ale.lives"]:
                t = True
                self._last_live = info["ale.lives"]
                if self._last_live > 0:
                    self._reset_flag = False
                else:
                    self._last_live = 5
                    self._reset_flag = True
            if t:
                terminal = True

        if len(self.previous_frames) > 3:
            self.previous_frames = self.previous_frames[1:] + [state]
        else:
            self.previous_frames += [state]
        state = np.stack(self.previous_frames)
        return state, np.array(np.sum(reward_list) > 0), terminal

new_env=CustomEnv()

2-モデルの準備

ここでは、ReNomDL のモデルを作成します。通常のモデルを定義する場合は、以下のように定義してください。

q_network = rm.Sequential([rm.Conv2d(32, filter=8, stride=4),
                           rm.Relu(),
                           rm.Conv2d(64, filter=4, stride=2),
                           rm.Relu(),
                           rm.Conv2d(64, filter=3, stride=1),
                           rm.Relu(),
                           rm.Flatten(),
                           rm.Dense(512),
                           rm.Relu(),
                           rm.Dense(custom_env.action_shape)])

3-強化学習の実装

以上の2つを用意した上で、次に強化学習を用いた学習方法を紹介します。今回は、DQN のモデルを例として使用します。

import renom as rm
from renom_rl.discrete.dqn import DQN

model = DQN(custom_env, q_network)

最後にDQNのmodelを実行します。実行する際には以下のように記述してください。

result = model.fit(render=False, greedy_step=1000000, random_step=5000, update_period=10000)

このように実装することで、DQNを実行することが可能です。環境、その他の強化学習アルゴリズムについてはAPIページを参照いただけると幸いです。