モンテカルロ・シミュレーションに用いる着手の確率分布を学習させる方法を記述します. 使用している手法はBradley-Terryモデルを用いたMinorization Maximization法 (以下, MM法) です.
学習するSGFファイルを用意してください. なお, Rayに実装しているSGFパーサは分岐を扱えないため, 分岐のないSGFファイルである必要があります. 用意したSGFファイルは適当なディレクトリに配置し, 1.sgf, 2.sgf, 3.sgf, ...,と"<数値>.sgf"というファイル名に統一してください.
はじめに学習する配石パターンのターゲットを収集します. 学習対象とする配石パターンの収集処理はsrc/learn/PatternAnalyzer.cppに実装しています. 特に実装について変更する必要はありません.
パターン収集に関するパラメータは下記の通りです. 各パラメータはinclude/learn/PatternAnalyzer.hppに定義しています.
項目 | 概要 | デフォルト値 | 変更の要否 |
---|---|---|---|
ANALYZE_KIFU_PATH | パターンを収集するSGFファイルが格納されているディレクトリのパス. 後述するTRAIN_KIFU_PATHと一致させてください. | *** | 環境に合わせて変更 |
ANALYZE_KIFU_START | 棋譜の最初のファイルインデックス. | 1 | 実行環境に合わせて変更 |
ANALYZE_KIFU_END | 棋譜の最後のファイルインデックス. | 30000 | 実行環境に合わせて変更 |
HASH_TABLE_MAX | マンハッタン距離3以上のパターンを記録するハッシュテーブルのサイズ. | 16777216 | 変更不要 |
HASH_TABLE_LIMIT | マンハッタン距離3以上のパターンの登録するレコード数の上限. | 16000000 | 変更不要 |
HASH_TABLE_HALF | マンハッタン距離3以上のパターンを記録するハッシュテーブルの半分のサイズ | HASH_TABLE_MAX / 2 | 変更不要 |
APPEARANCE_MIN | 学習するパターンの出現回数の閾値 (1以上の整数) | 10 | 適当な値を設定 |
APPEARANCE_MINの値を小さくすると学習対象パターン数が多くなりますが, 過学習しやすくなります.
一方でAPPEARANCE_MINの数を大きくすると配石パターンの過学習を抑制できますが, 学習対象パターン数が少なくなります.
最適な値は不明なので, この値については調整の余地があると思われます.
include/learn/PatternAnalyzer.hppを変更し終わったら, src/RayMain.cppにあるAnalyzePattern関数の呼び出しのコメントアウトを解除し, GTP_main関数の呼び出しをコメントアウトしてから, プログラムを再ビルドしてください. ビルドが完了したら, オプションを設定せずに下記コマンドを実行してください.
# ./ray
プログラムの実行が完了するとlearning_result/pattern-targetディレクトリに下記4つのファイルが生成されます.
- MD2Target.txt : 学習対象とするマンハッタン距離2の配石パターン
- MD3Target.txt : 学習対象とするマンハッタン距離3の配石パターン
- MD4Target.txt : 学習対象とするマンハッタン距離4の配石パターン
- MD5Target.txt : 学習対象とするマンハッタン距離5の配石パターン
本学習で利用するファイルはMD2Target.txtのみです.
学習対象の配石パターンを収集し終わったら, Minorization-Maximization法を用いて学習を実行します. 学習の処理はsrc/learn/MinorizationMaximization.cppに実装しています. 何らかの特徴を追加, 削除して学習したい場合は本ファイルの変更が必要です.
本学習で使用するパラメータは下記の通りです. 各パラメータはinclude/learn/LearningSetttings.hppに定義しています.
項目 | 概要 | デフォルト値 | 変更の要否 |
---|---|---|---|
TRAIN_THREAD_NUM | 学習に使用するスレッド数. 使用するCPUに合わせて変更してください. スレッド数が増えるほど速くできます. | 8 | 実行環境に合わせて変更 |
TRAIN_KIFU_PATH | 学習に使用するSGFファイルが格納されているディレクトリのパス. ANALYZE_KIFU_PATHと一致させてください. | *** | 実行環境に合わせて変更 |
TRAIN_KIFU_START_INDEX | 学習する棋譜の最初のファイルインデックス | 1 | 実行環境に合わせて変更 |
TRAIN_KIFU_LAST_INDEX | 学習する棋譜の最後のインデックス | 30000 | 実行環境に合わせて変更 |
TEST_KIFU_PATH | 着手予測精度評価用のSGFファイルが格納されているディレクトリのパス. | *** | 実行環境に合わせて変更 |
TEST_KIFU_START_INDEX | 着手予測精度評価用の棋譜の最初のファイルのインデックス | 40001 | 実行環境に合わせて変更 |
TEST_KIFU_LAST_INDEX | 着手予測精度評価用の棋譜の最後のファイルのインデックス | 70000 | 実行環境に合わせて変更 |
MM_UPDATE_INTERVAL | 全ての特徴を更新するのに必要なステップ数 | 8 | 適当な値を設定 |
MM_UPDATE_STEPS | 学習ループ実行回数 | 30 | 適当な値を設定 |
MM_UPDATE_MAX | 学習ループの総実行回数 | MM_UPDATE_INTERVAL * MM_UPDATE_STEPS | 変更不要 |
LEARNING_RESULT_DIR_NAME | 学習結果を格納するディレクトリ名 | "learning_result" | 変更不要 |
PATTERN_TARGET_DIR_NAME | 学習対象の配石パターンファイルを格納したディレクトリ名 | "pattern-target" | 変更不要 |
SIMULATION_RESULT_DIR_NAME | 本学習結果を格納するディレクトリ名 | "simulation" | 変更不要 |
ACCURACY_LOG_DIR_NAME | 着手予測正解率を記録したファイルを格納するディレクトリ名 | "accuracy" | 変更不要 |
ACCURACY_LOG_FILE_NAME | 着手予測正解率を記録するファイル名 | "accuracy.log" | 変更不要 |
MD2_TARGET_FILE_NAME | 学習対象のマンハッタン距離2の配石パターンを記録したファイル名 | "MD2Target.txt" | 変更不要 |
include/learn/LearningSettings.hppを変更し終わったら, src/RayMain.cppTrainBTModelByMinorizationMaximization関数のコメントアウトを解除してプログラムを再ビルドしてください. ビルドが完了したら, オプションを設定せずに書きコマンドを実行してください.
# ./ray
学習ループがUPDATE_INTERVAL回ごとにlearning_result/simulation/resultディレクトリにパラメータを出力し, learning_result/accuracy/accuracy.logファイルにテストファイルでの正解率の計測結果を追記していきます. 各特徴の名前をつけられたテキストファイル(ex. SIM_ATARI.txt)は学習経過ファイルなので, 特に必要ありません. 学習したパラメータを利用する場合はlerning_result/simulation以下にあるresultディレクトリの内容をsim_paramsに配置してください.
特徴を追加する場合は, 特徴の定義をinclude/feature/SimulationFeature.hppに, 特徴の判定処理をinclude/feature/SimulationFeature.cppに定義してください. src/learn/MinorizationMaximization.cppに追加した特徴の判定と更新処理, 学習用の変数(mm_t型)を追加することで, 新たに追加した特徴の学習を実行できます.
特徴を更新する際には注意が必要です. 具体的には同時に現れることのない特徴は一度に更新可能ですが, 同時に現れる可能性がある特徴はそれぞれ別の更新ステップで更新する必要があります. 例えば, 配石パターン(3x3, md2)は1つの交点に1種類のみ出現するため, これらは1度の更新処理で全て同時に更新できますが, トリの特徴とアタリの特徴は1つの交点にそれぞれが同時に出現することがあり得るため, 別々のステップで更新するように実装しています.
パラメータが発散してしまう場合は, 学習に使用する棋譜の数を減らしてください. 使用する棋譜の質にもよりますが, 40000局以上を学習させようとするとパラメータが発散する可能性があることは確認しています. 強さの観点で言えば, 20000局あればほぼ十分だと思われます.
不明です. ただし, 1にすると顕著に過学習する傾向があるようです. 棋譜の数, 性質に合わせて, 調整してください.
accuracy.logを見ながら調整してください.
特徴をたくさん増やすとその分収束に必要な実行回数が増えますが, 50回もループさせれば十分だと思います.
デフォルトの特徴だけであれば, 30回で十分です.