Beispiel #1
0
void ReductionLayer<Dtype>::Forward_cpu(
    const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  const Dtype* mult_data = NULL;
  if (sum_multiplier_.count() > 0) {
    mult_data = sum_multiplier_.cpu_data();
  }
  Dtype* top_data = top[0]->mutable_cpu_data();
  for (int i = 0; i < num_; ++i) {
    switch (op_) {
    case ReductionParameter_ReductionOp_SUM:
    case ReductionParameter_ReductionOp_MEAN:
      *top_data = caffe_cpu_dot(dim_, mult_data, bottom_data);
      break;
    case ReductionParameter_ReductionOp_ASUM:
      *top_data = caffe_cpu_asum(dim_, bottom_data);
      break;
    case ReductionParameter_ReductionOp_SUMSQ:
      *top_data = caffe_cpu_dot(dim_, bottom_data, bottom_data);
      break;
    default:
      LOG(FATAL) << "Unknown reduction op: "
          << ReductionParameter_ReductionOp_Name(op_);
    }
    bottom_data += dim_;
    ++top_data;
  }
  if (coeff_ != Dtype(1)) {
    // Reset the top_data pointer.
    top_data = top[0]->mutable_cpu_data();
    caffe_scal(num_, coeff_, top_data);
  }
}
 void TestForward(ReductionParameter_ReductionOp op,
                  float coeff = 1, int_tp axis = 0) {
     LayerParameter layer_param;
     ReductionParameter* reduction_param = layer_param.mutable_reduction_param();
     reduction_param->set_operation(op);
     if (coeff != 1.0) {
         reduction_param->set_coeff(coeff);
     }
     if (axis != 0) {
         reduction_param->set_axis(axis);
     }
     shared_ptr<ReductionLayer<Dtype> > layer(
         new ReductionLayer<Dtype>(layer_param));
     layer->SetUp(this->blob_bottom_vec_, this->blob_top_vec_);
     layer->Forward(this->blob_bottom_vec_, this->blob_top_vec_);
     const Dtype* in_data = this->blob_bottom_->cpu_data();
     const int_tp num = this->blob_bottom_->count(0, axis);
     const int_tp dim = this->blob_bottom_->count(axis);
     for (int_tp n = 0; n < num; ++n) {
         Dtype expected_result = 0;
         for (int_tp d = 0; d < dim; ++d) {
             switch (op) {
             case ReductionParameter_ReductionOp_SUM:
                 expected_result += *in_data;
                 break;
             case ReductionParameter_ReductionOp_MEAN:
                 expected_result += *in_data / dim;
                 break;
             case ReductionParameter_ReductionOp_ASUM:
                 expected_result += fabs(*in_data);
                 break;
             case ReductionParameter_ReductionOp_SUMSQ:
                 expected_result += (*in_data) * (*in_data);
                 break;
             default:
                 LOG(FATAL) << "Unknown reduction op: "
                            << ReductionParameter_ReductionOp_Name(op);
             }
             ++in_data;
         }
         expected_result *= coeff;
         const Dtype computed_result = this->blob_top_->cpu_data()[n];
         EXPECT_FLOAT_EQ(expected_result, computed_result)
                 << "Incorrect result computed with op "
                 << ReductionParameter_ReductionOp_Name(op) << ", coeff " << coeff;
     }
 }
void ReductionLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
    const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) {
  if (!propagate_down[0]) { return; }
  // Get bottom_data, if needed.
  const Dtype* bottom_data = NULL;
  switch (op_) {
  // Operations that don't need bottom_data
  case ReductionParameter_ReductionOp_SUM:
  case ReductionParameter_ReductionOp_MEAN:
    break;
  // Operations that need bottom_data
  case ReductionParameter_ReductionOp_ASUM:
  case ReductionParameter_ReductionOp_SUMSQ:
    bottom_data = bottom[0]->cpu_data();
    break;
  default:
    LOG(FATAL) << "Unknown reduction op: "
        << ReductionParameter_ReductionOp_Name(op_);
  }
  const Dtype* top_diff = top[0]->cpu_diff();
  Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
  for (int i = 0; i < num_; ++i) {
    Dtype bottom_coeff = (*top_diff) * coeff_;
    if (op_ == ReductionParameter_ReductionOp_MEAN) {
      bottom_coeff /= dim_;
    }
    switch (op_) {
    case ReductionParameter_ReductionOp_SUM:
    case ReductionParameter_ReductionOp_MEAN:
      caffe_set(dim_, bottom_coeff, bottom_diff);
      break;
    case ReductionParameter_ReductionOp_ASUM:
      caffe_cpu_sign(dim_, bottom_data, bottom_diff);
      caffe_scal(dim_, bottom_coeff, bottom_diff);
      break;
    case ReductionParameter_ReductionOp_SUMSQ:
      caffe_cpu_scale(dim_, 2 * bottom_coeff, bottom_data, bottom_diff);
      break;
    default:
      LOG(FATAL) << "Unknown reduction op: "
          << ReductionParameter_ReductionOp_Name(op_);
    }
    bottom_data += dim_;
    bottom_diff += dim_;
    ++top_diff;
  }
}