5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

HandyRLの使い方

Last updated at Posted at 2022-12-12

Qiita 初投稿です。研究で HandyRL を使うことになったので、使い方などを備忘録としてまとめようと思います。HandyRL を使ってみたいけどやり方が分からない人の参考になればと思います。
HandyRL

目次

HandyRLとは
使い方
- 準備
- 実行
応用
- 2台の計算機を使って並列学習をする
- 学習の勝率の可視化
そのほか
- パラメータの詳細
- 参考文献

HandyRLとは

HandyRL は DeNA が開発した最新の並列強化学習のフレームワークです。 この HandyRL は 「誰でも強化学習を手軽に扱える」「対戦ゲームにおいて強くて勝てるAIが作れる」「並列度を上げて学習がスケールする」ことの3つを目指して開発されたらしいです(参考元)。実際に kaggle で行われた Hungry Geese コンペティション(ヘビのゲーム)で優勝もしている強くて勝てるAIです。本当に手軽に動かすことができるので、強化学習に興味がある方はぜひ動かしてみてください。また実装するのが難しい並列強化学習を簡単に使うことができ、高速で学習することができるようになっています。

使い方

内容はほぼ GitHub の README 通りですが、ちょっと補足とか自分が詰まった点とかを書いときます。

書いてる人の動作環境

  • MacBook Pro(2017)
  • macOS Monterey バージョン:12.6.1( Ubuntu16.04.7 でも動かせた)
  • Visual Studio Code バージョン:1.73.1
  • anaconda バージョン:4.13.0

必要なもの

  • Python バージョン:3.7 以上

準備

インストール

HandyRLのリポジトリを自分の手元の環境に落とします。

GitHubからクローンする場合

以下を実行でGitHubからクローンを作成

ターミナル
git clone https://github.com/DeNA/HandyRL.git

GitHubから直接ダウンロードする場合

1. HandyRLのGitHubページにアクセス
2. ページ内の< > Code ▼ (緑色のボタン)をクリック
3. Download Zipから自分の手元の環境にzipファイルをダウンロード
4. お好きなところでzipファイルを解凍

HandyRLで使うライブラリのインストール

HandyRLのディレクトリに移動

ターミナル
cd HandyRL

追加のライブラリ (numpy、pytorch など) をインストール

ターミナル
pip3 install -r requirements.txt

Dockerや仮想環境上で実行(pythonの環境構築が必要)

kaggleの環境(Hungry Geeseなど)を使う場合には以下も追加でインストール

ターミナル
pip3 install -r handyrl/envs/kaggle/requirements.txt

実行

パラメータを設定する

config.yamlでパラメータの設定をすることができます。デフォルトの環境は Tic-Tac-Toe(三目並べ) になっていて、他には geister や kaggleのコンペであった Hungry Geese, Parallel Tic-Tac-Toe を選択することができます。また自分で作成した環境を利用して学習させることも可能となっています。私自身研究用の環境を作成して追加したことがあります。興味がある方はぜひ別記事(後日公開予定)を読んでみてください。

config.yaml
env_args:
    env: 'TicTacToe' #環境指定

train_args:
    ...
    batch_size: 64 #バッチサイズ
    ...

上記のコードの場合は環境を Tic-Tac-Toe に, バッチサイズを64に設定しています。

学習させる

パラメータ設定後、以下のコマンドで学習させることができます。学習済みのモデルはmodels内に保存されます。

ターミナル
python main.py --train

config.yamlのエポック数を決めるパラメータが初期状態だとepochs:-1になっていて学習が止まらないので注意

学習させたモデルを評価する

以下のコマンドで任意のモデルを評価することができます。下の場合は評価のプロセス数を4つに指定し、100ゲーム行ったときのmodels/1.pthのモデルを評価してます。

ターミナル
python main.py --eval models/1.pth 100 4

応用

2台の計算機を使って並列学習をする

計算機の性能次第ですが、学習速度がめちゃめちゃ早くなります。
うまく使えば AWS とか GoogleColab とかでも動かせるかも?(やり方わからないので有識者いたらコメントください)

パラメータの設定

config.yamlの以下の部分を設定します

config.yaml
woker_args:
    server_address: '' # サーバーのIPアドレス
    num_parallel: 8 # ワーカーの数

おそらく外部からアクセスできるアドレスじゃないと接続できないので注意

学習させる

以下を親サーバ側(server_addressに設定したIPアドレスの方)で実行します

ターミナル
python main.py --train-server

以下を子サーバ側で実行します

ターミナル
python main.py --worker

いろいろな実行方法
python main.py *** (***の部分は短縮可能)

  • 通常の学習:--train or -t
  • 学習サーバを起動:--train-server or -ts
  • ワーカーを起動:--worker or -w
  • モデルの評価:--eval or -e

学習させたモデルを評価する

通常時と同様

ターミナル
python main.py --eval models/1.pth 100 4

学習の勝率の可視化

scripts/win_rate_plot.pyを使うことで可視化ができます。
学習時の出力を任意の.txtに出力する必要があります。
ちなみに公式はあまり推奨していなさそう?なので自己責任でお願いします。(可視化のコードに注意書きがありました)

ライブラリを追加インストール

ターミナル
pip3 install -r scripts/requirements.txt

可視化する際の学習方法(ファイル出力)

今回はteeコマンドを使って txt ファイルに学習時のログを出力します。

ターミナル
python main.py --train | tee train-log-000.txt

上記コードの000の部分は任意の値でOK(txtファイル自体の名称も任意で大丈夫だったはず・・・)

学習の可視化

ターミナル
python3 scripts/win_rate_plot.py train-log-000.txt all

train-log-000.txtの部分で可視化したいログファイルを指定し、allでグラフのタイトルを指定できます。

ログのパスに注意(上記のコードだとmain.pyと同じ階層にtxtファイルがある)

可視化できずにエラーが出た場合

エラー内容

ターミナル
ValueError: x and y must have same first dimension, but have shapes (86,) and (87,)

原因

ログファイルの終わりの部分が前後している可能性があるので修正します。

train-log-000.txt(修正前)
epoch 98
win rate = 0.826 (73.5 / 89)
generation stats = 0.000 +- 0.928
loss = p:-0.038 v:0.104 ent:1.491 total:-0.037
updated model(295)
20300 20400 opened worker 0
closed worker 0
opened worker 3
~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~~
disconnected
disconnected

epoch 99
win rate = 0.753 (67.0 / 89)
generation stats = 0.000 +- 0.939
loss = p:-0.041 v:0.114 ent:1.505 total:-0.031
updated model(298)
disconnected
finished server

上記の通り epoch 98epoch 99の間にopend woker ~などが入っています(上はepochs:100で実行した場合です)。通常の場合は、epoch 99の後に表示されるのが変な位置で表示されているためエラーが出ているっぽいです。

対処法

力技になりますがログファイルをちょっと書き換えます。

train-log-000.txt(修正後)
epoch 98
win rate = 0.826 (73.5 / 89)
generation stats = 0.000 +- 0.928
loss = p:-0.038 v:0.104 ent:1.491 total:-0.037
updated model(295)
20300 20400
epoch 99
win rate = 0.753 (67.0 / 89)
generation stats = 0.000 +- 0.939
loss = p:-0.041 v:0.114 ent:1.505 total:-0.031
updated model(298)
disconnected
finished server

open woker ~などをバッサリ削除してepoch 98epoch 99を繋げました。これで可視化できるはず・・・。
ちなみにopen woker ~部分は可視化に影響しないので消して大丈夫です。

そのほか

パラメータの詳細

ここではconfig.yaml内のパラメータについて記載します。
間違っていたらご指摘いただけると幸いです。

環境のパラメータ設定(env_args)

  • env(string型)
    • 学習させる環境名
    • TicTacToe, Geister, ParallelTicTacToe, HungryGeese
    • 自身で作成した環境を使用する場合はhandyrl/envs/環境名.pyに自作環境を置く必要がある
      • environment.pyENVにも追加する必要があるかも?

学習のパラメータ設定(train_args)

ここのパラメータは学習時に使われます。(python main.py --train or python main.py --train-server

  • turn_based_training(bool型)
    • 環境がターン制のゲーム(複数のプレイヤーが交互に行うゲーム)かどうかのフラグ
    • True:ターン制のゲーム(Tic-Tac-Toe, Geister)
    • False:ターン制じゃないゲーム(HungryGeese)
  • observation(bool型)
    • 学習時に対戦相手の機能を使用するかどうか
  • gamma(double型)
    • 0.0 <= gamma <= 1.0 の範囲で設定
    • 割引率
  • forward_steps(int型)
    • 学習に何ステップ先までの情報を用いるかの設定
  • compress_steps(int型)
    • 効率的にデータを処理するためにエピソードのデータを圧縮する手順?
    • 注意点】システムで使われるパラメータらしいので初期設定でもOK
  • entropy_regularization (double型)
    • 0.0 <= entropy_regularizationの範囲で設定
    • エントロピー正則化係数
  • entropy_regularization_decay (double型)
    • 0.0 <= entropy_regularization_decay <= 1.0 の範囲で設定
    • ステップ進行中のエントロピー正則化の減衰率
    • 注意点】HandyRLの場合は、ターンが進むにつれて減衰するらしい
    • 注意点】値が大きいほど効果が小さく、値が小さいほど効果が大きくなる
  • update_episodes(int型)
    • モデルを更新して保存するエピソードの間隔の設定
    • 設定したタイミングでワーカーのモデルが更新される
  • batch_size(int型)
    • バッチサイズ
  • minimum_episodes(int型)
    • エピソードのデータを保存するための最小のバッファサイズ
    • minimum_episodes以上のエピソードのデータが貯まったら学習が開始される
  • maximum_episodes(int型)
    • minimum_episodes <= maximum_episodesの範囲で設定
    • エピソードのデータを保存する最大のバッファサイズ
    • maximum_episodes以上にデータが貯まると古いものから無くなる
  • epochs(int型)
    • トレーニングを停止するエポックの設定
    • 注意】 0未満に設定した場合は無限にトレーニングする
  • num_batchers(int型)
    • マルチプロセスでバッチデータを作成するバッチャーの数
  • eval_rate(double型)
    • 評価に使うワーカーの割合
    • 残りはデータ生成用のワーカー
  • worker
    • num_parallel(int型)
      • ワーカーの数
  • lambda(double型)
    • 0.0 <= lambda <= 1.0 の範囲で設定
    • モンテカルロ法と1ステップTD法の両方で用いられるラムダの値
    • 注意】詳細はTD(λ)wikiを参照
    • 注意】HandyRLではTD, V-Trace, UPGOのラムダを使用して値を計算する
  • policy_target(enum型)
  • value_target(enum型)
  • seed(int型)
    • learnerとworkerのseedの設定
    • 注意】現状は再現性が保証されてない
  • restart_epoch(int型)
    • 学習を再開するエポック数
    • 100と設定するとmodels/100.pthから学習が再開されて、次のモデルmodels/101.pthから保存されるようになる

ワーカーのパラメータ設定(worker_args)

ここのパラメータは並列学習するときにのみ使われます。(python main.py --worker)

  • server_address(string型)
    • ワーカーから接続されるトレーニングサーバーのアドレス
    • 注意】クラウドサービス(GCP,AWSなど)でモデルを学習する場合、仮想マシンの内部/外部のIPをここで設定できるらしい
  • num_parallel(int型)
    • ワーカーの数

参考文献

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?