今までいろいろな強化学習アルゴリズムを実装してきましたが、以下の問題を毎回感じていました。
- アルゴリズム毎に環境と学習のための実装が必要
(gym等は環境側のインタフェースまでは提供されているが、学習を含めた実装は提供されていない) - アルゴリズムの学習フローがそもそも複雑になりやすい(デバッグしづらい)
- 分散学習まで考えるとなお大変
- アルゴリズムと環境が分離しきれず結構依存する
- Atariの画像の前処理とその入力に依存したニューラルネットワークの設計
- アクションが離散値と連続値の場合によるアルゴリズム側の違い
- よくある数フレーム入力やフレームスキップ、実行できないアクション等を加味した場合の変更
- 学習フローの差異(AlphaZeroやモデルベース強化学習など)
- ログや可視化等の作成
既存のフレームワークを試したりしましたが自作アルゴリズムを作ろうとした場合、フレームワークの理解から勉強が必要になりかなりハードルが高いような気がしました。
そこでなるべくハードルが低くなるようなフレームワークを自作しようと思い作成しました。
このフレームワークの特徴は以下です。
- カスタマイズ可能な環境の提供
- カスタマイズ可能な強化学習アルゴリズムの提供
- 環境とアルゴリズム間のインタフェースの自動調整
- 分散強化学習のサポート
- 有名な強化学習アルゴリズムの提供
- (新しいアルゴリズムへの対応)
本記事はフレームワークの説明をすると共に実装しているアルゴリズムも説明していこうかと思います。
各項目については別記事にして少しずつ作成する予定です。
Github
各項目
- 概要(この記事)
- 最初に
- フレームワークの使い方
- 技術関係
- 価値ベース
- 方策ベース
- Alphaシリーズ
- WorldModelsシリーズ
- その他の強化学習アルゴリズム
- オリジナル
- 最適化アルゴリズム
- フレームワークとは関係ない機械学習関係の記事
- Tensorflow/ディープラーニング関係
- 0から理解する誤差逆伝播法(理論からコードの実装まで)
- 基本的な出力層の活性化関数と損失関数の組み合わせまとめ(TF2.0)
- LSTM(RNN)で可変長な時系列と隠れ状態について調べてみた(Tensorflow2.0)
- 乱数の固定方法(random/numpy/tensorflow/gym)
- 混合密度ネットワーク(Tensorflow2.0)
- tf.GradientTapeで正則化項が反映されているか調査してみた(過学習の公式チュートリアルを添えて)
- 離散空間のReparameterizationTrick(GumbelMaxTrick/StraightGradients/VQ-VAE)
- ELBO(変分下限)を最大化するという意味をゼロから理解する(尤度、最尤推定)
- その他
1.インストール
Github からの pip install を想定しています。(PyPIへの登録予定は今のところありません)
また、ダウンロードだけでも使えます。詳細はGitHubを見てください。
インストールする一例は以下です。
git clone https://github.com/pocokhc/simple_distributed_rl.git
cd simple_distributed_rl
pip install .
2.使い方
import numpy as np
import srl
# --- 1. 使うアルゴリズムをimport
from srl.algorithms import ql
def main():
# --- 2. 各configを設定
env_config = srl.EnvConfig("Grid") # 環境config
rl_config = ql.Config() # アルゴリズムconfig
# --- 3. Runnerを作成
runner = srl.Runner(env_config, rl_config)
# --- 4. 学習
if True:
# 逐次学習の場合
runner.train(timeout=20)
else:
# 分散学習の場合
runner.train_mp(timeout=20)
# 評価
rewards = runner.evaluate(max_episodes=10)
print(f"10回テストした結果の平均報酬: {np.mean(rewards)}")
# 可視化
# Terminal上で1エピソードを見る
runner.render_terminal()
# 1エピソードをアニメーション化('opencv-python','pillow','matplotlib','pygame'が別途必要)
runner.animation_save_gif("_Grid.gif")
if __name__ == '__main__':
main()
- アニメーション
- Terminal上での結果
10回テストした結果の平均報酬: 0.7960000045597553
### 0, action 3, rewards [0.], next 0
env None
work0 None
......
. G.
. . X.
.P .
......
← : 0.10151
↓ : 0.07913
→ : 0.02751
*↑ : 0.36339
### 1, action 3, rewards [-0.04], next 0
env {}
work0 {}
......
. G.
.P. X.
. .
......
← : 0.17283
↓ : 0.11623
→ : 0.17698
*↑ : 0.48977
### 2, action 2, rewards [-0.04], next 0
env {}
work0 {}
......
.P G.
. . X.
. .
......
← : 0.23222
↓ : 0.18907
*→ : 0.61112
↑ : 0.24942
### 3, action 2, rewards [-0.04], next 0
env {}
work0 {}
......
. P G.
. . X.
. .
......
← : 0.25572
↓ : 0.31604
*→ : 0.76530
↑ : 0.32385
### 4, action 2, rewards [-0.04], next 0
env {}
work0 {}
......
. PG.
. . X.
. .
......
← : 0.32941
↓ : 0.26414
*→ : 0.92709
↑ : 0.44327
### 5, action 2, rewards [-0.04], next 0
env {}
work0 {}
......
. PG.
. . X.
. .
......
← : 0.32941
↓ : 0.26414
*→ : 0.92709
↑ : 0.44327
### 6, action 2, rewards [1.], done(env), next 0
env {}
work0 {}
......
. P.
. . X.
. .
......
おわりに
少しずつ開発しているので温かく見守っていただければ幸いです。