【入門強化学習】とりあえず動かしてみる強化学習

# はじめに

強化学習ついて、なんとなくのイメージしかなかったため、とりあえず実際に動かしてみました。
今回は、OpenAI Gymというツール上で強化学習アルゴリズムを動かしています。

とりあえず動かしてみるだけなので、強化学習アルゴリズムの詳しい説明はしていません。

## 対象読者

- 強化学習を実際に動かしてみたい

# 強化学習とは

強化学習とは、**ある環境下で試行錯誤しながら報酬を最大化するための行動を学習していく仕組み**です。
ディープラーニングの登場によりできることが増え、有名なAlphaGoでも強化学習が使われています。

# OpenAI Gymとは

OpenAI Gymは、強化学習アルゴリズムを開発/比較するためのツールとなります。
棒立てや車での山登り、スペースインベーダーなど様々な環境で強化学習アルゴリズムを試すことが出来ます。

参考：[Gymで使える環境一覧](https://gym.openai.com/envs/#classic_control)

## 動かしてみる

とりあえず、gymを動かしてみます。
ここでは棒立ての環境で動かします。

アクション（棒が立っている場所を左右どちらに動かすか）はランダムに決定します。

```python
import gym

# 環境の生成
env = gym.make('CartPole-v0')

for i_episode in range(20):
    # 環境を初期化してobsersavationを取得
    observation = env.reset()
    for t in range(100):
        env.render()
        print(observation)
        # アクションの決定(ランダム)
        action = env.action_space.sample()
        # アクション後のデータを取得
        observation, reward, done, info = env.step(action)
        if done:
            print("Episode finished after {} timesteps".format(t+1))
            break
env.close()
```

![random.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246138/47f7264b-65ca-fcbf-a7fb-8e2a4ab9f129.gif)

アクションをランダムに決定しているので、すぐに倒れてしまいます。

# 強化学習で動かす

次に、強化学習アルゴリズムを使って、アクションを選択するようにします。
今回は、DQN(Deep Q-Learning)というアルゴリズムを使って学習させます。

## 使用するライブラリ

強化学習ライブラリにはkeras-rlを使います。
ただし、**tensorflow 2から統合されたKerasを使っている場合は、keras-rl2を使う必要がある**ことに注意してください。

今回使うライブラリのバージョンは下記の通りになります。

```
keras-rl2==1.0.4
tensorflow==2.3.0
```

## DQNで学習

それでは実際にDQNを用いて学習させていきます。

棒立てが終了するまでが1エピソードに、棒を立てている場所を左右どちらかに動かす1アクションが1ステップに相当します。
ここでは50000ステップまで学習させます。

```python
import gym
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from tensorflow.keras.optimizers import Adam
from rl.agents.dqn import DQNAgent
from rl.policy import BoltzmannQPolicy
from rl.memory import SequentialMemory

# 環境の生成
env = gym.make('CartPole-v0')
nb_actions = env.action_space.n

# モデルの定義
model = Sequential()
model.add(Flatten(input_shape=(1,) + env.observation_space.shape))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(16))
model.add(Activation('relu'))
model.add(Dense(nb_actions))
model.add(Activation('linear'))

# エージェントの設定
memory = SequentialMemory(limit=50000, window_length=1)
policy = BoltzmannQPolicy()
dqn = DQNAgent(model=model, nb_actions=nb_actions, memory=memory, nb_steps_warmup=10,
               target_model_update=1e-2, policy=policy)
dqn.compile(Adam(lr=1e-3), metrics=['mae'])

# 学習
dqn.fit(env, nb_steps=50000, visualize=True, verbose=2)

# モデルをテスト
dqn.test(env, nb_episodes=5, visualize=True)
```

64エピソード学習後...

![dqn_64.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246138/40dc0e04-b0f5-eb47-2db9-100d50814dae.gif)

216エピソード学習後...

![dqn_216.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246138/77753afb-55db-63ba-e7f1-d3da8ff40e57.gif)

## 学習済みモデルでテスト

50000ステップ学習させた結果、以下のように安定して棒を立てられるようになりました。

![dqn_test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246138/86f78247-3d5c-3dcd-1e88-a25e1bf73da5.gif)

# kaggleのコンペ

機械学習コンペのプラットフォームである[kaggle](https://www.kaggle.com/)でも、強化学習で学習させたモデル同士を戦わせて競い合うコンペがありました。

[Connect X | Kaggle](https://www.kaggle.com/c/connectx)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246138/5cc0fef7-5175-efe1-c954-af02a42b06b7.png)

こちらのコンペは、Connect Fourと呼ばれる４目並べにおいて、学習させたエージェント同士を戦わせてレートを決め、順位を決める形式になっております。
自分が作ったエージェントを戦わせるのが結構面白いので、ぜひ挑戦してみてください。

kaggle内にもConnect Xのコンペを通して、ゲームAIと強化学習を学べるレクチャーもあるため、こちらから挑戦するのもいいと思います。
[Learn Intro to Game AI and Reinforcement Learning Tutorials | Kaggle](https://www.kaggle.com/learn/intro-to-game-ai-and-reinforcement-learning)

# まとめ

- とりあえず強化学習のアルゴリズムを動かすことができた
- 他の環境でも試してみたい

今後はしっかり中身のアルゴリズムを理解したいと思います。

# 参照

- [深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト ](https://www.amazon.co.jp/%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-G%E6%A4%9C%E5%AE%9A-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%A9%E3%83%AA%E3%82%B9%E3%83%88-%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4798157554)
- [OpenAI](https://openai.com/)
- [Gym](https://gym.openai.com/)
- [openai/gym](https://github.com/openai/gym)
- [wau/keras-rl2](https://github.com/wau/keras-rl2)
- [強化学習システムの設計指針](http://sysplan.nams.kyushu-u.ac.jp/gen/papers/sice99.pdf)
- [Connect X | Kaggle](https://www.kaggle.com/c/connectx)
- [Learn Intro to Game AI and Reinforcement Learning Tutorials | Kaggle](https://www.kaggle.com/learn/intro-to-game-ai-and-reinforcement-learning)