From 2a6636ae446c8072ed9f9c265d8b95165f2ee162 Mon Sep 17 00:00:00 2001 From: yssaya Date: Sun, 25 Dec 2022 18:35:02 +0900 Subject: [PATCH 1/5] sum-tree. --- learn/yss.cpp | 6 ++ learn/yss_dcnn.cpp | 152 +++++++++++++++++++++++++++++++++++++-- src/playshogi/readme.txt | 7 ++ 3 files changed, 159 insertions(+), 6 deletions(-) diff --git a/learn/yss.cpp b/learn/yss.cpp index 598b605..745f11b 100644 --- a/learn/yss.cpp +++ b/learn/yss.cpp @@ -998,6 +998,11 @@ int shogi::LoadCSA() if ( s < 0 || s > 10000 ) DEBUG_PRT("Err s=%d,v=%s\n",s,str); pz->v_score_x10k.push_back((unsigned short)s); has_root_score = true; + } else if ( strstr(str,"r=") ) { + count--; + float score = atof(str+2); + int s = (int)(score * 10000); + if ( s < 0 || s > 10000 ) DEBUG_PRT("Err s=%d,v=%s\n",s,str); } else { all_visit = atoi(str); pz->v_playouts_sum.push_back(all_visit); @@ -1007,6 +1012,7 @@ int shogi::LoadCSA() if ( (count&1)== 0 ) { if ( b0==0 && b1==0 ) DEBUG_PRT(""); int v = atoi(str); + if ( v==0 ) DEBUG_PRT("v=0,%s\n",str); if ( v > 0xffff ) v = 0xffff; sum_visit += v; unsigned short m = (((unsigned char)b0) << 8) | ((unsigned char)b1); diff --git a/learn/yss_dcnn.cpp b/learn/yss_dcnn.cpp index f7892d2..685e24c 100644 --- a/learn/yss_dcnn.cpp +++ b/learn/yss_dcnn.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "yss_ext.h" /** load extern **/ #include "yss_prot.h" /** load prototype function **/ @@ -2763,7 +2764,8 @@ void free_zero_db_struct(ZERO_DB *p) //const int ZERO_DB_SIZE = 267000000; // AI_book2 //const int ZERO_DB_SIZE = 20000000; // gct001-075 //const int ZERO_DB_SIZE = 1000000; // 100000, 500000 -const int ZERO_DB_SIZE = 2190000; // 100000, 500000 +//const int ZERO_DB_SIZE = 2190000; // 100000, 500000 +const int ZERO_DB_SIZE = 500000; // 100000, 500000 const int MAX_ZERO_MOVES = 513; // 512手目を後手が指して詰んでなければ。513手目を先手が指せば無条件で引き分け。 ZERO_DB zdb_one; @@ -2778,11 +2780,11 @@ const int ZDB_POS_MAX = ZERO_DB_SIZE * 128; // 128 = average moves. 64 = gct001- //const int ZDB_POS_MAX = ZERO_DB_SIZE * 1; // AI book2 int zdb_count = 0; -int zdb_count_start = 59020000;//58410000;//51000000;//1000000; //53920000; 52320000;48000000;1000000;48300000;18000000; 10000000;11600000; 10300000; 9500000;8500000; 7400000; //5220000; //3200000; //2100000; //390000;//130000;//460000;//29700000; //18200000;//23400000; //20300000; //18800000; //16400000; //10300000; //5200000; // 400万棋譜から読み込む場合は4000000 +int zdb_count_start = 61300000; //59020000;//58410000;//51000000;//1000000; //53920000; 52320000;48000000;1000000;48300000;18000000; 10000000;11600000; 10300000; 9500000;8500000; 7400000; //5220000; //3200000; //2100000; //390000;//130000;//460000;//29700000; //18200000;//23400000; //20300000; //18800000; //16400000; //10300000; //5200000; // 400万棋譜から読み込む場合は4000000 uint64_t zero_kif_pos_num = 0; int zero_kif_games = 0; int zero_pos_over250; -const int MINI_BATCH = 256; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 +const int MINI_BATCH = 128; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 //const int MINI_BATCH = 32; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 const int ONE_SIZE = DCNN_CHANNELS*B_SIZE*B_SIZE; // 362*9*9; *4= 117288 *64 = 7506432, 7MBにもなる mini_batch=64 int nGCT_files; // 1つの selfplay_gct-00*.csa に入ってる棋譜数 @@ -2793,6 +2795,111 @@ int zero_pos_over250; const int fWwwSample = 0; // fReplayLearning も同時に1 +// Sum-Tree用 +// Prioritized Experience Replayのsum-treeの実装 +// https://tadaoyamaoka.hatenablog.com/entry/2019/08/18/154610 +// https://github.com/jaromiru/AI-blog/blob/master/SumTree.py + +const bool fSumTree = true; + +const int LEAVES = 41352794; // 棋譜の数ではない。局面数。ZERO_DB_SIZE; +const int SUMTREE_SIZE = 2*LEAVES - 1; +int sumtree[SUMTREE_SIZE]; +int add_n = 0; +int capacity = LEAVES; +std::mt19937 get_mt_rand; + +void stree_propagate(int idx, int change) { + int parent = (idx - 1) / 2; + sumtree[parent] += change; + if ( sumtree[parent] > INT_MAX/2 ) DEBUG_PRT("sumtree:too big =%d\n",sumtree[parent]); + if ( parent != 0 ) stree_propagate(parent, change); +} +int stree_retrieve(int idx, int s) { + int left = 2 * idx + 1; + int right = left + 1; +// if ( left >= len(st) ) return idx; + if ( left >= SUMTREE_SIZE ) return idx; + if ( s <= sumtree[left] ) { + return stree_retrieve(left, s); + } else { + return stree_retrieve(right, s - sumtree[left]); + } +} +void stree_update(int idx, int p) { + int change = p - sumtree[idx]; + if ( p <= 0 ) DEBUG_PRT("idx=%d,change=%d,p=%d\n",idx,change,p); + sumtree[idx] = p; + stree_propagate(idx, change); +} +int stree_total() { + return sumtree[0]; +} +void stree_add(int p) { + if ( p <= 0 ) DEBUG_PRT(""); + int idx = add_n + capacity - 1; + stree_update(idx, p); + + add_n += 1; + if ( add_n >= capacity ) add_n = 0; +} +// 要素が10個なら idx = 9...18 となる。idx - (LEAVES-1) が求めたい値 +int stree_get(int s) { + if ( s <= 0 ) DEBUG_PRT(""); + int idx = stree_retrieve(0, s); + return idx; // sumtree[idx] +} +int stree_get_i(int s) { // 0 <= i <= LEAVES-1 + int i = stree_get(s) - (LEAVES-1); + if ( i < 0 || i >= LEAVES ) DEBUG_PRT(""); + return i; +} +void init_stree() { + std::random_device rd; + get_mt_rand.seed(rd()); + for (int i=0; i= LEAVES ) DEBUG_PRT("n=%d,p=%d",n,p); + int idx = n + (LEAVES-1); + if ( idx >= SUMTREE_SIZE ) DEBUG_PRT(""); + stree_update(idx, p); +} + + +#if 0 +void stree_test() +{ + std::random_device rd; + std::mt19937 get_mt_rand(rd()); +// get_mt_rand.seed(time(NULL)); + + PRT("total=%d\n",stree_total()); + +// int P[LEAVES] = { 6, 48, 31, 26, 49, 43, 93, 74, 79, 13 }; +// int P[LEAVES] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + int P[LEAVES] = { 2, 1, 1, 1, 1, 3, 1, 1, 1, 2 }; + int i; + for (i=0; i dist(0, t-1); // 0からt-1までの一様乱数 + int p_sum[SUMTREE_SIZE] = {0}; + for (i=0;i<10000;i++) { +// int s = (get_mt_rand() % t)+1; // +1 が必要。% はやや不正確 + int s = dist(get_mt_rand) + 1; // +1 が必要。一様乱数 + int idx = stree_get(s); + p_sum[idx]++; + } + for (i=0;i MAX_GAMES ) nHandicapLastID[i] = zdb_count - MAX_GAMES; } + static int s_sum[101]; zero_kif_pos_num = 0; zero_kif_games = 0; zero_pos_over250 = 0; @@ -3237,6 +3345,24 @@ void update_pZDBsum() if ( GCT_SELF==1 ) pZDBplayouts_sum[n] = 0; pZDBscore_x10k[n] = p->v_score_x10k[j]; if ( m0 >= 250 ) zero_pos_over250++; + + if ( fSumTree ) { +// int s = pZDBplayouts_sum[n]; + int s = pZDBscore_x10k[n]; + int k = 10; // 20 20 20 20 10 10 20 20 20 20 + if ( s < 3900 || s > 6100 ) k = 20; + if ( s < 3000 || s > 7000 ) k = 30; +// if ( s < 2500 || s > 7500 ) k = 20; +// if ( s < 100 || s > 990 ) k = 5; + stree_replace(n, k); +// s_sum[s/100]++; + int prev_s = 0; + if ( j > 0 ) prev_s = pZDBscore_x10k[n-1]; + if (j&1) s = 10000 - s; + else prev_s = 10000 - prev_s; + if ( j==0 ) prev_s = s; + s_sum[abs(s - prev_s)/100]++; + } } // PRT("%d/%d,%lu,",i,loop,zero_kif_pos_num); zero_kif_pos_num += p->moves; @@ -3347,6 +3473,8 @@ void update_pZDBsum() // save_average_winrate(ave_winrate); // PRT("H:"); for (i=0;i dist(0, stree_total()-1); + // pos_sum の中から64個ランダムで選ぶ int *ri = new int[mini_batch]; int *ri_moves = new int[mini_batch]; int i; for (i=0;iCopyTrainedLayersFrom(sNet); // caffemodelを読み込んで学習を再開する場合 +// net->CopyTrainedLayersFrom(sNet); // caffemodelを読み込んで学習を再開する場合 // load_aoba_txt_weight( net, "/home/yss/w000000000689.txt" ); // 既存のw*.txtを読み込む。*.caffemodelを何か読み込んだ後に LOG(INFO) << "Solving "; PRT("fReplayLearning=%d\n",fReplayLearning); @@ -4361,7 +4501,7 @@ void start_zero_train(int *p_argc, char ***p_argv ) //nLoop = (int)((float)nLoop * 0.72727f); //nLoop = (int)((float)nLoop * 0.701); if ( GCT_SELF ) nLoop = 800000*1; -nLoop = 800000*1; +nLoop = 100000*1; PRT("nLoop=%d,add=%d,add_mul=%.3f,MINI_BATCH=%d,kDataSize=%d,remainder=%d,iteration=%d(%d/%d),rand=%lu/%lu(%lf)\n",nLoop,add,add_mul,MINI_BATCH,kDataSize,remainder,iteration,iter_weight,iter_weight_limit, rand_try,rand_batch,(double)rand_try/(double)rand_batch); int loop; diff --git a/src/playshogi/readme.txt b/src/playshogi/readme.txt index c0ccc43..ce76207 100644 --- a/src/playshogi/readme.txt +++ b/src/playshogi/readme.txt @@ -29,6 +29,12 @@ bin/playshogi -rsm 800 -P 25 -B 7 -U 0 -H 1 -c /bin/bash -W w1650.txt -0 "bin/ao 2純<絽吾筝"-d 1" 薤純<篁ヤ茹(2)蕋(3)2(4)4(5)6(6) bin/playshogi -frsm 800 -d 4 -0 "bin/aobaz -p 400 -msafe 30 -w w1525.txt" -1 "bin/aobaz -p 10 -msafe 30 -w w1525.txt" >> 2mai_p400_vs_p10.csa +dlshogi1100playoutсdlshogiplayout絎純拷 +bin/playshogi -brsm 400 -i usi0.txt:usi0.txt -c /bin/bash -P 7 -U 0 -B 3 -H 1 -W w4195.txt -0 "./aobaz -p 100 -e 0 -w w4195.txt" -1 "./dlshogi_dr2_exhi/usi/bin/usi_dr2e_po 100" >> w4195_b1t1_p100_vs_dlshogi_dr2_b1t1_100p.csa +$ cat usi0.txt +setoption name DNN_Batch_Size value 1 +setoption name UCT_Threads value 1 + 羈 ubuntu 16 "-c /bin/bash" 篁AobaZero祉拷篏障 @@ -86,6 +92,7 @@ Other options: -T STR Specifies the number of threads for CPU BLAS computation. STR can contain two numbers separated by ':'. The default is -1 (means an upper bound of the number). + -i STR USI setoption file. STR can contain two numbers separated by ':'. Example: playshogi -0 "~/aobaz -w ~/w0.txt" -1 "~/aobaz -w ~/w1.txt" Generate a gameplay between 'w0.txt' (black) and 'w1.txt' (white) From 8347fc8e1408e329bbb46011f56bbcbe9527f6f3 Mon Sep 17 00:00:00 2001 From: yssaya Date: Sun, 26 Mar 2023 22:09:28 +0900 Subject: [PATCH 2/5] change selective probability by position winrate. --- learn/yss.cpp | 18 +- learn/yss.h | 3 +- learn/yss_dcnn.cpp | 759 ++++++++++++++++++++++++++++++++++++++++----- learn/yss_dcnn.h | 4 +- learn/yss_misc.cpp | 6 +- 5 files changed, 705 insertions(+), 85 deletions(-) diff --git a/learn/yss.cpp b/learn/yss.cpp index 745f11b..304e4a3 100644 --- a/learn/yss.cpp +++ b/learn/yss.cpp @@ -974,6 +974,8 @@ int shogi::LoadCSA() if ( pz->vv_move_visit.size() != (size_t)tesuu ) { DEBUG_PRT("pz->vv_move_visit.size()=%d,tesuu=%d Err\n",pz->vv_move_visit.size(),tesuu); } + vector vc; + pz->vv_raw_policy.push_back(vc); back_move(); char *p = lpLine + 1; int count = 0, all_visit = 0, sum_visit = 0; @@ -1003,8 +1005,10 @@ int shogi::LoadCSA() float score = atof(str+2); int s = (int)(score * 10000); if ( s < 0 || s > 10000 ) DEBUG_PRT("Err s=%d,v=%s\n",s,str); + pz->v_rawscore_x10k.push_back((unsigned short)s); } else { all_visit = atoi(str); + if ( all_visit > 0xffff ) all_visit = 0xffff; pz->v_playouts_sum.push_back(all_visit); if ( has_root_score == false ) pz->v_score_x10k.push_back(NO_ROOT_SCORE); } @@ -1017,8 +1021,19 @@ int shogi::LoadCSA() sum_visit += v; unsigned short m = (((unsigned char)b0) << 8) | ((unsigned char)b1); int move_visit = (m << 16) | v; - pz->vv_move_visit[tesuu].push_back(move_visit); + pz->vv_move_visit[tesuu].push_back(move_visit); b0 = b1 = 0; + int len = strlen(str); + if ( len > 0 ) { + char c = str[len-1]; + if ( ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ) { + if ( c >= 'a' ) c = c - 'a' + 26; + else c = c - 'A'; + if ( c < 0 || c > 51 ) DEBUG_PRT("str=%s\n",str); + pz->vv_raw_policy[tesuu].push_back(c); + } + } + } else { if ( getMoveFromCsaStr(&bz, &az, &tk, &nf, str)==0 ) DEBUG_PRT(""); int c = (tesuu + fGotekara)&1; @@ -1221,6 +1236,7 @@ P-00AL for (i=0;i<(int)pz->vv_move_visit.size();i++) { sum += pz->vv_move_visit[i].size(); } + if ( pz->vv_move_visit.size() != pz->vv_raw_policy.size() ) DEBUG_PRT("pz->vv_raw_policy.size()=%d\n",pz->vv_raw_policy.size()); PRT("handicap=%d,moves=%d,result=%d, mv_sum=%d,%.1f\n",pz->handicap,pz->moves,pz->result,sum, (double)sum/(tesuu+0.00001f)); if ( pz->result_type == RT_NONE ) DEBUG_PRT(""); #endif diff --git a/learn/yss.h b/learn/yss.h index c8c159b..db34d62 100644 --- a/learn/yss.h +++ b/learn/yss.h @@ -443,7 +443,8 @@ class shogi { int make_www_samples(); void get_piece_num_diff(bool bGoteTurn, int d[]); void sum_pwv(double z, bool bGoteTurn, double sumd[]); - + void same_pos_check(); + int is_koshikake_gin(ZERO_DB *p); // fish関連 bool is_pseudo_legalYSS(Move m, Color sideToMove); diff --git a/learn/yss_dcnn.cpp b/learn/yss_dcnn.cpp index 685e24c..8f41d86 100644 --- a/learn/yss_dcnn.cpp +++ b/learn/yss_dcnn.cpp @@ -1004,6 +1004,15 @@ int get_dlshogi_policy(int bz, int az, int tk, int nf) { return index; } +// 移動先、とその位置に来る方向(8+2)、成(8+2)、駒打ち、で 9x9 * (10 + 10 + 7) = 81*27 = 2187 通りで一意に決まる +// https://tadaoyamaoka.hatenablog.com/entry/2017/05/07/155418 +// 最小の1496通り、盤外からの移動、4段目以上から4段目以上への成、 +// 谷合さんの電竜戦3報告 https://drive.google.com/file/d/1jC6kmlTHNSvUs-jCyHBAkiL5zRAZEdrJ/view +// 盤外からの移動や、打てない駒、4段目以上での下から以外の移動での成、を削除すると 1600? 通り。指し手の最大が593だから半分近い! +// 1496通り、らしいです。https://tokumini.hatenablog.com/entry/2021/09/19/160000 +// 2187で使わない場所をチェックして、2187通りの空いてるところを埋める? + + void prt_dcnn_data(int stock_num,int c,int turn_n) { int x,y; @@ -2751,21 +2760,23 @@ void free_zero_db_struct(ZERO_DB *p) p->result_type = 0; p->moves = 0; p->handicap = 0; - std::vector().swap(p->v_kif); // memory free hack for vector. - std::vector().swap(p->v_playouts_sum); + vector().swap(p->v_kif); // memory free hack for vector. + vector().swap(p->v_playouts_sum); vector< vector >().swap(p->vv_move_visit); - std::vector().swap(p->v_score_x10k); + vector().swap(p->v_score_x10k); + vector().swap(p->v_rawscore_x10k); + vector< vector >().swap(p->vv_raw_policy); #if ( GCT_SELF==1) - std::vector().swap(p->v_init_pos); + vector().swap(p->v_init_pos); #endif } //const int ZERO_DB_SIZE = 267000000; // AI_book2 //const int ZERO_DB_SIZE = 20000000; // gct001-075 -//const int ZERO_DB_SIZE = 1000000; // 100000, 500000 -//const int ZERO_DB_SIZE = 2190000; // 100000, 500000 -const int ZERO_DB_SIZE = 500000; // 100000, 500000 +//const int ZERO_DB_SIZE = 500000; // 100000, 500000 +const int ZERO_DB_SIZE = 1000000; // 100000, 500000 +//const int ZERO_DB_SIZE = 4000000;//3980000; const int MAX_ZERO_MOVES = 513; // 512手目を後手が指して詰んでなければ。513手目を先手が指せば無条件で引き分け。 ZERO_DB zdb_one; @@ -2780,18 +2791,18 @@ const int ZDB_POS_MAX = ZERO_DB_SIZE * 128; // 128 = average moves. 64 = gct001- //const int ZDB_POS_MAX = ZERO_DB_SIZE * 1; // AI book2 int zdb_count = 0; -int zdb_count_start = 61300000; //59020000;//58410000;//51000000;//1000000; //53920000; 52320000;48000000;1000000;48300000;18000000; 10000000;11600000; 10300000; 9500000;8500000; 7400000; //5220000; //3200000; //2100000; //390000;//130000;//460000;//29700000; //18200000;//23400000; //20300000; //18800000; //16400000; //10300000; //5200000; // 400万棋譜から読み込む場合は4000000 +int zdb_count_start = 62400000;//40000000;//61950000;//59030000;//61950000;//61300000; //59020000;//58410000;//51000000;//53920000; 52320000;48000000;1000000;48300000;18000000; 10000000;11600000; 10300000; 9500000;8500000; 7400000; //5220000; //3200000; //2100000; //390000;//130000;//460000;//29700000; //18200000;//23400000; //20300000; //18800000; //16400000; //10300000; //5200000; // 400万棋譜から読み込む場合は4000000 uint64_t zero_kif_pos_num = 0; int zero_kif_games = 0; int zero_pos_over250; +//const int MINI_BATCH = 256; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 const int MINI_BATCH = 128; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 -//const int MINI_BATCH = 32; // aoba_zero.prototxt の cross_entroy_scale も同時に変更すること!layerのnameも要変更 const int ONE_SIZE = DCNN_CHANNELS*B_SIZE*B_SIZE; // 362*9*9; *4= 117288 *64 = 7506432, 7MBにもなる mini_batch=64 int nGCT_files; // 1つの selfplay_gct-00*.csa に入ってる棋譜数 int gct_csa = 1; // ファイル番号 int sum_gct_loads = 0; // 1ファイルの全棋譜を読み込んだ後に加算される -const int fReplayLearning = 1; // すでに作られた棋譜からWindowをずらせて学習させる +const int fReplayLearning = 0; // すでに作られた棋譜からWindowをずらせて学習させる const int fWwwSample = 0; // fReplayLearning も同時に1 @@ -2802,20 +2813,23 @@ int zero_pos_over250; const bool fSumTree = true; -const int LEAVES = 41352794; // 棋譜の数ではない。局面数。ZERO_DB_SIZE; +const int LEAVES = ZDB_POS_MAX;//46334390;//41352794; // 棋譜の数ではない。局面数。ZERO_DB_SIZE; const int SUMTREE_SIZE = 2*LEAVES - 1; -int sumtree[SUMTREE_SIZE]; +//int64_t sumtree[SUMTREE_SIZE]; +int64_t *sumtree; + int add_n = 0; int capacity = LEAVES; -std::mt19937 get_mt_rand; +std::mt19937_64 get_mt_rand; +int over_sumtree_leaves = 0; -void stree_propagate(int idx, int change) { +void stree_propagate(int idx, int64_t change) { int parent = (idx - 1) / 2; sumtree[parent] += change; - if ( sumtree[parent] > INT_MAX/2 ) DEBUG_PRT("sumtree:too big =%d\n",sumtree[parent]); + if ( sumtree[parent] > INT64_MAX/2 ) DEBUG_PRT("sumtree:too big =%lld,add_n=%d,idx=%d\n",sumtree[parent],add_n,idx); if ( parent != 0 ) stree_propagate(parent, change); } -int stree_retrieve(int idx, int s) { +int stree_retrieve(int idx, int64_t s) { int left = 2 * idx + 1; int right = left + 1; // if ( left >= len(st) ) return idx; @@ -2826,16 +2840,16 @@ int stree_retrieve(int idx, int s) { return stree_retrieve(right, s - sumtree[left]); } } -void stree_update(int idx, int p) { - int change = p - sumtree[idx]; - if ( p <= 0 ) DEBUG_PRT("idx=%d,change=%d,p=%d\n",idx,change,p); +void stree_update(int idx, int64_t p) { + int64_t change = p - sumtree[idx]; + if ( p <= 0 ) DEBUG_PRT("idx=%d,change=%lld,p=%lld\n",idx,change,p); sumtree[idx] = p; stree_propagate(idx, change); } -int stree_total() { +int64_t stree_total() { return sumtree[0]; } -void stree_add(int p) { +void stree_add(int64_t p) { if ( p <= 0 ) DEBUG_PRT(""); int idx = add_n + capacity - 1; stree_update(idx, p); @@ -2844,12 +2858,12 @@ void stree_add(int p) { if ( add_n >= capacity ) add_n = 0; } // 要素が10個なら idx = 9...18 となる。idx - (LEAVES-1) が求めたい値 -int stree_get(int s) { +int stree_get(int64_t s) { if ( s <= 0 ) DEBUG_PRT(""); int idx = stree_retrieve(0, s); return idx; // sumtree[idx] } -int stree_get_i(int s) { // 0 <= i <= LEAVES-1 +int stree_get_i(int64_t s) { // 0 <= i <= LEAVES-1 int i = stree_get(s) - (LEAVES-1); if ( i < 0 || i >= LEAVES ) DEBUG_PRT(""); return i; @@ -2859,8 +2873,8 @@ void init_stree() { get_mt_rand.seed(rd()); for (int i=0; i= LEAVES ) DEBUG_PRT("n=%d,p=%d",n,p); +void stree_replace(int n, int64_t p) { + if ( n < 0 || n >= LEAVES ) DEBUG_PRT("n=%d,p=%lld",n,p); int idx = n + (LEAVES-1); if ( idx >= SUMTREE_SIZE ) DEBUG_PRT(""); stree_update(idx, p); @@ -2897,7 +2911,17 @@ void stree_test() } } #endif - +float char_to_raw_policy[52]; +void init_char_to_raw_policy() { + for (int i=0;i<52;i++) { + double k = 1.144; + double min = 0.001; + double p = pow(k,i) * min; +// int c = 'A' + i + (i >= 26)*6; +// PRT("%2d:%c:p=%f\n",i,c,p); + char_to_raw_policy[i] = p; + } +} void init_zero_kif_db() @@ -2909,9 +2933,11 @@ void init_zero_kif_db() pZDBplayouts_sum = (unsigned short*)malloc( ZDB_POS_MAX * sizeof(short) ); pZDBscore_x10k = (unsigned short*)malloc( ZDB_POS_MAX * sizeof(short) ); zdb = (ZERO_DB*) malloc(ZERO_DB_SIZE * sizeof(ZERO_DB)); - if ( zdb == NULL ) DEBUG_PRT(""); + sumtree = (int64_t*)malloc(SUMTREE_SIZE * sizeof(int64_t)); + if ( zdb == NULL || sumtree == NULL ) DEBUG_PRT(""); memset(pZDBsum,0,ZERO_DB_SIZE * sizeof(int)); + memset(sumtree,0,SUMTREE_SIZE * sizeof(int64_t)); int i; for (i=0;i 20000 if ( GCT_SELF ) { @@ -3063,7 +3090,8 @@ int find_kif_from_archive(int search_n) int find_kif_from_pool(int search_n) { - char dir_pool[] = "/home/yss/koma_syn/pool"; +// char dir_pool[] = "/home/yss/koma_syn/pool"; + char dir_pool[] = "/home/yss/tcp_backup/pool"; char filename[TMP_BUF_LEN]; if ( USE_XZ ) { sprintf(filename,"%s/no%012d.csa.xz",dir_pool,search_n); @@ -3162,6 +3190,8 @@ void shogi::add_one_kif_to_db() pdb->v_playouts_sum = p->v_playouts_sum; pdb->vv_move_visit = p->vv_move_visit; pdb->v_score_x10k = p->v_score_x10k; + pdb->v_rawscore_x10k= p->v_rawscore_x10k; + pdb->vv_raw_policy = p->vv_raw_policy; // PRT("%6d:index=%d,res=%d,%3d:%08x %08x %08x\n",zdb_count,pdb->index,p->result,p->moves,hash_code1,hash_code2,hash_motigoma); zdb_count++; } @@ -3191,7 +3221,8 @@ int is_exist_kif_file(int search_n) int nHandicapLastID[HANDICAP_TYPE]; int nHandicapRate[HANDICAP_TYPE]; const char HANDICAP_ID_FILE[] = "handicap_rate.txt"; -const char HANDICAP_SYN[] = "/home/yss/koma_syn/handicap/handicap.txt"; +//const char HANDICAP_SYN[] = "/home/yss/koma_syn/handicap/handicap.txt"; +const char HANDICAP_SYN[] = "/home/yss/tcp_backup/handicap/handicap.txt"; void load_handicap_rate() { @@ -3310,15 +3341,28 @@ void update_pZDBsum() int games_sum[H] = {0}; const int G1000 = 1000*H; const int WR_OK_GAMES = 8000; // 直近のこの対局数の勝率でレートを変動 - + float kld_sum = 0; + float sdiff_sum = 0; if ( GCT_SELF==0 ) load_handicap_rate(); const int MAX_GAMES = (WR_OK_GAMES*12/10)*H; int i; for (i=0;i MAX_GAMES ) nHandicapLastID[i] = zdb_count - MAX_GAMES; } + const int KLD_MOVES_MAX = 300; + float kld_moves_sum[KLD_MOVES_MAX] = {0}; + int kld_moves_count[KLD_MOVES_MAX] = {0}; + float sdiff_moves_sum[KLD_MOVES_MAX] = {0}; + int sdiff_moves_count[KLD_MOVES_MAX] = {0}; + int kld_count = 0; + + const int S_SUM_MAX = 101; + static int64_t s_sum[S_SUM_MAX]; + const int SWR_MAX = 20; + static float swr[SWR_MAX]; + static int swr_count[SWR_MAX]; + static int pos_count[SWR_MAX]; - static int s_sum[101]; zero_kif_pos_num = 0; zero_kif_games = 0; zero_pos_over250 = 0; @@ -3345,23 +3389,171 @@ void update_pZDBsum() if ( GCT_SELF==1 ) pZDBplayouts_sum[n] = 0; pZDBscore_x10k[n] = p->v_score_x10k[j]; if ( m0 >= 250 ) zero_pos_over250++; + unsigned short raw_score_x10k = 0; + if ( (int)p->v_rawscore_x10k.size() >= j+1 ) raw_score_x10k = p->v_rawscore_x10k[j]; + + size_t size = p->vv_move_visit[j].size(); + int playouts_sum = p->v_playouts_sum[j]; + float kld = 0.0; + if ( p->vv_raw_policy.size() > 0 && p->vv_raw_policy[j].size() == size ) { +// if ( size != p->vv_raw_policy[j].size() ) DEBUG_PRT("size=%d,raw_size=%d,%d\n",size,p->vv_raw_policy.size(),p->vv_raw_policy[j].size()); + float policy_sum = 0; + for (int m=0;m<(int)size;m++) { + int c = p->vv_raw_policy[j][m]; + float p0 = char_to_raw_policy[c]; + policy_sum += p0; + } + if ( policy_sum == 0 ) DEBUG_PRT(""); + + for (int m=0;m<(int)size;m++) { + unsigned int x = p->vv_move_visit[j][m]; + int visit = x&0xffff; + int c = p->vv_raw_policy[j][m]; + float p0 = char_to_raw_policy[c] / policy_sum; + float p1 = (float)visit / playouts_sum; +// if ( p0 != 0 && p1 != 0 ) kld += p0 * log(p0 / p1); + if ( p0 != 0 && p1 != 0 ) kld += p1 * log(p1 / p0); // policyが小さいのに探索ノード数が多い、と大きく + } + } + + float s0 = (float)raw_score_x10k / 10000; + float s1 = (float)pZDBscore_x10k[n] / 10000; + float sdiff = (s0 - s1)*(s0 - s1); + const int PLATOUTS_MIN = 800; +// if ( playouts_sum > PLATOUTS_MIN && s1 < 0.800 && s1 > 0.200 ) { + if ( playouts_sum > PLATOUTS_MIN ) { + sdiff_sum += sdiff; + kld_sum += kld; + if ( j < KLD_MOVES_MAX ) { + kld_moves_sum[j] += kld; + kld_moves_count[j]++; + sdiff_moves_sum[j] += sdiff; + sdiff_moves_count[j]++; + } + kld_count++; + } +// if ( n < 1000 ) PRT("%8d:%3d/%3d:%5d/%5d,msize=%3d,kld=%9f,sdiff=%9f,visit=%5d\n",n,j,p->moves,pZDBscore_x10k[n],raw_score_x10k, (int)size, kld,sdiff, playouts_sum); if ( fSumTree ) { -// int s = pZDBplayouts_sum[n]; + int v = pZDBplayouts_sum[n]; int s = pZDBscore_x10k[n]; int k = 10; // 20 20 20 20 10 10 20 20 20 20 - if ( s < 3900 || s > 6100 ) k = 20; - if ( s < 3000 || s > 7000 ) k = 30; + +// if ( (j&1)==0 ) k = 10; +// if ( (j&1)==1 ) k = 7; + +// if ( playouts_sum > PLATOUTS_MIN && s < 8000 && s > 2000 ) { + if ( playouts_sum > PLATOUTS_MIN ) { +// k = (int)(sdiff*1000.0); +// k = (int)(pow(sdiff, 1.0 / 2.0) * 100.0); +// k = 100 - (int)(sdiff*1000.0); +// k = (int)(kld*100.0); +// if ( k <= 130 ) k = 130; + } else { + k = 1; + } + +// k = v; +// if ( k > 8000 ) k = 8000; +// if ( k <= 0 ) k = 1; +/* + int win_r = 0; + if ( p->result == ZD_S_WIN ) win_r = +1; + if ( p->result == ZD_G_WIN ) win_r = -1; + if ( p->result == ZD_DRAW ) win_r = 0; + + unsigned int score_x10k = pZDBscore_x10k[n]; + float score_div = (float)score_x10k / 10000.0f; + float score = score_div * 2.0f - 1.0f; // +1.0 >= x >= -1.0, 自分から見た勝率 + if ( j&1 ) { + win_r = -win_r; + } + float ave_r = ((float)win_r + score) / 2.0; +// float r_diff = fabs(win_r - score); // 0 < x < 2 + float r_diff = fabs(ave_r - score); +// k = r_diff * 100; +// if ( k <= 1 ) k = 1; +*/ + +// if ( 40 <= j && j < 80 ) { +// if ( s < 2000 || s > 8000 ) k = k * 80/10; +// else if ( s < 3000 || s > 7000 ) k = k * 150/10; +// else if ( s < 4000 || s > 6000 ) k = k * 20/10; +// if ( j > 80 ) { +// if ( s < 4000 || s > 6000 ) k = 20; +// if ( s < 3000 || s > 7000 ) k = 30; +// } // if ( s < 2500 || s > 7500 ) k = 20; // if ( s < 100 || s > 990 ) k = 5; - stree_replace(n, k); // s_sum[s/100]++; - int prev_s = 0; +/* int prev_s = 0; if ( j > 0 ) prev_s = pZDBscore_x10k[n-1]; if (j&1) s = 10000 - s; else prev_s = 10000 - prev_s; if ( j==0 ) prev_s = s; - s_sum[abs(s - prev_s)/100]++; + int d = abs(s - prev_s)/100; +// s_sum[d]++; + k = 10; + if ( d > 2 ) k = 15; + if ( d > 4 ) k = 20; + if ( d > 10 ) k = 30; + if ( d > 20 ) k = 50; +*/ +// k = 10; + + if ( p->result == ZD_DRAW ) { +// k = 5; + } else { + int mywin = (p->result == ZD_S_WIN && (j&1)==0) || (p->result == ZD_G_WIN && (j&1)==1); + int myloss = (p->result == ZD_S_WIN && (j&1)==1) || (p->result == ZD_G_WIN && (j&1)==0); + if ( mywin + myloss != 1 ) DEBUG_PRT("j=%d,p->result=%d\n",j,p->result); +// if ( (mywin && s < 4000) || (myloss && s > 6000) ) k = 15; +// if ( (mywin && s < 3500) || (myloss && s > 6500) ) k = 20; +// if ( (mywin && s < 3000) || (myloss && s > 7000) ) k = 30; + } + +// if ( (j&1)==1 ) k = 1; +// if ( j < 40 ) k = 5; +// if ( j < 30 ) k = 3; +// if ( j < 20 ) k = 2; +// if ( j < 10 ) k = 1; + + double no_res = 1.0; + if ( 0 && p->moves > 40 ) { + int s = pZDBscore_x10k[zero_kif_pos_num + 40]; + if ( s > 9000 || s < 1000 ) no_res = 0.1; // 投了禁止で、だらだら指してるだけ + } + + int x = j; + double e80 = (1.0 / (1.0 + exp(-0.3*(x-80+15))) - 1.0 / (1.0 + exp(-0.3*(x-80-15))))*0.7 + 1.0; // *0.7 で1.7倍。70手から89手の確率をx倍に + e80 = 1.0; + + double ss = s; + if ( s < 5000 ) ss = 10000 - s; + ss = ss / 100; // 50 < s < 100 + if ( ss < 50 || ss > 100 ) DEBUG_PRT("s=%d",s); + const double xx = 77;//75; + double e0 = +(1.0 / (1.0 + exp(-0.5*(ss-xx+ 5))) - 1.0 / (1.0 + exp(-0.5*(ss-xx- 5))))*12.0 + 1.0; + double e1 = +(1.0 / (1.0 + exp(-0.5*(ss-95+15))) - 1.0 / (1.0 + exp(-0.5*(ss-95-15))))* 7.0 + 0.0; + double ess = e0+e1; // 1.0 < ess < 12 + + x = p->moves; + if ( x > 40 ) x = 40; + double res_moves_e = exp(5.0*(x)/40); // 1 < e < 148 + + x = j; + if ( x > 40 ) x = 40; +// double e = exp(15.0*(x)/60); + double e = 1.0 / ( 1.0 + exp(-0.3*(x-20)))*10000.0; // x > 40 で 24 < e < 9999 + k = (int)(e*res_moves_e*e80*no_res*k*ess); + if ( k < 1 ) k = 1; + if ( p->vv_move_visit[j].size() == 1 && raw_score_x10k == 5000 ) k = 1; // 王逃げ1手だけ + + int sk = v/200; + sk = k / 350000; + if ( sk > S_SUM_MAX-1 ) sk = S_SUM_MAX-1; + s_sum[sk]++; + stree_replace(n, k); } } // PRT("%d/%d,%lu,",i,loop,zero_kif_pos_num); @@ -3402,6 +3594,17 @@ void update_pZDBsum() mv_total_sum[h] += n; mv_total_inc[h]++; } + + int rm = p->moves / 10; + float wr = 0; + if ( p->result == ZD_S_WIN ) wr = +1; + if ( p->result == ZD_G_WIN ) wr = 0; + if ( p->result == ZD_DRAW ) wr = 0.5; + if ( rm > SWR_MAX-1 ) rm = SWR_MAX-1; + swr[rm] += wr; + swr_count[rm]++; + + pos_count[rm]++; } if ( loop > 0 ) for (i=0;iweight_n; + int i; + for (i=0;i91 um i=%d,%d,%d\n",i,zdb_count,w); + } + if ( b[0x99]==0x8e && b[0x11]==0x0e && bz == 0x11 && az == 0x99 ) { +// PRT("91->19 um i=%d,%d,%d\n",i,zdb_count,w); + } + if ( b[0x99] && b[0x11] && is_pseudo_legalYSS((Move)pack_te(0x99,0x11,b[0x11],0), (Color)((tesuu&1)==1)) ) { +// PRT("19->91 tk=%02x, i=%3d,%d,%d, movable\n",b[0x11],i,zdb_count,w); +// hyouji(); + } + if ( b[0x19] && b[0x91] && is_pseudo_legalYSS((Move)pack_te(0x19,0x91,b[0x91],0), (Color)((tesuu&1)==1)) ) { +// PRT("91->19 tk=%02x, i=%3d,%d,%d, movable\n",b[0x91],i,zdb_count,w); +// hyouji(); + } + if ( b[0x99]==0x8e && b[0x11]==0x0e && is_pseudo_legalYSS((Move)pack_te(0x99,0x11,0x0e,0), (Color)((tesuu&1)==1)) ) { +// PRT("19->91 um i=%d,%d,%d, movable\n",i,zdb_count,w); + } + if ( (bz == 0x99 && az == 0x11) || (bz==0x19 && az==0x91) || (bz==0x91 && az==0x19) || (bz == 0x11 && az == 0x99) ) { +// PRT("%02x->%02x move i=%3d,%d,%d,tk=%02x\n",bz,az,i,zdb_count,w,tk); + } + if ( bz == 0x11 && az == 0x99 ) { +// PRT("19->91 move i=%3d,%d,%d,tk=%02x\n",i,zdb_count,w,tk); + } + + if ( i<=60 && (i&1)==0 && b[0x73]==0x06 && b[0x83]==0x07 && b[0x64]==0x00 && b[0x55]==0x00 && b[0x46]==0x00 && + ( (b[0x63]==0x00 && b[0x53]==0x00 && b[0x43]==0x00 && b[0x33]==0x00 && b[0x23]==0x87 ) || + (b[0x63]==0x00 && b[0x53]==0x00 && b[0x43]==0x00 && b[0x33]==0x87 ) || + (b[0x63]==0x00 && b[0x53]==0x00 && b[0x43]==0x87) || + (b[0x63]==0x00 && b[0x53]==0x87) ) + ) { + PRT("kakuoute sunuki? i=%d,%d,%d,bz=%02x,%02x,%02x,%02x\n",i,zdb_count,w,bz,az,tk,nf); + hyouji(); + return 0; + } + if ( i<=60 && (i&1)==0 && b[0x62]==0x06 && b[0x22]==0x87 && b[0x82]==0x07 && + b[0x32]==0 && b[0x42]==0 && b[0x52]==0 && b[0x72]==0 && + b[0x53]==0 && b[0x44]==0 && b[0x35]==0 && b[0x26]==0 ) { + PRT("sunuki? i=%d,%d,%d,bz=%02x,%02x,%02x,%02x\n",i,zdb_count,w,bz,az,tk,nf); + hyouji(); + return 0; + } + + forth_move(); +// continue; +// if ( i<=40 && b[0x45]==0x84 && b[0x65]==0x04 && mo_m[6] && mo_c[6] ) { + if ( 0 && i<=40 && b[0x45]==0x00 && b[0x65]==0x00 && mo_m[6] && mo_c[6] ) { + PRT("kakugawari koshikakegin? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + return 0; + } + if ( 0 && i<=50 &&((b[0x91]==0x08 && b[0x81]==0x02 && b[0x92]==0x03 && b[0x82]==0x04) || + (b[0x99]==0x08 && b[0x89]==0x02 && b[0x98]==0x03 && b[0x88]==0x04) || + (b[0x11]==0x88 && b[0x21]==0x82 && b[0x12]==0x83 && b[0x22]==0x84) || + (b[0x19]==0x88 && b[0x29]==0x82 && b[0x18]==0x83 && b[0x28]==0x84)) ) { + PRT("anaguma?%10d(%4d)i=%2d, %02x,%02x,%02x,%02x\n",zdb_count,w,i,b[0x91],b[0x99],b[0x11],b[0x19]); + hyouji(); + return 0; + } +// if ( 1 && i==24 && (kn[1][1]&0x0f)>=0x07 && (b[0x82]==0x07 || b[0x83]==0x07 || b[0x84]==0x07 || b[0x85]==0x07) ) { + if ( 0 && i==36 && (kn[1][1])==0x99 && (b[0x82]==0x07 || b[0x83]==0x07 || b[0x84]==0x07 || b[0x85]==0x07) ) { + int n = (b[0x82]==0x07)*0 + (b[0x83]==0x07)*1 + (b[0x84]==0x07)*2 + (b[0x85]==0x07)*3; + static int c[4],v[4]; v[n]+=(all_tesuu&1)==1; PRT("sente furibisha?%10d(%4d)i=%2d,n=%d,c=%4d,v=%4d\n",zdb_count,w,i,n,++c[n],v[n]); + hyouji(); + return 0; + } +// if ( 1 && i==24 && (kn[2][1]&0x0f)<=0x03 && (b[0x28]==0x87 || b[0x27]==0x87 || b[0x26]==0x87 || b[0x25]==0x87) ) { + if ( 0 && i==36 && kn[2][1]==0x11 && (b[0x28]==0x87 || b[0x27]==0x87 || b[0x26]==0x87 || b[0x25]==0x87) ) { + int n = (b[0x28]==0x87)*0 + (b[0x27]==0x87)*1 + (b[0x26]==0x87)*2 + (b[0x25]==0x87)*3; + static int c[4],v[4]; v[n]+=(all_tesuu&1)==0; PRT("gote furibisha?%10d(%4d)i=%2d,n=%d,c=%4d,v=%4d\n",zdb_count,w,i,n,++c[n],v[n]); + hyouji(); + return 0; + } + + if ( 0 && i==29 && mo_c[6] && mo_m[6] && + (b[0x48]==0x07 || b[0x58]==0x07 || b[0x68]==0x07 || b[0x88]==0x07) && + (b[0x62]==0x87 || b[0x52]==0x87 || b[0x42]==0x87 || b[0x22]==0x87) ) { + int n = 0; + if ( b[0x45]==0x84 || b[0x65]==0x04 ) { + n = 1; PRT("kakugawari koshikakegin? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + } + if ( (b[0x66]==0x04 || b[0x77]==0x04 || b[0x57]==0x04 || mo_m[4]) && + (b[0x44]==0x84 || b[0x33]==0x84 || b[0x53]==0x84 || mo_c[4]) ) { + n = 2; PRT("kakugawari hayakuri gin? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + } + if ( (b[0x78]==0x04 || b[0x68]==0x04 || b[0x59]==0x04 || b[0x58]==0x04 || mo_m[4]) && + (b[0x32]==0x84 || b[0x42]==0x84 || b[0x51]==0x84 || b[0x52]==0x04 || mo_c[4]) ) { + n = 3; PRT("kakugawari bougin? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + } + if ( n==0 ) { + PRT("kakugawari? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + } + } + if ( 0 && i==29 && mo_c[6]==0 && mo_m[6]==0 && mo_c[7]==0 && mo_m[7]==0 ) { + int aigakari[2]; + aigakari[0] = nifu_m(0x78); + aigakari[1] = nifu_c(0x22); + if ( b[0x83]==0x05 && b[0x74]==0x04 ) { + static int c,v; c++; v+=(all_tesuu&1)==1; PRT("sente gangi? i=%d,%d,%d, c=%d(%.3f)\n",i,zdb_count,w,c,100.0*v/c); + if ( c<20 ) hyouji(); + } + if ( b[0x27]==0x85 && b[0x36]==0x84 ) { + static int c,v; c++; v+=(all_tesuu&1)==0; PRT("gote gangi? i=%d,%d,%d, c=%d(%.3f)\n",i,zdb_count,w,c,100.0*v/c); + if ( c<20 ) hyouji(); + } + if ( b[0x83]==0x05 && b[0x27]==0x85 && b[0x74]!=0x04 && b[0x36]!=0x84 && aigakari[0] && aigakari[1] ) { + static int c,v; c++; v+=(all_tesuu&1)==1; PRT("aigakari? i=%d,%d,%d, c=%d(%.3f)\n",i,zdb_count,w,c,100.0*v/c); + if ( c<20 ) hyouji(); + } + if ( b[0x83]==0x05 && b[0x27]==0x85 && b[0x74]!=0x04 && b[0x36]!=0x84 && aigakari[0]==0 && aigakari[1]==0 ) { + static int c,v; c++; v+=(all_tesuu&1)==1; PRT("yagura? i=%d,%d,%d, c=%d(%.3f)\n",i,zdb_count,w,c,100.0*v/c); + if ( c<20 ) hyouji(); + } + } + if ( 0 && i==15 && b[0x35]==0x06 && b[0x55]==0x86 ) { + PRT("ransen? i=%d,%d,%d\n",i,zdb_count,w); + hyouji(); + } + } +// PRT("all_=%d,",all_tesuu); + return 0; +} + +void shogi::same_pos_check() // from aoba_calc_stat() +{ + int new_kif_n = zdb_count; + + static int res_total_sum[4] = { 0,0,0,0 }; + static uint64 moves_total_sum = 0; + static int max_moves_total = 0; + static int res_kind[4] = { 0,0,0,0 }; + static int res_type[7] = { 0,0,0,0,0,0,0 }; + static int count = 0; + static int long_moves[6] = { 0,0,0,0,0,0 }; + static int short_moves[11] = { 0 }; + const int ACC_MAX = 200; + static int acc_moves[ACC_MAX] = { 0 }; + + const int H = 1; + const bool fBook = true; + const int BOOK_MOVES = 30; + const int SAME_MAX = 600000*2; // sum=281595, 最大 n=23 ... 99番目,n=3, 431番目,n=2, 200万棋譜(150万棋譜・350万棋譜),6枚落ち + static unsigned int same_hash[H][SAME_MAX][5]; + static int same_num[H] = { 0 }; + static int same_count[H] = { 0 }; + static int same_all = 0; +// const int STR_SIZE = 85+5*BOOK_MOVES+20; +// const int POS_SIZE = 81+7*2; +// static char same_str[H][SAME_MAX][STR_SIZE]; +// static char same_pos[H][SAME_MAX][POS_SIZE]; + + static int furi_file[4][9] = {0}; + + new_kif_n++; + + if ( zdb_count <= 0 ) DEBUG_PRT(""); + ZERO_DB *p = &zdb[(zdb_count-1) % ZERO_DB_SIZE]; +// if ( p->weight_n == 0 ) continue; +// is_koshikake_gin(p); + + if ( p->moves == 0 ) { DEBUG_PRT("Err. p->moves=0\n"); } + if ( p->result < 0 || p->result >=4 ) DEBUG_PRT("p->result=%d\n",p->result); + res_total_sum[p->result]++; + if ( p->moves == MAX_ZERO_MOVES ) max_moves_total++; + if ( p->result_type == RT_KACHI ) { + res_kind[p->result]++; + res_kind[3]++; + } + res_type[p->result_type]++; + + + long_moves[p->moves/100]++; + moves_total_sum += p->moves; + + int s = p->moves/10; + if ( s > 10 ) s = 10; + short_moves[s]++; + s = p->moves; + if ( s > ACC_MAX ) { s = ACC_MAX; acc_moves[s-1] += p->moves - ACC_MAX; } + { for (int i=0;imoves >= BOOK_MOVES ) { + PS->jump_move(BOOK_MOVES); + const int h = 0; + same_count[h]++; + int n = same_num[h]; + int j; + for (j=0;jhash_code1 && same_hash[h][j][1] == PS->hash_code2 ) break; + } + if ( j == n ) { + if ( n < SAME_MAX ) { +// const int USI_POS_MAX_SIZE = 8192; +// char str[USI_POS_MAX_SIZE]; +// PS->make_usi_position(str, h, BOOK_MOVES); +// sprintf(same_str[h][n],"%s",str); + for (int y=0;y<9;y++) for (int x=0;x<9;x++) { + int k = PS->init_ban[(y+1)*16+x+1]; +// same_pos[h][n][y*9+x] = k; + if ( (k&0x87)==0x07 ) furi_file[0+((kn[1][1]&0x0f)>=6)][x]++; + if ( (k&0x87)==0x87 ) furi_file[2+((kn[2][1]&0x0f)<=4)][x]++; + } + for (int k=0;k<7;k++) { +// same_pos[h][n][81+0+k] = PS->mo_m[k+1]; +// same_pos[h][n][81+7+k] = PS->mo_c[k+1]; + } + + same_hash[h][n][0] = PS->hash_code1; + same_hash[h][n][1] = PS->hash_code2; + same_hash[h][n][2] = 1; + same_hash[h][n][3] = p->index; + same_num[h]++; + } else { + static int fDone = 0; + if ( fDone == 0 ) PRT("SAME_MAX over. h=%d\n",h); + fDone = 1; + } + } else { + same_hash[h][j][2]++; + } + } + same_all++; + + +#if 1 + if ( (same_all % ZERO_DB_SIZE)==0 ) { + int h = 0; + int i,j; + const int D = 2; // 4; + const int LOOP = 3; // same_num[h]-1; // all + for (i=0; i dist(0, stree_total()-1); + std::uniform_int_distribution dist(0, stree_total()-1); + + const int R_STREE_MAX = 1000; + static int r_stree[R_STREE_MAX] = {0}; + static int r_stree_sum = 0; // pos_sum の中から64個ランダムで選ぶ int *ri = new int[mini_batch]; @@ -3919,8 +4457,9 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po int r = rand_m521() % zero_kif_pos_num; // 0 <= r < zero_kif_pos_num, 最初に右辺がunsigned longで評価されるようで、マイナスにはならない。gccでも if ( fSumTree ) { - int s = dist(get_mt_rand) + 1; // +1 が必要。一様乱数 + int64_t s = dist(get_mt_rand) + 1; // +1 が必要。一様乱数 r = stree_get_i(s); + if ( (uint64_t)r >= zero_kif_pos_num ) { i--; over_sumtree_leaves++; continue; } } rand_try++; @@ -3933,19 +4472,18 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po if ( pZDBscore_x10k[r] == NO_ROOT_SCORE ) { i--; continue; } } if ( 1 ) { - int m = pZDBmaxmove[r]; - int n = pZDBmove[r]; -// if ( m <= 40 && (rand_m521() % 10) != 0 ) { i--; continue; } - if ( m <= 40 && (rand_m521() % 4) != 0 ) { i--; continue; } -// if ( n < 30 && (int)(rand_m521() % 300) > (n*9+30) ) { i--; continue; } - if ( n < 30 && (float)(rand_m521() % 3000) > exp(8.0*(30-n)/30) ) { i--; continue; } +// int m = pZDBmaxmove[r]; +// int n = pZDBmove[r]; +// if ( m <= 40 && (rand_m521() % 4) != 0 ) { i--; continue; } +// if ( m <= 40 ) { i--; continue; } +// if ( n < 30 && (float)(rand_m521() % 3000) < exp(8.0*(30-n)/30) ) { i--; continue; } // if ( n < 30 && (float)(rand_m521() % 1000) > pow(2.0,n) ) { i--; continue; } // if ( n < 24 ) { i--; continue; } +// if ( !(110 <= n && n < 120) ) { i--; continue; } // double x = 1.0 + abs(n-60) / 10.0;// from policy weight surprize. around 60 moves is most difficult. // if ( x > 6 ) x = 6; // double y = 0.003*x*x*x - 0.058*x*x + 0.141*x + 0.896; // if ( (double)(rand_m521() % 1000) > y*1000 ) { i--; continue; } -// if ( n < 250 ) { i--; continue; } } if ( 1 ) { int s = pZDBplayouts_sum[r]; @@ -3962,6 +4500,14 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po if ( ri[j] == r ) break; } if ( j != i ) { i--; continue; } +// if ( (uint64_t)r >= zero_kif_pos_num - R_STREE_MAX ) { + if ( (uint64_t)r < R_STREE_MAX ) { +// int n = zero_kif_pos_num - r - 1; + int n = r; + if ( n < 0 || n>=R_STREE_MAX ) DEBUG_PRT(""); + r_stree[n]++; + r_stree_sum++; + } ri[i] = r; } rand_batch += mini_batch; @@ -4021,7 +4567,6 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po int s = p->v_playouts_sum[t]; int x = p->v_score_x10k[t]; if ( s < 50 && (x==0 || x==10000) ) { static int count; PRT("r=%8d,t=%3d,s=%5d,x=%5d,count=%d\n",r,t,s,x,count++); } -// if ( s < 50 ) PRT("r=%8d,t=%3d,s=%5d,x=%d\n",r,t,s,x); } int bz,az,tk,nf; @@ -4048,7 +4593,7 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po // 実際の勝敗と探索値の平均を学習。https://tadaoyamaoka.hatenablog.com/entry/2018/07/01/121411 float ave_r = ((float)win_r + score) / 2.0; -// float ave_r = ((float)win_r*0 + score*10) / 10.0; +// float ave_r = ((float)win_r*9.0 + score*1.0) / 10.0; // float m = pZDBmaxmove[r]; // float n = pZDBmove[r]; @@ -4128,13 +4673,17 @@ void shogi::prepare_kif_db(int fPW, int mini_batch, float *data, float *label_po if ( PIECE_LEARN ) sum_pwv(win_r, bGoteTurn, piece_d_sum); if ( fPW ) PRT("%3d ",p->weight_n); -// if ( fPW ) PRT("%d(%3d) ",bi,p->weight_n); static int tc[MAX_ZERO_MOVES],tc_all; int tt = t; if ( tt>199 ) tt=199; tc[tt]++; tc_all++; -// if ( (tc_all % 1000000)==0 ) { PRT("tc="); for (int k=0;k<200;k++) PRT("%f,",(float)tc[k]/tc_all); PRT("\n"); } + if ( (tc_all % 1000000)==0 ) { + PRT("tc="); for (int k=0;k<200;k++) { PRT("%f,",(float)tc[k]/tc_all); } PRT("\n"); + PRT("stree_total()=%lld,zero_kif_pos_num=%lu,over_sumtree_leaves=%d/%lu\n",stree_total(),zero_kif_pos_num,over_sumtree_leaves,rand_batch); +// for (int k=0;kinit_prepare_kif_db(); if ( fWwwSample ) { PS->make_www_samples(); return; } + PRT("stree_total()=%lld,zero_kif_pos_num=%lu\n",stree_total(),zero_kif_pos_num); // MemoryDataLayerはメモリ上の値を出力できるDataLayer. // 各MemoryDataLayerには入力データとラベルデータ(1次元の実数)の2つを与える必要があるが, @@ -4400,6 +4959,7 @@ void start_zero_train(int *p_argc, char ***p_argv ) //評価用のデータを取得 const auto net = solver->net(); +#if 0 // const char sNet[] = "/home/yss/shogi/learn/snapshots/20210604/_iter_10000.caffemodel"; // w0001 // const char sNet[] = "/home/yss/shogi/learn/snapshots/20210607/_iter_60000.caffemodel"; // const char sNet[] = "/home/yss/shogi/learn/snapshots/20210610/_iter_90000.caffemodel"; @@ -4435,13 +4995,51 @@ void start_zero_train(int *p_argc, char ***p_argv ) // const char sNet[] = "/home/yss/shogi/learn/20220712_111426_256x20b_ave_exp_8_30_30_x_m40_4_loop_div4_from_51000k_20220601_005103/_iter_800000.caffemodel"; // const char sNet[] = "/home/yss/shogi/learn/20221105_181114_256x20b_ave_exp_8_30_30_x_m40_4_cos_from_58410k_20220712_111426/_iter_480000.caffemodel"; // const char sNet[] = "/home/yss/shogi/learn/20221107_170923_ave_exp_8_30_30_x_m40_4_cos_from_58410k_20221105_181114/_iter_400000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/20221230_133012_cos_005_001/_iter_100000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/20230115_183754_base_cos_005_001_from_61950k/_iter_100000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/20230202_174637_256x20b_e80_x17_mb256_from_43000k/_iter_1600000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/20230210_120324_256x20b_e80_x17_mb256_from_20230202_174637/_iter_800000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/20230311_213246_256x20b_ess77_mb256_from_43000k/_iter_1600000.caffemodel"; +#else +// const char sNet[] = "20190419replay_lr001_wd00002_100000_1018000/_iter_36000.caffemodel"; // w449 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/_iter_300376.caffemodel"; +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/_iter_3160000.caffemodel"; // w627 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20190817/_iter_1080000.caffemodel"; // w681 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20190907/_iter_540000.caffemodel"; // w708 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20191001/_iter_580000.caffemodel"; // w737 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20191002/_iter_20000.caffemodel"; // w738 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20191010/_iter_220000.caffemodel"; // w749 +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20191021/_iter_300000.caffemodel"; // w764 bug fix +// const char sNet[] = "/home/yss/shogi/yssfish/snapshots/20191029/_iter_200000.caffemodel"; // w774 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20191029/_iter_312.caffemodel"; // w775 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20191107/_iter_3432.caffemodel"; // w786 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20200328/_iter_1370000.caffemodel"; // w923 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20200708/_iter_5260000.caffemodel"; // w1449 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20200928/_iter_5970000.caffemodel"; // w2046 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20201027/_iter_2440000.caffemodel"; // w2290 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20201109/_iter_1520000.caffemodel"; // w2442 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20201206/_iter_3070000.caffemodel"; // w2749 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20201228/_iter_2720000.caffemodel"; // w3021 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20210111/_iter_1760000.caffemodel"; // w3076 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20210131/_iter_2272000.caffemodel"; // w3147 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20210311/_iter_4832000.caffemodel"; // w3298 +// const char sNet[] = "/home/yss/shogi/learn/40b_8x_39770000_games_iter_3870190.caffemodel"; // 40b, next = w3460 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20210426/_iter_5152000.caffemodel"; // w3459 = w3703 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20211225/_iter_2112000.caffemodel"; // w3769 +// const char sNet[] = "/home/yss/shogi/learn/20220222_125600_256x20b_swish_no_ave_no_30_from_20220218_071436_iter_600000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20220226/_iter_64000.caffemodel"; // w3883 +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20220522/_iter_4096000.caffemodel"; // w4011 +// const char sNet[] = "/home/yss/shogi/learn/20221107_170923_ave_exp_8_30_30_x_m40_4_cos_from_58410k_20221105_181114_iter_400000.caffemodel"; +// const char sNet[] = "/home/yss/shogi/learn/snapshots/20221221/_iter_325335.caffemodel"; // w4200 + const char sNet[] = "/home/yss/shogi/learn/20230320_102805_256x20b_ess77_mb256_from_20230311_213246_iter_800000.caffemodel"; // w4254 +#endif - int next_weight_number = 1170; // 現在の最新の番号 +1 + int next_weight_number = 4255; // 現在の最新の番号 +1 -// net->CopyTrainedLayersFrom(sNet); // caffemodelを読み込んで学習を再開する場合 + net->CopyTrainedLayersFrom(sNet); // caffemodelを読み込んで学習を再開する場合 // load_aoba_txt_weight( net, "/home/yss/w000000000689.txt" ); // 既存のw*.txtを読み込む。*.caffemodelを何か読み込んだ後に LOG(INFO) << "Solving "; - PRT("fReplayLearning=%d\n",fReplayLearning); + PRT("fReplayLearning=%d,stree_total()=%lld,zero_kif_pos_num=%lu\n",fReplayLearning,stree_total(),zero_kif_pos_num); int iteration = 0; // 学習回数 int add = 0; // 追加された棋譜数 @@ -4459,15 +5057,18 @@ void start_zero_train(int *p_argc, char ***p_argv ) // if ( iteration >= 100000*1 ) { PRT("done...\n"); solver->Snapshot(); return; } // if ( iteration > 1000 ) solver_param.set_base_lr(0.01); } else { - if ( 0 && iteration==0 && next_weight_number==1170 ) { - add = 200; // 初回のみダミーで10000棋譜追加したことにする + if ( 1 && iteration==0 && next_weight_number==4255 ) { + add = 3134; // 初回のみダミーで10000棋譜追加したことにする } else { add = PS->wait_and_get_new_kif(next_weight_number); } } +// const float ADJUST = 1.07142857; +// const float ADJUST = 1; + const float ADJUST = 0.4715; // 1棋譜、平均85.1手 * 0.7092 = 60.35手。1棋譜読み込んで60.35回学習、が1局面1回になる。60.35292 / 128 = 0.4715071875 const int AVE_MOVES = 128; // 1局の平均手数 - float add_mul = (float)AVE_MOVES / MINI_BATCH; + float add_mul = ADJUST * (float)AVE_MOVES / MINI_BATCH; int nLoop = (int)((float)add*add_mul); // MB=64でadd*2, MB=128でadd*1, MB=180でadd*0.711 // (ITER_SIZE*MINI_BATCH)=4096 なら最低でも32棋譜必要(32*128=4096) int min_n = ITER_SIZE*MINI_BATCH / AVE_MOVES; @@ -4477,7 +5078,7 @@ void start_zero_train(int *p_argc, char ***p_argv ) remainder = add - nLoop * min_n; } - const int ITER_WEIGHT_BASE = 10000*AVE_MOVES / (ITER_SIZE*MINI_BATCH); // 10000棋譜(平均128手)ごとにweightを作成 + const int ITER_WEIGHT_BASE = 14145; //32000*AVE_MOVES / (ITER_SIZE*MINI_BATCH); // 10000棋譜(平均128手)ごとにweightを作成 int iter_weight_limit = ITER_WEIGHT_BASE; float reduce = 1.0; // weightは10000棋譜ごとで学習回数を10000から8000などに減らす。棋譜生成速度が速すぎるため FILE *fp = fopen("reduce.txt","r"); @@ -4496,14 +5097,13 @@ void start_zero_train(int *p_argc, char ***p_argv ) } //nLoop /= 4; -//nLoop *= 0.602; // *= 2.66 ... 800000 iteration / ((600000 kifu/ 2000) * 1000 Loop) = 2.66 -//nLoop = (int)((float)nLoop * 0.029755f); -//nLoop = (int)((float)nLoop * 0.72727f); +//nLoop *= 0.158; // *= 2.66 ... 800000 iteration / ((600000 kifu/ 2000) * 1000 Loop) = 2.66 //nLoop = (int)((float)nLoop * 0.701); if ( GCT_SELF ) nLoop = 800000*1; -nLoop = 100000*1; +//nLoop = 800000*1; - PRT("nLoop=%d,add=%d,add_mul=%.3f,MINI_BATCH=%d,kDataSize=%d,remainder=%d,iteration=%d(%d/%d),rand=%lu/%lu(%lf)\n",nLoop,add,add_mul,MINI_BATCH,kDataSize,remainder,iteration,iter_weight,iter_weight_limit, rand_try,rand_batch,(double)rand_try/(double)rand_batch); + PRT("nLoop=%d,add=%d,add_mul=%.3f,MINI_BATCH=%d,kDataSize=%d,remainder=%d,iteration=%d(%d/%d),rand=%lu/%lu(%lf),",nLoop,add,add_mul,MINI_BATCH,kDataSize,remainder,iteration,iter_weight,iter_weight_limit, rand_try,rand_batch,(double)rand_try/(double)(rand_batch+0.00001)); + PRT("stree_total()=%lld,zero_kif_pos_num=%lu\n",stree_total(),zero_kif_pos_num); int loop; for (loop=0;loop input_data; // 大きいのでstaticで @@ -4550,7 +5150,8 @@ nLoop = 100000*1; } } -return; +//PRT("nLoop=%d,add=%d,add_mul=%.3f,MINI_BATCH=%d,kDataSize=%d,remainder=%d,iteration=%d(%d/%d),rand=%lu/%lu(%lf)\n",nLoop,add,add_mul,MINI_BATCH,kDataSize,remainder,iteration,iter_weight,iter_weight_limit, rand_try,rand_batch,(double)rand_try/(double)rand_batch); +//return; if ( GCT_SELF ) return; goto wait_again; } diff --git a/learn/yss_dcnn.h b/learn/yss_dcnn.h index 6e2088d..7543ccd 100644 --- a/learn/yss_dcnn.h +++ b/learn/yss_dcnn.h @@ -57,8 +57,10 @@ typedef struct ZERO_DB { #endif vector v_kif; // 棋譜 vector v_playouts_sum; // Rootの探索数。通常は800固定 - vector < vector > vv_move_visit; // (手+選択回数)のペア + vector < vector > vv_move_visit; // (手+選択回数)のペア。上位16bitが手、下位16bitが回数 vector v_score_x10k; // Rootの評価値。自分から見た勝率。1.0で勝ち。0.0で負け。1万倍されている。 + vector v_rawscore_x10k;// Networkのその局面の勝率 + vector < vector > vv_raw_policy; } ZERO_DB; extern ZERO_DB zdb_one; // 棋譜読み込みで使用 diff --git a/learn/yss_misc.cpp b/learn/yss_misc.cpp index 6504d0f..17e7b4d 100644 --- a/learn/yss_misc.cpp +++ b/learn/yss_misc.cpp @@ -426,16 +426,16 @@ void InitLockYSS() void shogi::hyouji() { int x,y,i; - PRT(" 1 2 3 4 5 6 7 8 9 \n"); + PRT(" 1 2 3 4 5 6 7 8 9 \n"); for (y=0;y<9;y++) { - PRT("%d│",y+1); + PRT("%d|",y+1); for (x=0;x<9;x++) { int n = ban[ (y+1)*16+x+1 ]; int k = kn[n][0]; if (k>0x80) k-=0x70; // PRT("%s",koma[i]); PRT("%s",koma_kanji[k]); - } PRT("│"); + } PRT("|"); if (y==0) { PRT(" COM :"); // for (i=1;i<8;i++) PRT("%s %x:",koma[i+16],mo_c[i]); From fb2b6c88f387972aaed3afd170095f381394b79b Mon Sep 17 00:00:00 2001 From: yssaya Date: Sun, 20 Aug 2023 16:05:39 +0900 Subject: [PATCH 3/5] caffemodel converter --- ..._del_bn_scale_factor_version_short_auto.py | 126 +++++++++++++++++- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/learn/extract/ep_del_bn_scale_factor_version_short_auto.py b/learn/extract/ep_del_bn_scale_factor_version_short_auto.py index 24a1a6d..c730645 100644 --- a/learn/extract/ep_del_bn_scale_factor_version_short_auto.py +++ b/learn/extract/ep_del_bn_scale_factor_version_short_auto.py @@ -1,6 +1,7 @@ #http://stackoverflow.com/questions/31324739/finding-gradient-of-a-caffe-conv-filter-with-regards-to-input #import os #import numpy as np +#import caffe #import sys #from google.protobuf import text_format @@ -14,8 +15,40 @@ #sys.exit() caffe.set_mode_cpu() +#net = caffe.Net("aya_i49.prototxt",caffe.TEST); # OK! +#net = caffe.Net("aya_i49.caffemodel",caffe.TEST); # Err +#net = caffe.Net("aya_i49.prototxt","aya_i49.caffemodel",caffe.TEST); # OK! +#net = caffe.Net("../20160114/aya_12_128.prototxt","../20160114/_iter_700000.caffemodel",caffe.TEST); # OK! +#net = caffe.Net("/home/yss/aya/Policy_F128/aya_i49.prototxt","/home/yss/aya/Policy_F128/i49_510_0619_266101.caffemodel",caffe.TEST); +#net = caffe.Net("","",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Value_F128/aya_v_predict.prototxt","/home/yss/aya/Value_F128/aya_v2k_f128.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/test/20160621_i50_v9x9_ft3/9x9_v500_F32_L11_0349_predict.prototxt","/home/yss/test/20160621_i50_v9x9_ft3/_iter_542053.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Policy_F128/19_F32_L11.prototxt","/home/yss/aya/Policy_F128/19_v_i50_0127_kgs4d_F32L11_435794.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Policy_F128/19_v_i50_F64L14_bn.prototxt","/home/yss/aya/Policy_F128/19_v_i50_0318_kgs4d_add300_F64L14bn_350000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Policy_F128/19_49_F32L12bn_m1.prototxt","/home/yss/aya/Policy_F128/19_49_F32L12bn_m1_s735.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Policy_F128/19_49_F32L12bn_m1.prototxt","/home/yss/aya/Policy_F128/19_49_F32L12bn_m1_0422.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/aya/Policy_F128/13_v_i50_F64L14.prototxt","/home/yss/aya/Policy_F128/13_v_i50_2k_r16_75_0518_F64L14_wd_b128_ft7_200000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/test/20180122_i362_pro_flood_F64L29_b64_1_half/yss_F64L29.prototxt","/home/yss/test/20180122_i362_pro_flood_F64L29_b64_1_half/_iter_1880000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/test/20180225_i361_t_pro_flood_F64L29_b64_ft4/yss_F64L29.prototxt","/home/yss/test/20180225_i361_t_pro_flood_F64L29_b64_ft4/_iter_1300000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/yssfish/i362_64x29.prototxt","/home/yss/yssfish/i362_64x29_init_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/yssfish/i362_64x29.prototxt","/home/yss/yssfish/i362_64x29_iter_1.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/yssfish/i362_64x29.prototxt","/home/yss/yssfish/20180620_i362_64x29_iter_380000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/f256b20.prototxt","/home/yss/prg/yssfish/snapshots/20180224_256x20b_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/f256b40.prototxt","/home/yss/prg/yssfish/snapshots/20180224_256x40b_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/yss_zero.prototxt","/home/yss/prg/yssfish/snapshots/20190226_64x15b_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/aoba_zero.prototxt","/home/yss/prg/yssfish/snapshots/20190226_64x15b_policy_visit_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/yss_zero.prototxt","/home/yss/prg/yssfish/snapshots/_iter_1.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/f64b3.prototxt","/home/yss/prg/yssfish/snapshots/20190301_64x3b_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/test/20190306_64L29_policy_160_139_bn_relu_cut_visit_x4_47000_1/aoba_zero.prototxt","/home/yss/test/20190306_64L29_policy_160_139_bn_relu_cut_visit_x4_47000_1/_iter_910000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/aoba_zero.prototxt","/home/yss/prg/yssfish/snapshots/_iter_0.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/aoba_zero_64x15b.prototxt","/home/yss/test/20190306_64L29_policy_160_139_bn_relu_cut_visit_x4_47000_1/_iter_910000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/prg/yssfish/aoba_zero_64x15b.prototxt","/home/yss/test/extract/_iter_148000.caffemodel",caffe.TEST); +#net = caffe.Net("/home/yss/shogi/yssfish/aoba_zero_256x20b.prototxt","/home/yss/shogi/yssfish/20190417replay_lr001_wd00002/_iter_964000.caffemodel",caffe.TEST); #net = caffe.Net("/home/yss/shogi/yssfish/aoba_zero_256x20b.prototxt","/home/yss/shogi/yssfish/20190419replay_lr001_wd00002_100000_1018000/_iter_36000.caffemodel",caffe.TEST); -net = caffe.Net("/home/yss/shogi/yssfish/aoba_zero_256x20b.prototxt",args[1],caffe.TEST); +#net = caffe.Net("/home/yss/shogi/yssfish/aoba_zero_256x20b.prototxt",args[1],caffe.TEST); +#net = caffe.Net("/home/yss/shogi/learn/aoba_zero_256x20b_mb128.prototxt",args[1],caffe.TEST); +#net = caffe.Net("/home/yss/shogi/learn/aoba_zero_256x40b_mb64.prototxt",args[1],caffe.TEST); +net = caffe.Net("/home/yss/shogi/learn/aoba_256x20b_swish_predict.prototxt",args[1],caffe.TEST); @@ -51,8 +84,8 @@ def short_str(s): - r = '%.6g' % s - #r = '%.3g' % s # LZ style. this is maybe ok. + #r = '%.6g' % s + r = '%.3g' % s # LZ style. this is maybe ok. u = r if ( r[0:2]== '0.' ) : u = r[1:] @@ -68,12 +101,48 @@ def short_str(s): fc_sum = 0 cv_sum = 0 -bf.write('2\n') # version +#bf.write('2\n') # version +bf.write('3\n') # version n_layer = len( net.params.items() ) print n_layer +#print net.params.items()[0][0] +#print net.params.items()[1] +#print net.params.items()[2] +# multi line comment from """ to """ +""" +for loop in range(n_layer): + name = net.params.items()[loop][0] + print loop, name + print net.params[name][0].data.shape + a0 = net.params[name][0].data.shape[0] + #print a0 + if 'conv' in name: + a1 = net.params[name][0].data.shape[1] + #if 'fc' in name: + if ('fc' in name or 'ip' in name): + b0 = net.params[name][1].data.shape[0] + print b0 + if 'bn' in name: + #print net.params[name][0].data.shape[0] + #print net.params[name][0].data.shape[1] + a1 = net.params[name][1].data.shape[0] + b0 = net.params[name][2].data.shape[0] + print loop , name, a0,a1, ":", b0 + #print net.params[name][3].data.shape[0] + for i in range(a0): + d = net.params[name][0].data[i] + print i,d + for i in range(a1): + d = net.params[name][1].data[i] + print i,d + d = net.params[name][2].data[0] + print d +sys.exit() +""" + for loop in range(n_layer): name = net.params.items()[loop][0] #print loop , name @@ -155,3 +224,52 @@ def short_str(s): sys.exit() +#for v in net.params.items() +# print [(v[0].data.shape, v[1].data.shape)] + +#print net.params[v][0].data.shape # >> (256, 256, 3, 3) +#print net.params['conv2_3x3_256'][0].data.shape # >> (256, 256, 3, 3) +#print net.params['conv11_3x3_256'][0].data.shape # >> (256, 256, 3, 3) +#print net.params['conv12_3x3_1_0'][0].data.shape # >> (1, 256, 3, 3) +print [(k, v[0].data.shape, v[1].data.shape) for k, v in net.params.items()] + +#print net.layers +#print net.layers[0].blobs +#print net.layers[1].blobs +#print len(net.layers[1].blobs) # >> 0 +#print net.layers[1].blobs[0].data.shape # Err + +print len(net.blobs['data'].data[0]) # >> 49 +#print net.blobs['data'].data[0] +print len(net.params['conv1_5x5_256'][0].data) # >> 256, +print net.params['conv1_5x5_256'][0].data[0][0][0][0] +#print net.params['conv1_5x5_256'][0].data # contains the weight parameters, an array of shape (256, 1, 5, 5) +print len(net.params['conv1_5x5_256'][1].data) # >> 256 +#print net.params['conv1_5x5_256'][1].data # bias, 256float, contains the bias parameters, an array of shape (256,) +#print net.params['conv1_5x5_256'][2].data # Err +print len(net.params['conv2_3x3_256'][0].data) # >> 256 +print len(net.params['conv2_3x3_256'][1].data) # >> 256 + +print 'conv12_3x3_1_0' +print len(net.params['conv12_3x3_1_0'][0].data) # >> 1 +#print net.params['conv12_3x3_1_0'][0].data +print len(net.params['conv12_3x3_1_0'][1].data) # >> 1 +#print net.params['conv12_3x3_1_0'][1].data +#print net.params['flat0'][0].data # Err +#print net.params['softmax0'][0].data # Err + +sys.exit() + +bf = open('binary.bin', 'wb') +sum = 0 +for i in range(256): + for j in range(49): + for k in range(5): + for m in range(5): + d = net.params['conv1_5x5_256'][0].data[i][j][k][m] + bf.write(struct.pack("f", d)) + sum += 1 + +bf.close() +print sum +print 'done' From 5b273915345a1419a52c73805d865365112c6b57 Mon Sep 17 00:00:00 2001 From: yssaya Date: Thu, 7 Dec 2023 12:32:45 +0900 Subject: [PATCH 4/5] kldinterval 400, kldgain 0.0000004, -p 12800, ave playouts is 3180/move. --- learn/aoba_solver.prototxt | 46 +++ learn/yss_dcnn.cpp | 43 ++- server.cfg | 2 +- src/autousi/play.cpp | 15 +- src/common/param.hpp | 4 +- src/playshogi/playshogi.cpp | 6 +- src/usi-engine/Network.cpp | 2 + src/usi-engine/bona/csa.cpp | 5 +- src/usi-engine/bona/data.cpp | 1 + src/usi-engine/bona/dfpn.cpp | 8 +- src/usi-engine/bona/evaluate.cpp | 2 +- src/usi-engine/bona/io.cpp | 73 ++-- src/usi-engine/bona/param.h | 35 +- src/usi-engine/bona/proce.cpp | 10 +- src/usi-engine/bona/quiesrch.cpp | 8 +- src/usi-engine/bona/r_book.cpp | 573 +++++++++++++++++++++++++++++++ src/usi-engine/bona/shogi.h | 8 +- src/usi-engine/bona/yss_dcnn.h | 7 + src/usi-engine/bona/yss_net.cpp | 44 ++- src/usi-engine/bona/ysszero.cpp | 114 ++++-- 20 files changed, 896 insertions(+), 110 deletions(-) create mode 100644 learn/aoba_solver.prototxt create mode 100644 src/usi-engine/bona/r_book.cpp diff --git a/learn/aoba_solver.prototxt b/learn/aoba_solver.prototxt new file mode 100644 index 0000000..1b50c9d --- /dev/null +++ b/learn/aoba_solver.prototxt @@ -0,0 +1,46 @@ +#net: "aoba_zero_256x40b.prototxt" +#net: "aoba_zero_256x20b.prototxt" +net: "aoba_zero_256x20b_mb128.prototxt" +#net: "aoba_zero_256x40b_mb64.prototxt" +#net: "aoba_zero_64x15b.prototxt" +#net: "aoba_64x10b_swish_mb32.prototxt" + +# test_iter specifies how many forward passes the test should carry out. +# In the case of MNIST, we have test batch size 100 and 100 test iterations, +# covering the full 10,000 testing images. +#test_iter: 100 +# Carry out testing every 500 training iterations. +test_interval: 500 +# The base learning rate, momentum and the weight decay of the network. +weight_decay: 0.0002 # 2021-03-11 again +#weight_decay: 0.00004 # 2020-12-06 +# The learning rate policy ~/caffe/src/caffe/proto/caffe.proto +#lr_policy: "inv" # base_lr * (1 + gamma * iter) ^ (- power) +# "step" base_lr * gamma ^ (floor(iter / step)) +# "exp" base_lr * gamma ^ iter +#gamma: 0.0001 +#power: 0.75 +# Display every 100 iterations +display: 100 +#display: 50 +# snapshot intermediate results +snapshot: 2000000 +snapshot_prefix: "snapshots/" +# solver mode: CPU or GPU +solver_mode: GPU +#solver_mode: CPU +#solver_type: ADAGRAD # default = SGD=0, NESTEROV=1, ADAGRAD=2 + +base_lr: 0.000002 # training at a learning rate of 0.01 = 1e-2 + +lr_policy: "step" # learning rate policy: drop the learning rate in "steps" + # by a factor of gamma every stepsize iterations + +gamma: 0.5 # drop the learning rate by a factor of 10 + # (i.e., multiply it by a factor of gamma = 0.1) + +stepsize: 100000000 # drop the learning rate every 100K iterations + +max_iter: 100010000 # train for 700K iterations total + +momentum: 0.9 diff --git a/learn/yss_dcnn.cpp b/learn/yss_dcnn.cpp index 8f41d86..a7c859e 100644 --- a/learn/yss_dcnn.cpp +++ b/learn/yss_dcnn.cpp @@ -1134,8 +1134,11 @@ void shogi::set_dcnn_channels(Color sideToMove, const int ply, float *p_data, in // move_hit_kif[], move_hit_hashcode[] に棋譜+探索深さの棋譜とハッシュ値を入れること int loop,back_num=0; - const int T_STEP = 6; -// const int T_STEP = 1; +// const int T_STEP = 6; + const int T_STEP = 1; + const int PREV_AZ = 0; + const int TWO_HOT = 1; // 自分の歩は +1、相手の歩は -1 で同じ面にエンコード + for (loop=0; loop=0x0e ) m--; // m = 1...14 m--; - // 先手の歩、香、桂、銀、金、角、飛、王、と、杏、圭、全、馬、竜 ... 14種類、+先手の駒が全部1、で15種類 + // 先手の歩、香、桂、銀、金、角、飛、王、と、杏、圭、全、馬、竜 ... 14種類 if ( k > 0x80 ) m += 14; int yy = y, xx = x; if ( flip ) { @@ -1153,8 +1156,17 @@ void shogi::set_dcnn_channels(Color sideToMove, const int ply, float *p_data, in xx = B_SIZE - x -1; m -= 14; if ( m < 0 ) m += 28; // 0..13 -> 14..27 - } - set_dcnn_data(stock_num, data, base+m, yy,xx); + } + + if ( TWO_HOT ) { + if ( m < 14 ) { + set_dcnn_data(stock_num, data, base+m , yy,xx, +1.0); + } else { + set_dcnn_data(stock_num, data, base+m-14, yy,xx, -1.0); + } + } else { + set_dcnn_data(stock_num, data, base+m, yy,xx); + } } base += add_base; @@ -1218,6 +1230,22 @@ void shogi::set_dcnn_channels(Color sideToMove, const int ply, float *p_data, in unpack_te(&bz,&az,&tk,&nf, m); remove_hit_hash(bz,az,tk,nf); current_t--; + + if ( T_STEP == 1 && PREV_AZ ) { + if ( bz == 0 || az == 0 ) DEBUG_PRT(""); + int x = (az & 0x0f) - 1; + int y = (az & 0xf0) >> 4; + y = y - 1; + int yy = y, xx = x; + if ( flip ) { + yy = B_SIZE - y -1; + xx = B_SIZE - x -1; + } + if ( 0<=xx && xx<=8 && 0<=yy && yy<=8 ) ; + else DEBUG_PRT(""); + set_dcnn_data(stock_num, data, base, yy,xx); + } + } back_num++; @@ -1237,7 +1265,10 @@ void shogi::set_dcnn_channels(Color sideToMove, const int ply, float *p_data, in } } - if ( T_STEP == 1 ) base += (28 + 14 + 3) * (6 - 1); + if ( T_STEP == 1 ) { + base += (28 + 14 + 3) * (6 - 1); + base += PREV_AZ; + } #if 1 // int prev_base = base; diff --git a/server.cfg b/server.cfg index 9f64798..f464fa2 100644 --- a/server.cfg +++ b/server.cfg @@ -1,7 +1,7 @@ # listening socket PortPlayer 20001 BackLog 64 -MaxAccept 5000 +MaxAccept 500 # default 5000, memory need MaxAccept * MaxRecv TimeoutSelect 100 # in msec TimeoutPlayer 600 # in sec MaxRecv 524288 # in byte diff --git a/src/autousi/play.cpp b/src/autousi/play.cpp index d16f85f..535b273 100644 --- a/src/autousi/play.cpp +++ b/src/autousi/play.cpp @@ -248,18 +248,25 @@ class USIEngine : public Child { argv[argc++] = opt_p_value; #else char opt_p[] = "-p"; -// char opt_p_value[] = "3200"; - char opt_p_value[] = "6400"; +// char opt_p_value[] = "3200"; +// char opt_p_value[] = "6400"; + char opt_p_value[] = "12800"; argv[argc++] = opt_p; argv[argc++] = opt_p_value; char opt_kld[] = "-kldgain"; // char opt_kld_value[] = "0.0000013"; // char opt_kld_value[] = "0.000006"; -// char opt_kld_value[] = "0.000005"; - char opt_kld_value[] = "0.00000075"; +// char opt_kld_value[] = "0.000005"; +// char opt_kld_value[] = "0.00000075"; + char opt_kld_value[] = "0.0000004"; argv[argc++] = opt_kld; argv[argc++] = opt_kld_value; + + char opt_kld_i[] = "-kldinterval"; + char opt_kld_i_value[] = "400"; // check kldgain each 400 playouts + argv[argc++] = opt_kld_i; + argv[argc++] = opt_kld_i_value; #endif char opt_n[] = "-n"; diff --git a/src/common/param.hpp b/src/common/param.hpp index aeb1afc..dde37b8 100644 --- a/src/common/param.hpp +++ b/src/common/param.hpp @@ -3,9 +3,9 @@ #pragma once namespace Ver { constexpr unsigned char major = 3; // 2...komaochi, 3...Swish - constexpr unsigned char minor = 7; // + constexpr unsigned char minor = 8; // // usi_engine is no use. MUST increase "minor" for kicking old engine by server. Only major and minor are sent to client. - constexpr unsigned short usi_engine = 39; // 1...18 AobaZero, 16...26 komaochi, 27...Swish AobaZero + constexpr unsigned short usi_engine = 41; // 1...18 AobaZero, 16...26 komaochi, 27...Swish AobaZero } #define AOBA_UNIQUE ".oeWK7ZhnLN" diff --git a/src/playshogi/playshogi.cpp b/src/playshogi/playshogi.cpp index 2ac6c22..b4fe3c5 100644 --- a/src/playshogi/playshogi.cpp +++ b/src/playshogi/playshogi.cpp @@ -616,8 +616,10 @@ static void start_engine(USIEngine &c, int i) noexcept { if (strcmp(line, "usiok") == 0) break; } - FILE *fp = fopen(fname_option[i].get_fname(),"r"); - if ( fp ) { + const char *opt_name = fname_option[i].get_fname(); + if ( strlen(opt_name) > 0 ) { + FILE *fp = fopen(opt_name,"r"); + if ( !fp ) die(ERR_INT("fail to open USI option %s.", opt_name)); for (;;) { char line[256]; if ( fgets( line, 256, fp ) == NULL ) break; diff --git a/src/usi-engine/Network.cpp b/src/usi-engine/Network.cpp index dd645c2..7b70ec4 100644 --- a/src/usi-engine/Network.cpp +++ b/src/usi-engine/Network.cpp @@ -1020,6 +1020,7 @@ Network::Netresult_old Network::get_output_internal( */ std::vector result; for (auto idx = size_t{0}; idx < outputs.size(); idx++) { +// myprintf("%5.3f,",idx,outputs[idx]); if ( ((idx+1)%9)==0 && ((idx+1+81-9)%81)==0 ) myprintf(" ch=%d",idx/81); if ( ((idx+1)%9)==0 ) myprintf("\n"); if ( ((idx+1)%81)==0 ) myprintf("\n"); // if ( idx < 100 ) myprintf("%3d:%f\n",idx,outputs[idx]); // myprintf("done tanh....%d,outputs.size()=%d\n",__LINE__,outputs.size()); // float v = outputs[idx]; @@ -1027,6 +1028,7 @@ Network::Netresult_old Network::get_output_internal( // result.emplace_back(v, idx); result.emplace_back(outputs[idx], idx); } +// myprintf("winrate_sig=%5.3f\n",winrate_sig); // myprintf("done net calc\n"); return std::make_pair(result, winrate_sig); diff --git a/src/usi-engine/bona/csa.cpp b/src/usi-engine/bona/csa.cpp index ef43aef..b3e26cc 100644 --- a/src/usi-engine/bona/csa.cpp +++ b/src/usi-engine/bona/csa.cpp @@ -435,7 +435,7 @@ str_CSA_move( unsigned int move ) std::string string_CSA_move( unsigned int move ) { const int size = 7+8; // +8 is "-Wformat-truncation" prevention - char str[size]; + char str[size] = {0}; int ifrom, ito, ipiece_move, is_promote; is_promote = (int)I2IsPromote(move); @@ -443,6 +443,9 @@ std::string string_CSA_move( unsigned int move ) { ifrom = (int)I2From(move); ito = (int)I2To(move); +//if ( ifrom <=0 || ifrom >= nsquare ) ifrom = 0; +//if ( ito <=0 || ito >= nsquare ) ito = 0; + if ( is_promote ) { snprintf( str, size, "%d%d%d%d%s", diff --git a/src/usi-engine/bona/data.cpp b/src/usi-engine/bona/data.cpp index ebc00ae..8f74674 100644 --- a/src/usi-engine/bona/data.cpp +++ b/src/usi-engine/bona/data.cpp @@ -145,6 +145,7 @@ unsigned char book_section[ MAX_SIZE_SECTION+1 ]; unsigned char adirec[ nsquare ][ nsquare ]; unsigned char is_same[ 16 ][ 16 ]; char str_cmdline[ SIZE_CMDLINE ]; +char str_usi_position[ SIZE_CMDLINE ]; char str_message[ SIZE_MESSAGE ]; char str_buffer_cmdline[ SIZE_CMDBUFFER ]; const char *str_error; diff --git a/src/usi-engine/bona/dfpn.cpp b/src/usi-engine/bona/dfpn.cpp index 2483cff..bd06065 100644 --- a/src/usi-engine/bona/dfpn.cpp +++ b/src/usi-engine/bona/dfpn.cpp @@ -132,11 +132,11 @@ dfpn( tree_t * restrict ptree, int turn, int ply, unsigned int *pret_move, int d // const char *str = str_CSA_move(pnode->children[i].move); *pret_move = pnode->children[i].move; std::string s = string_CSA_move(*pret_move); - if ( fView ) PRT( "RESULT: WIN %s\n", s.c_str()); + if ( fView ) PRT( "RESULT: WIN %s,", s.c_str()); DFPNOut( "WIN %s\n", s.c_str()); } else { - if ( fView ) PRT( "RESULT: LOSE\n" ); + if ( fView ) PRT( "RESULT: LOSE," ); DFPNOut( "LOSE\n" ); } @@ -165,11 +165,11 @@ dfpn( tree_t * restrict ptree, int turn, int ply, unsigned int *pret_move, int d if ( !fView ) return iret; PRT( "n=%" PRIu64 " sat=%3.1f%%", ptree->node_searched, fsat ); - PRT( " age=%u sum_phi=%u", dfpn_hash_age, pdfpn_tree->sum_phi_max ); + PRT( " age=%u,phi=%u", dfpn_hash_age, pdfpn_tree->sum_phi_max ); PRT( " time=%.2f cpu=%.1f%% nps=%.2fK,ply=%d,limit=%d\n", (float)( elapse1 - elapse0 + 1U ) / 1000.0F, fcpu_percent, fnps / 1e3F, ply, dfpn_node_limit ); - PRT( "\n" ); +//PRT( "\n" ); // return 1; return iret; diff --git a/src/usi-engine/bona/evaluate.cpp b/src/usi-engine/bona/evaluate.cpp index 518ef97..990045f 100644 --- a/src/usi-engine/bona/evaluate.cpp +++ b/src/usi-engine/bona/evaluate.cpp @@ -87,7 +87,7 @@ eval_material( const tree_t * restrict ptree ) return material; } -// piece value from AobaZero kifu. https://524.teacup.com/yss/bbs/3946 +// piece value from AobaZero kifu. http://www.yss-aya.com/bbs_log/bbs2022.html#bbs64 int aoba_piece_v[13] = { // FU KY KE GI KI KA HI TO NK NG NG UM RY 100,198,367,562,674,775,871, 496,364,459,649,1133,1408 diff --git a/src/usi-engine/bona/io.cpp b/src/usi-engine/bona/io.cpp index c5f9af7..465e1fe 100644 --- a/src/usi-engine/bona/io.cpp +++ b/src/usi-engine/bona/io.cpp @@ -332,6 +332,46 @@ open_history( const char *str_name1, const char *str_name2 ) } +//Ow}oB +int +get_previous_move_from_pos( const tree_t * restrict ptree, int ply) +{ + int ret_z = 0; + if ( ptree->nrep == 0 ) return ret_z; + int np = ptree->nrep + ply - 1; + if ( np <= 0 ) { PRT("err np"); debug(); } + const min_posi_t *p0 = &ptree->record_plus_ply_min_posi[np-0]; + const min_posi_t *p1 = &ptree->record_plus_ply_min_posi[np-1]; + int x,y,n=0,diff[2],d[2]; + diff[0] = diff[1] = 0; + for (y=0;y<9;y++) for (x=0;x<9;x++) { + int z = y*9 + x; +// fprintf( pf, "%d,",p0->asquare[z]); + if ( p0->asquare[z] == p1->asquare[z] ) continue; + if ( n == 2 ) continue; + d[n] = (y+1) + (10 - (x+1))*10; + diff[n++] = z; // X1 + } + int bz = diff[0]; +//int az = diff[1]; + int b0 = d[0]; + int a0 = d[1]; + if ( n==2 ) { + if ( p0->asquare[bz] != 0 ) { +// bz = diff[1]; +// az = diff[0]; + b0 = d[1]; + a0 = d[0]; + } + } else { + b0 = 0; + a0 = d[0]; +// az = diff[0]; + } + ret_z = b0*100 + a0; + return ret_z; +} + int out_board( const tree_t * restrict ptree, FILE *pf, unsigned int move, int is_strict ) @@ -401,34 +441,13 @@ out_board( const tree_t * restrict ptree, FILE *pf, unsigned int move, // fprintf( pf, "moves=%d, pr->games=%d,moves=%d,lines=%d\n",ptree->nrep, pr->games,pr->moves,pr->lines ); fprintf( pf, "moves=%3d(%d), turn %c, nHandicap=%d, seq_hash=%016" PRIx64 ,ptree->nrep+sfen_current_move_number,sfen_current_move_number, ach_turn[(root_turn)&1], nHandicap, ptree->sequence_hash ); if ( ptree->nrep > 0 ) { + int ret_z = get_previous_move_from_pos(ptree, 1); // ply1n const min_posi_t *p0 = &ptree->record_plus_ply_min_posi[ptree->nrep-0]; - const min_posi_t *p1 = &ptree->record_plus_ply_min_posi[ptree->nrep-1]; - int x,y,n=0,diff[2],d[2]; - diff[0] = diff[1] = 0; - for (y=0;y<9;y++) for (x=0;x<9;x++) { - int z = y*9 + x; -// fprintf( pf, "%d,",p0->asquare[z]); - if ( p0->asquare[z] == p1->asquare[z] ) continue; - if ( n == 2 ) continue; - d[n] = (y+1) + (10 - (x+1))*10; - diff[n++] = z; // X1 - } - int bz = diff[0]; - int az = diff[1]; - int b0 = d[0]; - int a0 = d[1]; - if ( n==2 ) { - if ( p0->asquare[bz] != 0 ) { -// bz = diff[1]; - az = diff[0]; - b0 = d[1]; - a0 = d[0]; - } - } else { - b0 = 0; - a0 = d[0]; - az = diff[0]; - } + int b0 = ret_z / 100; + int a0 = ret_z - b0 * 100; + int x = a0 / 10; + int y = a0 - x*10; + int az = (y-1)*9 + (9-x); // fprintf( pf, "%d,02d%d%s\n",n,b0,a0,astr_table_piece[abs(p0->asquare[az])]); fprintf( pf, ", %c%02d%d%s\n",ach_turn[(root_turn+1)&1],b0,a0,astr_table_piece[abs(p0->asquare[az])]); } diff --git a/src/usi-engine/bona/param.h b/src/usi-engine/bona/param.h index 725593a..e28df23 100644 --- a/src/usi-engine/bona/param.h +++ b/src/usi-engine/bona/param.h @@ -1,17 +1,26 @@ // 2019 Team AobaZero // This source code is in the public domain. -#define DPawn 87 /* 174 */ -#define DLance 232 /* 464 */ -#define DKnight 257 /* 514 */ -#define DProPawn 534 /* 621 */ -#define DProLance 489 /* 721 */ -#define DSilver 369 /* 738 */ -#define DProKnight 510 /* 767 */ -#define DProSilver 495 /* 864 */ -#define DGold 444 /* 888 */ -#define DBishop 569 /* 1138 */ -#define DRook 642 /* 1284 */ -#define DHorse 827 /* 1396 */ -#define DDragon 945 /* 1587 */ +// AobaZero Bona6 +#define DPawn 100 /* 87 174 */ +#define DLance 198 /* 232 464 */ +#define DKnight 367 /* 257 514 */ +#define DProPawn 496 /* 534 621 */ +#define DProLance 364 /* 489 721 */ +#define DSilver 562 /* 369 738 */ +#define DProKnight 459 /* 510 767 */ +#define DProSilver 649 /* 495 864 */ +#define DGold 674 /* 444 888 */ +#define DBishop 775 /* 569 1138 */ +#define DRook 871 /* 642 1284 */ +#define DHorse 1133 /* 827 1396 */ +#define DDragon 1408 /* 945 1587 */ #define DKing 15000 +/* +AobaZero薈箴≦ +http://www.yss-aya.com/bbs_log/bbs2022.html#bbs64 + 罩 薤 罅 茹 蕋 薤 罅 薤 蘊 +100 198 367 562 674 775 871 496 364 459 649 1133 1408 + 罩 薤 罅 茹 蕋 (薈) +106 351 403 663 889 924 1257 +*/ diff --git a/src/usi-engine/bona/proce.cpp b/src/usi-engine/bona/proce.cpp index ea4a7be..482b2b3 100644 --- a/src/usi-engine/bona/proce.cpp +++ b/src/usi-engine/bona/proce.cpp @@ -59,7 +59,7 @@ static int CONV cmd_mnjmove( tree_t * restrict ptree, char **lasts, #if defined(USI) static int CONV proce_usi( tree_t * restrict ptree ); // int CONV usi_posi( tree_t * restrict ptree, char **lasts ); -static int CONV usi_go( tree_t * restrict ptree, char **lasts ); +//static int CONV usi_go( tree_t * restrict ptree, char **lasts ); static int CONV usi_ignore( tree_t * restrict ptree, char **lasts ); static int CONV usi_option( tree_t * restrict ptree, char **lasts ); #endif @@ -491,6 +491,11 @@ static int CONV proce_usi( tree_t * restrict ptree ) kill_usi_child(); return cmd_quit(); } + if ( ! strcmp( token, "make_book" ) ) { + make_r_book(ptree); + return 1; + } + if ( ! strcmp( token, "d" ) ) { /* fprintf(stderr,"print board\n"); @@ -540,7 +545,7 @@ usi_ignore( tree_t * restrict ptree, char **lasts ) } -static int CONV +int CONV usi_go( tree_t * restrict ptree, char **lasts ) { const char *token; @@ -836,6 +841,7 @@ usi_posi( tree_t * restrict ptree, char **lasts ) moves_ignore[0] = MOVE_NA; sfen_current_move_number = 0; nHandicap = 0; + strcpy(str_usi_position, *lasts); bool sfen = false; token = strtok_r( NULL, str_delimiters, lasts ); diff --git a/src/usi-engine/bona/quiesrch.cpp b/src/usi-engine/bona/quiesrch.cpp index b51f6d4..9e3756c 100644 --- a/src/usi-engine/bona/quiesrch.cpp +++ b/src/usi-engine/bona/quiesrch.cpp @@ -253,14 +253,14 @@ search_quies_aoba( tree_t * restrict ptree, int alpha, int beta, int turn, int p } if ( ply >= PLY_MAX-1 ) { - if ( alpha_old != alpha ) { pv_close( ptree, ply, no_rep ); } +// if ( alpha_old != alpha ) { pv_close( ptree, ply, no_rep ); } MOVE_CURR = MOVE_NA; return stand_pat; } ptree->anext_move[ply].next_phase = next_quies_gencap; while ( gen_next_quies_aoba( ptree, alpha, turn, ply, qui_ply ) ) { -// PRT( "\nexpand %s (%" PRIu64 ")%2d", str_CSA_move(MOVE_CURR), ptree->node_searched,ply ); + PRT( "\nexpand %s (%" PRIu64 ")%2d", str_CSA_move(MOVE_CURR), ptree->node_searched,ply ); MakeMove( turn, MOVE_CURR, ply ); if ( InCheck(turn) ) { UnMakeMove( turn, MOVE_CURR, ply ); @@ -285,8 +285,8 @@ search_quies_aoba( tree_t * restrict ptree, int alpha, int beta, int turn, int p // PRT( "\nall searched (%" PRIu64 ")\n", ptree->node_searched ); if ( alpha_old != alpha ) { - if ( alpha == stand_pat ) { pv_close( ptree, ply, no_rep ); } - else { pv_copy( ptree, ply ); } +// if ( alpha == stand_pat ) { pv_close( ptree, ply, no_rep ); } +// else { pv_copy( ptree, ply ); } } return alpha; diff --git a/src/usi-engine/bona/r_book.cpp b/src/usi-engine/bona/r_book.cpp new file mode 100644 index 0000000..d631e6f --- /dev/null +++ b/src/usi-engine/bona/r_book.cpp @@ -0,0 +1,573 @@ +鏤// 2023 Team AobaZero +// This source code is in the public domain. +#include "../config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#if !defined(_MSC_VER) +#include +#include +#endif + +#include "../Network.h" +#include "../GTP.h" +#include "../Random.h" + +#include "shogi.h" + +#include "lock.h" +#include "yss_var.h" +#include "yss_dcnn.h" +#include "process_batch.h" + + +/* +絎憟∈蕭絮≪10絎莊<篏 +綵≪10違荐吟腆榊綮吟篏 +26罩0.65吾(76罩0.20)284罩0.50 +3 +26罩(0.65) * 84罩(0.50) = 0.325 吾 +76罩(0.20) = 0.200 +78(0.10) = 0.100 +*/ + + +const char R_BOOK_FILE[] = "r_book.bin"; +//const char R_BOOK_FILE[] = "r_book_lose.bin"; +//const char R_BOOK_FILE[] = "r_book_kaku35.bin"; + +typedef struct R_BOOK : HASH_SHOGI { // Realization Probability Book 罕篏膓帥с篏帥鴻 + double prob; // Realization Probability + std::string str_seq; // 憜絮≪障с +// int weight; // 篏weight +} R_BOOK; + +std::vector r_book; +const int R_BOOK_SIZE = 1024*64; +int R_BOOK_MASK; +int r_book_use = 0; +double total_prob; + +const int R_INIT = 0; +const int R_DONE = 1; // 絮羝 + + +void r_book_reset() +{ + for (int i=0;ideleted = 1; + LockInit(r->entry_lock); + std::vector().swap(r->child); // memory free hack for vector. + } + r_book_use = 0; +} + +void r_book_clear() +{ + R_BOOK_MASK = R_BOOK_SIZE - 1; + HASH_ALLOC_SIZE size = sizeof(R_BOOK) * R_BOOK_SIZE; + r_book.resize(R_BOOK_SIZE); // reserve()荀膣潟潟鴻帥莎違с + PRT("R_BOOK_SIZE=%7d(%3dMB),sizeof(R_BOOK)=%d,sizeof(CHILD)=%d\n",R_BOOK_SIZE,(int)(size/(1024*1024)),sizeof(R_BOOK),sizeof(CHILD)); + r_book_reset(); +} + +void save_r_book() +{ + FILE *fp = fopen(R_BOOK_FILE,"wb"); + if ( !fp ) DEBUG_PRT(""); + fwrite( &r_book_use ,sizeof(int), 1, fp); + for (int i=0;ihashcode64 ,sizeof(uint64), 1, fp); + fwrite( &r->hash64pos ,sizeof(uint64), 1, fp); + fwrite( &r->mate_bit ,sizeof(int ), 1, fp); + fwrite( &r->win_sum ,sizeof(float ), 1, fp); + fwrite( &r->squared_eval,sizeof(float ), 1, fp); + fwrite( &r->games_sum ,sizeof(int ), 1, fp); + fwrite( &r->col ,sizeof(int ), 1, fp); + fwrite( &r->age ,sizeof(int ), 1, fp); + fwrite( &r->net_value ,sizeof(float ), 1, fp); + fwrite( &r->child_num ,sizeof(int ), 1, fp); + for (int j=0; jchild_num; j++) { + fwrite( &r->child[j],sizeof(CHILD), 1, fp); + } + fwrite( &r->prob ,sizeof(double ), 1, fp); + int size = r->str_seq.size(); + fwrite( &size ,sizeof(int ), 1, fp); + fwrite( r->str_seq.c_str() , size , 1, fp); + } + fclose(fp); +} + +void load_r_book() +{ + FILE *fp = fopen(R_BOOK_FILE,"rb"); + if ( !fp ) { + PRT("no %s. start new book.\n",R_BOOK_FILE); + return; + } + if ( fread( &r_book_use ,sizeof(int), 1, fp) != 1 ) DEBUG_PRT(""); + int cv[100] = {0}; + int cc[2] = {0}; + for (int i=0;ihashcode64 ,sizeof(uint64), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->hash64pos ,sizeof(uint64), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->mate_bit ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->win_sum ,sizeof(float ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->squared_eval,sizeof(float ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->games_sum ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->col ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->age ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->net_value ,sizeof(float ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( fread( &r->child_num ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + + int max_g = 0, max_i = -1, dones = 0; + r->child.resize(r->child_num); + for (int j=0; jchild_num; j++) { + CHILD *pc = &r->child[j]; + if ( fread( pc,sizeof(CHILD), 1, fp) != 1 ) DEBUG_PRT(""); + if ( pc->mate_bit == R_DONE ) dones++; + if ( pc->games > max_g ) { max_g = pc->games; max_i = j; } +// PRT("%2d:%8x,%3d,(%6.3f),bias=%6.3f\n",j,pc->move,pc->games,pc->value,pc->bias); + } + if ( fread( &r->prob ,sizeof(double ), 1, fp) != 1 ) DEBUG_PRT(""); + int size = 0; + if ( fread( &size ,sizeof(int ), 1, fp) != 1 ) DEBUG_PRT(""); + if ( size==0 ) DEBUG_PRT(""); + char *buf = new char[size+1]; + if ( fread( buf, size , 1, fp) != 1 ) DEBUG_PRT(""); + buf[size] = 0; + r->str_seq = buf; + delete buf; + cc[r->col]++; + CHILD *pc = &r->child[max_i]; + float v = pc->value; + if ( r->col == 1 ) v = -v; + v = (v + 1.0) * 50; // -1 < v < +1 --> 0 < v < +100 + if ( v < 0 ) v = 0; + if ( v > +99 ) v = +99; + cv[(int)v]++; + int book_ply = std::count(r->str_seq.begin(), r->str_seq.end(), ' ')-2; + if ( i > r_book_use-10 || book_ply > 51 ) PRT("%4d:%10f,%016" PRIx64 ",%8d,%d,%6.3f,%2d,ply=%d,%s\n",i,r->prob,r->hash64pos,r->games_sum,r->col,pc->value,dones,book_ply,r->str_seq.c_str()+23); + } + + int same = 0; + for (int i=0;ihash64pos == 0 ) continue; + for (int j=i+1;jhash64pos == 0 ) continue; + if ( r->hash64pos == q->hash64pos ) { q->hash64pos = 0; same++; } + } + } + for (int i=0;i<100;i++) if ( cv[i] ) PRT("%3d:%4d(%5.2f %%)\n",i,cv[i],100.0*cv[i]/r_book_use); + PRT("r_book_use=%d,same=%d,cc[]=%d,%d\n",r_book_use,same,cc[0],cc[1]); + if ( same ) DEBUG_PRT(""); + fclose(fp); +} + +void find_next_extend(int *p_max_i, int *p_max_c) +{ + double max_b = -DBL_MAX; + int max_i = -1; + int max_c = 0; + for (int i=0;igames_sum == 0 ) DEBUG_PRT(""); + + for (int j=0; jchild_num; j++) { + CHILD *pc = &r->child[j]; + if ( pc->mate_bit == R_DONE ) continue; // 絮羝 + if ( pc->games == 0 ) continue; + + float v = pc->value; + if ( r->col == 1 ) v = -v; + v = (v + 1.0) * 50; // -1 < v < +1 --> 0 < v < +100 + if ( v > +55+10 || v < +55-10 ) continue; // 蕭篏絮 + + double a = (double)pc->games / r->games_sum; + double b = r->prob + log(a); + if ( b > max_b ) { + max_b = b; + max_i = i; + max_c = j; + } +// PRT("%3d:%2d:%8x,%3d,(%6.3f),bias=%6.3f,%d,%lf,%lf,%lf\n",i,j,pc->move,pc->games,pc->value,pc->bias,r->games_sum,a,b,max_b); + } + } + if ( max_i < 0 ) DEBUG_PRT(""); + R_BOOK *r = &r_book[max_i]; + CHILD *pc = &r->child[max_c]; + *p_max_i = max_i; + *p_max_c = max_c; + PRT("max_i=%d,c=%d,%8x,%3d,(%6.3f),bias=%6.3f\n",max_i,max_c,pc->move,pc->games,pc->value,pc->bias); +} + +int add_book(tree_t * restrict ptree, std::string pos_str, double prob) +{ + PRT("%lf:%d:ply=%d,%s\n",prob,r_book_use,std::count(pos_str.begin(), pos_str.end(), ' ')-2, pos_str.c_str()); + strcpy(str_cmdline, pos_str.c_str()); + char *lasts; + strtok_r( str_cmdline, str_delimiters, &lasts ); + usi_posi( ptree, &lasts ); + + uint64 hash64pos = get_marge_hash(ptree, root_turn); + int i; + for (i=0;ihash64pos ) break; + } + if ( i != r_book_use ) { + static int count = 0; + PRT("same pos=%d/%d, count=%d\n",i,r_book_use,++count); + return 0; + } + + const char *p = "go visit"; + strcpy(str_cmdline, p); + strtok_r( str_cmdline, str_delimiters, &lasts ); + usi_go( ptree, &lasts ); + + HASH_SHOGI *phg = HashShogiReadLock(ptree, root_turn); + UnLock(phg->entry_lock); + + R_BOOK *r = &r_book[r_book_use]; + r->child.resize(phg->child_num); + + for (int i=0; ichild_num; i++) { + CHILD *pc = &phg->child[i]; + r->child[i] = *pc; + r->child[i].mate_bit = R_INIT; + char buf[7] = "resign"; +// pc->move = 0; + if ( pc->move ) csa2usi( ptree, str_CSA_move(pc->move), buf ); +// if ( pc->games ) PRT("%2d:%s,%3d,(%6.3f),bias=%6.3f,%s\n",i,str_CSA_move(pc->move),pc->games,pc->value,pc->bias,buf); + } + + r->hashcode64 = phg->hashcode64; + r->hash64pos = phg->hash64pos; + r->mate_bit = phg->mate_bit; + r->win_sum = phg->win_sum; + r->squared_eval = phg->squared_eval; + r->games_sum = phg->games_sum; + r->col = phg->col; + r->age = phg->age; + r->net_value = phg->net_value; + r->child_num = phg->child_num; + + r->prob = prob; + r->str_seq = pos_str; + r_book_use++; + if ( r->games_sum == 0 ) DEBUG_PRT(""); + +// copy(phg->child.begin(), phg->child.end(), back_inserter(r->child)); + PRT("r_book_use=%d,child_num=%d\n",r_book_use,r->child.size()); + if ( 0 ) for (int i=0; ichild_num; i++) { + CHILD *pc = &r->child[i]; + char buf[7] = "resign"; + if ( pc->move ) csa2usi( ptree, str_CSA_move(pc->move), buf ); + if ( pc->games ) PRT("%2d:%s,%3d,(%6.3f),bias=%6.3f,%s\n",i,str_CSA_move(pc->move),pc->games,pc->value,pc->bias,buf); + } + return 1; +} + + +const char *lose_str[10] = { +// dlshogi - AobaZero +"position startpos moves 2g2f 8c8d 7g7f 8d8e 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a4b 9g9f 7a6b 4g4f 4b3c 3i4h 7c7d 6i7h 1c1d 3g3f 4a3b 4h4g 9c9d 1g1f 8a7c 5i6h 5a4b 2i3g 6c6d 4i4h 6b6c 4g5f 6a6b 2h2i 8b8a 2f2e 4b4a 6g6f 4a5b 6h7i 5b4b 7i8h 6c5d 3g4e 3c2b 3f3e 3d3e 1f1e 1d1e 2e2d 2c2d 2i2d 8e8f 8g8f P*8g 7h8g P*8e 8f8e 2b2c 2d2i P*2h 2i2h 4c4d P*2d 2c3d P*1b 7c8e 7g8f 4d4e 1b1a+ N*3f P*8b 8a8b 2h1h 3f4h+ 1a2a B*6h N*4d 3b3c 1h1e 6h5g+ P*8c 8b8c P*8d 8c8b 4f4e 3d4e 5f4e 5d4e 2d2c+ 3c4d 1e1b+ 4b4c P*5e 4d3d B*1a P*4b S*5a P*2b 1b2b 5g6f 8h9h 6f5e 2c2d S*7h 2d3d 4c3d G*3c 3d4d 2b2d N*3d 3c3d 4d5d 3d3e P*3d 1a5e+ 5d5e 2d2f 3d3e L*5g G*5f B*3c G*4d 5g5f 4e5f 2f3e 5e6f G*6h L*9g 8i9g 7h8g 9h8g G*7g 8f7g 8e7g+ 6h7g 6f5g 3c4d+ P*8f 8g8f 5g5h 5a6b B*5g 6b7c 5g3e+ 4d3e R*6e 3e3f S*4g 3f4f 5f6g+ 7g8g 8b8a N*7g P*8e 9g8e 6e6f 4f5e 4g5f+ 5e6f 5f6f B*3f B*4g 3f4g 4h4g R*2i 6f7f 8g7f B*4i G*3i 4i2g+ L*5i 5h6h P*6i 6h5i 3i3h 5i5h S*4i 5h5g B*3e 5g5f 3h4g 5f4e 4g4f 4e3d G*4d 3d2e G*1e", +// 若蕋荵 - AobaZero +"position startpos moves 7g7f 8c8d 6i7h 8d8e 8h7g 3c3d 7i6h 2b7g+ 6h7g 3a4b 3i3h 7a6b 5i6h 4b3c 4g4f 9c9d 9g9f 4a3b 1g1f 1c1d 3g3f 7c7d 2i3g 5a4b 3h4g 6c6d 4i4h 8a7c 4g5f 6b6c 6g6f 8b8a 2g2f 6a6b 2f2e 8a4a 6h7i 4a8a 7i6h 4b4a 2h2i 4a3a 6h7i 3a4b 7i8h 6c5d 5f4e 5d6c 4e5f 6c5d 5f4e 5d6c 2i6i 6b7b 4e5f 6c5d 4f4e 4b3a B*4f 8a6a 6i3i 3a2b 3i2i 6d6e 6f6e 9d9e 9f9e 7d7e 7f7e 5d6e P*6f P*7f 7g6h 6e6f P*6g 6f7e P*7d P*6d 7d7c+ 7b7c 8h7i 6a8a 7i6i 8e8f 8g8f 7e8f 6i5h 8f8g 7h8g 8a8g+ 2e2d 2c2d P*2e 2b3a 2e2d P*2h 2i3i B*8f P*7g 8g8h S*9g 8f9g+ 9i9g G*7h 6h5i 8h8i 5h4g 7h6h 5f6e 6h5i N*2c 3a4b 6e6d 7c6d 4f6d S*6b G*6a S*5a 2c1a+ P*6c 6d9a+ P*8b 2d2c+ 3b2c L*2f 2h2i+ 2f2c+ 2i3i 1a2a 8i8e 2c3c 4b5b 6a5a 6b5a 3c4c 5b6b 4c5c 6b5c S*4d 5c6d B*5c 6d7c L*7e 8e7e 5c7e+ P*4f 4g4f N*5d 4f5f R*4f 5f5e 4f4e 5e4e G*4f 4e5d L*5b 5d4c 5a4b 4c4b P*4a 4b5a S*4b 5a6a 3i3h S*7d", +// TMOQ - AobaZero +"position startpos moves 7g7f 8c8d 2g2f 8d8e 8h7g 3c3d 7i6h 2b7g+ 6h7g 3a4b 3i3h 7a6b 6i7h 4b3c 3g3f 4a3b 4g4f 9c9d 9g9f 1c1d 1g1f 6c6d 2i3g 5a4b 3h4g 7c7d 5i6h 8a7c 2h2i 6b6c 4i4h 6a6b 6g6f 8b8a 4g5f 4b4a 6h7i 4a5b 7i8h 5b4b 2f2e 6c5d 3g4e 3c2b 3f3e 3d3e 2e2d 4c4d 7f7e B*5b 2d2c+ 2b2c P*2d 2c3d B*2c 5d4c 7e7d 5b7d P*3c 2a3c 2c3d+ 4c3d S*2c P*2h 2i2h P*2g 2h2g P*2f 2g2f P*2e 2c3d+ 2e2f P*7e 7d6c 2d2c+ 3b2c 3d2c 3c4e 4f4e P*7f 7g6h N*8f 7h7i 9d9e N*7d 9e9f P*9h 6c7d 7e7d 9f9g+ 9h9g 9a9g+ 8h9g P*9f 9g8h 9f9g+ 8h9g R*9f 9g8h 9f9i+ 8h9i P*9h 9i8h B*9i 8h9g 8a9a R*9f 9a9f 9g9f R*9d R*9e N*8d 9f9g 9d9e B*9f 9e9f", +// Novice - AobaZero +"position startpos moves 2g2f 8c8d 2f2e 8d8e 7g7f 4a3b 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a2b 1g1f 1c1d 6i7h 2b3c 3i4h 7a6b 4g4f 9c9d 9g9f 6c6d 3g3f 5a4b 4h4g 7c7d 5i6h 8a7c 2i3g 6b6c 4i4h 6a6b 2h2i 8b8a 4g5f 4b4a 6g6f 4a5b 6h7i 5b4b 7i8h 6c5d 3g4e 3c2b 3f3e 3d3e 1f1e 1d1e 2e2d 2c2d 2i2d 8e8f 8g8f 2b2c 4e5c+ 6b5c 2d5d 5c5d B*6c P*8g 8h8g 8a8c P*2d 2c2d 6c5d+ R*5i 5d6d 4b3c 6d7d 5i8i+ S*8h P*8e 7d8c 8e8f 8g8f B*4b 8f8g P*8f 7g8f 4b8f 8g8f 8i7h 8c7c 7h8h P*8g N*6a 7c5a S*4b 5a6a P*7c G*3d 3c3d B*4e 3d3c R*3d 3c2c 3d3b+ 2c3b N*4d 4c4d G*2c 3b4a 4e6c+ 4a3a N*4c 4b4c 6a4c S*7g 8f7e G*7d 6c7d 7c7d 7e6d B*8b 6d5c R*8c S*6c 8b7a 5c5d N*6b 6c6b+ G*5c 4c5c 8c5c 5d5c 7a6b 5c6b S*5c 6b7a 5c6b 7a6b P*6a 6b5a B*8d 5a5b 8d5a G*4a", +// koron - AobaZero +"position startpos moves 7g7f 8c8d 2g2f 8d8e 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a4b 6i7h 7a6b 3g3f 4b3c 3i3h 4a3b 4g4f 9c9d 9g9f 1c1d 2i3g 6c6d 1g1f 5a4b 3h4g 7c7d 4i4h 8a7c 2h2i 6b6c 5i6h 6a6b 4g5f 8b8a 6g6f 4b4a 2f2e 4a5b 6h7i 5b4b 7i8h 6c5d 3g4e 3c2b 3f3e 3d3e 1f1e 1d1e 2e2d 2c2d 2i2d 8e8f 8g8f 2b2c 4e5c+ 6b5c 2d5d 5c5d B*6c P*8g 8h8g 8a8c P*2d 2c2d 6c5d+ R*5i 5d6d 4b3c 6d7d 5i8i+ S*8h P*8e 7d8c 8e8f 8g8f B*4b 8f8g P*8f 7g8f 4b8f 8g8f 8i7h 8c7c 7h8h P*8g N*6a 7c5a S*4b 5a6a P*7c B*5e 3c2c 5e7c+ N*8a G*3d 2c3d R*8d 3d2c 8d8a+ S*9b 8a7a G*8a 7a6b 8h4h N*2f 4h5g N*4d 3b3a N*5d P*8d 7c8d 4b3c 6a4c P*4b 5d4b+ 3a4b 6b4b 5g8g 8f8g P*8f 8g8f N*7d 8d7d G*7e 7d7e G*3a 4b3a 2d2e 3a3b 2c2d G*2c", +NULL +}; + +int find_next_add_lose_game(tree_t * restrict ptree) +{ + static int lose_n = 0; + static int m = 0; + + if ( m > 90 ) { m = 0; lose_n++; } + + const char *p = lose_str[lose_n]; + if ( p == NULL ) return 0; + char c = 0; + int i,count = 0; + for (i=0; ;i++) { + c = *(p+i); + if ( c==0 ) break; + if ( c!=' ' ) continue; + count++; + if ( count == m+3 ) break; + } + m++; + if ( c==0 ) return 0; + std::string str = p; + str = str.substr(0,i); + PRT("lose_n=%d,m=%d\n",lose_n,m); + return add_book(ptree, str, log(1)); +} + + +int find_next_add(tree_t * restrict ptree) +{ + std::string str; + if ( r_book_use == 0 ) { +// const char *p = "position startpos moves 7g7f 8b3b 2g2f 3a4b"; + const char *p = "position startpos moves"; +// const char *p = "position startpos moves 2g2f 8c8d 2f2e 8d8e 7g7f 4a3b 8h7g 3c3d 7i8h 2b7g+ 8h7g 3a2b 1g1f 1c1d 6i7h 2b3c 3i4h 7c7d 4g4f 7a6b 4h4g 5a4b 3g3f 6c6d 2i3g 8a7c 5i6h 6b6c 9g9f 9c9d 4i4h 6a6b 2h2i 8b8a 4g5f" // 茹35障 + + str = p; + total_prob = log(1); + } else { + int max_i,max_c; + find_next_extend(&max_i, &max_c); + + R_BOOK *r = &r_book[max_i]; + CHILD *pc = &r->child[max_c]; + + strcpy(str_cmdline, r->str_seq.c_str()); + char *lasts; + strtok_r( str_cmdline, str_delimiters, &lasts ); + usi_posi( ptree, &lasts ); + char buf[7] = "resign"; + if ( pc->move ) csa2usi( ptree, str_CSA_move(pc->move), buf ); + str = r->str_seq + " " + buf; + pc->mate_bit = R_DONE; + double a = (double)pc->games / r->games_sum; + total_prob = r->prob + log(a); + } + return add_book(ptree, str, total_prob); +} + +int book_node; +int start_book_ply; +// min-maxф「(茲医茖翫) ユ若羈min-maxц箴≦ゃ羆「膣(脂)若違綏т拭с馹 +float min_max_book(tree_t * restrict ptree, std::string pos_str, int ply, int *err) +{ + const int D_P = 0; + *err = 0; + int book_ply = std::count(pos_str.begin(), pos_str.end(), ' ')-2; + if ( book_node ==0 ) start_book_ply = book_ply; + book_node++; + if ( ply<=D_P ) PRT("book ply=%d,%d,book_node=%4d:%s\n",book_ply, ply, book_node,pos_str.c_str()); + strcpy(str_cmdline, pos_str.c_str()); + char *lasts; + strtok_r( str_cmdline, str_delimiters, &lasts ); + usi_posi( ptree, &lasts ); + + uint64 hash64pos = get_marge_hash(ptree, root_turn); + int n; + for (n=0;nhash64pos ) break; + } + if ( n == r_book_use ) { + PRT("not found Err.book ply=%d,%d,book_node=%4d:%s\n",book_ply, ply, book_node,pos_str.c_str()); + *err = 1; + return 0; + } + + int i_max = -1; // 絮羝帥筝с + float v_max = -999; + int max_games = 0; + float max_value = -999; // 絮翫菴 + std::string str; + R_BOOK *r = &r_book[n]; + + char usi_buf[MAX_LEGAL_MOVES][7] = {0}; + for (int i=0; ichild_num; i++) { + CHILD *pc = &r->child[i]; + csa2usi( ptree, str_CSA_move(pc->move), usi_buf[i]); // 「膣≪ptree絎鴻紊c障т + } + + for (int i=0; ichild_num; i++) { + CHILD *pc = &r->child[i]; +// if ( strcmp(usi_buf[i],"2b7g+")==0 ) continue; // 緇茹篋ゆ胼罩≪鐚 + if ( pc->mate_bit == R_INIT || ply > book_ply - start_book_ply ) { + if ( pc->games > max_games ) { + max_games = pc->games; + max_value = pc->value; + } + continue; + } + if ( pc->games == 0 ) continue; + if ( pc->value == ILLEGAL_MOVE ) continue; + str = r->str_seq + " " + usi_buf[i]; + int b = book_node; +// if ( ply<=D_P ) PRT("%2d:%2d,%7s,ret_v=%8.5f,g=%8d,raw_v=%8.5f(%7d),n=%4d,before\n",ply,i,usi_buf[i],0.0f,pc->games,pc->value,book_node-b,n); + float v = -min_max_book(ptree, str, ply+1,err); + if ( *err ) continue; + if ( ply<=D_P ) PRT("%2d:%2d,%7s,ret_v=%8.5f,g=%8d,raw_v=%8.5f(%7d),n=%4d\n",ply,i,usi_buf[i],v,pc->games,pc->value,book_node-b,n); + if ( v > v_max ) { + v_max = v; + i_max = i; + } + } + float ret_v; + if ( i_max < 0 ) { + ret_v = max_value; + } else { + ret_v = v_max; + } + if ( ply<=D_P ) PRT("%2d:%4d:ret_v=%8.5f,i_max=%d,book_node=%d\n",ply,n,ret_v,i_max,book_node); + return ret_v; +} + +void make_r_book(tree_t * restrict ptree) +{ + r_book_clear(); + load_r_book(); +#if 1 + std::string s = "position " + (std::string)str_usi_position; + const char *p = s.c_str(); +// const char *p = "position startpos moves 7g7f 4a3b 2g2f 8c8d 7i7h 3c3d"; + int err; + book_node = 0; + min_max_book(ptree, p, 0, &err); + return; +#endif + for (int i=0; i= R_BOOK_SIZE ) break; + } +} + +int get_force(tree_t * restrict ptree, HASH_SHOGI *phg) +{ + std::string s = "position " + (std::string)str_usi_position; +// PRT("s='%s'\n",s.c_str()); + + typedef struct MANE { + int winner; // 緇<1 + const char *str; + } MANE; + MANE mane[100] = { + // N+Lightweight, N-dlshogi with HEROZ, 篌若 + { 0, "position startpos moves 2g2f 8c8d 2f2e 8d8e 6i7h 4a3b 3i3h 9c9d 9g9f 7a7b 3g3f 8e8f 8g8f 8b8f 5i6h 1c1d 2i3g 7c7d 2e2d 2c2d 2h2d P*2c 2d7d 7b7c P*8g 8f8b 7d7e 7c6d 7e2e 3c3d 7g7f 4c4d 4g4f 3a4b 4i4h 4b4c 3h4g 6a5b 6h5h 2a3c 2e2i 8b7b 7h7g 5c5d 5h6h 2b3a 7i7h 7b8b 1g1f 5a4a 6g6f 8a7c 8g8f 8b8d 7g8g P*7e 6f6e 6d6e 4f4e 5d5e 8h5e 8d7d 7f7e 3a7e P*7f 7e5c 7h6g P*8e P*6d 6e5d 7f7e 7d8d 8f8e 8d8e P*8f 8e8d 5e8h 4d4e 4g5f P*5e 5f5e 5d5e 8h5e 5c6d 5e6d 8d6d S*7d P*7b 7d7c 7b7c N*5f 6d8d P*4d 4c5d B*7f S*6e 7f6e 5d6e S*4c S*4b 8i7g 6e5f 4c3b 4a3b 6g5f P*5h S*2a 3b4a 2i2c+ B*5d 5f6e B*5i 6h5h 5i4h+ 5h4h N*5e B*2i S*4g 2i4g 5e4g+ 4h4g B*6i 4g3h 4a5a P*6b G*4g 3h2i 5a6b N*7d 7c7d 6e5d 4g3g 7g6e 6i4g+ 2i1h N*6a B*4a P*5a P*6d N*7a 6d6c+ 5b6c 2c3b 4g3f 1h2i 3f4g 2i1h 3g2h 1h2h P*2g 2h3i 4g5g G*4h 5g7e 3b4b 7e4b 5d6c 7a6c S*7c 6a7c G*5c 4b5c 6e5c+ 6b5c 4d4c+" }, + { 0, NULL } + }; + + for (int loop = 0; ;loop++) { + if ( mane[loop].str == NULL ) break; + std::string m = mane[loop].str; + if ( root_turn != mane[loop].winner || m.find(s) == std::string::npos ) continue; + size_t n = s.size(); + std::string m0 = m.substr(n).c_str(); + size_t i = m0.find(" "); + if ( i == 0 ) { + m0 = m0.substr(1); + i = m0.find(" "); + } + if ( i == std::string::npos ) continue; + const char *p = m0.substr(0,i).c_str(); + PRT("'%s'\n",p); + + for (int i=0; ichild_num; i++) { + CHILD *pc = &phg->child[i]; + char buf[7] = "resign"; + if ( pc->move ) csa2usi( ptree, str_CSA_move(pc->move), buf); + if ( strcmp(buf, p)==0 ) { + PRT("copy winner move[%d]=%s,winner=%d\n",loop,p,mane[loop].winner); + return pc->move; + } + } +// PRT("find %d,%s\n",n,m.substr(n).c_str()); + } + + // 44罩ц罩≪AobaZero絖膺у冴紊茯絨鴻 + if ( s == "position startpos moves 2g2f" ) return 0x00008c21; // 34罩 + if ( s == "position startpos moves 7g7f" ) return 0x00008c21; // 34罩 + if ( s == "position startpos moves 7g7f 3c3d 2g2f" ) return 0x00008ba0; // 44罩 + if ( s == "position startpos moves 2g2f 3c3d 7g7f" ) return 0x00008ba0; // 44罩 + if ( s == "position startpos moves 2g2f 3c3d 6i7h" ) return 0x00008ba0; // 44罩 + if ( s == "position startpos moves 2g2f 3c3d 2f2e 2b3c 7g7f" ) return 0x00008ba0; // 44罩 + + if ( s == "position startpos moves 5i5h 5a5b 5h5i 5b5a 2g2f" ) return 0x00008c21; // 34罩 紫4 + if ( s == "position startpos moves 5i5h 5a5b 5h5i 5b5a" ) return 0x00009c2f; // 76罩 紫4 + + return 0; +} + +int get_book_move(tree_t * restrict ptree, HASH_SHOGI *phg) +{ +return 0; // no book + static int bDone = 0; + if ( ! bDone ) { + r_book_clear(); + load_r_book(); + bDone = 1; + } + int book_move = 0; + + int force_move = get_force(ptree, phg); + if ( force_move ) { + PRT("force!\n"); + return force_move; + } + + uint64 hash64pos = get_marge_hash(ptree, root_turn); + int n; + for (n=0;nhash64pos ) break; + } + if ( n == r_book_use ) { + PRT("no book move.\n"); + return book_move; + } + + int max_i = -1; // + int max_games = 0; + R_BOOK *r = &r_book[n]; + for (int i=0; ichild_num; i++) { + CHILD *pc = &r->child[i]; + if ( pc->games ) PRT("%2d:%7s,%08x,%7d(%6.3f)%d,bias=%6.3f\n",i,str_CSA_move(pc->move),pc->move,pc->games,pc->value,pc->mate_bit,pc->bias); + if ( pc->games < max_games ) continue; + max_games = pc->games; + max_i = i; + } + if ( max_i < 0 ) { + PRT("no best book move? Err\n"); + return book_move; + } + + CHILD *pc = &r->child[max_i]; + book_move = pc->move; + + char buf[7] = "resign"; + if ( pc->move ) csa2usi( ptree, str_CSA_move(pc->move), buf); + PRT("book_move=%s, n=%d,max_i=%d/%d,g=%d/%d,v=%7.4f(%6.2f%%),raw_v=%7.4f(%6.2f%%)\n",buf,n,max_i,r->child_num,pc->games,r->games_sum,pc->value,(pc->value+1.0)/2.0*100,r->net_value,(r->net_value+1.0)/2.0*100); + return book_move; +} + diff --git a/src/usi-engine/bona/shogi.h b/src/usi-engine/bona/shogi.h index 549ee1c..87e6acc 100644 --- a/src/usi-engine/bona/shogi.h +++ b/src/usi-engine/bona/shogi.h @@ -136,7 +136,9 @@ extern unsigned char ailast_one[512]; //#define BNZ_VER "36" // 20220626 pawn ,rook, bishop are always promoted. discovered attack moves have 30% of best policy. safe LCB, kldgain 0.000005. //#define BNZ_VER "37" // 20220626 kldgain 000000075. ave playouts is 1568/move. //#define BNZ_VER "38" // 20221110 test get_best_move_alphabeta_usi(). -#define BNZ_VER "39" // 20221221 raw value and policy are recorded in *.csa. Dynamic Variance-Scaled cPUCT. NN is not called for one reply king escape position. +//#define BNZ_VER "39" // 20221221 raw value and policy are recorded in *.csa. Dynamic Variance-Scaled cPUCT. NN is not called for one reply king escape position. +//#define BNZ_VER "40" // 20230519 dfpn is called from all threads. make_book, kldinterval. +#define BNZ_VER "41" // 20231207 kldgain 0.0000004, kldinterval 400, -p 12800, ave playouts is 3180/move. #define BNZ_NAME "AobaZero" //#define BNZ_VER "16" // 20210528 komaochi, mate3 @@ -763,6 +765,7 @@ struct tree { int reached_ply; int max_reached_ply; int sum_reached_ply; + unsigned int path[PLY_MAX]; // UCTф #endif uint64_t node_searched; unsigned int *move_last[ PLY_MAX ]; @@ -981,6 +984,7 @@ extern unsigned char adirec[nsquare][nsquare]; extern unsigned char is_same[16][16]; extern char str_message[ SIZE_MESSAGE ]; extern char str_cmdline[ SIZE_CMDLINE ]; +extern char str_usi_position[ SIZE_CMDLINE ]; extern char str_buffer_cmdline[ SIZE_CMDBUFFER ]; extern const char *str_error; @@ -1112,6 +1116,7 @@ int read_board_rep1( const char *str_line, min_posi_t *pmin_posi ); int CONV com_turn_start( tree_t * restrict ptree, int flag ); int read_record( tree_t * restrict ptree, const char *str_file, unsigned int moves, int flag ); +int get_previous_move_from_pos( const tree_t * restrict ptree, int ply); int out_board( const tree_t * restrict ptree, FILE *pf, unsigned int move, int flag ); int make_root_move_list( tree_t * restrict ptree ); @@ -1387,6 +1392,7 @@ int CONV csa2usi( const tree_t * restrict ptree, const char *str_csa, char *str_usi ); int analyze( tree_t * restrict ptree ); int CONV usi_posi( tree_t * restrict ptree, char **lasts ); +int CONV usi_go( tree_t * restrict ptree, char **lasts ); #else # define USIOut( ... ) #endif diff --git a/src/usi-engine/bona/yss_dcnn.h b/src/usi-engine/bona/yss_dcnn.h index f71454e..c80517e 100644 --- a/src/usi-engine/bona/yss_dcnn.h +++ b/src/usi-engine/bona/yss_dcnn.h @@ -115,6 +115,8 @@ bool isKLDGainSmall(tree_t * restrict ptree, int sideToMove); void init_KLDGain_prev_dist_visits_total(int games_sum); void clear_opening_hash(); void make_balanced_opening(tree_t * restrict ptree, int sideToMove, int ply); +HASH_SHOGI* HashShogiReadLock(tree_t * restrict ptree, int sideToMove); +uint64 get_marge_hash(tree_t * restrict ptree, int sideToMove); // yss_net.cpp void init_network(); @@ -151,4 +153,9 @@ int get_motigoma(int m, int hand); unsigned int get_best_move_alphabeta_usi(tree_t * restrict ptree, int sideToMove, int ply); void kill_usi_child(); +// r_book.cpp +void make_r_book(tree_t * restrict ptree); +int get_book_move(tree_t * restrict ptree, HASH_SHOGI *phg); + + #endif //]] INCLUDE__GUARD diff --git a/src/usi-engine/bona/yss_net.cpp b/src/usi-engine/bona/yss_net.cpp index 469b9f2..9c2b56a 100644 --- a/src/usi-engine/bona/yss_net.cpp +++ b/src/usi-engine/bona/yss_net.cpp @@ -473,6 +473,8 @@ void set_dcnn_channels(tree_t * restrict ptree, int sideToMove, int ply, float * #ifdef USE_POLICY2187 const int T_STEP = 6; // const int T_STEP = 1; + const int PREV_AZ = 0; // 1贋菴遵翫1T_STEP=1 + const int TWO_HOT = 0; // 罩 +1御罩 -1 у≪潟潟若 #else const int T_STEP = 8; #endif @@ -504,7 +506,16 @@ void set_dcnn_channels(tree_t * restrict ptree, int sideToMove, int ply, float * m -= 14; if ( m < 0 ) m += 28; // 0..13 -> 14..27 } - set_dcnn_data(data, base+m, yy,xx); + + if ( TWO_HOT ) { + if ( m < 14 ) { + set_dcnn_data(data, base+m , yy,xx, +1.0f); + } else { + set_dcnn_data(data, base+m-14, yy,xx, +0.01f); + } + } else { + set_dcnn_data(data, base+m, yy,xx); + } } base += add_base; @@ -562,7 +573,23 @@ void set_dcnn_channels(tree_t * restrict ptree, int sideToMove, int ply, float * } } -// if ( T_STEP == 1 ) base += (28 + 14 + 3) * (6 - 1); + if ( T_STEP==1 && PREV_AZ ) { + int ret_z = get_previous_move_from_pos(ptree, ply); + int b0 = ret_z / 100; + int a0 = ret_z - b0 * 100; + int x = a0 / 10; + int y = a0 - x*10; + x = 9 - x; // 0<=x<=8 + y = y - 1; // 0<=y<=8 + if ( flip ) { + y = B_SIZE - y -1; + x = B_SIZE - x -1; + } + if ( ptree->nrep > 0 ) set_dcnn_data( data, base, y,x); + PRT("ret_z=%d,b0=%d,a0=%d,x=%d,y=%d\n",ret_z,b0,a0,x,y); + } + + if ( T_STEP == 1 ) base += (28 + 14 + 3) * (6 - 1); #ifdef USE_POLICY2187 /* nnet.cpp уュ劫彰fill篁ュфс28絽吾罧17fill荐4528+10=38絽吾1+6=7 fill @@ -796,6 +823,13 @@ float get_network_policy_value(tree_t * restrict ptree, int sideToMove, int ply, set_dcnn_channels(ptree, sideToMove, ply, data); // if ( 1 || ply==1 ) { prt_dcnn_data_table((float(*)[B_SIZE][B_SIZE])data); } // if ( 1 && ptree->nrep+ply==101+3 ) { int sum=0; int i; for (i=0;inrep); } + if ( 0 ) { + FILE *fp = fopen("nninput.bin","ab"); + if ( fp ) { + for (int i=0;ichild_num; unsigned int * restrict pmove = ptree->move_last[0]; @@ -1395,7 +1429,7 @@ int get_dlshogi_policy_id(int bz, int az, int tk, int nf) { if ( dx > 0 ) dir = 0; if ( dx < 0 ) dir = 4; } else { - if ( abs(dx) != abs(dy) ) DEBUG_PRT(""); + if ( abs(dx) != abs(dy) ) DEBUG_PRT("bz=%02x,%02x,%02x,%02x\n",bz,az,tk,nf); if ( dx > 0 && dy > 0 ) dir = 1; if ( dx < 0 && dy > 0 ) dir = 3; if ( dx < 0 && dy < 0 ) dir = 5; @@ -1407,7 +1441,7 @@ int get_dlshogi_policy_id(int bz, int az, int tk, int nf) { int ay = (az & 0xf0) >> 4; int z81 = (ay-1)*9 + (ax-1); int index = z81 + 81*dir + fNari*(81*10) + fDrop*(81*20); - if ( index < 0 || index >= 2187 || dir < 0 ) DEBUG_PRT(""); + if ( index < 0 || index >= 2187 || dir < 0 ) DEBUG_PRT("bz=%02x,%02x,%02x,%02x,index=%d,dir=%d\n",bz,az,tk,nf,index,dir); return index; } @@ -1443,7 +1477,7 @@ void add_dirichlet_noise(float epsilon, float alpha, HASH_SHOGI *phg) CHILD *pc = &phg->child[i]; float score = pc->bias; score = score * (1 - epsilon) + epsilon * eta_a; - { static int count; if ( count++<100 ) PRT("%3d:%8s,noise=%.9f, bias=%.9f -> %.9f\n",i,str_CSA_move(pc->move),eta_a,pc->bias,score); } + { static int count; if ( count++<100 ) PRT("%3d:%8s,noise=%.9f, bias=%.9f -> %.9f,%08x\n",i,str_CSA_move(pc->move),eta_a,pc->bias,score,pc->move); } pc->bias = score; } } diff --git a/src/usi-engine/bona/ysszero.cpp b/src/usi-engine/bona/ysszero.cpp index b3f02a2..3c9681e 100644 --- a/src/usi-engine/bona/ysszero.cpp +++ b/src/usi-engine/bona/ysszero.cpp @@ -48,6 +48,7 @@ int fClearHashAlways = 0; int fUsiInfo = 0; bool fLCB = true; double MinimumKLDGainPerNode = 0; //0.000002; 0х≦, lc0 0.000005 +int KLDGainAverageInterval = 100; bool fResetRootVisit = false; bool fDiffRootVisit = false; bool fSkipOneReply = true; // 1絮≪荅箴< @@ -259,13 +260,16 @@ const int USI_BESTMOVE_LEN = MAX_LEGAL_MOVES*(8+1+5)+10+10; int YssZero_com_turn_start( tree_t * restrict ptree ) { if ( 0 ) { - if ( ptree->nrep > 180 ) { - dLimitSec = 1.8; - } else { - dLimitSec = 4.8; + dLimitSec = 1.7; + if ( ptree->nrep < 144 ) { + if ( root_turn == 1 ) { // denryu-sen, sente 300-2f, gote 600-2f, first 4 moves is dummy + dLimitSec = 10; + } else { + dLimitSec = 6; + } } } - + if ( 0 ) { int ct1 = get_clock(); int i; @@ -454,7 +458,7 @@ void inti_rehash() int IsHashFull() { - if ( hash_shogi_use >= Hash_Shogi_Table_Size*90/100 ) { + if ( (uint64)hash_shogi_use >= (uint64)Hash_Shogi_Table_Size*90/100 ) { PRT("hash full! hash_shogi_use=%d,Hash_Shogi_Table_Size=%d\n",hash_shogi_use,Hash_Shogi_Table_Size); return 1; } @@ -915,12 +919,17 @@ int uct_search_start(tree_t * restrict ptree, int sideToMove, int ply, char *buf const float alpha = 0.15f; // alpha ... Chess = 0.3, Shogi = 0.15, Go = 0.03 if ( fAddNoise ) add_dirichlet_noise(epsilon, alpha, phg); //{ void test_dirichlet_noise(float epsilon, float alpha); test_dirichlet_noise(0.25f, 0.03f); } - PRT("root phg->hash=%" PRIx64 ", child_num=%d\n",phg->hashcode64,phg->child_num); + PRT("root phg->sequence_hash=%" PRIx64 ",pos=%" PRIx64 ", child_num=%d\n",phg->hashcode64,phg->hash64pos,phg->child_num); init_KLDGain_prev_dist_visits_total(phg->games_sum); search_start_ct = get_clock(); + int book_move = get_book_move(ptree,phg); + if ( book_move ) { + return book_move; + } + int thread_max = cfg_num_threads; std::vector ths(thread_max); uct_count = 0; @@ -1321,7 +1330,7 @@ int uct_search_start(tree_t * restrict ptree, int sideToMove, int ply, char *buf static int playouts_dist[M] = { 0 }; search_sum++; playouts_sum += playouts; - int m = playouts / 100; + int m = playouts / KLDGainAverageInterval; if ( m > M-1 ) m = M-1; playouts_dist[m]++; FILE *fp = fopen("playouts_dist.log","a"); @@ -1356,8 +1365,8 @@ int uct_search_start(tree_t * restrict ptree, int sideToMove, int ply, char *buf } - PRT("%.2f sec, c=%d,net_v=%.6f,h_use=%d,po=%d,%.0f/s,ave_ply=%.1f/%d (%d/%d),Noise=%d,g=%d,mt=%d,b=%d\n", - ct,phg->child_num,phg->net_value,hash_shogi_use,playouts,(double)playouts/ct,ave_reached_ply,max_r_ply,ptree->nrep,nVisitCount,fAddNoise,default_gpus.size(),thread_max,cfg_batch_size ); + PRT("%.2f sec, c=%d,net_v=%6.2f%%(%.6f),h_use=%d,po=%d,%.0f/s,ave_ply=%.1f/%d (%d/%d),Noise=%d,g=%d,mt=%d,b=%d\n", + ct,phg->child_num,(phg->net_value+1.0)*50.0,phg->net_value,hash_shogi_use,playouts,(double)playouts/ct,ave_reached_ply,max_r_ply,ptree->nrep,nVisitCount,fAddNoise,default_gpus.size(),thread_max,cfg_batch_size ); return best_move; } @@ -1440,6 +1449,44 @@ if (0) { // if ( move_num==1 ) PRT("move_num=1,ply=%d,%d/%d\n",ply,++count,all); } + + // 罩∽「膣≪х冴蕋茹腱糸уソ + if (0) { +// static tree_t copy_tree; +// copy_tree = *ptree; + int alpha = -30000, beta = +30000; +// ptree->move_last[ply] = ptree->move_last[0]; + for (i=2;i<=ply;i++) ptree->move_last[i] = ptree->move_last[1]; + for (i=0; ichild[i]; + MakeMove( sideToMove, pc->move, ply ); + MOVE_CURR = pc->move; +// ptree->path[ply] = pc->move; + if ( InCheck(sideToMove) ) DEBUG_PRT("escape check err. %2d:%8s(%2d/%3d):selt=%3d\n",ply,str_CSA_move(pc->move),pc->games,phg->games_sum,i); + int now_in_check = InCheck(Flip(sideToMove)); + if ( now_in_check ) { + ptree->nsuc_check[ply+1] = (unsigned char)( ptree->nsuc_check[ply-1] + 1U ); + } else { + ptree->nsuc_check[ply+1] = 0; + } +// int v = -search_quies( ptree, -beta, -alpha, Flip(sideToMove), 2, 1 ); +// int v = -search_quies_aoba( ptree, -INT_MAX, +INT_MAX, Flip(sideToMove), ply+1, 1 ); + int v = -search_quies_aoba( ptree, -beta, -alpha, Flip(sideToMove), ply+1, 1 ); +// print_board(ptree); + PRT("root %3d,ply=%2d:%8s,v=%5d(%4d),%d\n",i,ply,str_CSA_move(pc->move),v,(int)ptree->node_searched,now_in_check); + UnMakeMove( sideToMove, pc->move, ply ); +// out_pv( ptree, int value, int turn, unsigned int time ); + } +// int *p = reinterpret_cast(ptree); +// int *q = reinterpret_cast(©_tree); +// int sz = sizeof(tree_t); +// PRT("sz=%d\n",sz); +// for (i=0;i<170000;i++) if ( *(p+i) != *(q+i) ) PRT("%d,",i); +// *ptree = copy_tree; + +// print_board(ptree); + } + if ( NOT_USE_NN ) { // softmax const float temperature = 1.0f; @@ -1490,7 +1537,7 @@ if (0) { } } -// { PRT("ply=%2d,sideToMove=%d(white=%d),move_num=%3d,v=%.5f\n",ply,sideToMove,white,move_num,v); print_board(ptree); } +// { PRT("ply=%2d,sideToMove=%d(white=%d),move_num=%3d,v=%.5f,eval=%d\n",ply,sideToMove,white,move_num,v,evaluate(ptree,ply,sideToMove)); print_board(ptree); } } if ( sideToMove==white ) v = -v; @@ -1538,7 +1585,7 @@ if (0) { // 泣薈亥(腱糸薈х) // 腥冴хЩ緇薈т薈翫薈х鐔х翫 int d[8] = {+1,-1,+9,-9,+10,-10,+8,-8}; - int j,za[2],ka[2]; + int j,ka[2]; for (j=0;j<8;j++) { ka[(j&1)] = 0; int dz = d[j]; @@ -1550,7 +1597,7 @@ if (0) { if ( (prev%9)==0 && (z%9)==8 ) break; int k = BOARD[z]; if ( k ) { - za[(j&1)] = z; +// za[(j&1)] = z; ka[(j&1)] = k; break; } @@ -1569,7 +1616,7 @@ if (0) { if ( (ipiece&0x07) != 6 && (ipiece&0x07) != 7 && abs((iking%9)-(ito%9))<=1 && abs(iking/9-ito/9)<=1 ) ok = 0; if ( (ipiece&0x07) >= 6 && abs((ifrom%9)-(ito%9))<=1 && abs(ifrom/9-ito/9)<=1 ) ok = 0; // 2剛札筝 if ( ok==0 ) continue; - PRT("ply=%2d,col=%d:%3d:%s %2d -> %2d(%2d,%d),z0=%2d,z1=%2d,k0=%3d,k1=%2d,OU=%2d,bias=%.5f\n",ply,sideToMove,i, string_CSA_move(move).c_str(),ifrom,ito,ipiece,(is_promote!=0),za[0],za[1],ka[0],ka[1],iking,pc->bias); +// PRT("ply=%2d,col=%d:%3d:%s %2d -> %2d(%2d,%d),k0=%3d,k1=%2d,OU=%2d,bias=%.5f\n",ply,sideToMove,i, string_CSA_move(move).c_str(),ifrom,ito,ipiece,(is_promote!=0),ka[0],ka[1],iking,pc->bias); // print_board(ptree); float b = max_bias / 3.0; if ( pc->bias < b ) pc->bias = b; @@ -1591,19 +1638,6 @@ if (0) { } - if ( 0 ) { // 1罩∽「膣≪ - for (i = 0; i < phg->child_num; i++) { - CHILD *pc = &phg->child[i]; - unsigned int move = pc->move; - MakeMove( sideToMove, move, ply ); - int v = -search_quies_aoba( ptree, -INT_MAX, +INT_MAX, Flip(sideToMove), ply+1, 1 ); -// int v = -search_quies( ptree, -INT_MAX, +INT_MAX, Flip(sideToMove), ply+1, 1 ); - UnMakeMove( sideToMove, move, ply ); - PRT("ply=%2d,col=%d:%3d:%08x(%s) v=%5d(%d)\n",ply,sideToMove,i, move,string_CSA_move(move).c_str(),v,(int)ptree->node_searched); -// out_pv( ptree, int value, int turn, unsigned int time ); - } - } - if ( 0 ) { // 茖罩cvalue罐処Τ鐚value800playout緇(紊у違)0菴ャ上 float add[40] = { 0.004, 0.012, 0.016, 0.060, 0.081, 0.106, 0.145, 0.157, 0.152, 0.140, @@ -1706,14 +1740,14 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal PRT("init_v=%9f:w_sum=%7.2f,g_sum=%5d,ply=%2d\n",init_v,phg->win_sum,phg->games_sum,ply); */ bool do_dfpn = false; - if ( ptree->tlp_id == 0 ) { +// if ( ptree->tlp_id == 0 ) { // 鴻阪劫障cャ鐚罩祉сゃ // if ( ply==1 && (phg->mate_bit & MATE_3) ==0 ) { phg->mate_bit |= MATE_3; do_dfpn = true; } if ( phg->games_sum >= 10 && (phg->mate_bit & MATE_DFPN_0)==0 ) { phg->mate_bit |= MATE_DFPN_0; do_dfpn = true; } if ( phg->games_sum >= 100 && (phg->mate_bit & MATE_DFPN_1)==0 ) { phg->mate_bit |= MATE_DFPN_1; do_dfpn = true; } if ( phg->games_sum >= 1000 && (phg->mate_bit & MATE_DFPN_2)==0 ) { phg->mate_bit |= MATE_DFPN_2; do_dfpn = true; } if ( phg->games_sum >= 10000 && (phg->mate_bit & MATE_DFPN_3)==0 ) { phg->mate_bit |= MATE_DFPN_3; do_dfpn = true; } if ( phg->games_sum >= 100000 && (phg->mate_bit & MATE_DFPN_4)==0 ) { phg->mate_bit |= MATE_DFPN_4; do_dfpn = true; } - } +// } if ( is_do_mate3() && do_dfpn ) for (;;) { if ( 0 ) { @@ -1723,11 +1757,12 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal unsigned int move; dfpn(ptree, sideToMove, ply, &move, phg->games_sum*1000); Lock(phg->entry_lock); -// static int count; PRT("%2d:dfpn =%d,games=%d(%d)\n",ply,count++,phg->games_sum*1000,phg->games_sum); +// if ( ply == 2 ) { static int count; PRT("%2d:%6s:dfpn=%3d,games=%d(%d)\n",ply,string_CSA_move(ptree->path[ply-1]).c_str(),count++,phg->games_sum*1000,phg->games_sum); } if ( move == MOVE_NA ) break; MOVE_CURR = move; } - PRT("dfpn mate: ply=%2d,col=%d,move=%08x(%s),games=%d\n",ply,sideToMove, MOVE_CURR,string_CSA_move(MOVE_CURR).c_str(),phg->games_sum); + if ( ply <= 4 ) PRT("dfpn mate: ply=%2d,col=%d,%-6s:move=%s:games=%d,%016" PRIx64 "\n",ply,sideToMove, string_CSA_move(ptree->path[ply-1]).c_str(), string_CSA_move(MOVE_CURR).c_str(),phg->games_sum, ptree->sequence_hash); + if ( ! is_move_valid( ptree, MOVE_CURR, sideToMove ) ) break; // 1荅違3荅違吾潟gユ帥 @@ -1871,6 +1906,7 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal } // PRT("%2d:%s:SHash=%016" PRIx64,ply,str_CSA_move(pc->move),ptree->sequence_hash); MakeMove( sideToMove, pc->move, ply ); + ptree->path[ply] = pc->move; // PRT(" -> %016" PRIx64 "\n",ptree->sequence_hash); MOVE_CURR = pc->move; @@ -1996,7 +2032,7 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal } } - if ( ply >= PLY_MAX-10 ) { PRT("depth over=%d\n",ply); debug(); } + if ( ply >= PLY_MAX-10 ) { DEBUG_PRT("depth over=%d\n",ply); } if ( skip_search == 0 ) { int down_tree = 0; @@ -2015,7 +2051,7 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal create_node(ptree, Flip(sideToMove), ply+1, phg2); } else { // static int count; PRT("has come already? ply=%d,%d\n",ply,++count); //debug(); // 緇? 茲違鴻翫 - if ( force_do_playout == 0 ) down_tree = 1; + down_tree = 1; } if ( fSkipOneReply && phg2->child_num == 1 ) { // PRT("down_tree:ply=%d\n",ply); @@ -2039,7 +2075,7 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal Lock(phg->entry_lock); } // PRT("down_tree=%d,do_playout=%d,ply=%d\n",down_tree,do_playout,ply); - if ( down_tree ) { + if ( down_tree && force_do_playout==0 ) { // down tree const int fVirtualLoss = 1; const int VL_N = 1; @@ -2077,7 +2113,7 @@ double uct_tree(tree_t * restrict ptree, int sideToMove, int ply, int *pExactVal if ( is_use_exact() && pc->exact_value == EX_WIN ) { // 医 *pExactValue = EX_LOSS; - PRT("mate: ply=%2d,col=%d,move=%08x(%s)win=%5.2f -> +1.0\n",ply,sideToMove, MOVE_CURR,string_CSA_move(MOVE_CURR).c_str(),win); +// PRT("mate: ply=%2d,col=%d,move=%08x(%s)win=%5.2f -> +1.0\n",ply,sideToMove, MOVE_CURR,string_CSA_move(MOVE_CURR).c_str(),win); win = +1.0; } @@ -2228,10 +2264,15 @@ int getCmdLineParam(int argc, char *argv[]) } #endif if ( strstr(p,"-kldgain") ) { - PRT("MinimumKLDGainPerNode=%f\n",nf); + PRT("MinimumKLDGainPerNode=%.10f\n",nf); MinimumKLDGainPerNode = nf; continue; } + if ( strstr(p,"-kldinterval") ) { + PRT("KLDGainAverageInterval=%d\n",n); + KLDGainAverageInterval = n; + continue; + } if ( strstr(p,"-reset_root_visit") ) { fResetRootVisit = true; PRT("fResetRootVisit=%d\n",fResetRootVisit); @@ -2742,7 +2783,6 @@ std::vector prev_dist_; int prev_dist_visits_total_; bool isKLDGainSmall(tree_t * restrict ptree, int sideToMove) { - const int KLDGainAverageInterval = 100; if ( MinimumKLDGainPerNode <= 0 ) return false; bool ret = false; HASH_SHOGI *phg = HashShogiReadLock(ptree, sideToMove); From 1bb3934cb6319cc5743801267a3a0bc1f7a4633d Mon Sep 17 00:00:00 2001 From: yssaya Date: Fri, 8 Dec 2023 19:00:21 +0900 Subject: [PATCH 5/5] for vs2017 compile err. --- src/usi-engine/Makefile | 2 +- src/usi-engine/bona/proce.cpp | 2 ++ src/usi-engine/msvc/VS2017/leela-zero.vcxproj | 2 ++ src/usi-engine/msvc/VS2017/leela-zero.vcxproj.filters | 6 ++++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/usi-engine/Makefile b/src/usi-engine/Makefile index 49468da..ce38c83 100644 --- a/src/usi-engine/Makefile +++ b/src/usi-engine/Makefile @@ -71,7 +71,7 @@ bases = Network Leela Utils Zobrist GTP Random SMP OpenCL OpenCLScheduler NNCac ifneq ($(CPU_ONLY), 1) bases += iobase xzi err shogibase osi nnet nnet-cpu nnet-ocl nnet-srv opencli nnet-ipc option endif -bases += $(addprefix bona/, data main io proce utility ini attack book makemove unmake time csa valid bitop iterate searchr search quiesrch evaluate swap hash root next movgenex genevasn gencap gennocap gendrop mate1ply rand learn1 learn2 evaldiff problem ponder thread sckt debug mate3 genchk phash dfpn dfpnhash ysszero yss_net pipe) +bases += $(addprefix bona/, data main io proce utility ini attack book makemove unmake time csa valid bitop iterate searchr search quiesrch evaluate swap hash root next movgenex genevasn gencap gennocap gendrop mate1ply rand learn1 learn2 evaldiff problem ponder thread sckt debug mate3 genchk phash dfpn dfpnhash ysszero yss_net pipe r_book) sources = $(addsuffix .cpp, $(bases)) objects = $(addsuffix .o, $(bases)) diff --git a/src/usi-engine/bona/proce.cpp b/src/usi-engine/bona/proce.cpp index 482b2b3..d4a3918 100644 --- a/src/usi-engine/bona/proce.cpp +++ b/src/usi-engine/bona/proce.cpp @@ -1,5 +1,7 @@ // 2019 Team AobaZero // This source code is in the public domain. +#include "../config.h" + #include #include #include diff --git a/src/usi-engine/msvc/VS2017/leela-zero.vcxproj b/src/usi-engine/msvc/VS2017/leela-zero.vcxproj index 4eb62e2..e24fcf0 100644 --- a/src/usi-engine/msvc/VS2017/leela-zero.vcxproj +++ b/src/usi-engine/msvc/VS2017/leela-zero.vcxproj @@ -106,12 +106,14 @@ + + diff --git a/src/usi-engine/msvc/VS2017/leela-zero.vcxproj.filters b/src/usi-engine/msvc/VS2017/leela-zero.vcxproj.filters index 0c7c84c..0488880 100644 --- a/src/usi-engine/msvc/VS2017/leela-zero.vcxproj.filters +++ b/src/usi-engine/msvc/VS2017/leela-zero.vcxproj.filters @@ -362,6 +362,12 @@ Source Files\common + + Source Files\bona + + + Source Files\bona +