void AccuracyLayer<Ftype, Btype>::Forward_cpu(const vector<Blob*>& bottom,
    const vector<Blob*>& top) {
  float accuracy = 0.F;
  const Ftype* bottom_data = bottom[0]->cpu_data<Ftype>();
  const Ftype* bottom_label = bottom[1]->cpu_data<Ftype>();
  const int dim = bottom[0]->count() / outer_num_;
  const int num_labels = bottom[0]->shape(label_axis_);
  if (top.size() > 1) {
    nums_buffer_.set_data(0.F);
    top[1]->set_data(0.F);
  }
  std::vector<std::pair<float, int>> bottom_data_vector(num_labels);
  int count = 0;
  for (int i = 0; i < outer_num_; ++i) {
    for (int j = 0; j < inner_num_; ++j) {
      const int label_value = static_cast<int>(bottom_label[i * inner_num_ + j]);
      if (has_ignore_label_ && label_value == ignore_label_) {
        continue;
      }
      if (top.size() > 1) {
        ++nums_buffer_.mutable_cpu_data()[label_value];
      }
      DCHECK_GE(label_value, 0);
      DCHECK_LT(label_value, num_labels);
      // Top-k accuracy
      for (int k = 0; k < num_labels; ++k) {
        bottom_data_vector[k] = std::make_pair(
            static_cast<float>(bottom_data[i * dim + k * inner_num_ + j]), k);
      }

      std::partial_sort(
          bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_,
          bottom_data_vector.end(), std::greater<std::pair<float, int>>());

      // check if true label is in top k predictions
      for (int k = 0; k < top_k_; k++) {
        if (bottom_data_vector[k].second == label_value) {
          accuracy += 1.F;
          if (top.size() > 1) {
            Ftype* top_label = top[1]->mutable_cpu_data<Ftype>();
            top_label[label_value] = top_label[label_value] + 1.;
          }
          break;
        }
      }
      ++count;
    }
  }

  top[0]->mutable_cpu_data<Ftype>()[0] = accuracy / count;
  if (top.size() > 1) {
    for (int i = 0; i < top[1]->count(); ++i) {
      const float num = nums_buffer_.cpu_data()[i];
      Ftype* top_label = top[1]->mutable_cpu_data<Ftype>();
      top_label[i] = num == 0.F ? 0. : top_label[i] / num;
    }
  }
  // Accuracy layer should not be used as a loss function.
}
示例#2
0
void ArgMaxLayer<Dtype, MItype, MOtype>::Forward_cpu(
       const vector<Blob<MItype>*>& bottom,
       const vector<Blob<MOtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = top[0]->mutable_cpu_data();
  int_tp dim, axis_dist;
  if (has_axis_) {
    dim = bottom[0]->shape(axis_);
    // Distance between values of axis in blob
    axis_dist = bottom[0]->count(axis_) / dim;
  } else {
    dim = bottom[0]->count(1);
    axis_dist = 1;
  }
  int_tp num = bottom[0]->count() / dim;
  vector<std::pair<Dtype, int_tp> > bottom_data_vector(dim);
  for (int_tp i = 0; i < num; ++i) {
    for (int_tp j = 0; j < dim; ++j) {
      bottom_data_vector[j] = make_pair(
        bottom_data[(i / axis_dist * dim + j) * axis_dist + i % axis_dist], j);
    }
    std::partial_sort(
        bottom_data_vector.begin(), bottom_data_vector.begin() + top_k_,
        bottom_data_vector.end(), std::greater<std::pair<Dtype, int_tp> >());
    for (int_tp j = 0; j < top_k_; ++j) {
      if (out_max_val_) {
        if (has_axis_) {
          // Produces max_val per axis
          top_data[(i / axis_dist * top_k_ + j) * axis_dist + i % axis_dist]
            = bottom_data_vector[j].first;
        } else {
          // Produces max_ind and max_val
          top_data[2 * i * top_k_ + j] = bottom_data_vector[j].second;
          top_data[2 * i * top_k_ + top_k_ + j] = bottom_data_vector[j].first;
        }
      } else {
        // Produces max_ind per axis
        top_data[(i / axis_dist * top_k_ + j) * axis_dist + i % axis_dist]
          = bottom_data_vector[j].second;
      }
    }
  }
}