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/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' diff --git a/learn/yss.cpp b/learn/yss.cpp index 598b605..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; @@ -998,8 +1000,15 @@ 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); + 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); } @@ -1007,12 +1016,24 @@ 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); 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; @@ -1215,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 f7892d2..a7c859e 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 **/ @@ -1003,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; @@ -1124,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 ) { @@ -1143,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; @@ -1208,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++; @@ -1227,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; @@ -2750,20 +2791,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 = 1000000; // 100000, 500000 +//const int ZERO_DB_SIZE = 4000000;//3980000; const int MAX_ZERO_MOVES = 513; // 512���ܤ��꤬�ؤ��Ƶͤ�Ǥʤ���С�513���ܤ���꤬�ؤ���̵���ǰ���ʬ���� ZERO_DB zdb_one; @@ -2778,21 +2822,139 @@ 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 = 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 = 32; // aoba_zero.prototxt �� cross_entroy_scale ��Ʊ�����ѹ����뤳�ȡ�layer��name�����ѹ� +//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 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 +// 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 = ZDB_POS_MAX;//46334390;//41352794; // ����ο��ǤϤʤ������̿���ZERO_DB_SIZE; +const int SUMTREE_SIZE = 2*LEAVES - 1; +//int64_t sumtree[SUMTREE_SIZE]; +int64_t *sumtree; + +int add_n = 0; +int capacity = LEAVES; +std::mt19937_64 get_mt_rand; +int over_sumtree_leaves = 0; + +void stree_propagate(int idx, int64_t change) { + int parent = (idx - 1) / 2; + sumtree[parent] += change; + 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, int64_t 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, 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); +} +int64_t stree_total() { + return sumtree[0]; +} +void stree_add(int64_t 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(int64_t s) { + if ( s <= 0 ) DEBUG_PRT(""); + int idx = stree_retrieve(0, s); + return idx; // sumtree[idx] +} +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; +} +void init_stree() { + std::random_device rd; + get_mt_rand.seed(rd()); + for (int i=0; i= LEAVES ) DEBUG_PRT("n=%d,p=%lld",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= 26)*6; +// PRT("%2d:%c:p=%f\n",i,c,p); + char_to_raw_policy[i] = p; + } +} + + void init_zero_kif_db() { if ( pZDBsum == NULL ) pZDBsum = (int*)malloc( ZERO_DB_SIZE * sizeof(int) ); @@ -2802,9 +2964,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 ) { @@ -2956,7 +3121,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); @@ -3055,6 +3221,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++; } @@ -3084,7 +3252,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() { @@ -3203,13 +3372,27 @@ 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]; zero_kif_pos_num = 0; zero_kif_games = 0; @@ -3237,6 +3420,172 @@ 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 v = pZDBplayouts_sum[n]; + int s = pZDBscore_x10k[n]; + int k = 10; // 20 20 20 20 10 10 20 20 20 20 + +// 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; +// 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; + 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); zero_kif_pos_num += p->moves; @@ -3276,6 +3625,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); + + 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]; int *ri_moves = new int[mini_batch]; int i; for (i=0;i= zero_kif_pos_num ) { i--; over_sumtree_leaves++; continue; } + } + rand_try++; // 40��ޤǤ���λ���Ƥ�����10ʬ��1 // 0���ܤ���30���ܤ� 0���ܤ�10ʬ��1��30���ܤ�1, n * 9/300 + 30/300 @@ -3793,19 +4503,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]; @@ -3822,6 +4531,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; @@ -3881,7 +4598,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; @@ -3908,7 +4624,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]; @@ -3988,13 +4704,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�Ĥ�Ϳ����ɬ�פ����뤬�� @@ -4260,6 +4990,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"; @@ -4294,14 +5025,52 @@ void start_zero_train(int *p_argc, char ***p_argv ) // const char sNet[] = "/home/yss/shogi/learn/20220904_061307_256x20b_ave_book_softmax_from_20220831_152345/_iter_1600000.caffemodel"; // 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/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���ɤ߹���dzؽ���Ƴ������� // 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; // �ɲä��줿����� @@ -4319,15 +5088,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; @@ -4337,7 +5109,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���褴�Ȥdzؽ������10000����8000�ʤɤ˸��餹����������®�٤�®�����뤿�� FILE *fp = fopen("reduce.txt","r"); @@ -4356,14 +5128,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 = 800000*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�� @@ -4410,7 +5181,8 @@ nLoop = 800000*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]); 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/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 +dlshogiと1手100playoutで。dlshogiはplayoutが指定可能なように改造したもの +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) 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/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 ) } +//���O�̎w�����Ֆʐ}������o���B������������ +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; // �ύX��1�����Ȃ��� + } + 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); // ply��1����n�܂� 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; // �ύX��1�����Ȃ��� - } - 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..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 @@ -59,7 +61,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 +493,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 +547,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 +843,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)。2手目△84歩が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の内容が変わってしまうので事前に + } + + 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手前の場所だけを追加する場合に1。T_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が通常、残り17がfill。合計45。28+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 ) { // 勝率補正。valueは楽観的?。初期valueは800playoutした後(最大回数の手の勝率)、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 ) { // スレッド固定だと特定の手にまったく来ないことがある?頓死するのでとりあえず削除。 // 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手詰を選び、連続王手の千日手になるのを避ける @@ -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); 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 +