Merge pull request #955 from kloudkl/data-layers
authorEvan Shelhamer <shelhamer@imaginarynumber.net>
Wed, 3 Sep 2014 21:04:06 +0000 (14:04 -0700)
committerEvan Shelhamer <shelhamer@imaginarynumber.net>
Wed, 3 Sep 2014 21:04:06 +0000 (14:04 -0700)
Further simplify the data layers and extend the MemoryDataLayer.

- design BaseDataLayer and BasePrefectingDataLayer for simplification
- refactor DataLayer, ImageDataLayer, and WindowDataLayer
- pull up `transform_param` into layer message for de-duplication
- add transformation to MemoryDataLayer

1  2 
include/caffe/data_layers.hpp
include/caffe/loss_layers.hpp
include/caffe/neuron_layers.hpp

@@@ -23,32 -23,55 +23,60 @@@ namespace caffe 
  #define HDF5_DATA_DATASET_NAME "data"
  #define HDF5_DATA_LABEL_NAME "label"
  
-  * @brief Provides data to the Net from a LevelDB or LMDB.
-  *
-  * TODO: DataLayer, ImageDataLayer, and WindowDataLayer all have the
-  * same basic structure and a lot of duplicated code.
 +/**
++ * @brief Provides base for data layers that feed blobs to the Net.
 + *
 + * TODO(dox): thorough documentation for Forward and proto params.
 + */
  template <typename Dtype>
- class DataLayer : public Layer<Dtype>, public InternalThread {
+ class BaseDataLayer : public Layer<Dtype> {
   public:
-   explicit DataLayer(const LayerParameter& param)
-       : Layer<Dtype>(param),
-         data_transformer_(param.data_param().transform_param()) {}
-   virtual ~DataLayer();
+   explicit BaseDataLayer(const LayerParameter& param);
+   virtual ~BaseDataLayer() {}
+   // LayerSetUp: implements common data layer setup functionality, and calls
+   // DataLayerSetUp to do special data layer setup for individual layer types.
+   // This method may not be overridden except by the BasePrefetchingDataLayer.
    virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
+   virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
+       vector<Blob<Dtype>*>* top) {}
  
-   virtual inline LayerParameter_LayerType type() const {
-     return LayerParameter_LayerType_DATA;
-   }
-   virtual inline int ExactNumBottomBlobs() const { return 0; }
-   virtual inline int MinTopBlobs() const { return 1; }
-   virtual inline int MaxTopBlobs() const { return 2; }
+   virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
+       const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {}
+   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
+       const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {}
+   int datum_channels() const { return datum_channels_; }
+   int datum_height() const { return datum_height_; }
+   int datum_width() const { return datum_width_; }
+   int datum_size() const { return datum_size_; }
  
   protected:
+   TransformationParameter transform_param_;
+   DataTransformer<Dtype> data_transformer_;
+   int datum_channels_;
+   int datum_height_;
+   int datum_width_;
+   int datum_size_;
+   Blob<Dtype> data_mean_;
+   const Dtype* mean_;
+   Caffe::Phase phase_;
+   bool output_labels_;
+ };
+ template <typename Dtype>
+ class BasePrefetchingDataLayer :
+     public BaseDataLayer<Dtype>, public InternalThread {
+  public:
+   explicit BasePrefetchingDataLayer(const LayerParameter& param)
+       : BaseDataLayer<Dtype>(param) {}
+   virtual ~BasePrefetchingDataLayer() {}
+   // LayerSetUp: implements common data layer setup functionality, and calls
+   // DataLayerSetUp to do special data layer setup for individual layer types.
+   // This method may not be overridden.
+   void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+       vector<Blob<Dtype>*>* top);
    virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
    virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
@@@ -74,23 -115,8 +120,13 @@@ class DataLayer : public BasePrefetchin
    MDB_txn* mdb_txn_;
    MDB_cursor* mdb_cursor_;
    MDB_val mdb_key_, mdb_value_;
-   int datum_channels_;
-   int datum_height_;
-   int datum_width_;
-   int datum_size_;
-   Blob<Dtype> prefetch_data_;
-   Blob<Dtype> prefetch_label_;
-   Blob<Dtype> data_mean_;
-   bool output_labels_;
-   Caffe::Phase phase_;
  };
  
 +/**
 + * @brief Provides data to the Net generated by a Filler.
 + *
 + * TODO(dox): thorough documentation for Forward and proto params.
 + */
  template <typename Dtype>
  class DummyDataLayer : public Layer<Dtype> {
   public:
@@@ -195,19 -211,13 +231,18 @@@ class HDF5OutputLayer : public Layer<Dt
    Blob<Dtype> label_blob_;
  };
  
 +/**
 + * @brief Provides data to the Net from image files.
 + *
 + * TODO(dox): thorough documentation for Forward and proto params.
 + */
  template <typename Dtype>
- class ImageDataLayer : public Layer<Dtype>, public InternalThread {
+ class ImageDataLayer : public BasePrefetchingDataLayer<Dtype> {
   public:
    explicit ImageDataLayer(const LayerParameter& param)
-       : Layer<Dtype>(param),
-         data_transformer_(param.image_data_param().transform_param()) {}
+       : BasePrefetchingDataLayer<Dtype>(param) {}
    virtual ~ImageDataLayer();
-   virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+   virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
  
    virtual inline LayerParameter_LayerType type() const {
    virtual inline int ExactNumTopBlobs() const { return 2; }
  
   protected:
-   virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
-       vector<Blob<Dtype>*>* top);
-   virtual void 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, vector<Blob<Dtype>*>* bottom) {}
-   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
-       const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {}
+   shared_ptr<Caffe::RNG> prefetch_rng_;
    virtual void ShuffleImages();
-   virtual void CreatePrefetchThread();
-   virtual void JoinPrefetchThread();
    virtual void InternalThreadEntry();
  
-   DataTransformer<Dtype> data_transformer_;
-   shared_ptr<Caffe::RNG> prefetch_rng_;
    vector<std::pair<std::string, int> > lines_;
    int lines_id_;
-   int datum_channels_;
-   int datum_height_;
-   int datum_width_;
-   int datum_size_;
-   Blob<Dtype> prefetch_data_;
-   Blob<Dtype> prefetch_label_;
-   Blob<Dtype> data_mean_;
-   Caffe::Phase phase_;
  };
  
 -/* MemoryDataLayer
 -*/
 +/**
 + * @brief Provides data to the Net from memory.
 + *
 + * TODO(dox): thorough documentation for Forward and proto params.
 + */
  template <typename Dtype>
- class MemoryDataLayer : public Layer<Dtype> {
+ class MemoryDataLayer : public BaseDataLayer<Dtype> {
   public:
    explicit MemoryDataLayer(const LayerParameter& param)
-       : Layer<Dtype>(param) {}
-   virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+       : BaseDataLayer<Dtype>(param), has_new_data_(false) {}
+   virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
  
    virtual inline LayerParameter_LayerType type() const {
   protected:
    virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
-   virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
-       const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {}
-   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
-       const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) {}
  
+   int batch_size_;
    Dtype* data_;
    Dtype* labels_;
-   int datum_channels_;
-   int datum_height_;
-   int datum_width_;
-   int datum_size_;
-   int batch_size_;
    int n_;
    int pos_;
+   Blob<Dtype> added_data_;
+   Blob<Dtype> added_label_;
+   bool has_new_data_;
  };
  
 +/**
 + * @brief Provides data to the Net from windows of images files, specified
 + *        by a window data file.
 + *
 + * TODO(dox): thorough documentation for Forward and proto params.
 + */
  template <typename Dtype>
- class WindowDataLayer : public Layer<Dtype>, public InternalThread {
+ class WindowDataLayer : public BasePrefetchingDataLayer<Dtype> {
   public:
    explicit WindowDataLayer(const LayerParameter& param)
-       : Layer<Dtype>(param) {}
+       : BasePrefetchingDataLayer<Dtype>(param) {}
    virtual ~WindowDataLayer();
-   virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
+   virtual void DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
        vector<Blob<Dtype>*>* top);
  
    virtual inline LayerParameter_LayerType type() const {
Simple merge
Simple merge