cpuForward

ConvolutionalLayer.cpuForward()

CPUによる順伝播

ソース

cpuForward() {
    var prev_layer = this.prevLayer;

    var prev_y_dt = prev_layer.y_.dt;
    var z_dt = this.z_.dt;
    var y_dt = this.y_.dt;

    // 出力先
    var output_idx = 0;

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

        // すべての特徴マップに対し
        for (var channel_idx = 0; channel_idx < this.numChannels; channel_idx++) {

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

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

                    var sum = 0.0;
                    var weight_idx = channel_idx * prev_layer.numChannels * this.filterSize * this.filterSize;
                    var prev_y_base = batch_idx * prev_layer.numChannels * prev_layer.numRows * prev_layer.numCols;

                    // 入力のチャネルに対し
                    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 prev_y_idx = prev_y_base + (r1 + r2) * prev_layer.numCols + (c1 + c2);
                                sum += prev_y_dt[prev_y_idx] * this.weight.dt[weight_idx];
                                weight_idx++;
                            }
                        }
                        prev_y_base += prev_layer.numRows * prev_layer.numCols;
                    }

                    var z_val = sum + this.bias.dt[channel_idx];

                    z_dt[output_idx] = z_val;

                    // 活性化関数
                    switch(this.activationFunction){
                    case ActivationFunction.none:
                        y_dt[output_idx] = z_val;
                        break;

                    case ActivationFunction.sigmoid:
                        y_dt[output_idx] =  sigmoid(z_val);
                        break;

                    case ActivationFunction.ReLU:
                        y_dt[output_idx] = (0.0 < z_val ? z_val : 0.0);
                        break;
                    }

                    output_idx++;
                }

            }
        }
    }
}