cpuDeltaWeight

ConvolutionalLayer.cpuDeltaWeight()

CPUによるδweightの計算

ソース

cpuDeltaWeight() {
    var prev_layer = this.prevLayer;
    var num_rows_cols = this.numRows * this.numCols;
    var prev_num_rows_cols = prev_layer.numRows * prev_layer.numCols;

    // 出力のチャネルに対し
    var weight_idx = 0;
    for (var channel_idx = 0; channel_idx < this.numChannels; channel_idx++) {

        // 入力のチャネルに対し
        for(var prev_channel_idx = 0; prev_channel_idx < prev_layer.numChannels; prev_channel_idx++){

            // フィルターの行に対し
            for (var r2 = 0; r2 < this.filterSize; r2++) {

                // フィルターの列に対し
                for (var c2 = 0; c2 < this.filterSize; c2++) {

                    var delta_w = 0.0;

                    // 出力の行に対し
                    for (var r1 = 0; r1 < this.numRows; r1++) {

                        // 出力の列に対し
                        for (var c1 = 0; c1 < this.numCols; c1++) {

                            var delta_z_idx = channel_idx * num_rows_cols + r1 * (this.numCols | 0) + c1;
                            var prev_y_idx = prev_channel_idx * prev_num_rows_cols + (r1 + r2) * (prev_layer.numCols | 0) + (c1 + c2);

                            // バッチ内のデータに対し
                            for (var batch_idx = 0; batch_idx < miniBatchSize; batch_idx++) {

                                var delta = this.deltaZ.dt[delta_z_idx];
                                if (delta != 0) {

                                    delta_w += delta * prev_layer.y_.dt[prev_y_idx];
                                }

                                delta_z_idx += this.unitSize;
                                prev_y_idx += (prev_layer.unitSize | 0);
                            }
                        }
                    }

                    this.deltaWeight.dt[weight_idx] = delta_w;
                    weight_idx++;
                }
            }
        }
    }
    Assert(weight_idx == this.deltaWeight.dt.length);
}