TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

【iOS開発】Audio Spectrum Monitorバージョンアップアップ

3年半ぶりにiPhoneアプリのAudio Spectrum Monitorをバージョンアップしました。

Audio Spectrum Monitor

Audio Spectrum Monitor

  • Tadao Yamaoka
  • ミュージック
  • ¥120

身に付けた機械学習の知識を使って、解析精度アップを行う予定ですが、その前に要望のあったインポート/エクスポート機能を実装しました。
録音したファイルをiCloudにエクスポートしたり、iCloudにアップロードしたwaveファイルをインポートできるようになりました。


久しぶりのバージョンアップだったので、アプリの申請を行うために追加で必要になっていることがいくつもあり大変でした。
iPhone Xのノッチに対応することが必須になっていたり、iPad Proのスクリーンショットが必要だったり、プライバシーポリシーが必須だったり。

ノッチ対応していないと、ノッチの箇所にチューナーが描画されてしまったり、ボタンの配置がずれたりした状態となりました。
UIViewのsafeAreaInsetsでSafeAreaを取得してその範囲に描画することで対応できました。

強化学習におけるバッチサイズとエントロピー正則化

※ほぼ自分用の実験ノートです。

世界コンピュータ将棋選手権の少し前から、自己対局におけるノードの再利用とバッチサイズの変更(1024→2048)を行った。
250万局面の生成と学習を8サイクル行ったところ、技巧2に対して勝率が上がったため、大会には最新のモデルを使用した。

しかし、その後学習を続けたところ、valueの損失(floodgateの棋譜の勝敗に対する交差エントロピー)が一時的に下がったが、policyの損失が上がり続けるという結果になった。
valueの損失も上昇しだしたため、実験を中止した。
f:id:TadaoYamaoka:20190510220606p:plain
※173サイクルから変更
173サイクル以降、accuracyも徐々に低下した。
f:id:TadaoYamaoka:20190510220918p:plain

原因の考察

policyの損失が上昇し続けていることから、局所的な戦略を覚えてしまい新しい手を試さなくなってしまったと考えられる。
valueの損失が下がり続けているのは、わかりやすい局面での勝敗の予測精度が一時的に上昇したためと考えられる。

局所的な戦略を覚えてしまう状況では、policyの予測手が特定の一手に偏る傾向になると思われる。
そのことを確かめるために、floodgateの棋譜の局面をpolicyで予測した際のエントロピーを測定した。

エントロピーは、すべての手が均等に選ばれる場合に最大となり、特定の1手の確率が高くなる場合、低い値になる。
測定用コード

エントロピーの測定

f:id:TadaoYamaoka:20190510231016p:plain
予測通り、173サイクル以降エントロピーは下がり続けていた(最後だけ少し上昇しているが)。

バッチサイズの影響

ノードの再利用とバッチサイズのどちらが影響しているかを確認するため、生成した同じ局面を使ってバッチサイズの1024で学習してみた。
f:id:TadaoYamaoka:20190510223118p:plain
エントロピーは、次のようになった。
f:id:TadaoYamaoka:20190510233437p:plain

174サイクルでエントロピーが上昇したが、その後低下している。
生成して学習のサイクルを回していないため、学習したデータ自体に偏りがあるため、自己対局のサイクルを回した場合も検証してみる予定。
このデータからは何が原因がよくわからない。

ノードの再利用が影響している可能性も高い。
ノードの再利用なしで、バッチサイズを2048にした条件でも検証してみる必要がありそう。

エントロピー正則化

強化学習でpolicyが特定の戦略に偏らないようにするには、エントロピー正則化という手法が使われるらしい。

www.slideshare.net
スライド85

エントロピー正則化を行うことでpolicyの損失の上昇を抑えられるか検証してみた。

エントロピー正則化の実装

エントロピー正則化は、policyの損失に負のエントロピーを加えることで実現する。
そうすることで、エントロピーが高くなるように学習される。
つまり、特定の手に偏らなくなる。

policyの出力を{\bf p}とすると、エントロピーH({\bf p})は、
H({\bf p}) = -\sum_i p_i \log p_i
で与えられる。
p_iが小さい場合、\log p_iが-infになるため、注意が必要である。
policyの出力{\bf y}がlogitsの場合、-infになることを回避できる。
logitsを使うと、エントロピーは、Softmaxの定義から、\log p=y - Cとなるため、
H({\bf p}) = -\sum_i p_i (y_i-C)
で計算できる。Cは定数のため損失から削除しても問題ない。
※Cは定数にならないので間違っています。こちらの記事で、書き直しました。

負のエントロピーに、小さな係数\betaを掛けて損失に加えると、損失は、
Loss(\theta)=Loss_{policy}(\theta)+\beta \sum_i p_i y_i
となる。

Chainerでは、次のように実装できる(合っているかあまり自信なし)。

loss = F.softmax_cross_entropy(y, t) + args.beta * F.mean(F.sum(F.softmax(y) * y, axis=1))
エントロピー正則化の効果測定

係数\betaを0.01として、上記と同じ局面を学習してみた。
エントロピーは以下のようになった。
f:id:TadaoYamaoka:20190510233727p:plain
エントロピーが上昇していることが確認できた。
しかし、損失は以下のようになり、policy、valueともに上昇している。
f:id:TadaoYamaoka:20190510233807p:plain

係数が大きすぎた可能性があるため、小さな係数で追試を行う予定。

まとめ

ノード再利用もしくは、バッチサイズを大きくしたことにより、policyが偏る現象が起きた。
エントロピーを測定することで、policyの偏りを測定することができる。
エントロピー正則化によりpolicyの偏りを抑制できる。

ノード再利用、バッチサイズのどちらの影響かは今回の実験ではわからなかったため、追試を行う予定。

2019/5/12 追記

エントロピー正則化の係数を小さく(\beta=0.0001、バッチサイズ1024)して実験してみた。
エントロピーは以下のようになった。
f:id:TadaoYamaoka:20190512000815p:plain
エントロピーなしの場合とあまり変わっていない。
損失は以下のようになった。
f:id:TadaoYamaoka:20190512001853p:plain

2019/5/13 追記

\beta=0.001として実験してみた。
f:id:TadaoYamaoka:20190513000819p:plain
損失は以下のようになった。
f:id:TadaoYamaoka:20190513001135p:plain

wcsc29で負けた対局の分析

2次予選1局のKristallweizenとの対局について、敗因を分析してみた。

評価値は以下のようになっており、Kristallweizen側の評価値も124手で先手が優勢となっていた。
f:id:TadaoYamaoka:20190506231639p:plain

125手目の2七桂打が悪手で、一手で後手優勢に傾いた。

125手目の局面を、Aperyで分析すると最善手は2五桂打で先手に405点有利となっていた。
2七桂打は、後手が992点有利となった。

dlshogiのpolicyの確率とvalueの勝率と、探索後の勝率は、

policy value 探索後の勝率
2七桂打(dlshogiの着手) 0.0461798 0.670166 0.828524
2五桂打(Aperyの最善手) 0.312096 0.671631 0.68564

となっており、policyは正しく最善手を予測できていた。
valueは、1手後の局面を正しく予測できていない。
探索後の勝率も、誤差がより広がっていた。

2七桂打の後のPVは、2六龍を読んでいたが、実際指されたのは6六角成でこれが敗因となった。
6六角成を指された後の局面では、後手優勢に気付いている。
短い時間(10秒)の探索では先手有利となったため、深く探索しないと気付かない局面となっていた。
2七桂打を指した後の後手の局面でも、長く探索すると6六角成を読めていた。

2七桂打を指した後の後手の局面のpolicyの確率とvalueの勝率は以下の通りとなっていた。

policy value
2六龍(dlshogiのPV) 0.330778 0.438965
6六角成(実際に指された手) 0.130268 0.308594

ここでは、policy、valueともに最善手から外れていた。

終盤の複雑な局面でのモデルの精度が低いことが原因と言えそうだ。
また、深く読めば気付けているため、終盤の複雑な局面に時間配分をした方がよさそうだ。
実際の対局では3秒で指していた。

Multi Ponderについて

今年の世界コンピュータ将棋選手権はMulti Ponderを採用しているチームが多く関心も高かったようです。

dlshogiでも、Multi Ponderの考え方を取り入れていました。
Multi Ponderは、どの手にどれだけのリソースを配分すると誤差を最小化できるかという問題としてとらえられると解釈しました。

モンテカルロ木探索の場合、UCB1が最大になる手にリソースを配分することで、理論的に最善でない手を調べる期待値をO(log n)に押させることができます。
これは、相手番で単純に相手局面に対してモンテカルロ木探索を行い、自分の手番では相手が指した枝から続きの探索をするだけで実現できます。

選択的探索と、Multi Ponderの親和性は高いと思っています。
(αβ探索の場合も近い考え方はできそうですが、自分としてはαβ探索に手を出すつもりはないです。)

第29回世界コンピュータ将棋選手権の感想

dlshogiは、前回に続いて1次予選を通過し、2次予選まで進むことができました。
2次予選は、2勝できればよいと考えていましたが、結果は4勝5敗と善戦できました。
ただし、1勝は相手チームのサーバダウンによるものなので、実質は3勝と思っています。
順位は24チーム中17位でした。

対局結果

対局相手 手番 結果 手数 戦型
1局 Kristallweizen 先手 lose 143手 角換わり
2局 Novice 先手 Timeout(win) 82手 横歩取り
3局 CGP 後手 win 165手 角換わり 振り飛車
4局 狸王 先手 lose 103手 横歩取り
5局 nozomi 後手 lose 66手 横歩取り
6局 たこっと 後手 win 215手 横歩取り
7局 Apery 先手 入玉宣言(lose) 217手 角換わり
8局 dainomaruDNNc 後手 win 93手 後手横歩取り
9局 大合神クジラちゃん 先手 lose 79手 角換わり

2次予選の感想

やねうら王ライブラリのソフト相手にも中盤まで優勢が続くこともありましたが、終盤の1手の悪手で崩れて負けるという傾向でした。
終盤の精度にまだ問題がありそうです。

Aperyとの対局では、相入玉となり初めて入玉宣言法で負けました。入玉宣言法の教師局面が少ないため持将棋を理解していなかったかもしれません。
引き分けを教師データから除いていたことも問題があったかもしれません。

負けた対局については、もう少し分析して課題を具体化したいと思います。

選手権の感想

AlphaZeroの再現実験を行っているAobaZeroは自分よりずっと大きな計算リソースで実験されているようなので、来年には追い抜かれそうです。
山下さんとは実装の話をさせていただいて参考になる点がありました。
dlshogiは、AlphaZeroの再現は目指さず別の工夫で学習効率を上げることを目指したいと思っています。

Miacisの迫田さんからは、強化学習の理論面で情報をもらえて、勉強になりました。
PGQ: Combining Policy Gradient And Q-learningという論文を教えてもらい、自分のソフトの学習でも参考にできそうです。

Noviceは、Policyをαβの枝刈りに使用して強くなったという話を聞き、Policyの読み漏れで逆に終盤が弱くなっていないかと思いましたが、そのようなことはないようです。
モンテカルロ木探索では、探索される手が確率が上位数手に集中するのに対して、αβではカットした手以外は全探索しているので、カットする手に最善手が含まれていなければ問題ないということかもしれません。

ねね将棋とは、1次予選で初の直接対決を行えました。
ねね将棋はやねうら王の棋譜を使った教師あり学習で、dlshogiは強化学習で学習していました。
ねね将棋に勝つことができ(1回の対局で判断できるものではありませんが)、強化学習の成果が確認できたかと思います。

Crazy ShogiのRemiさんとは、英語力(とコミュ力)が足りずほとんど話せませんでしたが、GPU使用率が高く探索の効率が高そうに思えました。
dlshogiは、CPUネックでGPU待ちが発生しているため、GPUの使用率を上げる探索方式に見直そうと思っています。


この大会では、dlshogiの序中盤の強さを示せたと思います。
コンピュータ将棋でのディープラーニングの手法への関心を高めることにつながればうれしい限りです。

来年も開催されるようなので、次回はさらに上位を目指したいと思います(できれば決勝に残りたい)。

dlshogi(wcsc29版)のビルド済みファイル公開

dlshogiの第29回世界コンピュータ将棋選手権バージョンのビルド済みファイルを公開しました。

wcsc28版は、詰み探索用にAperyの評価関数が必要でしたが、df-pnによる詰み探索を実装したため、評価関数は不要になりました。
CUDA、cuDNNはライセンス上の問題が起きないように同梱していませんので、別途インストールが必要です。下記のページの説明を参照してください。

追加学習が行えるように、学習用のモデルも同梱しています。

Release 第29回世界コンピュータ将棋選手権バージョン · TadaoYamaoka/DeepLearningShogi · GitHub

世界コンピュータ将棋選手権 1次予選の感想

dlshogiは、世界コンピュータ将棋選手権 1次予選、8位でぎりぎり通過できました。

3敗したうち、2つはやねうら王ライブラリのソフトでかなり棋力差がある感じでしたが、8戦目のあやめとの対局は去年の2次予選では勝っていたソフトなので、60手であっさり負けてしまいくやしい負けでした。
事前に探索して作成した定跡に問題があるのかと思って、帰ってから調べましたが、定跡の手には問題なさそうでした。

1手ずつやねうら王で検証してみましたが、38手目の以下の局面での3八銀打が悪手だったようです。
f:id:TadaoYamaoka:20190503231836p:plain

やねうら王の最善手は7二銀打で、評価値は互角ですが、3八銀打の後に評価値200程先手有利に傾いていました。

問題の局面で、方策ネットワークの指し手の確率が、
3八銀打 : 0.205184
7二銀打 : 0.000438275
となっており、7二銀打が完全に読みから外れており探索されていない状態となっていました。

policyの読み漏れは、以前は少しノイズを入れて対策していましたが、今回はノイズは入れていませんでした。
試しにノイズを入れて探索してみましたが、7二銀打の評価が良くなるわけではなく、根本的にはpolicyの精度を上げるしかなさそうです。

誤差の大きい局面の精度をどう上げるかが今後の課題となりそうです。


明日の2次予選通過は厳しそうですが、(今から何かできるわけではありませんが)できれば2勝したいところです。

2019/5/7 追記

valueの評価については、以下の通りとなっていました。
3八銀打 : 0.40625
7二銀打 : 0.01416

Apery(wcsc28)で検討すると、上記局面の最善手は、2七馬で評価値65の互角でした。
policy : 0.0615937
value : 0.379883(先手有利)
policyは比較的高いですが、valueはAperyの互角の評価とずれています。

Aperyは、7二銀打は、先手優勢1015点となっており、Aperyが正しいとすると、
7二銀打のpolicyとvalueの精度は正しいことになります。

なお、policyとvalueの上位5つは以下の通りとなっていました。

policy value
1 3八銀打(0.203322) 2九馬(0.563965)
2 2九馬(0.203322) 3八銀打(0.40625)
3 3八馬(0.089332) 3八馬(0.399902)
4 4五桂(0.0789503) 2七馬(0.379883)
5 2七馬(0.0615937) 4五桂(0.316895)