評価パラメタ (3)

前回示した表を見て、少し気になったこと。
KPP/KKPの値が、玉の存在する位置では必ず0になっていると思っていたが、そうなっていない場所もある。同じ場所に複数の駒が存在することはできないので、玉と玉以外の駒が同じ場所にある局面を学習する機会は存在しない。つまり、そのような駒の位置関係に対する評価パラメタνのdJ/dνは0の筈である。0に初期化された状態で学習を開始して、常にdJ/dν=0のνがどうして0以外の値を持っているのだろうか?

ソースを読み直して、勘違いをしていたことに気付いた。
KPP/KKPの値を実際に更新している処理は、learn2.cのrparam()である。

rparam( short *pv, float dv, int istep )
{
  int v;

  istep += brand();
  istep += brand() - 1;
  v      = *pv;

  if      ( v > 0 ) { dv -= (float)FV_PENALTY; }
  else if ( v < 0 ) { dv += (float)FV_PENALTY; }

  if      ( dv >= 0.0 && v <= SHRT_MAX - istep ) { v += istep; }
  else if ( dv <= 0.0 && v >= SHRT_MIN + istep ) { v -= istep; }
  else { out_warning( "A fvcoef parameter is out of bounce.\n" ); }

  *pv = (short)v;
}

ここで、*pvが現在使用している評価パラメタ値、dvがdJ/dνの値である。よく見ると、dvが0でも値が更新(v += istep)されている。これを見落としていた。このようになっていても、学習の繰り返しの中でパラメタ値が増え続けていく訳ではない。パラメタがプラスに更新されると、次回のstepではdvがFV_PENALTY(= 0.5/32)だけ減らされている。学習機会がない、もしくは非常に少ないパラメタの場合にはdvが小さいので、これによってdvがマイナスになり、今度は逆方向に更新(v -= istep)されるからである。
istepは各stepで割り当てられるパラメタ更新量である。学習を実行するコマンド引数のnstepとして、30, 50あるいは100を指定した場合、以下のように各回のistep値が与えられる。

 30: 8, 8, 7, 4, 2, 1
 50: 8, 8, 8, 8, 8, 5, 3, 1, 1
100: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 3, 2, 1

実際には、brand()関数(ランダムに0または1を返す)を二回使用して、istepに±1の範囲で揺らぎを持たせている。
それにしても何故、dJ/dν=0のときに値を更新しているのだろう?