gradientCheck

Layer.gradientCheck(batch_Y, exp_work, cost, batch_idx, layer_idx)

勾配の計算のチェック

引数:
  • batch_Y (float[]) – 正解の出力
  • exp_work (float[]) – 作業用データ
  • cost (double) – コスト
  • batch_idx (int) – ミニバッチ内のインデックス
  • layer_idx (int) – レイヤーのインデックス

ソース

gradientCheck(batch_Y, exp_work, cost, batch_idx, layer_idx){
    if(! this.prevLayer){
        return;
    }

    var last_layer = net.layers[net.layers.length - 1];
    var last_delta_y_dt = new Float32Array(last_layer.deltaY.dt.length);

    if(this.deltaX){

        var prev_layer = this.prevLayer;

        var idx_list = random.RandomSampling(prev_layer.unitSize, 3);

        for(let i of idx_list){
            var k = batch_idx * prev_layer.unitSize + i;
            var x = prev_layer.y_.dt[k];
            var dx = this.deltaX.dt[k];
            var eps = x * 0.01;

            prev_layer.y_.dt[k] = x - eps;
            var cost1 = net.forwardCost(batch_Y, exp_work, batch_idx, layer_idx, last_delta_y_dt);

            prev_layer.y_.dt[k] = x + eps;
            var cost2 = net.forwardCost(batch_Y, exp_work, batch_idx, layer_idx, last_delta_y_dt);

            var diff = dx * 2 * eps - (cost2 - cost1);
            console.log("delta-X : %f dC:%f eps:%f cost:%f,%f,%f", diff, dx, eps, cost1, cost - cost1, cost2 - cost);

            prev_layer.y_.dt[k] = x;
        }
    }

    if(this.deltaBias){

        net.paramGradientCheck("bias", this.bias.dt, this.deltaBias.dt, batch_Y, exp_work, cost, batch_idx, layer_idx, last_delta_y_dt);
    }

    if(this.deltaWeight){

        net.paramGradientCheck("weight", this.weight.dt, this.deltaWeight.dt, batch_Y, exp_work, cost, batch_idx, layer_idx, last_delta_y_dt);
    }
}