#include #include #include "caffe/layers/lifted_struct_similarity_softmax_layer.hpp" #include "caffe/util/math_functions.hpp" namespace caffe { template void LiftedStructSimilaritySoftmaxLossLayer::LayerSetUp(const vector*>& bottom, const vector*>& top) { LossLayer::LayerSetUp(bottom, top); CHECK_EQ(bottom[0]->height(), 1); CHECK_EQ(bottom[0]->width(), 1); CHECK_EQ(bottom[1]->channels(), 1); CHECK_EQ(bottom[1]->height(), 1); CHECK_EQ(bottom[1]->width(), 1); // List of member variables defined in /include/caffe/loss_layers.hpp; // diff_, dist_sq_, summer_vec_, loss_aug_inference_; dist_sq_.Reshape(bottom[0]->num(), 1, 1, 1); dot_.Reshape(bottom[0]->num(), bottom[0]->num(), 1, 1); ones_.Reshape(bottom[0]->num(), 1, 1, 1); // n by 1 vector of ones. for (int i=0; i < bottom[0]->num(); ++i){ ones_.mutable_cpu_data()[i] = Dtype(1); } blob_pos_diff_.Reshape(bottom[0]->channels(), 1, 1, 1); blob_neg_diff_.Reshape(bottom[0]->channels(), 1, 1, 1); } template void LiftedStructSimilaritySoftmaxLossLayer::Forward_cpu(const vector*>& bottom, const vector*>& top) { const int channels = bottom[0]->channels(); for (int i = 0; i < bottom[0]->num(); i++){ dist_sq_.mutable_cpu_data()[i] = caffe_cpu_dot(channels, bottom[0]->cpu_data() + (i*channels), bottom[0]->cpu_data() + (i*channels)); } int M_ = bottom[0]->num(); int N_ = bottom[0]->num(); int K_ = bottom[0]->channels(); const Dtype* bottom_data1 = bottom[0]->cpu_data(); const Dtype* bottom_data2 = bottom[0]->cpu_data(); Dtype dot_scaler(-2.0); caffe_cpu_gemm(CblasNoTrans, CblasTrans, M_, N_, K_, dot_scaler, bottom_data1, bottom_data2, (Dtype)0., dot_.mutable_cpu_data()); // add ||x_i||^2 to all elements in row i for (int i=0; i > label_mat(N_, vector(N_, false)); for (int i=0; icpu_data()[i] == bottom[1]->cpu_data()[j]); } } Dtype margin = this->layer_param_.lifted_struct_sim_softmax_loss_param().margin(); Dtype loss(0.0); num_constraints = Dtype(0.0); const Dtype* bin = bottom[0]->cpu_data(); Dtype* bout = bottom[0]->mutable_cpu_diff(); // zero initialize bottom[0]->mutable_cpu_diff(); for (int i=0; imutable_cpu_data()[0] = loss; } template void LiftedStructSimilaritySoftmaxLossLayer::Backward_cpu(const vector*>& top, const vector& propagate_down, const vector*>& bottom) { const Dtype alpha = top[0]->cpu_diff()[0] / num_constraints / Dtype(2.0); int num = bottom[0]->num(); int channels = bottom[0]->channels(); for (int i = 0; i < num; i++){ Dtype* bout = bottom[0]->mutable_cpu_diff(); caffe_scal(channels, alpha, bout + (i*channels)); } } #ifdef CPU_ONLY STUB_GPU(LiftedStructSimilaritySoftmaxLossLayer); #endif INSTANTIATE_CLASS(LiftedStructSimilaritySoftmaxLossLayer); REGISTER_LAYER_CLASS(LiftedStructSimilaritySoftmaxLoss); } // namespace caffe