コンピューター将棋開発者オフ会in梅田に行ってきたのじぇ!
今日はコンピューター将棋開発者オフ会に行ってきたのじぇ
将棋ソフト開発者オフ会 in 梅田、本日が募集締め切りです。開催は14日20:00~。参加したいという開発者の方おられましたら、ぜひともご参加のほど、よろしくお願いします! https://t.co/5ESAAmgWFt
— 香上 智@Labyrinthus+# (@kagami_tomo) 2016年9月11日
なう! pic.twitter.com/anHvOaLsMn
— 香上 智@Labyrinthus+# (@kagami_tomo) 2016年9月14日
将棋ソフト開発者オフ会おわったりっ。焼き肉おいしかったでよっ!( ^ω^)
— 香上 智@Labyrinthus+# (@kagami_tomo) 2016年9月14日
参加者はSquirrelの開発者であるまりちゃとLabyrinthus+#の開発者の香上さんとCGPの開発者のwainさんだったのじぇ
どんなひとなのかわからない人はここをみて確認すればいいのじぇ。
denou.jp
どうだったの焼き肉は?
いや~~もうお二方の賢さに圧倒されるだけの焼き肉だったのじぇ。
特にwainさんのコンピューターの根本に関わることに関する知識は半端なかったのじぇ
でも色々役に立つお話を聞くことが出来て大変良かったのじぇ!
leaと呼ばれる命令があってその命令を使えば*5,*9も普通の掛け算演算子を使うよりも早く計算できるらしいのじぇ!(11/7修正)
if()でCPUが過去の履歴から予測したのと逆の条件分岐に移るときに10clockぐらいロスになり、最近のプロセッサでは1clockで3命令ぐらい処理できるのでかなりのロスに成ってしまうらしいのじぇ!(11/7修正)
まりちゃの使っているパソコンのcpu:core2duoでの3秒探索は最新のcpuで言うところの0.5秒探索ぐらいらしいのじぇ!
そしてまりちゃのソフトがレッサー改より弱くなり、20キロnpsしか出ていないという話をするとStockFish7式の探索でcore2duoであれば250キロnpsは出るはずであるのでバグを探せと教えて頂いたのじぇ!
ゆゆっ!?すごい情報を手に入れたね!
そうなのじぇ!これからは頑張ってコードの無駄な部分を探してnpsを増やしていく改良をしていくのじぇ!
めざせ!250knps!!!
電王トーナメント出場が決まったのじぇ!!
電王トーナメント出場が決まったのじぇ!!
やったね!!
やったわね!
やったよ!!
最近なかなかモチベーションが上がらなかったけど
モチベーション回復したのじぇ!!
大会までもうひと踏ん張りなのじぇ!!
floodgateの棋譜を技巧風DBに変換するツールなのじぇ。
floodgateの棋譜を技巧風の学習用DBに変換するためのツールを作ったのじぇ。
技巧が読み込んでいる棋譜ファイルは
1行目: <棋譜番号> <対局開始日> <先手名> <後手名> <勝敗(0:引き分け,1:先手勝ち,2:後手勝ち)> <手数> <棋戦> <戦型>
2行目: <CSA形式の指し手(1手6文字)を一行に並べたもの>
という形式になっているみたいでこれは便利だと思ったのじぇ。
ちなみに2015年からFGの棋譜の中に対局者のレートが載るようになったようなので
それを利用してレート2800以下のソフトの棋譜は使わないように設定しているのじぇ。
これを用いて2015年のFGの棋譜を変換してレート2800位上のソフトの棋譜14380局が集まったのじぇ!!!
これでSquirrelお勉強計画が進むわね!!!!
えっお勉強...??
お勉強は嫌いだよ~~楽して強くなりたいよ~~!
楽して強く慣れれば苦労しないのじぇ。
これから強くなるまで一週間でも2週間でもぶっ続けでお勉強させてあげるのじぇ(暗黒微笑)
(´;ω;`)
ただこのツールは自分用にかなり適当に作ったのでバグ等や改善等あればプルリクしていただけると嬉しいのじぇ!!
このソフトは「なのは(将棋)」の作者さんの作られたfggatherを参考に作ったのじぇ。ありがとうございますなのじぇ。
でもwindows.h関連が理解できなかったからまりちゃが作ったのはwindows.hを用いなかったので、コードとしてはぜんぜん違うのじぇ。
ADADELTAの論文を読もうじぇ
タイトルの通りなのじぇ。
論文はここにあるのじぇ
http://www.matthewzeiler.com/pubs/googleTR2012/googleTR2012.pdf
第3.2章から何言っているのかわからなくなってしまったのじぇ.....
Unitってなんなのじぇ.....
まあ備忘録的にここにまとめて残しておくのじぇ。
~~ABSTRACT~~~
Adadeltaとは
勾配効果法の為の次元ごとの学習率調整方法
(ここで言う次元とはベクトルの要素数のことだと考えられる。例.(x,y,z):3次元)
(特徴)
ファーストオーダーインフォメーションしか用いない
(ファーストオーダーインフォメーションとは一回微分の結果のことだと考えられる)
何もなしのSGDを超える小さな計算時間
外乱に対する耐性
~~1 INTRODUCTION~~
SGDでは学習率ハイパーパラメータ(η)は手動で与えなければならなかった
(ADADELTA アプローチの利点)
手動で学習率を決める必要が無い
ハイパーパラメータ関係ない
次元ごとに学習率を分ける。
計算量が少ない
外乱に耐性がある
localまたは分散のある環境にも適応できる。(どういうこと?)
~~2 RELATED WORK~~
Newton methodではヘッセ行列の逆行列を使って計算をする。
しかしこれでは時間がかかりすぎるので
一回微分の結果を用いるか2回微分の値を予測するかする改良をする必要がある。
~~2.1 学習率焼きなまし~~
ローカルミニマムでは学習率を下げればよい学習率であるといえる。
極小値の周りで値は振動してしまうのでこれを防ぐために、一つの方法としては、
学習率が下がってくるに従ってパラメータの更新を遅くする方法もある。
しかし、その代わりに何epoch(epochとはなに???)が経過したかによって学習率を焼き鈍す方法が提案されている。
~~2.2 次元毎の一回微分Method~~
次元あたりに異なる学習率を用いる方法を紹介する
~~2.2.1 Momentum~~
Momentum Methodの主な考え方は
勾配が同じ方向を向いて変わらないdimensionには学習を加速させ、勾配の符号が変化し続けているところでは学習率を下げる。
これは前回のパラメーター更新の値を指数関数的に減衰させながら利用する事によって実装されている。
ρは前回のパラメーター更新の値の減衰をコントロールするための定数。
谷底が緩やかに傾いているような谷を想像すれば良い
谷底に沿うような方向には学習率を上げて、谷をまたぐ方向には学習率を下げることで谷をまたぐ方向の振動を和らげる。
~~2.2.3 ADAGRAD~~
この方法は一回微分の結果に頼っているが2回微分の結果と焼きなましの特性も持っている。
分母はこれまでの全次元ごとの学習率の勾配のL2ノルム
ηはすべての次元で共有される学習率
手動で調整しなければならないηは全次元共通ではあるけれども、それぞれの次元は自分の動的学習率を持っている。
学習率は勾配の大きさの逆数に依存するので大きな勾配は小さな学習率小さな勾配は大きな学習率を持つ。
最初の勾配が大きいものであれば残りの学習率も小さいものになってしまう
学習率はどんどん小さくなっていくので偶然0になって学習が停止してしまうことも起こりうる。
~~2.3 2回微分を用いたメゾッド~~
2回微分の情報はとても有益であるが計算に時間がかかるため
ヘッセ行列の対角成分の近似方法が提案された。
~~3 ADADELTA~~
ADAGRADの2つの欠点を改善させるためにADADELTAのアイディアをこの論文に発表する。
ADAGRADの欠点
(1)トレーニング中ずっと学習率が低下していってしまう
(2)学習率を手動調整しなければならない
~~3.1 idea1 蓄積に直近何回まで蓄積するかを設ける~~
ずっと勾配の2乗和を蓄積する代わりに、直近何回蓄積するかの窓を設ける。
これによって分母は無限まで大きくなることはない
ずっと誤差の2乗和を保存しておくのは効果的ではないので指数関数的減衰させていく。
~~3.2 idea2 ヘッセ行列の近似により、Unitを修正する~~
(Unitとは何なのか??)
パラメータの更新を考えるときunitsは調和されなければならない。
パラメータの変化はunitsの変化でもあるはずである
SGDやMomentumと言った方法ではunitsは勾配と結びついていた。
しかし、2回微分を用いる方法ではunitはパラメータの更新と関係がある????
(此処から先はよくわからない.......)
肉じゃが牛丼を食べるのじぇ!
某大御所コンピューター将棋開発者がこんなことをつぶやいていたのじぇ。
すき家の牛丼にファミマの肉じゃがぶっかけて、レンジでチンすると肉じゃが味のつゆだく風になってめちゃうまい。
— やねうら王 (@yaneuraou) 2016年7月15日
これはクックパッド、ランキング上位不可避ですわwww pic.twitter.com/2f2urhR8c9
ゆゆっ!?
おいしそうだよ~~!れいみゅも食べてみたいよ!
まりちゃもそう思うのじぇ!
早速買ってきて食べてみようじぇ!!!
まりちゃ。れいみゅ。あんまりファストフードばかり食べるのは都会派じゃないわ!
お野菜さんを使ったバランスの良いごはんさんもちゃんと食べないと!
まりちゃは若いからだいじょうぶなのじぇ~~
じゃあ早速買ってくるのじぇ!!!!
(30分後~~~)
ただいま~なのじぇ!買ってきたのじぇ!
ゆゆっ?すき家じゃなくって吉野家の牛丼なの?
すき家は家の近くになかったので諦めて吉野家なのじぇ!
しかも牛丼じゃなくて豚丼ね...
牛丼は豚丼よりも50円高かったのじぇ!
50円ぐらいケチらずに払いなさいよ^^;
まあたまにはだきょうっ!も必要なのじぇ!
早速料理するのじぇ~~♪
肉じゃがを上にかけてレンジでチンするだけだよ!
簡単だね!
完成なのじぇ!さあ早速食べようじぇ!!!
むーしゃむーしゃ...
・・・・あれ?そんなにおいしくないのじぇ?
確かにそんなにおいしくないね.....
これ肉じゃがをかけてないほうが美味しいのじぇ.......
吉野家の豚丼には肉じゃがは合わなかったみたいなのじぇ....
今度はちゃんとすき家の牛丼に肉じゃがかけて食べるのじぇ.....
~~今回のまとめ~~
吉野家の豚丼にはファミマの肉じゃがは合わなかった^^;
今度はちゃんとすき家の牛丼にファミマの肉じゃがかけて食べる
差し手生成部なのじぇ
ふうぅ~とりあえずやねうら王とAperyの差し手生成部を読んだのじぇ
お疲れさまね…..
ざっくりとした概略を文字で書くならこんな感じなのじぇ
やねうら王について
movepickerのmoves[600]が差し手配列 差し手生成関数は探索関数中のMovePicker mp(pos,ttMove);から呼び出される。 MovePicker(const Position& pos_,Move ttMove) の中で呼び出される template<MOVE_GEN_TYPE GenType> ExtMove* generateMoves(const Position& pos, ExtMove* mlist) 先手後手で呼び出す関数を分けるもの template<MOVE_GEN_TYPE GenType, bool All> ExtMove* generateMoves(const Position& pos, ExtMove* mlist,Square sq = SQ_NB) 指し手のタイプ別に分けるものの3種類あり template<MOVE_GEN_TYPE GenType,Color Us,bool All> ExtMove* generate_general(const Position& pos, ExtMove* mlist,Square recapSq=SQ_NB) 指し手の駒種別に差し手を生成するのは ~駒移動 struct GeneratePieceMovesでありこれには5しゅるいあり、 角飛車の移動 からの make_move_target 成れない手による移動 からの make_move_target 成れない手(王を除く) からのMAKE_MOVE_TARGET(target2); 歩の移動 からのmake_move or make_move_promote 桂馬香車銀の移動 からの make_move_target ここで差し手は生成される。 ~駒うち struct GenerateDropMovesの内部の (歩)FOREACH_BB(target2, sq, { mlist++->move = make_move_drop(PAWN,sq); }); (どこでも打てる)make_move_drop (香車桂馬)FOREACH_BB(target2, sq, { UNROLLER1({ mlist++->move = (Move)(drops[i] + sq); }); });
Apery twgについて
movepickerのMoveStack leagalmoves_[594]が差し手配列 探索関数の中のnextmove()でgonextphaseが呼ばれ goNextPhaseでフェーズにより分けられながら差し手が生成されている(!タイプ別差し手遅延生成!) その中で template <MoveType MT> MoveStack* generateMoves(MoveStack* moveStackList, const Position& pos)というのが呼ばれている (駒うちはgenerateMoves<Drop>(currMove(), pos());) その中でさらに色別で分けられ(template <MoveType MT, Color US, bool ALL = false>struct GenerateMoves ) その中で全駒種別に用意された(template <MoveType MT, PieceType PT, Color US, bool ALL> struct GeneratePieceMoves)の中の 成り makePromoteMove<MT>(Pawn, from, to, pos); 成らず makeNonPromoteMove<MT>(Pawn, from, to, pos); この関数の中の template <MoveType MT, PromoteMode PM> inline Move selectedMakeMove(const PieceType pt, const Square from, const Square to, const Position& pos) この関数内でようやく movetype別差し手生成が行われる 駒打ち generateMoves<Drop>(currMove(), pos())からの (色分け) template <MoveType MT> MoveStack* generateMoves(MoveStack* moveStackList, const Position& pos) からの (種類分け(drop固定)) template <Color US> struct GenerateMoves<Drop, US> (駒打ち) template <Color US> MoveStack* generateDropMoves(MoveStack* moveStackList, const Position& pos, const Bitboard& target)からの makeDropMove
やたらと複雑ね…
図にするとこうなるのじぇ
やねうら王
Apery
同じような名前の関数templateとそれに包まれた同じような関数templateが多すぎるのじぇ!
分かりにくいと思うけど我慢するのじぇ
多分この呼び出し構造だけでもわかれば読んでいくのも楽になるはずなのじぇ
間違ってるところがあれば指摘してほしいのじぇ
ちょっと複雑すぎるよ!なんでこんな似たような名前のtemplate関数ばっかりなの!?
似たような名前でわかりにくいのはまりちゃも同意なのじぇ。
これにはどういった最適化に関する意味があるのかはまりちゃには分からないのじぇ。コードが読みにくくなるだけだと思うのじぇ。
でもあのやねうら王もAperyもわざわざこんなことをするということは何か意味があると思っているのじぇ。
でもtemplateをたくさん使っているのはなぜだか分るのじぇ
多分過コーディングを防ぐためであると思うのじぇ
過コーディング??
なんかよくわからないけどあんまりコードが長くなりすぎると棋力が下がってしまうらしいのじぇ。
(平岡さんの2016年3月2日のツイート参照)
それとtemplateってどう関係があるのかしら?
ちょっとまりちゃもあんまりよくわかってないけど
やねうら王さんのコンピューター将棋ブログの
Stockfish完全解析のsearch 探索部の記事の
search.cppのtemplate
(勝手にリンクを張るのは怖いのじぇ)
多分ここの部分もそういう原理だと思うのじぇ
template<MOVE_GEN_TYPE GenType,Color Us,bool All>
ExtMove* generate_general()
にconst Bitboard targetってのがあるし…
ごめんなさいこの記事プログラミングあんまりよくわかってないときに書いた記事だから信用しないでください(;´・ω・)
templateについてはmerom686さんに昔聞いてみたことがあるのでここを読んでください(´・ω・`) ask.fm 条件分岐を減らせたり、データを読みとる必要がなくなったりして高速化できることがtemplateを使っている理由だと今では思っています
平岡さんの言っていた過コーディングについてはいまだに何のことなのかわかってないです(´・ω・`) 過コーディングはtemplateとは関係がないような気がしますね