cpuDeltaX

ConvolutionalLayer.cpuDeltaX()

CPUによるδxの計算

ソース

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

    var prev_y_idx = 0;

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

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

            // 入力の行に対し
            for (var r3 = 0; r3 < prev_layer.numRows; r3++) {

                // 入力の列に対し
                for (var c3 = 0; c3 < prev_layer.numCols; c3++) {

                    var sum = 0.0;

                    // 出力のチャネルに対し
                    for(var channel_idx = 0; channel_idx < this.numChannels; channel_idx++){
                        var delta_z_base = batch_idx * this.unitSize + channel_idx * num_rows_cols;
                        var weight_base = (channel_idx * prev_layer.numChannels + prev_channel_idx) * this.filterSize * this.filterSize;

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

                            // 出力の行
                            var r1 = r3 - r2;

                            if(0 <= r1 && r1 < this.numRows){

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

                                    // 出力の列
                                    var c1 = c3 - c2;

                                    if(0 <= c1 && c1 < this.numCols){

                                        var delta_z_idx = delta_z_base + r1 * this.numCols + c1;
                                        var weight_idx = weight_base + r2 * this.filterSize + c2;
                                        sum += this.deltaZ.dt[delta_z_idx] * this.weight.dt[weight_idx];
                                    }
                                }
                            }
                        }
                    }

                    this.deltaX.dt[prev_y_idx] = sum;
                    prev_y_idx++;
                }
            }
        }
    }
    Assert(prev_y_idx == miniBatchSize * prev_layer.unitSize);
}