0.0フィルター数の違いを、グラフにしてみます。これも増やせば増やすほど、賢くなっていきますが、学習時間の増え方もすごいですね。身の丈に合っていないような気がするので(笑)、ここから先はひとまずフィルター数は32で続けていきます。ここまでは、ネットワーク構成をいろいろ試してきましたが、ここで一度、ネットワークに対する入力を変更してみたいと思います。今現在は、石の配置の2面だけですが、これに「その場所の石のダメの数」を加えた3面にしてみました。数値はtanh(ダメの数*0.05)して0と1の間に収めました(0~1に正規化するのは、Kerasのサンプルがそうなっていたので)。ダメの数/32)など、まあ何でもいいような気はします。ところで19路盤の最大ダメ数っていくらなんでしょう?ダメなしとダメありとでの違いを、グラフにしてみます。うーん、ちょっと効果が薄いですね。ダメの数は特に必要な情報でないからなのか、石の配置を見ればそんなことは分かるからなのかちょっとはっきりしませんが、ネットワークへの入力でがんばれることは、意外とあんまり無いのかもしれません。いえ、効果が全く無いわけではないので、ここから先はひとまず入力はダメありの3面で続けていきます。Normalizationです。そのあたりも含めて調べてみます。Normalizationを置くバージョン。Normalizationを置くバージョン。576.0これも、グラフにします。Lossも10をはっきりと切ってきました。Normalization、僕も大好きです(笑)。1エポックあたりの学習時間は大幅に増えて、たしかに重いのは重いんですが、学習が速くなるのであれば、それも少なくともある程度はペイしそうです。Normalizationは活性化関数の前なのか後なのか問題」ですが、今回のケースでは、「活性化関数の後」が良さそうです。今回は検証用データの量が絶対的に少ないので、もう少しちゃんと調べないと、はっきりしたことは言えません。Normalizationを置く形で続けていきます。いやあ、それにしても長い記事になりました。大量に追記することになります。ここまで、やってきて一番思うのは、「学習データって大事」ってことです。これは量も質もですね。最初始めた時、「学習データなんてなんでもいいよ。俺はディープなラーニングがしたいだけなんだよ」って思ってた自分を引っ叩いてやりたい(笑)。当初はここまで良い数字が出るとは、正直思ってなかったから、ということもあります。仮にそれができたら、Keras.js使って、もうこれは何て言うか一丁上がりなんですが、なかなか事前にそこまで夢みることはできませんでした。いう訳で、とにかく学習データです。今現在、COSUMIのサーバを使って学習データを大量に作成中です(負荷が低くなったら、自動的に作り始めるようにした)。それができあがったら、また引き続きいろいろ試してみたいと思います。2017/5/2]あの後、学習データをたくさん作りました。前回使用したデータと今回分との、形勢の分布のグラフを。比較しやすいように、スケールは調整してあります。前回分のデータの分布を最初に見た時、いくらなんでもこれは分散が足らないんじゃないかと思ったので、今回は平均近辺を適当に間引きながらデータを作成したのですが、あんまりきれいな間引き方になっていないような気がして、少しもったいなかったのですが、思いきって新規作成分の平均近辺をスクエアにぱすっと捨てて、それに前回作成分を足しました。えっと、なに言っている分からないと思いますが(笑)、とにかくグラフのような感じに、真ん中減らしました。前回、21.5だった平均偏差は27.8に。そこだけでいうと、今回の方が厳しいデータセットになっていると思います。今回使用分は15万局面分+α。これを対称形に8倍して、切り良く120万局面分に減らしました。前回と同じく、その内80%を学習用に、残りの20%を検証用に使用します。この新しい学習データで、前回最後のネットワーク構成から試してみたいと思います。Normalizationです。今回はここから、入力層の所にパディング付の3×3の畳み込み層を追加していく形で、どんどん深くしてみました。最後は3×3の畳み込み層が18層です。Lossが下げ止まったら、学習を止めるようにしました。これは本家のドキュメントも一緒で、例えば、日本語版ではこうなってます。stopped.私の英語力が確かなら、これも間違っています。patience=1の時は、最高なり最低なりを1回でも更新できなかったらそこですぐに止まるわけではなく、2回連続して更新できなかったら止まるんです。patience=2の時は、3回です。1回でも更新できなかったらすぐ止まるpatience=0を基準に、さらに何回待つかっていうのがこのpatienceですよ。みなさん気をつけてください。今回は最初の「3×3の畳み込み層が9層」の時のみpatience=2(ちょっと少なかった。加減が結構難しい...)、10層からはpatience=3に設定してみました。簡単に数字が良くなっていきます。「こんな風に深くするだけでいいんであれば、小細工なしにResNetってやつをやれば終了じゃない?」ということで、前半部分にショートカットを入れたバージョンの14層と18層も追加で試してみました。先ほどのpatienceは4にしました。14層ならコードはこんな感じ。outputs=output)ショートカットあるなしで比較してみます。「18層の時は、もしかしたらショートカットが効いてるのかな?」ってぐらいですね。そもそも、この程度ではまだぜんぜんネットワークが深すぎるっていうほどのものじゃないのかもしれません。深くしたからサチったのではなくて、そろそろ学習データの精度の問題かも...ここで一度、現在作っている評価関数が実際にどんな形勢判断を返してくるのか確認することにしてみました。使った評価関数のバージョンは、先ほどの「3×3の畳み込み層が18層/ショートカットあり」。これに、検証用データの先頭200局面分を予測させた時の数値のグラフがこちらです。当たり前の話なんですが、本当に形勢判断できるんですね(笑)。気になることもあって、この検証用データのラベルが8つずつ全く同じのが続くのは、同じ局面の対称形が連続して並んでいるからなんですが、評価関数の出力の方はなかなかきれいに揃わないですね。これはまた調べてみたいですね。今回の200局面分の予測の中で検証用データのラベルと一番食い違っているのが、グラフ中央右寄りにある100を超えているやつなので、この局面を探して実際に盤面を見てみることにしました。WGo.js.検証用データのラベルは約138.61。これは、「コミがないとすれば次の手番である白が138.61目勝っている」の意味です。最初に盤面で確認しておかないといけないのは、下辺の黒の大石の死活ですが、これはセキにはなりますが生きてますね(見損じしてないよね?)。自作評価関数の出力は対称形8つの平均で87.31。「石いっぱいあるから強ーい」ぐらいに思っているだけで(笑)、Ray先生のような高度な判断をしている訳ではないような気がしますが、とはいえ、こういった不正確なラベルのせいで、40目も余分に間違えていることにされるようなことがちょくちょくあったら、下がるはずのLossも下がりません。「機械学習では質の良い学習データを大量に用意することが肝心」、という結論にまた落ち着いてしまいますね。いうことで、現在、学習データの精度を上げるべく、COSUMIのサーバをまたぶん回しております。いつか、学習データの作成自体を、この評価関数にやらせたいですね。2017/6/11]あの後、ASUSのSTRIX-GTX1060-DC2O6GっていうGTX1060・メモリ6GBなビデオカード買いました。EC2への課金が100ドルを超えてきたので、EC2使い続けるのか、別の方法を取るのか、今決めてしまわないといけないと思い、かなりいろいろ考えて、結局GPU買っちゃいました。最初は、GPU買うなら中途半端はだめで、1080ti一択だなと思い込んでいたのですが、そうなってくると電源ユニットの買い直しが確定するので、それがちょっとなあと思っていました。調べてみると、その下のグレードでも十分実用性がありそうですし、なによりはるかに安いので、こういう選択肢になりました。1070でも良かったけど、電源が100%自信が持てなかったので1060に。使っているマザーはASUSのP8H77-Vで、H77と最近のビデオカードとでは動かない時がある、という話を見て少し心配していたのですが、全く問題ありませんでした。このビデオカードは、温度が低い時にファンが完全に止まる静音設計で、それも購入にあたって重視していた点なのですが、そもそもファンが回っていても、めちゃくちゃ静かです。4年半前に買った時は5,880円だった物が、今現在、値段が倍以上する感じで萎えまくりです。playoutで4目ずつ)。量も少し増やして、計159万局面分。今までと同じく、その内80%を学習用に、残りの20%を検証用に使用します。いうことで、新しいGPUと新しいデータでいろいろ試してみましたが、結局一番数字が良くなるのは、次のようなパディングとショートカットを入れながら、ひたすら3×3の畳み込み層を重ねるだけというシンプルなやつでした。outputs=output)ショートカットなし版との比較がこちら。ショートカットは、はっきり効果があるようです。問題は、深くするのが良いのか広くするのが良いのかなんですが、まずはフィルタ数を32で固定して、3×3の畳み込み層が24層、32層、40層の比較がこちら。次に、3×3の畳み込み層を24層に固定して、フィルタ数が32、48、64の比較がこちら。MomentumなSGDを少し試してみたけど、特に良さそうには見えないといった感じでしょうか。数字はだいぶ良くなってきたので、本当に何か使い道も考えてみたいですね。2017/6/14]今のデータ量で行けるところまでやってみようと、3×3の畳み込み層が30層、フィルタ数が48で50エポック回してみました。その30エポック目からAdamの学習率をKerasのデフォルト(そしてそれは論文の推奨値だそうです)の1e-3から1e-4に小さくしたのと、またさらに、その40エポック目から学習率を1e-5に小さくしたのとのグラフがこちら。この学習率を下げるのは手動でやっているのですが、本当はこのあたり、コンピュータにスマートによろしくやってもらわないといけないのでしょうね。keras.callbacks.LearningRateScheduler()使ったり、keras.optimizers.Adam()のdecayを設定すれば良いのかなと、少し試してみたりもしましたが、結局どのくらいずつ下げていけば良いのか事前にはっきり分からないので、もう手動でもいいかな...それと、学習率下げてはっきりしましたが、最後はほんの少し過学習ぎみですね。paramsが586,513の今回の大きさのネットワークあたりが限界かな、という気がしてます。Lossは3.6(!)を切ってきました。そんなのもう、ほとんどRay由来のノイズじゃないのかと思ってしまいます。uniformも試して比較してみました(本当に申し訳ないのですが、今回の追記分のテストは1ヶ月以上前にやっていたことで、他の細かい条件がはっきりとは分からなくなってしまいました。ブログに書けば良かった...(笑))。なんだか、あまり小さくない差があるように見えます。Lossをグラフにしてみました。uniformの1とそれなりに差があるように見えます。Lossですので、あまり真に受けてもいけないと思うのですが、「畳み込み層の初期値はなんでも良いわけではない」のは、間違いなさそうです。2018/2/11]続きの記事があります。