TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

pandoc-crossrefで参考文献を引用する方法

ほぼ個人用メモ

参考文献管理

Mendeleyを使う。

論文の場合は、PDFを登録する。

書籍の場合は、Google Scholar ボタンを使用して、Bib Tex形式をコピーしてMendelayに張り付ける。
参考:
Google Scholarプラグインから書籍のBibTeXを取得してMendeleyに突っ込む - かりっと揚げたらフライドポテト

BibTex形式でエクスポート

Mendelayから文献を選択して右クリック→Export...から、BibTex形式(.bib)で保存する。

Markdownでの引用の記述方法

# Title1

[@Huang2010]を参照

# 参考文献

のように記述する。

末尾の参考文献の下に引用文献の一覧が出力される。

参考:
Pandocで参考文献リストを処理する扱う方法 (PandocとZoteroで参考文献:後編)

スタイルを準備

引用スタイルがデフォルトだと、

(Huang, Coulom, and Lin 2010)を参照

のような表示になる。

これを

(1)を参照

のようにしたい場合、スタイルファイルを使用する。

Zotero Style Repositoryから、sist02.cslをダウンロードする。

Wordに変換する例

pandocはpdfにする場合が多いと思うが、wordに変換するコマンド例を示す。

pandoc -F pandoc-crossref --citeproc --bibliography=ShogiAIBook.bib --csl=sist02 a.md -o a.docx

第2回 電竜戦TSEC 結果報告

7/17~18にかけて実施された第2回 電竜戦TSECにdlshogiというソフトで参加しました。
チームとしてはGCT電竜でも参加しています。
第2回世界将棋AI 電竜戦TSEC -中継サイト

ファイナルリーグとB級リーグに分かれて実施されて、7/3に行われた予選で上位2チームでファイナルリーグ、それ以外がB級リーグで競うという構成です。

dlshogiは予選では、ファイナルリーグに残れなかったため、B級リーグでの参加です。
TSECは、通常のコンピュータ将棋の大会とは異なり、ほぼ互角の指定局面から開始するという特徴があります。
戦型別に3部構成に分かれて、第1部は相振B級その他部門、第2部 相居飛車部門、第3部は対抗系部門となっています。

結果は、B級48チーム中、

第一部 2位
第二部 1位
第三部 1位

で、2部門で優勝、B級総合優勝という結果でした。

予選は学習が間に合わずいまいちな成績でしたが、本選では調整が間に合いR+150くらい強くなっていました。

dlshogiとGCTの違い

GCT電竜の方は、世界コンピュータ選手権のdlshogi with GCTと同じモデルで参加しました。
これは、ResNet10ブロック192フィルタのモデルで、floodgateの棋譜とAobaZeroの棋譜とdlshogiの強化学習棋譜を混ぜて学習しています。

一方、今回のdlshogiの方は、ResNet15ブロック224フィルタで、モデルを初期値から学習しています。
教師データは、dlshogi with GCTの強化学習のデータと、入玉宣言の対策のために水匠などによる自己対局で入玉宣言まで対局した棋譜で事前学習して、強化学習で教師データを生成しました。

また、dlshogi with GCTは指し手のみを学習していましたが、方策の分布を学習するようにしています。
方策の分布を学習すると精度は高くなるものの、探索パラメータを調整しないと実際の対局では弱くなるため、時間をかけて探索パラメータの調整を行いました。

まとめ

B級での優勝なので、ディープラーニング+MCTSの将棋AIが、Stockfish系の将棋AIを上回ったというにはインパクトが少ないですが、秋の電竜戦では総合優勝できるように頑張りたいと思います。
将棋の検討に使えるようにモデルを公開したいのですが、モデルを公開してしまうとdlshogiを使って定跡を作られてしまってdlshogiの序中盤のアドバンテージがなくなってしまうため(個人的には定跡などアンチコンピュータ戦略で勝たれると面白くないので)、今のところ大会で成果を出すまでは公開を控えたいと思っています。

cshogiにWebアプリを追加

開発しているPythonの高速な将棋ライブラリcshogiに、ブラウザでUSIエンジン同士の対局が行える機能を追加した。
f:id:TadaoYamaoka:20210710233101p:plain

python -m cshogi.web.app --engine1 E:\game\shogi\gikou2_win\gikou.exe --engine2 E:\game\shogi\apery_wcsc28\bin\apery_wcsc28_bmi2.exe --byoyomi 1000 --port 8000

のように実行して、ブラウザから「http://localhost:8000/」にアクセスして、USIエンジン同士の対局を観戦することができる。

これだけだと、将棋所のような便利なネイティブアプリがあるのでわざわざこの機能を使う必要はないが、Google Colab上で実行することができる。

Google Colabで実行

USIエンジン同士の対局
# cshogiインストール
!pip install cshogi

# Lesserkaiビルド
!wget http://shogidokoro.starfree.jp/download/LesserkaiSrc.zip
!unzip LesserkaiSrc.zip
%cd LesserkaiSrc/Lesserkai
!make
%cd -

# 対局実行
import cshogi.web.app
cshogi.web.app.colab(engine1='/content/LesserkaiSrc/Lesserkai/Lesserkai', engine2='/content/LesserkaiSrc/Lesserkai/Lesserkai', byoyomi=1000)

のようにして実行できる。
f:id:TadaoYamaoka:20210710233717p:plain

人間との対局

engine1もしくは、engine2に「human」を指定すると、人間との対局もできる。

cshogi.web.app.colab(engine1='human', engine2='/content/LesserkaiSrc/Lesserkai/Lesserkai', byoyomi=1000)

まとめ

GPUをもっていない方にも、Google Colab上でディープラーニングの将棋AIの学習から、自分で学習したモデルとの対局を体験してもらいたくてWebアプリを開発した。

バックエンドは、Colabに標準でインストールされているFlaskを使用して、フロントエンドはBootstrapとjQueryを使用した。
デザインはシンプルで、ほぼ最低限の機能しか実装していないので、徐々に使いやすくしていきたい。
バグなど教えてもらえると助かります。

Windows TerminalでMSYS2を起動する設定

備忘録
settings.jsonのprofilesのリストに以下の設定を追加する。

    {
      "closeOnExit": true,
      "colorScheme": "Campbell",
      "commandline": "cmd.exe /c \"set CHERE_INVOKING=1&& set MSYSTEM=MINGW64&& C:\\msys64\\usr\\bin\\bash.exe --login\"",
      "fontFace": "Consolas",
      "fontSize": 10,
      "guid": "{xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}",
      "historySize": 9001,
      "icon": "C:\\msys64\\mingw64.ico",
      "name": "MSYS2 MinGW 64-bit",
      "snapOnInput": true,
      "startingDirectory": "c:\\msys64\\home\\%USERNAME%"
    },

guidは、PowerShellで、以下の実行して取得する。

[guid]::NewGuid()

将棋AI実験ノート:ブロック数とフィルタ数とSE有無の比較

同一データを学習した際に、ResNetのブロック数とフィルタ数とSE(Squeeze-and-Excitation)有無により、精度、強さがどう変わるかを比較した。

比較対象

  • ResNet 10ブロック、192フィルタ
  • ResNet 15ブロック、224フィルタ
  • ResNet 20ブロック、256フィルタ
  • 上の3パターンそれぞれについて、SE有無

教師データ

  • floodgate R3800以上 2019~2021/5 (mateで打ち切り)
  • 水匠3改で、100万ノード固定。初期局面から24手までにランダム16回(評価値最善手から200以内)
  • BURNING BRIDGES(TSEC電竜)で、100万ノード固定。初期局面から24手までにランダム16回(評価値最善手から200以内)
  • dlshogi with GCTで、3000プレイアウト

合計約3億局面

なお、やねうら王でhcpe3を生成できるように改造した。※生成が終わっても終了しないバグあり(原因不明。誰か直してくれると助かります)。

学習

  • 5エポック
  • 4096バッチ
  • 学習率 0.04から1エポックごとに半分
  • 平均化、評価値補正あり
  • 2エポックからSWA開始
  • 初期値から学習
  • 方策の分布を学習(dlshogi with GCTの棋譜のみ)

精度比較

テストデータに、floodgateのレート3500以上の対局の棋譜からサンプリングした856,923局面を使用した。

SWAなしモデル
  • SEなし
モデル 方策損失 価値損失 方策正解率 価値正解率 方策エントロピー
10ブロック 1.6379119 0.51276293 0.4730206 0.72314205 1.51876836
15ブロック 1.61451681 0.54952968 0.47836673 0.70189649 1.51121722
20ブロック 1.60430686 0.5144527 0.4825369 0.71952424 1.41729831
  • SEあり
モデル 方策損失 価値損失 方策正解率 価値正解率 方策エントロピー
10ブロック 1.64183599 0.51881258 0.47337911 0.71709992 1.48604457
15ブロック 1.62213967 0.5027243 0.47863532 0.73173113 1.43584003
20ブロック 1.60740022 0.50509531 0.48131072 0.72798019 1.43475938

ブロック数が大きいほど精度が高くなり、SE有無ではSEありの方が精度が上がる。
(SEなし15ブロックの価値は、10ブロックよりも価値の損失が上がっているが、その分方策の損失が低くなっている。
 方策と価値は交互に学習が進むため、エポックごとにどちらの損失が下がるかが入れ替わることがある。)

SWAありモデル
  • SEなし
モデル 方策損失 価値損失 方策正解率 価値正解率 方策エントロピー
10ブロック 1.57109508 0.49425657 0.48709244 0.7399652 1.51186802
15ブロック 1.54070064 0.48825147 0.49433273 0.74414004 1.47669404
20ブロック 1.5281703 0.48567744 0.49743904 0.74624089 1.46332859
  • SEあり
モデル 方策損失 価値損失 方策正解率 価値正解率 方策エントロピー
10ブロック 1.57355652 0.49556847 0.48687874 0.73878457 1.4777351
15ブロック 1.5464818 0.48941931 0.49345689 0.74358067 1.43782014
20ブロック 1.53439988 0.488463 0.49672319 0.74488159 1.41932988

ブロック数が大きいほど精度が高い傾向は、SWAなしモデルと同じである。
SWAなしと比較して、SWAありの方が損失が大きく下がっており、精度が高くなっている。
意外なことに、SE有無では、SEなしの方が精度が高い。
SEとSWAは相性が悪いようだ。

強さ比較

SWAあり、SEなしのモデルについて、強さを比較した。
dlshogiのエンジン設定は2GPU、3スレッド。

持ち時間1分、1手1秒加算
  • ResNet10ブロック vs GCT電竜(model-0000167) vs 水匠3改(8スレッド)
# PLAYER          :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)     W    D     L  D(%)
1 susho3kai8th    :     5.0    6.3  2474.5    4847    51      90  2341  267  2239     6
2 model-0000167   :    -2.1    6.4  2404.5    4853    50      55  2225  359  2269     7
3 resnet10        :    -2.8    6.3  2396.0    4850    49     ---  2209  374  2267     8
  • ResNet10ブロック vs ResNet15ブロック vs 水匠3改(8スレッド)
# PLAYER          :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)     W    D     L  D(%)
1 resnet10        :    12.5    6.3  2642.0    5020    53      63  2498  288  2234     6
2 resnet15        :    10.7    6.5  2624.0    5022    52     100  2479  290  2253     6
3 susho3kai8th    :   -23.2    6.3  2264.0    5018    45     ---  2111  306  2601     6
  • ResNet10ブロック vs ResNet20ブロック vs 水匠3改(8スレッド)
# PLAYER          :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)     W    D     L  D(%)
1 resnet10        :    20.2    7.1  2093.0    3857    54     100  1953  280  1624     7
2 resnet20        :    -9.0    7.2  1855.0    3857    48      63  1699  312  1846     8
3 susho3kai8th    :   -11.2    7.3  1835.0    3852    48     ---  1691  288  1873     7

10ブロックの強さは、GCT電竜とほぼ同じになっている。
方策の分布を学習した場合でも強くできることが確認できた。
15ブロックと20ブロックの方が精度が高いが、10ブロックの方が強いという結果になった。

持ち時間5分、1手2秒加算
  • ResNet10ブロック vs GCT電竜(model-0000167) vs 水匠3改(8スレッド)
# PLAYER         :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)    W    D    L  D(%)
1 susho3kai8th   :    19.7   13.8   524.5     968    54      97  484   81  403     8
2 resnet10       :    -3.0   14.1   478.5     969    49      86  428  101  440    10
3 model-0000167  :   -16.7   14.2   452.0     973    46     ---  409   86  478     9
  • ResNet10ブロック vs ResNet15ブロック vs 水匠3改(8スレッド)
# PLAYER          :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)    W    D    L  D(%)
1 resnet15        :    11.3   13.5   515.0     984    52      86  476   78  430     8
2 susho3kai8th    :    -1.9   14.1   485.5     979    50      72  443   85  451     9
3 resnet10        :    -9.4   14.0   471.5     981    48     ---  428   87  466     9
  • ResNet10ブロック vs ResNet20ブロック vs 水匠3改(8スレッド)
# PLAYER          :  RATING  ERROR  POINTS  PLAYED   (%)  CFS(%)    W    D    L  D(%)
1 resnet20        :     8.5   13.8   515.5     995    52      84  464  103  428    10
2 resnet10        :    -3.6   13.5   488.5     992    49      55  436  105  451    11
3 susho3kai8th    :    -4.9   13.0   484.0     989    49     ---  442   84  463     8

持ち時間が長い場合は、10ブロックより15ブロック、20ブロックが強いという結果になった。
持ち時間が長い場合は、ブロック数が大きい方が有利と言えそうだ。
この持ち時間では15ブロックが一番良さそうである。
さらに持ち時間が長くなると20ブロックの方がよくなる可能性がある。

また、10ブロックのモデルがGCT電竜よりも強くなっている。
持ち時間が長い場合は、方策の分布を学習した方が良さそうである。

まとめ

同じ教師データを使用して学習した場合、モデルのブロック数が大きいほど精度が上がることがわかった。
SWAなしの場合、SEありの方が精度が高くなる。
しかし、意外なことに、SWAありだと、SEがない方が精度が高くなった。
SEとSWAは相性が悪いようだ。

強さの比較では、持ち時間が短い場合は、10ブロックで指し手のみを学習するのが強そうである。
しかし、持ち時間が長くなると、大きいブロック数で、方策の分布を学習した方が強くなりそうであることがわかった。
GCTが電竜戦で優勝して、世界コンピュータ選手権では振るわなかったことを裏付ける結果となった。

dlshogiをPyPIに登録

今までdlshogiの学習を行うために、python環境を作成して、boostをインストールして、C++からPythonモジュール(cppshogi)をビルドしてという手順が必要だったが、pipコマンドでインストールできるようにPyPIに登録した。

pip install dlshogi

アップデートの場合は、

pip install dlshogi -U

で、導入できるようにした。

学習用スクリプトも複数(train_hcpe.py~train_hcpe3.py)あったが、train.pyに統一した。

python -m dlshogi.train

で学習を実行できる。

これで、Google Colabでの学習も容易になる。


utilsにあったスクリプトは、dlshogi.utilsパッケージに移動した。

python -m dlshogi.utils.csa_to_hcpe3

のようにして、実行できる。

注意事項

新しいtrain.pyは、今までと保存形式が変わっている。互換性のために以前の形式も読めるようにしている。
詳細は、この記事を参照。

dlshogiの教師データのフォーマットには、hcpeフォーマット(指し手のみ、局面単位)と、hcpe3フォーマット(方策の分布、対局単位)の2つがあるが、自動判別してどちらも読めるようにしている。
複数ファイルを入力できるので、混在もできる。
hcpe3を指し手のみで学習するには、「--temperature 0」を指定する。
指し手のみの場合、方策が決定論的にならないように、エントロピー正則化項の係数「--beta 0.001」を指定するとよい。

「--use_average」と「--use_evalfix」と「--use_swa」はデフォルトオフだが指定した方がよい。

GPUにTensorCoreがある場合は、「--use_amp」を指定した方がよい。

その他

dlshogiのソースを修正しなくても、ユーザ定義のモデルファイルを学習できるように、「--user_network」オプションを追加した。
「--user_network package0.package1.ClassName」
のようにして、クラス名をパッケージ付きで指定する。

まとめ

学習環境の構築でハードルがあったが、簡単に構築できるようにした。
これでdlshogiの学習を簡単に試せるようになったと思う。


dlshogi.cppshogiと、cshogiと組み合わせて、Pythonのみでdlshogiのモデルを使って大会参加とかもできるので、ディープラーニングと将棋AIに興味あるけどC++は分からないという方も試してみてください。

将棋AIの進捗 その57(SWAの修正)

dlshogiの学習では、SWA(Stochastic Weight Averaging)を導入している。

今までは、1世代学習するごとに、平均化した重みを出力して、次の世代ではその重みを使用して学習していた。
しかし、SWAは通常複数エポックに渡って平均化してから、最後に平均化した重みを出力を行う。
また、Leela Chess Zeroでは、複数世代にわたって重みを平均化しているようなので、dlshogiもそのように変更した。

実装方法の変更

dlshogiにSWAを実装したときは、まだPyTorchに正式にSWAが組み込まれていなかったため、contribのソースをコピーして使用していたが、このソースはSWAモデルの保存/読み込みに対応していなかったので、PyTorch 1.7以降で使えるようになったAveragedModelを使用するように変更した。

forwardの複数引数対応

AveragedModelは、モデルのforwardの引数が一つの場合しか想定されていない。
dlshogiでは、2つの引数を使用するため、そのままでは利用できなかった。

そこで、AveragedModelのインスタンスのforwardメソッドを一時的に書き換える処理を行った。

以下のように2つの引数を1つの辞書で受け取って、それを展開して元のメソッドに渡すようにした。

        forward_ = swa_model.forward
        swa_model.forward = lambda x : forward_(**x)
        update_bn(hcpe_loader(train_data, args.batchsize), swa_model)
        del swa_model.forward

データローダでは、2つの入力を辞書で渡すようにした。

def hcpe_loader(data, batchsize):
    for x1, x2, t1, t2, value in Hcpe3DataLoader(data, batchsize, device):
        yield { 'x1':x1, 'x2':x2 }

精度比較

今までの1世代ごとに平均化する方法と、複数世代に渡って平均化する方法で精度を比較した。

訓練データには、dlshogiの強化学習で生成した3世代分のデータ(各世代1億局面)を使用した。
1世代目はSWAなしで学習し、2世代目からSWAありで学習した。
今までの方法では、2世代目平均化した重みを出力して、それを読み込んで3世代目を学習した。
新しい方法では、2世代目と3世代目で続けて重みを平均化した。
4回測定し、テスト損失の平均で評価した。
テストデータには、floodgateのレート3500以上の対局の棋譜からサンプリングした856,923局面を使用した。

テスト方策損失 テスト価値損失
今までの方法 1.782588468 0.522283693
新しい方法 1.780505845 0.521579308
SWAなし 1.84344225 0.545063128

新しい方法では、今までの方法より、方策、価値ともに損失が低下しており精度が向上している。
今までの方法でも、SWAなしよりは精度が高い。

使用方法

新しい方法は、dlshogiのtrain_hcpe3.pyに実装している。
複数世代でSWAの重みを引き継げるように、モデルと状態の保存形式を、PyTorchのcheckpoint形式に変更した。
今まではChainerからの互換性を引きずっていたので、モデルと状態は別々のファイルになっていた。

--checkpointと--resume

「--checkpoint」で、保存ファイル名を指定する。
PyTorchのチュートリアルによると拡張子に*.pthをつけるようだ。
読み込みは「--resume」に「--checkpoint」で保存したファイル名を指定する。

--initmodelと--stateの廃止

今まで使用していた「--initmodel(-m)」は廃止する(互換性のため残している)。
互換性のため「--resume」で今までの「--state」で保存した状態も読めるようにしている。
「--state」は廃止した。

--model

「--model」で、SWAの重みを反映したモデルを出力する。
このファイルは、これまでのモデルファイルと互換性がある。

その際、Batch Normalizationの再計算を行う。
ここが時間がかかるので、途中でSWAを反映したモデル出力が必要なければ、「--checkpoint」だけで学習は継続できる。

なお、Batch Normalizationの再計算は全訓練データの順伝播を行うため時間がかかるが、使用する訓練データの量が精度にかなり影響するため、減らさない方がよい。


今回の変更は、train_hcpe3.pyにしか反映していない(train_hcpe3.pyは、train_hcpe.pyと同等の学習もできる)。
train_hcpe.pyは互換性のために変更していない。

まとめ

複数世代に渡って重みを平均化できるように、SWAの実装を変更した。
新しい方法の方が精度が上がることが確かめられた。