cpuForward ==================== .. js:function:: ConvolutionalLayer.cpuForward() CPUによる順伝播 ソース ^^^^^^ .. code-block:: js 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++; } } } } }