見出し画像

強化学習フレームワークの比較:Dopamine、RLLib、Keras-RL、Coach、TRFL、TensorForceなど

以下の記事が面白かったので、ざっくり訳してみました。

A Comparison of Reinforcement Learning Frameworks: Dopamine, RLLib, Keras-RL, Coach, TRFL, Tensorforce, Coach and more

0. はじめに

「強化学習(RL)フレームワーク」は、RLアルゴリズムのコアコンポーネントの高レベル抽象化を作成することにより、エンジニアを支援します。これによりコードの開発が容易になり、読みやすくなり、効率が向上します。

しかし、フレームワークを選択すると、ある程度のロックインが発生します。フレームワークの学習と使用に投資すると、脱却するのが難しくなります。これは、訪問するパブを決定するときと同じです。場所がどんなに悪くても、ビールを買わないことは非常に難しいです。

この投稿では、利用可能な最も人気のあるRLフレームワークに関するいくつかのメモを提供します。

このような投稿は便利だと思いますが、動揺させてしまうかもしれません。私は誰も動揺させたくありません。もしそうなら、ごめんなさい。フレームワークの作成者が実行する作業は、並外れたものです。これは、私が利用できるわずかな時間を使った私のわずかな解釈です。

1. この投稿の本来の目的

私はオライリーのためにRLの本を書きます。その本の一部として、読者にさまざまなRLエージェントを構築および設計する方法を示したいと思っています。読者は、すでに確立されているフレームワークまたはライブラリのコードを使用することで恩恵を受けられると思います。

はじまりは「どのフレームワークがよいか?」という問でした。すでに多くのフレームワークが利用可能であり、これが8000ワードのモンスターに変わったことがわかりました。長さについては事前におわび申し上げます。多くの人がそれをすべて読むことは期待していません。

長さのため、これも書くのに時間がかかりました。これは、レビューに焦点がないことを意味します。時々、あるフレームワークで1つのことについてコメントし、別のフレームワークではまったくコメントしません。これについておわびします。網羅的であることを意図していませんでした。

2. 方法論

評価のほとんどは純粋な意見です。しかし、私たちが見ることができる、いくつかの定量的指標があります。つまり、Githubで利用可能になるリポジトリの統計です。開始点は、各フレームワークがどれほどよく知られているかを大まかに表しています。多くの場合、多くのスターを持つフレームワークは、より多くのマーケティング力を持っています。

その後、モジュール性、使いやすさ、柔軟性、成熟度の組み合わせを探しました。シンプルさも望まれていましたが、これは通常、モジュール性と柔軟性と相互排他的です。以下に示す意見は、これらの理想に基づいています。

再発するテーマの1つは、RLフレームワーク内での「ディープラーニング(DL)フレームワーク」の優位性です。多くの場合、DLフレームワークは抽象化を超えてブレークアウトし、RLフレームワークは前者の拡張機能にすぎません。これは、特定のDLソリューションをすでに使用している状況にいる場合は、それをそのまま使用することを意味します。

しかし私にとって、それはロックインを表しています。私の好みは、特定のDL実装を義務付けていないか、DLをまったく使用しないフレームワークです。その結果、すべてのGoogleフレームワークはTensorflowに向かう傾向があり、すべてのアカデミックフレームワークはPyTorchを使用します。

また、各フレームワークのGoogleランキングを調べようとしましたが、信頼性が低いことが判明しました。

3. 付属ノート

私これらのフレームワークの多くを試しました。そして、それらのいくつかは最初から優れたノートブックを持っていたので、それらをチェックアウトすることができます。

残りについては、Google Colabratoryで実行できる要点を公開しました。これは非常に未加工の形式で表示されます。包括的または説明的なものではありません。私は単純に、最も単純なケースではうまくいったことを再確認したかっただけです。

4. 強化学習フレームワーク

以下のフレームワークは、2019年6月時点でGithubリポジトリ内の星の数の順にリストされています。星の実際の数およびその他のメトリックは、各フレームワークのタイトルのすぐ下にバッジとして表示します。

以下のフレームワークを比較しました。

・OpenAI Gym
・Google Dopamine
・Ray RLlib
・Keras-RL
・TRFL
・Tensorforce
・Facebook Horizon
・Coach
・MAgent
・SLM-Lab
・DeeR
・Garage
・Surreal
・RLgraph
・Simple RL

5. OpenAI Gym

画像2

「OpenAI」は、非営利の純粋な研究会社です。さまざまなオープンソースの強化学習ツールを提供して、再現性を改善し、ベンチマークを作成し、最新技術を改善します。私はそれらを学界と産業界の架け橋と考えるのが好きです。
しかし、私はあなたが何を考えているか知っています。

「GymはRLフレームワークではありません。環境です。」

分かってる。RLアルゴリズムをテストするための環境である、クラシックコントロール、ロボティクス、ビデオゲーム、ボードゲームなどを提供します。しかし、強化学習の基礎として頻繁に使用されるため、ここに含めました。人々はフレームワークのようにそれを使用します。

これは、RL実装と環境の間のインターフェースと考えてください。それは非常に多作であり、以下にリストされている他のフレームワークの多くは、Gymとのインターフェースも備えています。さらに、すべてを比較するためのベースラインとして機能します。これはRLで最も人気のあるリポジトリの1つになります。

◎入門
Gymで何が起こっているかを視覚化する場合は、これらの環境をレンダリングする必要があります。ラップトップではほとんど動作しますが、ブラウザでは制限のため苦労します。

これを回避するには、仮想ディスプレイを使用する必要があります。基本的に、ビデオドライバーをモックアウトする必要があります。これは、「入門」コードのほとんどがビデオラッピングコードであることを意味します。

付属のノートブックで見つけることができるすべての退屈なものを無視すると、コアのGymコードは次のようになります。

import gym
from gym.wrappers.monitoring.video_recorder import VideoRecorder # Because we want to record a video

env = gym.make("CartPole-v1") # Create the cartpole environment
rec = VideoRecorder(env)      # Create the video recorder
rec.capture_frame()           # Capture the starting position
while True:
   action = env.action_space.sample()                   # Use a random action
   observation, reward, done, info = env.step(action)   # to take a single step in the environment
   rec.capture_frame()                                  # and record
   if done:
          break                                         # If the pole has fallen, quit.
rec.close()  # Close the recording
env.close()  # Close the environment

現時点ではランダム行動を渡すだけです。

6. Dopamine

画像2

「Dopamine」は、公式のGoogle製品ではありませんが、Googleの従業員によって作成され、Googleのgithubでホストされています。そして、RLフレームワークへの比較的新しい参入者です。多数のGithubスターと、Googleトレンドランキングを誇っています。プロジェクトが開始されてからのコミット、コミッター、および時間が限られているため、これは驚くべきことです。

とにかく、このフレームワークの素晴らしい点は、「Google gin-config」構成フレームワークを使用することで、コードとしての構成を強調していることです。利点は、実行に固有のすべてのパラメータを含む単一の構成ファイルをリリースできることです。欠点は、構成ファイルの複雑さが増し、理解できないコードでいっぱいの別のファイルのようになる可能性があることです。

欠点は、構成ファイルの複雑さが増すことで、理解できないコードで埋まっている別ファイルのようになる可能性があることです。個人的には、「Kubernetes Manifests」や「JSON」(他の多くのフレームワークと同様)などの「dumb」構成ファイルに固執します。接続はコードで行う必要があります。

主な利点の1つは、プラグ可能性と再利用を促進することです。これは、データサイエンス製品の開発時にしばしば無視されるOOPおよび機能の重要な概念です。

非常に短い時間でかなりのトラクションを獲得したことは明らかです。そして率直に言って、それは私を少し心配しています。貢献者は4人で、コミットは100件のみです。これらの4人のうち、3人はコミュニティからのものです(バグ修正など)。そして残りの1人が130万行を超えるコードをコミットしました。

コミット履歴から、コードは別のリポジトリから転送されたようです。120万行のコミットはベストプラクティスではありません。これはApacheライセンスですので、あまり奇妙なことはありませんが、著作権はGoogle Inc.に割り当てられています。でも貢献者の合意に安心しています。

モジュール性に関しては、それほど多くはありません。エージェントの抽象化はありません。これらは直接実装され、「gin config」から構成されます。実装されているものも多くありません。環境の公式な抽象化もありません。実際、Tensorflowオブジェクトをいたるところに渡しており、Tensorflowインターフェイスの使用を想定しているようです。公式OOPスタイルの抽象化は、他のほとんどのフレームワークとは異なります。

要するに、ほとんどモジュール化されておらず、再利用は不格好(IMO)であり、普及しているように見えますが、あまり成熟しておらず、コミュニティのサポートもありません。

◎入門
付属のノートブックで例を見つけることができますが、前提は、構成ファイルを介してRLアルゴリズムを構築することです。
これは次のようになります。

DQN_PATH = os.path.join(BASE_PATH, 'dqn')
# Modified from dopamine/agents/dqn/config/dqn_cartpole.gin
dqn_config = """
# Hyperparameters for a simple DQN-style Cartpole agent. The hyperparameters
# chosen achieve reasonable performance.
import dopamine.discrete_domains.gym_lib
import dopamine.discrete_domains.run_experiment
import dopamine.agents.dqn.dqn_agent
import dopamine.replay_memory.circular_replay_buffer
import gin.tf.external_configurables

DQNAgent.observation_shape = %gym_lib.CARTPOLE_OBSERVATION_SHAPE
DQNAgent.observation_dtype = %gym_lib.CARTPOLE_OBSERVATION_DTYPE
DQNAgent.stack_size = %gym_lib.CARTPOLE_STACK_SIZE
DQNAgent.network = @gym_lib.cartpole_dqn_network
DQNAgent.gamma = 0.99
DQNAgent.update_horizon = 1
DQNAgent.min_replay_history = 500
DQNAgent.update_period = 4
DQNAgent.target_update_period = 100
DQNAgent.epsilon_fn = @dqn_agent.identity_epsilon
DQNAgent.tf_device = '/gpu:0'  # use '/cpu:*' for non-GPU version
DQNAgent.optimizer = @tf.train.AdamOptimizer()

tf.train.AdamOptimizer.learning_rate = 0.001
tf.train.AdamOptimizer.epsilon = 0.0003125

create_gym_environment.environment_name = 'CartPole'
create_gym_environment.version = 'v0'
create_agent.agent_name = 'dqn'
TrainRunner.create_environment_fn = @gym_lib.create_gym_environment
Runner.num_iterations = 100
Runner.training_steps = 100
Runner.evaluation_steps = 100
Runner.max_steps_per_episode = 200  # Default max episode length.

WrappedReplayBuffer.replay_capacity = 50000
WrappedReplayBuffer.batch_size = 128
"""
gin.parse_config(dqn_config, skip_unknown=False)

コードはたくさんありますが、複雑なアルゴリズムを実装しているので、それを期待するかもしれません。ハイパーパラメータがそこにあることは非常にうれしいですが、すべてのダイナミックインジェクション(@クラスのインスタンスを示す)のファンであるかどうかはわかりません。支持者は「うわー、見て、このラインを変えるだけでオプティマイザを交換できる」と言うでしょう。しかし、私は普通の古いPythonでもそれができると考えています。

少しの訓練を行います。

tf.reset_default_graph()
dqn_runner = run_experiment.create_runner(DQN_PATH, schedule='continuous_train')
dqn_runner.run_experiment()

次に、実行状況のビデオ動画を行います。

rec = VideoRecorder(dqn_runner._environment.environment)
action = dqn_runner._initialize_episode()
rec.capture_frame()
while True:
   observation, reward, is_terminal = dqn_runner._run_one_step(action)
   rec.capture_frame()
   if is_terminal:
     break                                         # If the pole has fallen, quit.
   else:
     action = dqn_runner._agent.step(reward, observation)
dqn_runner._end_episode(reward)
rec.close()

7. Ray RLlib

画像3

「Ray」は、Pythonユーザーが主にMLの目的でスケーラブルなソフトウェアを構築できるようにすることを目的としたプロジェクトとして始まりました。それ以来、特定のMLユースケース専用のモジュールをいくつか追加しました。1つは分散ハイパーパラメーター調整で、もう1つは分散RLです。

その結果、人気の数値は、おそらくRLではなく、ハイパーパラメーターと汎用のスケーラビリティのユースケースに起因する可能性が高いです。
また、ライブラリの分散フォーカスは、エージェント実装が本質的に分散されるもの(A3Cなど)になる傾向があるか、収束するのに数年もかか​​らないように分散が必要な非常に複雑な問題を解決しようとすることを意味します(例:Rainbow)。

それにも関わらず、RLの本番稼働を検討している場合、またはハイパーパラメータチューニング、または環境改善のために訓練を何度も繰り返している場合は、「Ray」を使用してスケールアップしてフィードバック時間を短縮するのが理にかなっています。実際、他の多くのフレームワーク(具体的にはSLM-LabおよびRLgraph)は、この目的のために内部で「Ray」を使用しています。

「Ray」にはRLに強い適用性があると思います。分散計算に明確に焦点を当てることは良いことです。コミットと貢献者の膨大な数も安心です。しかし、多くの基礎となるコードはC++にあります。いくつかはJavaです。Pythonは60%だけです。

全体として、ドキュメントは優れており、明確な建築図面が提示されています。それはモジュール式で、拡張性が高く、コミュニティによって非常によくサポートされ、受け入れられています。唯一の欠点は、複雑さにあります。

◎入門
Google Colabにプリインストールされているpyarrowのバージョンには、「Ray」と互換性がありません。プリインストールされたバージョンをアンインストールし、ランタイムを再起動する必要があります。その後、動作します。

また、Dopamineの例と同じ方法でビデオ録画することができませんでした。私の仮説は、それらが別々のプロセスで実行されているため、偽のpyvirtualdisplayデバイスにアクセスできないということです。

例を試してみましょう。

!pip uninstall -y pyarrow
!pip install tensorflow ray[rllib] > /dev/null 2>&1

pyarrowを削除してrllibをインストールしたら、Notebookカーネルを再起動する必要があります。次に、Rayをインポートします。

import ray
from ray import tune

ray.init()

そして、DQNを使用してCartpole環境のハイパーパラメーター調整ジョブを実行します。

tune.run(
   "DQN",
   stop={"episode_reward_mean": 100},
   config={
       "env": "CartPole-v0",
       "num_gpus": 0,
       "num_workers": 1,
       "lr": tune.grid_search([0.01, 0.001, 0.0001]),
       "monitor": False,
   },
)

ここには多くのシンタックスシュガーがありますが、訓練機能をカスタマイズするのはかなり簡単です。

8. Keras-RL

画像4

私はKerasが大好きです。抽象化、シンプルさ、アンチロックインが大好きです。以下のコードを見ると、Kerasの魔法を見ることができます。したがって、「Keras-RL」が最適だと思います。

しかし、他のフレームワークほど多くの牽引力を得ていないようです。ドキュメントを見ると、空です。コミットを見ると、ほとんどの作業を行った少数の勇敢な魂だけがいます。これをメインのKerasプロジェクトと比較してください。

そして、私はその理由を知っていると思います。Kerasは、ユーザーがさまざまなDL構造をすばやくプロトタイプできるようにゼロから構築されました。これは、ニューラルネットワークを抽象化してモジュール化できるという事実に依存していました。しかし、keras-rlのコードを見ると、教科書にあるように実装されています。たとえば、SARSAとDQNの類似性にもかかわらず、各エージェントには独自の実装があります。モジュール性にはある程度のレベルがありますが、レベルが高すぎると思います。

しかし、手遅れではありません。多くの人が興味を持った場合、またはコアKerasプロジェクトからより多くのサポートがあった場合、これが将来のRLフレームワークになる可能性があります。

しかし今のところ、私はそうは思いません。すでに説明した他のフレームワークを使用することで、Kerasの利点を簡単に得ることができるからです。

◎入門
公式のサンプルはそのまま使用できます。私が行った変更は、模擬ディスプレイを使用して、テストのビデオ録画を追加することだけでした。

import numpy as np
import gym

from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.optimizers import Adam

from rl.agents.dqn import DQNAgent
from rl.policy import BoltzmannQPolicy
from rl.memory import SequentialMemory

ENV_NAME = 'CartPole-v0'

# Get the environment and extract the number of actions.
env = gym.make(ENV_NAME)
np.random.seed(123)
env.seed(123)
nb_actions = env.action_space.n

# Next, we build a very simple model.
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'))
print(model.summary())

# Finally, we configure and compile our agent. You can use every built-in Keras optimizer and
# even the metrics!
memory = SequentialMemory(limit=5000, 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'])

# Okay, now it's time to learn something! We visualize the training here for show, but this
# slows down training quite a lot. You can always safely abort the training prematurely using
# Ctrl + C.
dqn.fit(env, nb_steps=2500, visualize=True, verbose=2)

# After training is done, we save the final weights.
dqn.save_weights('dqn_{}_weights.h5f'.format(ENV_NAME), overwrite=True)

# Finally, evaluate our algorithm for 5 episodes.
dqn.test(Monitor(env, '.'), nb_episodes=5, visualize=True)

9. TRFL

画像5

「TRFL」は、DeepmindによるTensorflowの拡張版です。人気があると予想されますが、最初に気付くのは、コミットとサンプルとTensorflow 2.0サポートの明確な欠如です。

主な問題は、低レベルすぎることです。Keras-RLの正反対です。TRFLが提供する機能は、いくつかのヘルパー関数です。たとえばQ学習値関数は、抽象名を持つTensorflowテンソルの負荷を取り込みます。

◎入門
例として、このノートブックを見ることをお勧めします。
ただし、コードは非常に低レベルであることに注意してください。

10. Tensorforce

画像6

「Tensorforce」には、「TRFL」と同様の目的があります。Tensorflowをターゲットにしながら、RLプリミティブを抽象化しようとします。Tensorflowを使用することで、Tensorflowを使用することのすべての利点、つまりグラフモデル、簡単なクロスプラットフォーム展開が得られます。環境、ランナー、エージェント、モデルの4つの高レベルの抽象化があります。これらはほとんどあなたが期待することを行いますが、「モデル」抽象化は通常見られるものではありません。

モデルはエージェント内にあり、エージェントのポリシーを定義します。これは、たとえば、標準のQ学習モデルを1つの小さな関数のみを変更するQ学習nステップモデルでオーバーライドできるため、便利です。

これはまさに私が探していたTRFLとKerasの中間です。そして、それはOOP方式で実装されており、一部の人はそれを好み、他の人は好みません。しかし、少なくとも抽象化はあります。

このようなライブラリ、またはDLに焦点を当てたRLライブラリーの欠点は、コードの多くが基礎となるDLフレームワークによって複雑になることです。
ここでも同じことが言えます。
たとえばランダムモデル、つまりランダムアクション(正確に1行のコードを必要とするもの)を選択するモデルは、79行の長さです。私はここで少し面白くなっています(ライセンス、クラスボイラープレート、改行など)。

また、「単純な」RLアルゴリズム、つまりモデルを使用しないRLアルゴリズムの実装がないことも意味します。エントロピー、バンディッット、単純なMDP、SARSA、いくつかの表形式の方法など。これらのモデルにはDLフレームワークが必要ないためです。

要約すると、抽象化のレベルはスポットにあると思います。ただし、DLフレームワークに限定することの利点と問題は残っています。

これはバージョン0.4.3に基づいており、主要な書き直しが進行中であることに注意してください。

◎入門
入門のサンプルは賢明です。環境、エージェント、ランナー(実際にトレーニングを行うもの)を作成しています。ただし、エージェントの仕様は少し異なります。
標準のJSONを使用していることを除いて、Dopamine Ginの設定を思い出させます。サンプルでは、それらの仕様をexamplesディレクトリから取得していますが、それらを使用してハイパーパラメータ検索を実行することがどれほど簡単か想像できます。

environment = OpenAIGym(
   gym_id="CartPole-v0",
   monitor=".",
   monitor_safe=False,
   monitor_video=10,
   visualize=True
)

with urllib.request.urlopen("https://raw.githubusercontent.com/tensorforce/tensorforce/master/examples/configs/dqn.json") as url:
 agent = json.loads(url.read().decode())
 print(agent)
with urllib.request.urlopen("https://raw.githubusercontent.com/tensorforce/tensorforce/master/examples/configs/mlp2_network.json") as url:
 network = json.loads(url.read().decode())
 print(network)

agent = Agent.from_spec(
 spec=agent,
 kwargs=dict(
   states=environment.states,
   actions=environment.actions,
   network=network
 )
)

runner = Runner(
   agent=agent,
   environment=environment,
   repeat_actions=1
)

runner.run(
   num_timesteps=200,
   num_episodes=200,
   max_episode_timesteps=200,
   deterministic=True,
   testing=False,
   sleep=None
)
runner.close()

11. Horizon

画像8

「Horizo​​n」はFacebookのフレームワークで、PyTorch専用です。「Horizo​​n」の主な使用例は、バッチ設定でRLモデルを訓練することです。具体的には、入力データを考慮して可能な限り最良の方策を学習しようとします。

したがって、他のフレームワークと同様に、焦点は方策外のモデル駆動型RLとモデル内のDLです。これはPyTorchの使用により区別されます。KerasのバックエンドとしてPyTorchを使用して、これをKeras-RLと比較することもできます。

TensorForceのセクションで、このような焦点を絞ったフレームワークの短所について既に説明したので、再度説明しません。

ただし、いくつかの興味深い違いがあります。Gymとの緊密な統合はありません。代わりに、GymデータをJSONにダンプし、JSONをエージェントに読み戻すことで、意図的に2つを分離します。これは冗長に聞こえるかもしれませんが、実際にはデカップリングに非常に適しているため、よりスケーラブルで、脆弱性が少なく、柔軟性があります。欠点は、複雑さが増すため、ジャンプするフープが増えることです。

しかし、Horizo​​n用のpipインストーラーはありません。condaを使用し、onnxをインストールし、javaをインストールし、conda JAVA_HOMEを指すようにセットアップし、Sparkをインストールし、Gymをインストールし、Apache thriftをインストールしてから、Horizo​​nをビルドする必要があります。そのため、ノートブックにこれをインストールしようとは思いません。

◎入門
あなたは多くの時間と多くの忍耐を必要とします。

12. Coach

画像7

「Coach」のフレームワークで最初に気付くのは、実装されているアルゴリズムの数です。それは膨大であり、実装するのに何週間も何週間もかかったに違いありません。次に気付くのは、統合環境の数です。これにどれだけ時間がかかったのかを考えると、フレームワークの残りの部分に大きな希望を与えます。そして、非常に見栄えの良い専用のダッシュボードが付属しています。他のほとんどのフレームワークは、Tensorboardプロジェクトに依存しています。

これまで見たことのないすごい機能の1つは、Kubernetesの組み込み展開です。Coachによるオーケストレーションは遠すぎると思いますが、彼らがそれについて考えていたという事実は、標準的なツールでKuberentesにデプロイするのにおそらく十分にスケーラブルであることを意味します。

モジュール性のレベルは驚くべきものです。たとえば、あらゆる種類の探索戦略を実装し、さまざまなモデル設計にあらゆる種類の変更を加えることができるクラスがあります。

私が考えることができるのは少し面倒ですが、モデルとしてDLを使用するように強制するのと同じ制限です。私は、より単純なアプリケーションのサブセットはDLほど複雑なものを必要とせず、より伝統的な回帰法に利益をもたらすことができると確信しています。ただし、DLのものを削除する小さなスタブクラスを追加するのはかなり簡単であるはずです。

興味深いことに、フレームワークはKerasを使用しているため、TensorflowとMXNetをサポートしています。つまり、KerasはPyTorchをサポートしていないため、PyTorchはサポートされていません。

率直に言って、私はこのフレームワークが星やグーグルページ数の観点で人気がない理由を理解できません。最高のドキュメントと素晴らしいレベルのモジュール性を備えた最も包括的なフレームワークです。

◎入門
指摘したい重要な注意事項が2つあります。

まず、ドキュメントまたはデモのタグ付きバージョンを見ていることを確認してください。masterブランチには、pipがインストールされたバージョンでは機能しないいくつかの新機能があります。

第2に、colabにインストールされていないOpenAI Gymのバージョンに依存します。!pip install gym==0.12.5を実行してランタイムを再起動する必要があります。

import tensorflow as tf
tf.reset_default_graph() # So that we don't get an error for TF when we re-run

from rl_coach.agents.clipped_ppo_agent import ClippedPPOAgentParameters
from rl_coach.environments.gym_environment import GymVectorEnvironment
from rl_coach.graph_managers.basic_rl_graph_manager import BasicRLGraphManager
from rl_coach.graph_managers.graph_manager import ScheduleParameters
from rl_coach.core_types import TrainingSteps, EnvironmentEpisodes, EnvironmentSteps
from rl_coach.base_parameters import VisualizationParameters
global experiment_path; experiment_path = '.' # Because of some bizzare global in the mp4 dumping code


# Custom schedule to speed up training. We don't really care about the results.
schedule_params = ScheduleParameters()
schedule_params.improve_steps = TrainingSteps(200)
schedule_params.steps_between_evaluation_periods = EnvironmentSteps(200)
schedule_params.evaluation_steps = EnvironmentEpisodes(10)
schedule_params.heatup_steps = EnvironmentSteps(0)

graph_manager = BasicRLGraphManager(
   agent_params=ClippedPPOAgentParameters(),
   env_params=GymVectorEnvironment(level='CartPole-v0'),
   schedule_params=schedule_params,
   vis_params=VisualizationParameters(dump_mp4=True) # So we can dump the video
)

13. MAgent

画像9

「MAgent」は、多数エージェントRLの問題を解決できるフレームワークです。これは、単一またはごく少数のエージェントのみを使用する他のRLフレームワークと比較して、まったく目的が異なります。彼らは、何百万人ものエージェントにまで拡大できると主張しています。

しかし、これもpipインストーラーはありません。皆さん、プロジェクト用のpipインストーラーを作成してください。使いやすさ、ひいてはプロジェクトの牽引力にとって非常に重要です。おそらくパフォーマンス上の理由で、プロジェクト全体がCで書かれているからだと思います。

内部でTensorflowを使用し、独自のグリッドワールドのような環境を構築します。エージェントは、「実際の」シミュレーションを念頭に置いて設計されています。たとえば、エージェントのサイズ、表示できる範囲を指定できます。エージェントに渡される観察はグリッドで、行動は「移動」「攻撃」「方向転換」に限定されます。柔軟なルール定義に従って報酬が与えられます。

要するに、フレームワークは、ライフスタイルゲームのゲームをすぐに使えるようにセットアップされており、エージェントの振る舞いや報酬に関する追加のモジュール性を備えています。このため、より高度なDLメソッドのいくつかを使用して、複雑で調整されたタスクを実行するようにエージェントを訓練できます。詳細については、入門ガイドをご覧ください。

私はこのアイデアに非常に感銘を受けました。ただし、上記のGithubの統計からわかるように、1年に4回のコミットは基本的にほとんど使用されていないことを意味します。最後の主要な更新は2017年でした。これは他に類を見ないフレームワークであるだけに残念です。

◎入門
入門ガイドからいくつかのサンプルを試しました。訓練版には数時間かかります。しかし、examples/api_demo.pyは学習したモデルをテストしているだけなので、非常に高速です。

ただし、独自のテキスト形式で環境をレンダリングします。ブラウザでレンダーを解析してホストするWebウェブサーバを実行する必要がありますが、私たちは共同研究室にいるため、Webサーバを実行することはできません。
そのため、ファイルをダウンロードしようとしましたが、MacではなくColabでバイナリをビルドしたため、バイナリを実行できませんでした。

それで少しイライラしました。gifまたはmp4のmp4などの標準形式でレンダリングした場合は、はるかに簡単になります。また、残念なことに、私はいくつかの複雑な動作を生成することを楽しみにしていました。

しかし、以下の著者がのデモが目を楽しませてくれます。

そして、機能したコードの残りは次のとおりです。

!git clone https://github.com/geek-ai/MAgent.git
!sudo apt-get install cmake libboost-system-dev libjsoncpp-dev libwebsocketpp-dev
%cd MAgent
!bash build.sh

!PYTHONPATH=$(pwd)/python:$PYTHONPATH python examples/api_demo.py

この最後の呼び出しは、examplesフォルダ内の任意のpythonファイルと交換できます。

14. TF-Agents

画像11

「TF-Agents」は、Googleのもう1つのNOGPであり、Tensorflow専用のフレームワークです。したがってこれを、「TRFL」「TensorForce」「Dopamine」の直接の競合として扱います。

誰かが疑問を投げかけます。「TRFL」と「Dopamine」が既に存在するのに、なぜGoogle従業員が別のRLフレームワークを作成したのでしょうか。「TF-Agents」と「Dopamine」の関係を議論する中で、貢献者は次のように示唆しています。

「Dopamine」とTF-Agentは強く重複しているようです。「Dopamine」は、再現性がプロジェクトの中心に置かれているため、高速プロトタイピングとベンチマークに使用されることを目指していますが、「TF-Agent」は、生産レベルの強化学習アルゴリズムによって使用されます。

正直に言うと、「生産レベル」が何を意味するのかわかりません。コラボの優れたサンプルがいくつかありますが、ドキュメントはありません。そして、実稼働環境でノートブックを使用すべきではありません。

サンプルを掘り下げると、コードが非常に重いことが明らかになります。たとえば、単純なCartPoleのサンプルには多くのコード行があります。そこには多くの説明とデバッグコードがありますが、それは今後の兆候のように見えます。

ただし、コードは非常にきれいに見えます。それはうまく分離されており、モジュール性はよさそうです。あなたが期待するすべての抽象化はそこにあります。私が選びたいのはエージェントの抽象化だけです。これは基本クラスであり、Tensorflowに直接結合されています。これはかなりの量の複雑さを追加し、それが抽象化されて欲しいので、必要になるまで心配する必要はありませんでした。他の抽象化の大部分についても同じことが言えます。

とはいえこれは、「TRFL」よりもはるかに有能なライブラリであることは明らかです。

◎入門
リポジトリにはノートブックが用意されているので、ここにコピーして貼り付けるだけで時間を無駄にすることはありません。Colabで直接実行することもできます。

15. SLM-Lab

画像10

「SLM-Lab」は、PyTorchに基づくモジュラー型のRLフレームワークです。
研究者向けに設計されているようです。彼らはモジュール性の重要性を強調していますが、単純かつモジュール化することはおそらく不可能だと正しく述べています。興味深いことに、それはスケーラブルにするために、内部で「Ray」も使用されています。

2017年にスタートし、貢献者が少なく、GitHubスターの相対的な人気にもかかわらず、多くの活動があります。コミットの大部分はワンライナーですが、著者によるコミットは驚くべきものです。

残念ながら、これはpipでインストールできないフレームワークであり、ビルド関連のCライブラリとminicondaの全負荷をインストールしようとします。
これはColabでは問題です。優れたエンジニアであるため、すべてのドキュメントを無視し、試行錯誤を繰り返して自分で機能するように努めました。
それはほとんど機能しましたが、PyTorchを初期化するときに、修正方法がわからないという問題に遭遇しました。

ドキュメントに少し苦労しました。アーキテクチャドキュメントは限られており、残りの部分は、使用の方に重点を置いています。しかし、使用法とは、現在の実装で実験を実行することを意味します。モジュールをさまざまな方法で接続する方法を教えてくれるドキュメントを見つけるのに苦労しました。これはJSON仕様ファイルを介して行われるべきだと彼らは考えていると思います。実際、最初の動機は次のとおりです。

アルゴリズムと環境を比較し、仮説をテストするための実験をすばやくセットアップし、コンポーネントを再利用し、結果を分析して比較し、結果を記録できるフレームワークが必要でした。

そのため、ここでの目標は、「Dopamine」や「TensorForce」によく似た構成による再利用を可能にすることです。

この「構成としてのRL」はテーマのようです。しかし、私は確信していません。私は、コードがより慣用的で、より柔軟であると主張します。それは人々が慣れているものです。ユーザーが学習しなければならない別のドメイン固有言語(DSL)である構成を介して何かを行うたびに。そして、そのDSLは一般に静的である(Ginはそうではない)ため、DSLの実装が制限を設定します。DSLでカバーされないエッジケースが存在するため、すべての人に適しているわけではありません。

16. DeeR

画像12

「DeeR」の最初の印象は良いものでした。pipインストーラーがあります。それはモジュール性について叙情的です。Pythonの依存関係は、「numpy」と「Joblib」の2つだけです。

ドキュメントは明確ですが、全体的なアーキテクチャのドキュメントが欠落しています。ドキュメントを見つけるには、クラスとコードを掘り下げる必要があります。

「モジュール」は、「Environment」「Agent」「Policies」のように、予想どおりに分割されています。そして、「Controller」という興味深いクラスがあります。このクラスは、エピソード完了や行動実行毎などのライフサイクルフックを提供します。

たとえば、エピソードの最後に何らかのログを取りたい場合、このクラスをサブクラス化し、onEpisodeEndをオーバーライドできます。「Controller」のサンプルがいくつかあり、そのうちの1つが「EpsilonController」です。
これにより、e-greedyアルゴリズムの値etaまたはepsilon値を動的に変更できます。

実行中に学習プロセスを変更できるため、これは非常に強力です。しかし、ソフトウェアエンジニアリングの観点からすると、これは非常に危険です。「プログラマーはここにいる」ので、関数型プログラマーは別のオブジェクトの状態を変更しないように指示します。APIの機能がより優れていて、エージェントのeta状態を直接変更するのではなく、たとえばエージェントのnextを計算する関数を渡すことができれば、より便利でした。ただし、これにより若干複雑になる場合があります。

フレームワークにはいくつかの学習アルゴリズムも含まれていますが、Coachのような包括的なものではありません。

◎入門
pipのインストールと非常に少ない依存関係のおかげで、起動と実行が最も簡単なフレームワークでした。

!pip install git+git://github.com/VINF/deer.git@master
!git clone https://github.com/VinF/deer.git

例を実行できるように、gitリポジトリのクローンを作成しました。
次に、すべてをインポートします。

%cd /content/deer/examples/toy_env
import numpy as np
from deer.agent import NeuralAgent
from deer.learning_algos.q_net_keras import MyQNetwork
from Toy_env import MyEnv as Toy_env
import deer.experiment.base_controllers as bc

そしてサンプルを実行します。

rng = np.random.RandomState(123456)

# --- Instantiate environment ---
env = Toy_env(rng)

# --- Instantiate qnetwork ---
qnetwork = MyQNetwork(
   environment=env,
   random_state=rng)

# --- Instantiate agent ---
agent = NeuralAgent(
   env,
   qnetwork,
   random_state=rng)

# --- Bind controllers to the agent ---
# Before every training epoch, we want to print a summary of the agent's epsilon, discount and
# learning rate as well as the training epoch number.
agent.attach(bc.VerboseController())

# During training epochs, we want to train the agent after every action it takes.
# Plus, we also want to display after each training episode (!= than after every training) the average bellman
# residual and the average of the V values obtained during the last episode.
agent.attach(bc.TrainerController())

# All previous controllers control the agent during the epochs it goes through. However, we want to interleave a
# "test epoch" between each training epoch. We do not want these test epoch to interfere with the training of the
# agent. Therefore, we will disable these controllers for the whole duration of the test epochs interleaved this
# way, using the controllersToDisable argument of the InterleavedTestEpochController. The value of this argument
# is a list of the indexes of all controllers to disable, their index reflecting in which order they were added.
agent.attach(bc.InterleavedTestEpochController(
   epoch_length=500,
   controllers_to_disable=[0, 1]))

# --- Run the experiment ---
agent.run(n_epochs=100, epoch_length=1000)

ここでは、環境をインスタンス化し、Q-Learningアルゴリズムを作成し、そのアルゴリズムを使用するエージェントを作成しています。次にエージェントの関数attach()を使用して、これまでに説明してきたこれらすべてを追加します。ロギングとインターリーブのトレーニング期間とテスト期間を追加します。このいずれかを編集したい場合は、興味のある部分を再実装するだけです。

唯一の問題は、Toyのサンプルが機能しなかったことです。理由はわかりません。テストスコアが常に0であり、訓練損失が時間とともに増加するという点で、訓練値は少し奇妙に見えました。

17. Garage

画像13

「Garage」は「RLlab」の後続であり、同じ目的を持ちますが、個々のサポートではなく、コミュニティになります。ドキュメントは少しまばらです。たとえば、多数のアルゴリズムを実装していることを強調していません。
実際、この静かな小さなディレクトリには、必要なものがほとんどすべてあります。ただし、それが問題になる場合は、Tensorflowと非常に緊密に結合されています。

ここには多くの機能がありますが、完全に隠されています。コードはかなり適切に文書化されていますが、公開されていません。あなたはそれを見つけるためにそれを掘り下げる必要があります。

繰り返しますが、pipインストーラーはありません。いくつかのカスタムcondaのインストールといくつかのapt-get依存関係だけです。そのため、アルゴリズムの実装には非常に大きな価値があることがわかりますが、今回は開始をスキップします。

18. Surreal

画像14

「Surreal」は、アプリケーションのスイートです。まず第1に、それはRLフレームワークです。ただし、別のフレームワークを構築しないように、新しいRoboticsシミュレータ、オーケストレーター、クラウドインフラストラクチャプロビジョニング機能、分散コンピューティング用のプロトコルも提供します。それはスタンフォードから来ているため、アプローチとユースケースは学術的であるため、PyTorchのデフォルトの使用です。

私はすべてフレームワークとシミュレーターですが、オーケストレーター(Kubernetes)、インフラストラクチャー(Terraform)、およびプロトコル(Kafka / Nats / etc / etc)に標準の産業用コンポーネントを使用した方が簡単だったでしょう。これらの問題はすでに解決されています。

ロボットシミュレータは、MuJoCoシミュレーションのコレクションです。
そのため、これは(MuJoCoのライセンス条項にもかかわらず)環境リストに追加されました。

RLフレームワークには、人生に大きな調和が必要です。apt-getとcondaのインストールの別の組み合わせです。

ああすごい。私は、彼らがGithubの課題追跡を無効にしていることに気づきました。そして、各著者に属する明示的な著作権表示があります。これはオープンソースではありません。しかし、ロボスイートはMITライセンスを取得しているのでしょうか。非常に奇妙です。ここで停止します。

19. RLgraph

画像15

「RLgraph」には膨大な数のコミットがあると言うことから始めましょう。
彼らは年間4000件のコミットを実行しています。わずか221のOpenAI Gymと比較してください。誰かがこれら5人に休暇をとるように伝える必要があります。そして、それはほんの1歳です。フルタイムで使用されていることしか想像できません。

とにかく。他のフレームワークと同様に、スケーラビリティに焦点を合わせています。しかし、興味深いことに、彼らはTensorflowとPytorchの両方に直接マッピングしています。彼らはKerasを使用していません。それはそれ自体が大きな挑戦だったに違いありません。「Ray」を使用して、「SLM-Lab」のような作品を配布したようです。

しかし、これはpipインストーラーを持っています。エージェントの構成は、JSONを介して制御されます。しかし構成のみで、構造ではありません。

著者が「TensorForce」にも取り組んでいることを読んだばかりです。これは、私が感じているデジャヴの一部を説明しています。また、基礎となるDLフレームワークがRL実装コードに漏れることが多いという「TensorForce」での苦情が「RLgraph」で対処されたことを気に入っています。

テンソルの空間を論理的な構成から分離することにより、互換性のない形状を再び手動で処理することなくコンポーネントを再利用できます。上記のコードにはフレームワーク固有の概念は含まれず、空間のセットからの入力データフローのみを定義することに注意してください。

そして、これは入力と出力の抽象化によって達成されます。それ以外は、APIはおなじみです。環境とエージェント。 DLビルディングブロックを抽象化する非常にクールなコンポーネントクラスがあります。

ただし、ここには欠落している抽象化があります。ポリシーの抽象化はありません。探査の抽象化はありません。

それでも、私は感銘を受けました。

◎入門
CartPoleの開始例を少し変更して、SingleThreadedWorkerを使用し、環境でのレンダリングを有効にしてビデオ録画を取得しました。それ以外はすべて非常に馴染みがあるように見えます。

import numpy as np
from rlgraph.agents import DQNAgent
from rlgraph.environments import OpenAIGymEnv
from rlgraph.execution import SingleThreadedWorker

environment = OpenAIGymEnv('CartPole-v0', monitor=".", monitor_video=1, visualize=True)

# Create from .json file or dict, see agent API for all
# possible configuration parameters.
agent = DQNAgent.from_file(
 "configs/dqn_cartpole.json",
 state_space=environment.state_space,
 action_space=environment.action_space
)

episode_returns = []

def episode_finished_callback(episode_return, duration, timesteps, **kwargs):
 episode_returns.append(episode_return)
 if len(episode_returns) % 10 == 0:
   print("Episode {} finished: reward={:.2f}, average reward={:.2f}.".format(
     len(episode_returns), episode_return, np.mean(episode_returns[-10:])
   ))

worker = SingleThreadedWorker(env_spec=lambda: environment, agent=agent, render=True, worker_executes_preprocessing=False,
                             episode_finish_callback=episode_finished_callback)
print("Starting workload, this will take some time for the agents to build.")

# Use exploration is true for training, false for evaluation.
worker.execute_timesteps(1000, use_exploration=True)

20. Simple RL

画像16

他のすべてのフレームワークでは、目標はパフォーマンス/スケーラビリティ、モジュール性、再現性であると述べています。それらのどれも単純であるように設定されていません。これが「Simple RL」が介入する場所です。可能な限りシンプルになるようにゼロから構築されています。依存関係はnumpyとmatplotlibの2つのみです。そして、それは結果をプロットしたい場合のみです。そして、pipインストーラーがあります。ドキュメントは存在しません。

エージェント、実験、mdpと呼ばれる環境など、おなじみの抽象化されたコレクションを提供します。フレームワークは、行動、関数、状態など、モデルの他の部分も抽象化します。そして、次の行動の戦略を実装する計画クラス。まだ非常にモジュール化されていますが、他のフレームワークに合わせて命名規則の一部を変更する必要があります(標準化)。

そのため、「シンプル」は必ずしも理解しやすいという意味ではないことが明らかになりつつあります。一般に、抽象化が進むと理解しにくくなります。この場合のシンプルなのは「使いやすさ」です。それは残念だと思います。私は本当にアンダータンディングの点でシンプルさを望んでいました。しかし、より複雑なフレームワークのいくつかと競合することを目指しているようです。PyTorchによるDepp RLのサポートは開発中です。

フレームワーク市場には、非常にシンプルで理解可能なRLフレームワークのギャップがあり続けています。そして、なぜこのフレームワークが他と比べて星が少ないのか分かりません。おそらく、他の多くのフレームワークのように、他のDLフレームワークの人気をブートストラップしていないからでしょう。

◎入門
簡単です。しかし、コードの奥深くには、MatplotlibにTkAggバックエンドの使用を強制するいくつかの行があります。ノートブックでTkAggを動作させようとしましたが、できませんでした。グラフィカルなデスクトップ用に設計されているため、簡単ではないことが想像できます。

それが機能する場合/それは次のような単純なものでなければなりません。

from simple_rl.agents import QLearningAgent, RandomAgent, RMaxAgent
from simple_rl.tasks import GridWorldMDP
from simple_rl.run_experiments import run_agents_on_mdp

# Setup MDP.
mdp = GridWorldMDP(width=4, height=3, init_loc=(1, 1), goal_locs=[(4, 3)], lava_locs=[(4, 2)], gamma=0.95, walls=[(2, 2)], slip_prob=0.05)

# Setup Agents.
ql_agent = QLearningAgent(actions=mdp.get_actions())
rmax_agent = RMaxAgent(actions=mdp.get_actions())
rand_agent = RandomAgent(actions=mdp.get_actions())

# Run experiment and make plot.
run_agents_on_mdp([ql_agent, rmax_agent, rand_agent], mdp, instances=5, episodes=50, steps=10)

これにより、いくつかの異なるエージェントが訓練され、それぞれの報酬プロットが作成されます。私がお勧めする唯一のことは、「Simple RL」に環境の実装がないことです。それは範囲外です。Gymなどに任せてください。たとえば、gym-minigridには素晴らしいGridworld実装があります。


この記事が気に入ったらサポートをしてみませんか?