From: Yangqing Jia Date: Mon, 11 Nov 2013 19:40:31 +0000 (-0800) Subject: added infogain loss layer X-Git-Tag: submit/tizen/20180823.020014~874^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f0bfdd036e4e97c9659b0529bc06b95d8cd6671;p=platform%2Fupstream%2Fcaffeonacl.git added infogain loss layer --- diff --git a/include/caffe/vision_layers.hpp b/include/caffe/vision_layers.hpp index 2e24bef..2290f0f 100644 --- a/include/caffe/vision_layers.hpp +++ b/include/caffe/vision_layers.hpp @@ -345,6 +345,29 @@ class MultinomialLogisticLossLayer : public Layer { // const bool propagate_down, vector*>* bottom); }; +template +class InfogainLossLayer : public Layer { + public: + explicit InfogainLossLayer(const LayerParameter& param) + : Layer(param), infogain_() {} + virtual void SetUp(const vector*>& bottom, + vector*>* top); + + protected: + // The loss layer will do nothing during forward - all computation are + // carried out in the backward pass. + virtual void Forward_cpu(const vector*>& bottom, + vector*>* top) { return; } + virtual void Forward_gpu(const vector*>& bottom, + vector*>* top) { return; } + virtual Dtype Backward_cpu(const vector*>& top, + const bool propagate_down, vector*>* bottom); + // virtual Dtype Backward_gpu(const vector*>& top, + // const bool propagate_down, vector*>* bottom); + + Blob infogain_; +}; + // SoftmaxWithLossLayer is a layer that implements softmax and then computes // the loss - it is preferred over softmax + multinomiallogisticloss in the diff --git a/src/caffe/layer_factory.cpp b/src/caffe/layer_factory.cpp index 178607f..b663cb2 100644 --- a/src/caffe/layer_factory.cpp +++ b/src/caffe/layer_factory.cpp @@ -33,6 +33,8 @@ Layer* GetLayer(const LayerParameter& param) { return new EuclideanLossLayer(param); } else if (type == "im2col") { return new Im2colLayer(param); + } else if (type == "infogain_loss") { + return new InfogainLossLayer(param); } else if (type == "innerproduct") { return new InnerProductLayer(param); } else if (type == "lrn") { diff --git a/src/caffe/layers/loss_layer.cu b/src/caffe/layers/loss_layer.cu index 0a6f5ee..ac05ba4 100644 --- a/src/caffe/layers/loss_layer.cu +++ b/src/caffe/layers/loss_layer.cu @@ -6,6 +6,7 @@ #include "caffe/layer.hpp" #include "caffe/vision_layers.hpp" #include "caffe/util/math_functions.hpp" +#include "caffe/util/io.hpp" using std::max; @@ -17,7 +18,7 @@ template void MultinomialLogisticLossLayer::SetUp( const vector*>& bottom, vector*>* 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(top->size(), 0) << "Loss Layer takes no output."; CHECK_EQ(bottom[0]->num(), bottom[1]->num()) << "The data and label should have the same number."; CHECK_EQ(bottom[1]->channels(), 1); @@ -50,6 +51,49 @@ Dtype MultinomialLogisticLossLayer::Backward_cpu(const vector template +void InfogainLossLayer::SetUp( + const vector*>& bottom, vector*>* top) { + CHECK_EQ(bottom.size(), 2) << "Loss Layer takes two blobs as input."; + CHECK_EQ(top->size(), 0) << "Loss Layer takes no output."; + CHECK_EQ(bottom[0]->num(), bottom[1]->num()) + << "The data and label should have the same number."; + CHECK_EQ(bottom[1]->channels(), 1); + CHECK_EQ(bottom[1]->height(), 1); + CHECK_EQ(bottom[1]->width(), 1); + BlobProto blob_proto; + ReadProtoFromBinaryFile(this->layer_param_.source(), &blob_proto); + infogain_.FromProto(blob_proto); + CHECK_EQ(infogain_.num(), 1); + CHECK_EQ(infogain_.channels(), 1); + CHECK_EQ(infogain_.height(), infogain_.width()); +}; + + +template +Dtype InfogainLossLayer::Backward_cpu(const vector*>& top, + const bool propagate_down, + vector*>* bottom) { + const Dtype* bottom_data = (*bottom)[0]->cpu_data(); + const Dtype* bottom_label = (*bottom)[1]->cpu_data(); + const Dtype* infogain_mat = infogain_.cpu_data(); + Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff(); + int num = (*bottom)[0]->num(); + int dim = (*bottom)[0]->count() / (*bottom)[0]->num(); + CHECK_EQ(infogain_.height(), dim); + Dtype loss = 0; + for (int i = 0; i < num; ++i) { + int label = static_cast(bottom_label[i]); + for (int j = 0; j < dim; ++j) { + Dtype prob = max(bottom_data[i * dim + j], kLOG_THRESHOLD); + loss -= infogain_mat[label * dim + j] * log(prob); + bottom_diff[i * dim + j] = - infogain_mat[label * dim + j] / prob / num; + } + } + return loss / num; +} + + +template void EuclideanLossLayer::SetUp( const vector*>& bottom, vector*>* top) { CHECK_EQ(bottom.size(), 2) << "Loss Layer takes two blobs as input."; @@ -122,6 +166,7 @@ void AccuracyLayer::Forward_cpu(const vector*>& bottom, } INSTANTIATE_CLASS(MultinomialLogisticLossLayer); +INSTANTIATE_CLASS(InfogainLossLayer); INSTANTIATE_CLASS(EuclideanLossLayer); INSTANTIATE_CLASS(AccuracyLayer);