similarity index 54%
rename from src/caffe/layers/multinomial_logistic_loss_layer.cu
rename to src/caffe/layers/loss_layer.cu
index 5ffa4accc5029ce847afb66438a4aa4aae1c6e30..0c09a5dbe29f79d4d26cd5cbba0b2e939ff225a7 100644 (file)
rename from src/caffe/layers/multinomial_logistic_loss_layer.cu
rename to src/caffe/layers/loss_layer.cu
index 5ffa4accc5029ce847afb66438a4aa4aae1c6e30..0c09a5dbe29f79d4d26cd5cbba0b2e939ff225a7 100644 (file)
return loss / num;
}
-// TODO: implement the GPU version
+// TODO: implement the GPU version for multinomial loss
+
+template <typename Dtype>
+void EuclideanLossLayer<Dtype>::SetUp(
+ const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
+ CHECK_EQ(bottom.size(), 2) << "Loss Layer takes two blobs as input.";
+ CHECK_EQ(top->size(), 0) << "Loss Layer takes no as output.";
+ CHECK_EQ(bottom[0]->num(), bottom[1]->num())
+ << "The data and label should have the same number.";
+ CHECK_EQ(bottom[0]->channels(), bottom[1]->channels());
+ CHECK_EQ(bottom[0]->height(), bottom[1]->height());
+ CHECK_EQ(bottom[0]->width(), bottom[1]->width());
+ difference_.Reshape(bottom[0]->num(), bottom[0]->channels(),
+ bottom[0]->height(), bottom[0]->width());
+}
+
+template <typename Dtype>
+Dtype EuclideanLossLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const bool propagate_down, vector<Blob<Dtype>*>* bottom) {
+ int count = (*bottom)[0]->count();
+ int num = (*bottom)[0]->num();
+ caffe_sub(count, (*bottom)[0]->cpu_data(), (*bottom)[1]->cpu_data(),
+ difference_.mutable_cpu_data());
+ Dtype loss = caffe_cpu_dot(
+ count, difference_.cpu_data(), difference_.cpu_data()) / num / Dtype(2);
+ // Compute the gradient
+ caffe_axpby(count, Dtype(1) / num, difference_.cpu_data(), Dtype(0),
+ (*bottom)[0]->mutable_cpu_diff());
+ return loss;
+}
INSTANTIATE_CLASS(MultinomialLogisticLossLayer);
+INSTANTIATE_CLASS(EuclideanLossLayer);
} // namespace caffe