Mil #5747

Open
wants to merge 8 commits into
from
View
@@ -439,11 +439,11 @@ py$(PROJECT): py
py: $(PY$(PROJECT)_SO) $(PROTO_GEN_PY)
-$(PY$(PROJECT)_SO): $(PY$(PROJECT)_SRC) $(PY$(PROJECT)_HXX) | $(DYNAMIC_NAME)
+$(PY$(PROJECT)_SO): $(PY$(PROJECT)_SRC) $(PY$(PROJECT)_HXX) $(DYNAMIC_NAME)
@ echo CXX/LD -o $@ $<
$(Q)$(CXX) -shared -o $@ $(PY$(PROJECT)_SRC) \
-o $@ $(LINKFLAGS) -l$(PROJECT) $(PYTHON_LDFLAGS) \
- -Wl,-rpath,$(ORIGIN)/../../build/lib
+ -Wl,-rpath,$(ORIGIN)/../../$(BUILD_DIR)/lib
mat$(PROJECT): mat
@@ -498,6 +498,34 @@ class SliceLayer : public Layer<Dtype> {
vector<int> slice_point_;
};
+/* MILLayer
+*/
+template <typename Dtype>
+class MILLayer : public Layer<Dtype> {
+ public:
+ explicit MILLayer(const LayerParameter& param)
+ : Layer<Dtype>(param) {}
+ virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+ virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+ virtual inline const char* type() const { return "MIL"; }
+ virtual inline int ExactNumBottomBlobs() const { return 1; }
+ virtual inline int ExactNumTopBlobs() const { return 1; }
+ protected:
+ virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+ // virtual Dtype Forward_gpu(const vector<Blob<Dtype>*>& bottom,
+ // vector<Blob<Dtype>*>* top);
+ virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
+ // virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
+ // const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
+
+ int channels_, height_, width_, num_images_;
+};
+
+
} // namespace caffe
#endif // CAFFE_COMMON_LAYERS_HPP_
@@ -322,6 +322,42 @@ class WindowDataLayer : public BasePrefetchingDataLayer<Dtype> {
vector<std::pair<std::string, Datum > > image_database_cache_;
};
+
+/**
+ * @brief Uses a text file which specifies the image names, and a hdf5 file for the labels.
+ * Note that each image can have multiple positive labels.
+ *
+ * TODO(dox): thorough documentation for Forward and proto params.
+ */
+template <typename Dtype>
+class MILDataLayer : public BasePrefetchingDataLayer<Dtype> {
+ public:
+ explicit MILDataLayer(const LayerParameter& param)
+ : BasePrefetchingDataLayer<Dtype>(param) {}
+ virtual ~MILDataLayer();
+ virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+
+ virtual inline const char* type() const { return "MILData"; }
+ virtual inline int ExactNumBottomBlobs() const { return 0; }
+ virtual inline int ExactNumTopBlobs() const { return 2; }
+
+ protected:
+ virtual unsigned int PrefetchRand();
+ virtual void InternalThreadEntry();
+ int num_images_;
+ unsigned int counter_;
+ shared_ptr<Caffe::RNG> prefetch_rng_;
+ vector< std::pair<std::string, std::string > > image_database_;
+ hid_t label_file_id_;
+
+ vector<float> mean_value_;
+ Blob<Dtype> label_blob_;
+};
+
+
+
+
} // namespace caffe
#endif // CAFFE_DATA_LAYERS_HPP_
@@ -6,6 +6,7 @@
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/proto/caffe.pb.h"
+#include "opencv2/opencv.hpp"
namespace caffe {
@@ -87,6 +88,18 @@ class DataTransformer {
*/
void Transform(Blob<Dtype>* input_blob, Blob<Dtype>* transformed_blob);
+ /**
+ * @brief Imresizes the image so that the longer side is of length img_size
+ * and flip it if do_mirror is on
+ * @param cv_img
+ * cv::Mat for the image to transform
+ * @param img_size
+ * int, final length of the longer side
+ * @param do_mirror
+ * bool whether to flip or not
+ */
+ cv::Mat Transform_IDL(cv::Mat cv_img, int img_size, bool do_mirror);
+
protected:
/**
* @brief Generates a random integer from Uniform({0, 1, ..., n-1}).
@@ -651,6 +651,25 @@ class SigmoidCrossEntropyLossLayer : public LossLayer<Dtype> {
vector<Blob<Dtype>*> sigmoid_top_vec_;
};
+/* CrossEntropyLossLayer
+*/
+template <typename Dtype>
+class CrossEntropyLossLayer : public LossLayer<Dtype> {
+ public:
+ explicit CrossEntropyLossLayer(const LayerParameter& param)
+ : LossLayer<Dtype>(param) {}
+ virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+
+ protected:
+ virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
+ const vector<Blob<Dtype>*>& top);
+ virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+ const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
+};
+
+
+
// Forward declare SoftmaxLayer for use in SoftmaxWithLossLayer.
template <typename Dtype> class SoftmaxLayer;
@@ -11,6 +11,30 @@
namespace caffe {
template<typename Dtype>
+cv::Mat DataTransformer<Dtype>::Transform_IDL(cv::Mat cv_img, int img_size, bool do_mirror){
+ cv::Size cv_size; //(width, height)
+ if(cv_img.cols > cv_img.rows){
+ cv::Size tmp(img_size, round(cv_img.rows*img_size/cv_img.cols));
+ cv_size = tmp;
+ }
+ else{
+ cv::Size tmp(round(cv_img.cols*img_size/cv_img.rows), img_size);
+ cv_size = tmp;
+ }
+
+ cv::Mat cv_resized_img;
+ cv::resize(cv_img, cv_resized_img,
+ cv_size, 0, 0, cv::INTER_LINEAR);
+
+ // horizontal flip at random
+ if (do_mirror) {
+ cv::flip(cv_resized_img, cv_resized_img, 1);
+ }
+ return cv_resized_img;
+}
+
+
+template<typename Dtype>
DataTransformer<Dtype>::DataTransformer(const TransformationParameter& param,
Phase phase)
: param_(param), phase_(phase) {
@@ -0,0 +1,79 @@
+// Copyright 2014 BVLC and contributors.
+
+#include <algorithm>
+#include <cmath>
+#include <cfloat>
+#include <vector>
+
+#include "caffe/layer.hpp"
+#include "caffe/vision_layers.hpp"
+#include "caffe/util/math_functions.hpp"
+#include "caffe/util/io.hpp"
+
+using std::max;
+
+namespace caffe {
+
+template <typename Dtype>
+void CrossEntropyLossLayer<Dtype>::LayerSetUp(
+ const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
+}
+
+template <typename Dtype>
+void CrossEntropyLossLayer<Dtype>::Forward_cpu(
+ const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
+ const Dtype* bottom_data = bottom[0]->cpu_data();
+ const Dtype* bottom_label = bottom[1]->cpu_data();
+ int count = bottom[0]->count();
+ int num = bottom[0]->num();
+ Dtype loss = 0; Dtype l;
+ for (int i = 0; i < count; ++i) {
+ if(bottom_label[i] != 0){
+ l = -bottom_label[i]*log(max(bottom_data[i],Dtype(0.00001)));
+ loss += l;
+ }
+
+ if(bottom_label[i] != 1){
+ l = -(1-bottom_label[i])*log(max((1-bottom_data[i]),Dtype(0.00001)));
+ loss += l;
+ }
+ CHECK_GE(l, 0.) << "loss is not >= 0, loss: " << l << " bottom_label: " << bottom_label[i] << " bottom_data: " << bottom_data[i];
+ }
+ top[0]->mutable_cpu_data()[0] = loss / count;
+ // LOG(INFO) << "CrossEntropyLossLayer: " << loss / count;
+}
+
+template <typename Dtype>
+void CrossEntropyLossLayer<Dtype>::Backward_cpu(
+ const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down,
+ const vector<Blob<Dtype>*>& bottom) {
+
+ if (propagate_down[1]) {
+ LOG(FATAL) << this->type()
+ << " Layer cannot backpropagate to label inputs.";
+ }
+ if (propagate_down[0]) {
+ const Dtype* bottom_data = bottom[0]->cpu_data();
+ const Dtype* bottom_label = bottom[1]->cpu_data();
+ Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
+ int count = bottom[0]->count();
+ int num = bottom[0]->num();
+ memset(bottom_diff, 0, sizeof(Dtype) * bottom[0]->count());
+ for (int i = 0; i < count; ++i) {
+ Dtype val = 0;
+ if(bottom_label[i] != 0)
+ val = val - bottom_label[i]/max(bottom_data[i], Dtype(0.00001))/count;
+ if(bottom_label[i] != 1)
+ val = val - (-(1-bottom_label[i])/max(1-bottom_data[i], Dtype(0.00001))/count);
+
+ bottom_diff[i] = val;
+ }
+ const Dtype loss_weight = top[0]->cpu_diff()[0];
+ caffe_scal(count, loss_weight, bottom_diff);
+ }
+}
+
+INSTANTIATE_CLASS(CrossEntropyLossLayer);
+REGISTER_LAYER_CLASS(CrossEntropyLoss);
+
+} // namespace caffe
Oops, something went wrong.