#include #include "caffe/layers/euclidean_loss_layer.hpp" #include "caffe/util/math_functions.hpp" namespace caffe { template void EuclideanLossLayer::Reshape( const vector*>& bottom, const vector*>& top) { LossLayer::Reshape(bottom, top); CHECK_EQ(bottom[0]->count(1), bottom[1]->count(1)) << "Inputs must have the same dimension."; diff_.ReshapeLike(*bottom[0]); } template void EuclideanLossLayer::Forward_cpu(const vector*>& bottom, const vector*>& top) { int count = bottom[0]->count(); caffe_sub( count, bottom[0]->cpu_data(), bottom[1]->cpu_data(), diff_.mutable_cpu_data()); Dtype dot = caffe_cpu_dot(count, diff_.cpu_data(), diff_.cpu_data()); Dtype loss = dot / bottom[0]->num() / Dtype(2); top[0]->mutable_cpu_data()[0] = loss; } template void EuclideanLossLayer::Backward_cpu(const vector*>& top, const vector& propagate_down, const vector*>& bottom) { for (int i = 0; i < 2; ++i) { if (propagate_down[i]) { const Dtype sign = (i == 0) ? 1 : -1; const Dtype alpha = sign * top[0]->cpu_diff()[0] / bottom[i]->num(); caffe_cpu_axpby( bottom[i]->count(), // count alpha, // alpha diff_.cpu_data(), // a Dtype(0), // beta bottom[i]->mutable_cpu_diff()); // b } } } #ifdef CPU_ONLY STUB_GPU(EuclideanLossLayer); #endif INSTANTIATE_CLASS(EuclideanLossLayer); REGISTER_LAYER_CLASS(EuclideanLoss); } // namespace caffe