ディープラーニングで囲碁

2016/10/03

Detelfさんの学習済みデータを動かす
Caffeで使うデータベース
Oakfoamのソースを落とす
HDF5
C++からLevelDBの作成
AyaのCNNを計算する関数
Caffeのインストール
棋譜
学習データのシャッフル
PolicyNetのネットワーク構造を指定
ValueNetの構造を指定
ValueNetの学習局面
平塚の囲碁4段
Caffeのデータの吸出し
学習途中のグラフ表示
GPUの選択
参考文献
論文
オープンソースのソフト


Detelfさんの学習済みデータを動かす
まずはGPUなしでDetlefさんが作成された学習済みデータを動かしてみる
のが参考になると思います。

1. Caffeのインストール
2. CaffeのサンプルのMNIST学習を動かしてみる。CPUで20分、GPUで1分ぐらい。
3. Detlef Schmickerさんの公開学習済みデータを落とす
   http://computer-go.org/pipermail/computer-go/2015-April/007573.html
4. サンプルを動かしてみる。私が作ったのがこちら
   http://www.yss-aya.com/20150907detlef_test.zip

   Detlefさんはその後、直前手も入れて54%の一致率のデータも公開されています。
   [Computer-go] CNN with 54% prediction on KGS 6d+ data
   http://computer-go.org/pipermail/computer-go/2015-December/008324.html

Caffeで使うデータベース Caffeで難しいのは学習用のデータをLevelDB、lmdb、HDF5、のDB仕様で持つ 必要があるのと、ネットワーク構成の書き方だと思います。 まずお勧めは石の配置だけから次の1手を学習させることです。 以下ではLevelDBを使い、学習データとラベル、どちらもLevelDBに持たせています。 Ayaで使っている学習サンプルを落とします。 http://www.yss-aya.com/20161004aya.zip predict.prototxt 論文 Teaching Deep Convolutional Neural Networks to Play Go の ネットワーク構造をCaffeで書いたもの。予測のみ。 最初の4行の input_dim: 1 input_dim: 2 input_dim: 19 input_dim: 19 は上から、ミニバッチのサイズ、入力の数、縦、横、を示しています。 train.prototxt 上記論文の学習用 solver.prototxt 学習率などを指定したファイル。train.prototxt を指定する generate_leveldb.py 囲碁の局面を LevelDB に変換。 $ python generate_leveldb.py < data.txt のdata.txtは下のようなもの。 最初の行は全局面数。黒の石の配置(石があれば1)、白の石の配置、どこに打ったか(0-360) 白番の場合は白黒反転させて格納。(常に黒番として学習させる) ----------------------------------------------------------- 284341 0000000000000000000000000000000000000000000000000000100000001011011000000000000000000000000000000000000000010100000000000000010010000000000000000000110000000000111010000100000000000000001000000000001000000100000000000000000010000000000000000100000000000000000000000000000000000001001000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000001000000000000010000100000000100010000000000000000010000000000000000100000001110000100000100011001000000010000000000000000000000000010000000000000010101000000000000000000000000000000001010000000000000000000000000000000000000000000000010000000000010000000000000000000100000000000000000000000000000000000000000 216 0110000000000000000010110101000001000000011100001111100000010011011000010010001000110000000011000000000111011001000000000001100000100000000000010110010000001001011000011100000110111000000101000001100110001101000001110011111011000001000000100001100000111000001001011100010011101100000010011000101010000000010000000011001000000000000111011100000000000000000000000 0000000000000000000101001000000000010001100011000000010100001100100111101101010100001110011100000110111000100000000000010010000011000000010111100001000000010010100111100000011001000101011000010110010001110000101010000000000100100010100000011110000001000000000100100000100100000010011100100101010001101001001010111100100100001100001000000010100000000010000000000 299 ... ----------------------------------------------------------- 学習用局面が100万局面あったとすれば97万局面ぐらいを Train 3%程度の3万局面を Test に分ける必要があります。 Testの局面は学習には使わず、このデータをどのくらい予測できるか、で 性能を計ります。 LevelDBは場所をディレクトリで指定します。 学習用のデータを train_leveldb テスト用のデータを test_leveldb のディレクトリに作ります。 train.prototxt の中の source: で場所を指定します。 そして下記で学習を開始します。 $ /home/hoge/caffe/build/tools/caffe train --solver=solver.prototxt Caffeがsnapshotsに吐き出すデータは _iter_530000.caffemodel _iter_530000.solverstate の2つがあり、 *.solverstate は計算途中で停止させたとき、再開(resume)させるもの。 *.caffemodel が学習データでこちらが重要。 resumeはあまり使わず、学習させたデータから新たに 学習開始する finetune をよく使っています。 $ /home/hoge/caffe/build/tools/caffe train --solver=solver.prototxt -weights /home/hoge/test/snapshots/_iter_950000.caffemodel finetune で便利なのは、 name: "conv1_5x5_128" で、新たに学習させるネットワーク構造と同じ名前のデータがweightsで指定する データに含まれていれば、それがそのまま使われ、名前が一致しないときは乱数で初期化 される点です。 これで、深い層の学習が学習初期に何度も失敗するときは、浅い層で学習させて それをfinetuneすることで学習を進めることができます。 詳しくは公式を Caffe | Interfaces http://caffe.berkeleyvision.org/tutorial/interfaces.html Oakfoamのソースを落とす 上の学習を行うときに参考になりました。 https://bitbucket.org/francoisvn/oakfoam/downloads 以下のディレクトリのファイルが参考になります。 scripts\CNN\ HDF5 私は学習データ(局面)を LevelDB で持たせ、ラベル(どこに打ったか)を HDF5 で持たせています。 Facebookの3手先まで予測するモデルを作るときに、LevelDBだと 複数のLabelを持たせるやり方がよく分からなかった、のと HDF5 だと4GBを超えるデータ作成が うまくいかなかったためです。多分どちらもできるとは思います。 $ generate_m3_hdf5.py < valuenet_hdf5_sample.txt ValueNetだとこのような感じで、局面数(5)、局面ごとの勝敗、を与えます。 PolicyNetだと、局面数、局面ごとの打った位置(0-360)です。 test_value_hdf5 といったディレクトリを作り、その下に2つのファイルを置きます。 aya_data.h5 ... DB本体 aya_data_list.txt ... aya_data.h5 の絶対パスを指定。中身は /home/hoge/test_value_hdf5/aya_data.h5 という1行のテキストファイルです。train.prototxt の中で以下のように指定します。 layers { name: "mnist" type: HDF5_DATA top: "label" hdf5_data_param { source: "/home/hoge/test_value_hdf5/aya_data_list.txt" batch_size: 256 } include: { phase: TEST } } C++からLevelDBの作成 今はLevelDBのデータはC++から直接作成しています。pythonで作っていると何日もかかるので。 参考ソースは下記。convert_db() 関数が参考になると思います。 // convert to leveldb // http://stackoverflow.com/questions/24706361/c-modified-a-function-tried-to-recompile-got-undefined-reference-to-that-fu #include <algorithm> #include <fstream> // NOLINT(readability/streams) #include <string> #include <utility> #include <vector> #include "boost/scoped_ptr.hpp" #include "gflags/gflags.h" #include "glog/logging.h" #include "caffe/proto/caffe.pb.h" #include "caffe/util/db.hpp" #include "caffe/util/io.hpp" #include "caffe/util/rng.hpp" // ~/caffe/tools/convert_imageset.cpp // This program converts a set of images to a lmdb/leveldb by storing them // as Datum proto buffers. // using namespace caffe; // NOLINT(build/namespaces) using std::pair; using boost::scoped_ptr; void setOneToDatum(Datum* datum, int num_inputs, int height, int width, unsigned char *pData ) { datum->set_channels(num_inputs); datum->set_height(height); datum->set_width(width); //datum->set_label(label); datum->clear_data(); datum->clear_float_data(); std::string* datum_string = datum->mutable_data(); // ->mutable_float_data() // static char data[num_inputs][height][width]; for (int c = 0; c < num_inputs; c++) { for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { unsigned char v = pData[c*height*width + h*width + w]; datum_string->push_back( v ); // datum_string->push_back( data[c][h][w] ); } } } } // https://github.com/BVLC/caffe/blob/master/src/caffe/util/io.cpp // std::string buffer(num_inputs*height*width, ' '); // for(c;h;w) buffer[c*height*width + h*width + w] = v; // datum->set_data(buffer); // datum->set_float_data(int index, float value); // -> build\src\caffe\proto\caffe.pb.h(1079): // datum->add_float_data(); // $ ./convert_imageset train_dataset/ train.txt train_leveldb 1 -backend leveldb 28 28 const int CommitNum = 1000; void convert_db() { ::google::InitGoogleLogging("ayamc"); // Print output to stderr (while still logging) FLAGS_alsologtostderr = 1; #ifndef GFLAGS_GFLAGS_H_ namespace gflags = google; #endif // Create new DB scoped_ptr<db::DB> db(db::GetDB("leveldb")); // "lmdb" or "leveldb" db->Open("test_cpp_db", db::NEW); scoped_ptr<db::Transaction> txn(db->NewTransaction()); // Storing to db Datum datum; int count = 0; for (int line_id = 0; line_id < 445693; ++line_id) { const int num_inputs = 7; const int height = B_SIZE; const int width = B_SIZE; unsigned char c_data[num_inputs*height*width]; setOneToDatum(&datum, num_inputs, height, width, c_data); // sequential const int kMaxKeyLength = 256; char key_cstr[kMaxKeyLength]; int length = snprintf(key_cstr, kMaxKeyLength, "%08d", line_id); // Put in db std::string out; CHECK(datum.SerializeToString(&out)); txn->Put(std::string(key_cstr, length), out); if (++count % CommitNum == 0) { // Commit db txn->Commit(); txn.reset(db->NewTransaction()); LOG(INFO) << "Processed " << count << " files."; } } // write the last batch if (count % CommitNum != 0) { txn->Commit(); LOG(INFO) << "Processed " << count << " files."; } } static int count_convert_db; static Datum datum_convert_db; static scoped_ptr<db::DB> *p_db = NULL; static scoped_ptr<db::Transaction> *p_txn = NULL; void create_convert_db() { ::google::InitGoogleLogging("ayamc"); // Print output to stderr (while still logging) FLAGS_alsologtostderr = 1; #ifndef GFLAGS_GFLAGS_H_ namespace gflags = google; #endif // Create new DB static scoped_ptr<db::DB> db(db::GetDB("leveldb")); // "lmdb" or "leveldb" db->Open(CONVERT_DB_FILE, db::NEW); static scoped_ptr<db::Transaction> txn(db->NewTransaction()); p_db = &db; p_txn = &txn; count_convert_db = 0; } void add_one_data_datum(unsigned char *pData) { setOneToDatum(&datum_convert_db, DCNN_CHANNNELS, B_SIZE, B_SIZE, pData); // sequential const int kMaxKeyLength = 256; char key_cstr[kMaxKeyLength]; int length = snprintf(key_cstr, kMaxKeyLength, "%010d", count_convert_db); // Put in db std::string out; CHECK(datum_convert_db.SerializeToString(&out)); (*p_txn)->Put(std::string(key_cstr, length), out); if (++count_convert_db % CommitNum == 0) { // Commit db (*p_txn)->Commit(); (*p_txn).reset((*p_db)->NewTransaction()); LOG(INFO) << "Processed " << count_convert_db << " files."; } } void finish_data_datum() { // write the last batch if (count_convert_db % CommitNum != 0) { (*p_txn)->Commit(); LOG(INFO) << "Processed " << count_convert_db << " files."; } } AyaのCNNを計算する関数 マルチスレッドで使う場合に注意するのは毎回 set_mode(Caffe::GPU) を 指定する必要があることです。 Caffeはスレッドローカルなので、新しいスレッドではデフォルトがCPUになって 計算が遅くなります。 void setModeDevice(int gpu_id) { // Caffe::set_mode(Caffe::CPU); Caffe::set_mode(Caffe::GPU); // 新規threadではdefaultの CPU にされてしまう -> 10倍遅くなる原因 // Caffe context is thread-local storage. static boost::thread_specific_ptr<Caffe> thread_instance_; // Caffe::SetDevice(gpu_id); Caffe::SetDevice(0); // GPU1台 } #define OLD_CAFFE 0 // 2016年3月ごろのCaffe用 float getResultCNN(int col, go *pgo, float *result, int net_kind, int gpu_id) { float ret_v = 0; const int size = B_SIZE; int mini_batch = 1; // >= 1 int nModel = getNetModel(net_kind); int input_dim = getNetChannels(nModel); float *data = new float[mini_batch*input_dim*size*size]; pgo->setAyaChannels(col, data, net_kind, input_dim); int b; for (b=1;b<mini_batch;b++) { int c; for (c=0;c<input_dim;c++) { int x,y; for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) { float v = *(data + c*B_SIZE*B_SIZE + y*B_SIZE + x); // [c][y][x]; int z = (y+1)*256+x+1; int zR = get_rotate_z(z, b); int xx = zR & 0x00ff; int yy = zR >> 8; *(data + b*input_dim*B_SIZE*B_SIZE + c*B_SIZE*B_SIZE + (yy-1)*B_SIZE + (xx-1)) = v; // [b][c][yy-1][xx-1] } // prt_dcnn_data(stock_num, c, b); } } #if (OLD_CAFFE==1) Blob<float> *b=new Blob<float>(mini_batch, input_dim, size, size); b->set_cpu_data(data); vector<Blob<float>*> bottom; bottom.push_back(b); #endif setModeDevice(gpu_id); #if (OLD_CAFFE==0) Net<float> *net = p_caffe_net[gpu_id]; Blob<float> *input_layer = net->input_blobs()[0]; input_layer->Reshape(mini_batch, input_dim, size, size); // net->Reshape(); // これは必要?なくても正常動作 input_layer->set_cpu_data(data); // ポインタをセットしてるだけ const vector<Blob<float>*>& rr = net->Forward(); #else const vector<Blob<float>*>& rr = p_caffe_net[gpu_id]->Forward(bottom); #endif if ( nModel == AYA_V_I50 ) { int b; for (b=0;b<mini_batch;b++) { float v = rr[0]->cpu_data()[b]; ret_v += v / (float)mini_batch; } // global_v_result = ret_v; } else { int x,y; for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) { result[y*B_SIZE + x] = 0; } int b; for (b=0;b<mini_batch;b++) { for (y=0;y<B_SIZE;y++) for (x=0;x<B_SIZE;x++) { float v = rr[0]->cpu_data()[b*B_SIZE*B_SIZE+ y*B_SIZE + x]; int z = (y+1)*256+x+1; int zR = get_reverse_rotate_z(z, b); int xx = zR & 0x00ff; int yy = zR >> 8; result[(yy-1)*B_SIZE + (xx-1)] += v / (float)mini_batch; } } } /* float sum = 0; for (int j=0;j<B_SIZE;j++) { for (int k=0;k<B_SIZE;k++) { float a = rr[0]->cpu_data()[j*B_SIZE+k]; sum += a; PRT("%5.3f ",a); } PRT("\n"); } PRT("sum=%.3f\n",sum); */ delete[] data; #if (OLD_CAFFE==1) delete b; #endif return ret_v; } Caffeのインストール 公式ページで対応しているubuntu 14.04の新規インストールがお勧めです。 私が参考にしたのは下記ですが、情報がすぐ古くなるのでCaffeの最新のページを見た方がいいかもしれません。 (Windowsでの開発環境はかなり苦労する、とのことでお勧めしません) DetlefさんのDeep Learningを試してみました http://www.yss-aya.com/bbs_log/bbs2015.html#bbs131 Caffe Installation (公式) http://caffe.berkeleyvision.org/installation.html Amazon EC2の g2.2xlarge には2016年2月の時点では下のページどおりでインストールできました。 Install Caffe on EC2 from scratch (Ubuntu, CUDA 7, cuDNN 3) https://github.com/BVLC/caffe/wiki/Install-Caffe-on-EC2-from-scratch-(Ubuntu,-CUDA-7,-cuDNN-3) ただ g2.2xlarge は GTX 980の3分の1程度の速度しかないのでお勧めではないです。 2016年9月29日に最大16GPUまでのP2が登場しましたが、あまり速くはありません。 GTX 1080 benchmark 最新のcuDNNを入れると3倍以上速くなるので、対応している最新版を入れるといいと思います。 CUDA 7.5 と cuDNN 5.0 http://www.yss-aya.com/bbs_log/bbs2016.html#bbs127 cuDNNを入れてみました http://www.yss-aya.com/bbs_log/bbs2015.html#bbs300 棋譜 GoGoD, 8万局、プロの棋譜のみ。http://gogodonline.co.uk/ 有料 2000円ぐらい。論文での引用多し。 BudukMovies 59439 games https://badukmovies.com/pro_games プロの棋譜、無料 tygem 9d, 22477 games http://baduk.sourceforge.net/TygemAmateur.7z KGS 4d over, 1450946 games http://www.u-go.net/gamerecords-4d/ 囲碁クエスト 9路 14751局(上位119x最大200)棚瀬さんのtwitter 囲碁クエスト 9路 8607局。上位50人(一人最大200局まで)。対局者名の先頭に「:」がついたものはBotです。 囲碁クエスト 13路 9410局。上位40人(一人最大500局まで) 囲碁クエスト 13路 44881局。上位300人 囲碁クエスト 9路 49895局。 囲碁クエスト 9路+13路 161032局 + 200017局。 KGSの棋譜は一致率が57%、プロのGoGoDは51%〜53%?と、KGSの方が 簡単なので一致率は上がる。 DCNNの強さとしてはどっちが上かは不明。 学習データのシャッフル 岡谷さんの本によると 「ネットワークが『見慣れない』サンプルを提示すると学習が最も効率的に進む」 とのことです。 Facebookの論文ではシャッフルなしだと「すぐに過学習し、poor local minimaにトラップした」とあります。 GoGoDの棋譜を20000局面ごとにシャッフルして学習させたときは 棋譜の順番はそのままだったのですが、DCNNはあっさりと1800年代の棋譜と現代の棋譜の 違いを学習できるようでした。 DCNNの学習を始めてみました http://524.teacup.com/yss/bbs/2784 http://www.yss-aya.com/bbs_log/bbs2016.html#bbs1 そこで今は、8万局の棋譜を全部シャッフルしたあと、LevelDB格納時には 10万局面ごとにシャッフルしています。 PolicyNetのネットワーク構造を指定 Ayaで使っている学習用と予測用、の2つがあります。中身はほぼ同じですが aya/m3_i49_train.prototxt ... 19路で3手先まで予測する学習用。Filter128、12層 aya/m3_i49_predict.prototxt ... 予測用 aya/13x13_m3_i49_predict.prototxt ... 19路の学習データを13路で利用 使っている入力は49面です。 [Computer-go] DCNN can solve semeai? http://computer-go.org/pipermail/computer-go/2016-February/008606.html ValueNetの構造を指定 aya/19_v_F32_L11_predict.prototxt ... 19路用のValueNetの予測用 入力は50面で、PolicyNetに手番1面を追加したものです。 黒と白は手番で反転させずにそのまま入力しています。 ValueNetの学習局面 AlphaGoの論文では3000万局面を自己対戦で作成しています。 この数字が一般人には最大の壁かと思います。 Ayaは19路はGoGoD, tyegem 9d, KGS 4d overの棋譜 100万棋譜ぐらいを使い、 これらの棋譜の結果、を学習させています。B+Rなら黒勝ち (+1)、W+Rなら(-1)とします。 そして1つの棋譜から16局面を取り出して同じ結果を与えます。 16局面は全体の手数から均等な感じで乱数で選びます。1番目の局面と 9番目の局面は回転、対称の8回転を同じにします。つまり本質的に 同じ局面は平均200手として100手は離れています。 プロの結果はほぼ無条件で信用し、KGSの棋譜は最後の局面をAyaの500playoutで 判定し、それが棋譜の結果と一致したもののみ採用しています。置き碁は除いています。 コミが0.5や作り碁で+1.5目勝ち、と小さい場合も判定させています(コミ7.5で作成する場合)。 これで1600万局面を作り32Filter、14層で学習させたValueNetは 1手1000playoutで勝率0.66ぐらいの強さになりました。+100 Elo程度と小さいです。 ただ、1手に時間をかけると勝率が上がる傾向にあります。ValueNetは深い探索ほど効果的?かもしれません。 Playoutを行う局面でのValueNetの値とPlayoutの結果の平均を上に返す、という実装です。 またKGSで置き碁を除いた棋譜でも黒勝ちは42%程度で、かなり偏っています。 48%になるまで白勝ちをまびく必要がある?かもしれません。 また強さが違うplayerが対局したデータで学習させるのはまずいかもしれません。 9路、13路はAyaの2000playout、500playout(RootのみPolicy1回)の自己対戦から作っています。 9路は囲碁クエストの8607局から定石DBを作って乱数でばらけさせています。 13路は16手目までPolicyNetの確率にしたがって打たせています。 9路だとCGOSで2300点、13路は2400点です。 どちらも100万局です。1棋譜から16局面取り出しています。 1手1000playoutだと13路は+200程度、9路は+100程度で、13路が一番効果がありました。 細かいデータは掲示板のログに分散してますが書いてます。 AyaZBotについて http://www.yss-aya.com/bbs_log/bbs2016.html#bbs121 [Computer-go] Value Network http://computer-go.org/pipermail/computer-go/2016-March/008768.html 平塚の囲碁4段 有料ですがソースにDCNNをCPUで実行するコードが書いてあり参考になります。 http://www.vector.co.jp/soft/winnt/game/se513389.html オープンソースのリンクにあるDeltaGoにもCNNをCPUで計算するコードがあります。 Caffeのデータの吸出し Caffeで学習させた *.caffemodel に含まれる学習データをバイナリで吸い出します。 extract\ep.py を実行します。 学習途中のグラフ表示 cplogpng.sh を実行すると一致率やlossのグラフが出ます。基本はCaffeに付属しています。 tools\extra\plot_log.gnuplot.test あたりでがグラフを書くためのツールです。 GPUの選択 学習済みデータを動かすだけならCPUで十分ですが、 学習させようと思ったらGPUは必須だと思います。 速度が30倍ほど違うので。 またcore数が1000以上でcuDNNが使える最近のGPUを買った方がいいです。 私は2010年発売のGTS 450を持ってたのですが、cuDNNは未対応でした。 [Computer-go] What hardware to use to train the DNN http://computer-go.org/pipermail/computer-go/2016-February/008631.html GTX 1080 2560 1607MHz 180W 8GB 16nm 92,000円 8pin x1 TITAN X 3072core, 1000MHz, 250W, 12GB, 28nm 120,000円 GTX 980 2048core, 1126MHz, 165W, 4GB, 28nm 64,000円 6pin x2 山下所有 GTX 960 1024core, 1178MHz, 120W, 2GB, 28nm 17,000円 (中古) GTX 760 1152core, 980MHz, 170W, 2GB, 28nm 25,000円 GTX 750 Ti 640core, 1020MHz, 60W, 2GB, 28nm 12,000円 GTX 670 1344core 915MHz HiraBotさん所有 GTS 450 192core, 783MHz, 106W, 1GB, 40nm 3pin x1 GRID K520 1536 x2 797MHz 225W, 4GB, 28nm Amazon EC2 g2.2xlarge (2x GK104) Kepler Tesla K80 2496 x2 562MHz 149W, 12GB, 28nm Amazon EC2 p2.xlarge (2x GK210) Kepler GPU仕様一覧表 http://wikiwiki.jp/nvidiavga/?GPU%BB%C5%CD%CD%B0%EC%CD%F7%C9%BD お勧めは2016年5月27日に発売されたGTX 1080です。 プロセスルールが16nmと小さくなって発熱控えめで性能もGTX 980の2倍近いです。 とはいえ、お値段も高いので中古でGTX 960ぐらいを買うのがいいのかもしれません。 GTX 1080(Pascal世代)にはCUDA 8.0が必要です。 また、外部電源として6pinや8pinの補助電源がいるので、パソコンの電源が その端子を持っているか確認する必要があります。 http://ascii.jp/elem/000/000/515/515097/ 参考文献 深層学習 岡谷 貴之 (著) ... お勧めします。畳み込みの概念などが詳細に書いてあります。 http://www.amazon.co.jp/dp/4061529021 初めてのディープラーニング --オープンソース"Caffe"による演習付き 武井 宏将 (著) ... ちょっと簡単すぎるかもしれません https://www.amazon.co.jp/dp/4865940227 論文 Teaching Deep Convolutional Neural Networks to Play Go (2014年12月。最初のDCNN論文) http://arxiv.org/pdf/1412.3409v1.pdf Move Evaluation in Go Using Deep Convolutional Neural Networks (2014年12月。Ajaたちの最初の論文。KGSで55%) http://www.cs.toronto.edu/~cmaddis/pubs/deepgo.pdf Better Computer Go Player with Neural Network and Long-term Prediction (2015年10月。Facebookの論文。3手先まで予測。384Filterと巨大) http://arxiv.org/abs/1511.06410 Mastering the Game of Go with Deep Neural Networks and Tree Search (2016年 1月。AlphaGo、ValueNetでプロに勝つ) http://airesearch.com/wp-content/uploads/2016/01/deepmind-mastering-go.pdf オープンソースのソフト Ray http://computer-go-ray.com/ 電通大出身の小林さん作成です。ソースがきれいで読みやすいです。 Ray-nn https://github.com/zakki/Ray/tree/nn RayにPolicy,ValueをつけてCGOSで2900。zakkiさん作成。 Dark Forest https://github.com/facebookresearch/darkforestGo Facebook作成。DCNNのみでKGS 3dになった学習済みデータあり。Torch使用。cuDNN 5.0以降でないと動かないようです。 Leela https://sjeng.org/leela.html オープンソースではありませんがKGS 4dか5dくらいあり強いです。 DeltaGo http://home.q00.itscom.net/otsuki/delta.html 192filterで一致率54%。OpenMPで17倍高速に。AlphaGoに関する講演資料あり。大槻さん作成。