Add root_folder to ImageDataLayer
authorSergio <sguada@gmail.com>
Tue, 7 Oct 2014 18:19:16 +0000 (11:19 -0700)
committerSergio <sguada@gmail.com>
Thu, 16 Oct 2014 00:03:07 +0000 (17:03 -0700)
Makefile
include/caffe/net.hpp
src/caffe/data_transformer.cpp
src/caffe/layers/data_layer.cpp
src/caffe/layers/image_data_layer.cpp
src/caffe/layers/window_data_layer.cpp
src/caffe/net.cpp
src/caffe/proto/caffe.proto
src/caffe/util/io.cpp

index 26d5964..393fe18 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -281,6 +281,12 @@ ifeq ($(USE_CUDNN), 1)
        COMMON_FLAGS += -DUSE_CUDNN
 endif
 
+TIMING ?= 0
+# Timing Flag
+ifneq ($(TIMING), 0)
+       COMMON_FLAGS += -DTIMING
+endif
+
 # CPU-only configuration
 ifeq ($(CPU_ONLY), 1)
        OBJS := $(PROTO_OBJS) $(CXX_OBJS)
index 1d06dc4..879f474 100644 (file)
@@ -11,6 +11,9 @@
 #include "caffe/common.hpp"
 #include "caffe/layer.hpp"
 #include "caffe/proto/caffe.pb.h"
+#ifdef TIMING
+#include "caffe/util/benchmark.hpp"
+#endif
 
 namespace caffe {
 
@@ -76,9 +79,16 @@ class Net {
   void Reshape();
 
   Dtype ForwardBackward(const vector<Blob<Dtype>* > & bottom) {
+    #ifdef TIMING
+    Timer timer;
+    timer.Start();
+    #endif
     Dtype loss;
     Forward(bottom, &loss);
     Backward();
+    #ifdef TIMING
+    LOG(INFO) << "ForwardBackward Time: " << timer.MilliSeconds() << "ms.";
+    #endif
     return loss;
   }
 
index 8f14599..023396c 100644 (file)
@@ -193,8 +193,7 @@ void DataTransformer<Dtype>::Transform(const cv::Mat& cv_img,
   CHECK_LE(width, img_width);
   CHECK_GE(num, 1);
 
-  CHECK(cv_img.depth() == CV_8U || cv_img.depth() == CV_8S) <<
-      "Image data type must be unsigned or signed byte";
+  CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte";
 
   const int crop_size = param_.crop_size();
   const Dtype scale = param_.scale();
@@ -238,22 +237,19 @@ void DataTransformer<Dtype>::Transform(const cv::Mat& cv_img,
       h_off = (img_height - crop_size) / 2;
       w_off = (img_width - crop_size) / 2;
     }
-    cv::Rect roi(h_off, w_off, crop_size, crop_size);
+    cv::Rect roi(w_off, h_off, crop_size, crop_size);
     cv_cropped_img = cv_img(roi);
   } else {
     CHECK_EQ(img_height, height);
     CHECK_EQ(img_width, width);
   }
-  
-  // if (do_mirror) {
-  //   cv::flip(cv_cropped_img, cv_cropped_img, 1);
-  // }
+
   CHECK(cv_cropped_img.data);
 
   Dtype* transformed_data = transformed_blob->mutable_cpu_data();
   int top_index;
   for (int h = 0; h < height; ++h) {
-    const char* ptr = cv_cropped_img.ptr<char>(h);
+    const uchar* ptr = cv_cropped_img.ptr<uchar>(h);
     int img_index = 0;
     for (int w = 0; w < width; ++w) {
       for (int c = 0; c < img_channels; ++c) {
index 95c5427..95604e5 100644 (file)
@@ -8,7 +8,9 @@
 #include "caffe/dataset_factory.hpp"
 #include "caffe/layer.hpp"
 #include "caffe/proto/caffe.pb.h"
+#ifdef TIMING
 #include "caffe/util/benchmark.hpp"
+#endif
 #include "caffe/util/io.hpp"
 #include "caffe/util/math_functions.hpp"
 #include "caffe/util/rng.hpp"
@@ -82,8 +84,13 @@ void DataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
 // This function is used to create a thread that prefetches the data.
 template <typename Dtype>
 void DataLayer<Dtype>::InternalThreadEntry() {
+  #ifdef TIMING
   Timer batch_timer;
   batch_timer.Start();
+  float read_time = 0;
+  float trans_time = 0;
+  Timer timer;
+  #endif
   CHECK(this->prefetch_data_.count());
   CHECK(this->transformed_data_.count());
   Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
@@ -93,9 +100,6 @@ void DataLayer<Dtype>::InternalThreadEntry() {
     top_label = this->prefetch_label_.mutable_cpu_data();
   }
   const int batch_size = this->layer_param_.data_param().batch_size();
-  float read_time = 0;
-  float trans_time = 0;
-  Timer timer;
   for (int item_id = 0; item_id < batch_size; ++item_id) {
     timer.Start();
     // get a blob
@@ -105,31 +109,36 @@ void DataLayer<Dtype>::InternalThreadEntry() {
     if (datum.encoded()) {
        cv_img = DecodeDatumToCVMat(datum);
     }
+    #ifdef TIMING
     read_time += timer.MilliSeconds();
     timer.Start();
+    #endif
 
     // Apply data transformations (mirror, scale, crop...)
     int offset = this->prefetch_data_.offset(item_id);
     this->transformed_data_.set_cpu_data(top_data + offset);
     if (datum.encoded()) {
-      this->data_transformer_.Transform(cv_img, &(this->transformed_data_));  
+      this->data_transformer_.Transform(cv_img, &(this->transformed_data_));
     } else {
       this->data_transformer_.Transform(datum, &(this->transformed_data_));
     }
-    
     if (this->output_labels_) {
       top_label[item_id] = datum.label();
     }
+    #ifdef TIMING
     trans_time += timer.MilliSeconds();
+    #endif
     // go to the next iter
     ++iter_;
     if (iter_ == dataset_->end()) {
       iter_ = dataset_->begin();
     }
   }
-  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
-  DLOG(INFO) << "Read time: " << read_time << "ms.";
-  DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #ifdef TIMING
+  LOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
+  LOG(INFO) << "Read time: " << read_time << "ms.";
+  LOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #endif
 }
 
 INSTANTIATE_CLASS(DataLayer);
index 6749311..0abcd88 100644 (file)
@@ -6,7 +6,9 @@
 
 #include "caffe/data_layers.hpp"
 #include "caffe/layer.hpp"
+#ifdef TIMING
 #include "caffe/util/benchmark.hpp"
+#endif
 #include "caffe/util/io.hpp"
 #include "caffe/util/math_functions.hpp"
 #include "caffe/util/rng.hpp"
@@ -24,6 +26,7 @@ void ImageDataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
   const int new_height = this->layer_param_.image_data_param().new_height();
   const int new_width  = this->layer_param_.image_data_param().new_width();
   const bool is_color  = this->layer_param_.image_data_param().is_color();
+  string root_folder = this->layer_param_.image_data_param().root_folder();
 
   CHECK((new_height == 0 && new_width == 0) ||
       (new_height > 0 && new_width > 0)) << "Current implementation requires "
@@ -57,7 +60,7 @@ void ImageDataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
     lines_id_ = skip;
   }
   // Read an image, and use it to initialize the top blob.
-  cv::Mat cv_img = ReadImageToCVMat(lines_[lines_id_].first,
+  cv::Mat cv_img = ReadImageToCVMat(root_folder + lines_[lines_id_].first,
                                     new_height, new_width, is_color);
   const int channels = cv_img.channels();
   const int height = cv_img.rows;
@@ -92,8 +95,13 @@ void ImageDataLayer<Dtype>::ShuffleImages() {
 // This function is used to create a thread that prefetches the data.
 template <typename Dtype>
 void ImageDataLayer<Dtype>::InternalThreadEntry() {
+  #ifdef TIMING
   Timer batch_timer;
   batch_timer.Start();
+  float read_time = 0;
+  float trans_time = 0;
+  Timer timer;
+  #endif
   CHECK(this->prefetch_data_.count());
   CHECK(this->transformed_data_.count());
   Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
@@ -103,28 +111,32 @@ void ImageDataLayer<Dtype>::InternalThreadEntry() {
   const int new_height = image_data_param.new_height();
   const int new_width = image_data_param.new_width();
   const bool is_color = image_data_param.is_color();
+  string root_folder = image_data_param.root_folder();
 
   // datum scales
   const int lines_size = lines_.size();
-  float read_time = 0;
-  float trans_time = 0;
-  Timer timer;
   for (int item_id = 0; item_id < batch_size; ++item_id) {
     // get a blob
+    #ifdef TIMING
     timer.Start();
+    #endif
     CHECK_GT(lines_size, lines_id_);
-    cv::Mat cv_img = ReadImageToCVMat(lines_[lines_id_].first,
+    cv::Mat cv_img = ReadImageToCVMat(root_folder + lines_[lines_id_].first,
                                     new_height, new_width, is_color);
     if (!cv_img.data) {
       continue;
     }
+    #ifdef TIMING
     read_time += timer.MilliSeconds();
     timer.Start();
+    #endif
     // Apply transformations (mirror, crop...) to the image
     int offset = this->prefetch_data_.offset(item_id);
     this->transformed_data_.set_cpu_data(top_data + offset);
     this->data_transformer_.Transform(cv_img, &(this->transformed_data_));
+    #ifdef TIMING
     trans_time += timer.MilliSeconds();
+    #endif
 
     top_label[item_id] = lines_[lines_id_].second;
     // go to the next iter
@@ -138,9 +150,11 @@ void ImageDataLayer<Dtype>::InternalThreadEntry() {
       }
     }
   }
-  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
-  DLOG(INFO) << "Read time: " << read_time << "ms.";
-  DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #ifdef TIMING
+  LOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
+  LOG(INFO) << "Read time: " << read_time << "ms.";
+  LOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #endif
 }
 
 INSTANTIATE_CLASS(ImageDataLayer);
index 47e0fb2..8e65615 100644 (file)
@@ -13,7 +13,9 @@
 #include "caffe/common.hpp"
 #include "caffe/data_layers.hpp"
 #include "caffe/layer.hpp"
+#ifdef TIMING
 #include "caffe/util/benchmark.hpp"
+#endif
 #include "caffe/util/io.hpp"
 #include "caffe/util/math_functions.hpp"
 #include "caffe/util/rng.hpp"
@@ -193,8 +195,13 @@ template <typename Dtype>
 void WindowDataLayer<Dtype>::InternalThreadEntry() {
   // At each iteration, sample N windows where N*p are foreground (object)
   // windows and N*(1-p) are background (non-object) windows
+  #ifdef TIMING
   Timer batch_timer;
   batch_timer.Start();
+  float read_time = 0;
+  float trans_time = 0;
+  Timer timer;
+  #endif
   Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
   Dtype* top_label = this->prefetch_label_.mutable_cpu_data();
   const Dtype scale = this->layer_param_.window_data_param().scale();
@@ -221,14 +228,13 @@ void WindowDataLayer<Dtype>::InternalThreadEntry() {
   const int num_samples[2] = { batch_size - num_fg, num_fg };
 
   int item_id = 0;
-  float read_time = 0;
-  float trans_time = 0;
-  Timer timer;
   // sample from bg set then fg set
   for (int is_fg = 0; is_fg < 2; ++is_fg) {
     for (int dummy = 0; dummy < num_samples[is_fg]; ++dummy) {
       // sample a window
+      #ifdef TIMING
       timer.Start();
+      #endif
       const unsigned int rand_index = PrefetchRand();
       vector<float> window = (is_fg) ?
           fg_windows_[rand_index % fg_windows_.size()] :
@@ -245,8 +251,10 @@ void WindowDataLayer<Dtype>::InternalThreadEntry() {
         LOG(ERROR) << "Could not open or find file " << image.first;
         return;
       }
+      #ifdef TIMING
       read_time += timer.MilliSeconds();
       timer.Start();
+      #endif
       const int channels = cv_img.channels();
 
       // crop window out of image and warp it
@@ -364,7 +372,9 @@ void WindowDataLayer<Dtype>::InternalThreadEntry() {
           }
         }
       }
+      #ifdef TIMING
       trans_time += timer.MilliSeconds();
+      #endif
       // get window label
       top_label[item_id] = window[WindowDataLayer<Dtype>::LABEL];
 
@@ -404,9 +414,11 @@ void WindowDataLayer<Dtype>::InternalThreadEntry() {
       item_id++;
     }
   }
-  DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
-  DLOG(INFO) << "Read time: " << read_time << "ms.";
-  DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #ifdef TIMING
+  LOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
+  LOG(INFO) << "Read time: " << read_time << "ms.";
+  LOG(INFO) << "Transform time: " << trans_time << "ms.";
+  #endif
 }
 
 INSTANTIATE_CLASS(WindowDataLayer);
index 5b7152e..c0e5692 100644 (file)
@@ -9,7 +9,9 @@
 #include "caffe/layer.hpp"
 #include "caffe/net.hpp"
 #include "caffe/proto/caffe.pb.h"
+#ifdef TIMING
 #include "caffe/util/benchmark.hpp"
+#endif
 #include "caffe/util/insert_splits.hpp"
 #include "caffe/util/io.hpp"
 #include "caffe/util/math_functions.hpp"
@@ -500,8 +502,10 @@ void Net<Dtype>::GetLearningRateAndWeightDecay() {
 
 template <typename Dtype>
 Dtype Net<Dtype>::ForwardFromTo(int start, int end) {
+  #ifdef TIMING
   Timer timer;
   timer.Start();
+  #endif
   CHECK_GE(start, 0);
   CHECK_LT(end, layers_.size());
   Dtype loss = 0;
@@ -512,7 +516,9 @@ Dtype Net<Dtype>::ForwardFromTo(int start, int end) {
     loss += layer_loss;
     if (debug_info_) { ForwardDebugInfo(i); }
   }
+  #ifdef TIMING
   LOG(INFO) << "Forward time: " << timer.MilliSeconds() << "ms.";
+  #endif
   return loss;
 }
 
@@ -569,8 +575,10 @@ string Net<Dtype>::Forward(const string& input_blob_protos, Dtype* loss) {
 
 template <typename Dtype>
 void Net<Dtype>::BackwardFromTo(int start, int end) {
+  #ifdef TIMING
   Timer timer;
   timer.Start();
+  #endif
   CHECK_GE(end, 0);
   CHECK_LT(start, layers_.size());
   for (int i = start; i >= end; --i) {
@@ -580,7 +588,9 @@ void Net<Dtype>::BackwardFromTo(int start, int end) {
       if (debug_info_) { BackwardDebugInfo(i); }
     }
   }
+  #ifdef TIMING
   LOG(INFO) << "Backward time: " << timer.MilliSeconds() << "ms.";
+  #endif
 }
 
 template <typename Dtype>
index 53db6f7..b602d0e 100644 (file)
@@ -540,6 +540,7 @@ message ImageDataParameter {
   // DEPRECATED. See TransformationParameter. Specify if we want to randomly mirror
   // data.
   optional bool mirror = 6 [default = false];
+  optional string root_folder = 12 [default = ""];
 }
 
 // Message that stores parameters InfogainLossLayer
index 06b9deb..b136bc8 100644 (file)
@@ -150,8 +150,7 @@ bool DecodeDatum(const int height, const int width, const bool is_color,
 }
 
 void CVMatToDatum(const cv::Mat& cv_img, Datum* datum) {
-  CHECK(cv_img.depth() == CV_8U || cv_img.depth() == CV_8S) <<
-      "Image data type must be unsigned or signed byte";
+  CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte";
   datum->set_channels(cv_img.channels());
   datum->set_height(cv_img.rows);
   datum->set_width(cv_img.cols);
@@ -164,7 +163,7 @@ void CVMatToDatum(const cv::Mat& cv_img, Datum* datum) {
   int datum_size = datum_channels * datum_height * datum_width;
   std::string buffer(datum_size, ' ');
   for (int h = 0; h < datum_height; ++h) {
-    const char* ptr = cv_img.ptr<char>(h);
+    const uchar* ptr = cv_img.ptr<uchar>(h);
     int img_index = 0;
     for (int w = 0; w < datum_width; ++w) {
       for (int c = 0; c < datum_channels; ++c) {