MachineIntelligenceCore:NeuralNets
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
MaxPooling.hpp
Go to the documentation of this file.
1 
23 #ifndef SRC_MLNN_POOLING_HPP_
24 #define SRC_MLNN_POOLING_HPP_
25 
26 #include <mlnn/layer/Layer.hpp>
27 
28 namespace mic {
29 namespace mlnn {
30 namespace convolution {
31 
32 
38 template <typename eT=float>
39 class MaxPooling : public mic::mlnn::Layer<eT> {
40 public:
41 
42 
51  MaxPooling(size_t input_height_, size_t input_width_, size_t depth_,
52  size_t window_size_,
53  std::string name_ = "MaxPooling") :
54  Layer<eT>::Layer(input_height_, input_width_, depth_,
55  (input_height_ /window_size_), (input_width_ / window_size_), depth_,
56  LayerTypes::MaxPooling, name_),
57  window_size(window_size_)
58  {
59  // Mapping from input to output - every cell will contain address of input image.
60  m.add("pooling_map", Layer<eT>::outputSize(), 1);
61  };
62 
66  virtual ~MaxPooling() {};
67 
72  virtual void resizeBatch(size_t batch_size_) {
73  // Call base Layer resize.
74  Layer<eT>::resizeBatch(batch_size_);
75 
76  // Reshape pooling mask and map.
77  m["pooling_map"]->resize(Layer<eT>::outputSize(), batch_size_);
78 
79  }
80 
81 
82  void forward(bool test_ = false) {
83  LOG(LTRACE) << "MaxPooling::forward\n";
84 
85  // Get pointer to input batch.
86  mic::types::MatrixPtr<eT> batch_x = s['x'];
87  //std::cout<< "forward batch_x=\n" << (*batch) << std::endl;
88  //std::cout << "forward input x activation: min:" << (*batch_x).minCoeff() <<" max: " << (*batch_x).maxCoeff() << std::endl;
89 
90  // Get pointer to output batch - so the results will be stored!
91  mic::types::MatrixPtr<eT> batch_y = s['y'];
92  // Reset the whole batch.
93  batch_y->setZero();
94 
95  // Get pointer to the mask.
96  mic::types::MatrixPtr<eT> pooling_map = m["pooling_map"];
97  pooling_map->setZero();
98 
99  // TODO: should work for more channels - but requires testing!
100  //assert(input_depth == 1);
101 
102  // Iterate through batch - cannot be done in parallel:
103  // * pooling mask is shared (ok)
104  // * tmp variables storing input samples/channels are multiplied and OMP secured (ok)
105  // * pooling mask and output batch are edited on different addresses - OMP secured (ok)
106  #pragma omp parallel for
107  for (size_t ib = 0; ib < batch_size; ib++) {
108  // Get input sample from batch.
109  mic::types::MatrixPtr<eT> xs = lazyReturnInputSample(batch_x, ib);
110 
111  // Iterate through input/output channels.
112  for (size_t ic=0; ic< input_depth; ic++) {
113  // Get input channel from input sample.
114  mic::types::MatrixPtr<eT> xc = lazyReturnInputChannel(xs, ib, ic);
115 
116  // Iterate through "blocks" in a given channel.
117  for (size_t ih=0, oh=0; ih< input_height; ih+=window_size, oh++) {
118  for (size_t iw=0, ow=0; iw< input_width; iw+=window_size, ow++) {
119 
120  #pragma omp critical
121  {
122  // Get location of max element.
123  size_t maxRow, maxCol;
124  eT max_val = xc->block(ih, iw, window_size, window_size).maxCoeff(&maxRow, &maxCol);
125 
126  //std::cout << "xc->block(ih, iw, window_size, window_size) = " <<xc->block(ih, iw, window_size, window_size) <<std::endl;
127  //std::cout << " maxRow = " << maxRow << " maxCol = "<< maxCol << " max_val = "<< max_val << std::endl;
128 
129  // Calculate "absolute addresses.
130  size_t ia = (ib * Layer<eT>::inputSize()) + ic * input_height * input_width + (iw + maxCol) * input_height + (ih + maxRow);
131  size_t oa = (ib * Layer<eT>::outputSize()) + ic * output_height * output_width + (ow) * output_height + (oh);
132  /*std::cout << " ih = " << ih << " iw = " << iw << " ia = " << ia << std::endl;
133  std::cout << " oh = " << oh << " ow = " << ow << " oa = " << oa << std::endl;*/
134 
135  // Map output to input.
136  (*pooling_map)[oa] = ia;
137 
138  // Copy value to output.
139  (*batch_y)[oa] = max_val;
140  }
141 
142  }//: for width
143  }//: for width
144  }//: for channels
145  }//: for batch
146  LOG(LTRACE) << "MaxPooling::forward end\n";
147  }
148 
152  void backward() {
153  LOG(LTRACE) << "MaxPooling::backward\n";
154 
155  // Get pointer to dy batch.
156  mic::types::MatrixPtr<eT> batch_dy = g['y'];
157 
158  // Get pointer to dx batch.
159  mic::types::MatrixPtr<eT> batch_dx = g['x'];
160  batch_dx->setZero();
161 
162  mic::types::MatrixPtr<eT> pooling_map = m["pooling_map"];
163 
164  // Iterate through batch.
165  #pragma omp parallel for
166  for (size_t oi = 0; oi < batch_size * Layer<eT>::outputSize(); oi++) {
167 
168  // Map outputs to inputs.
169  //std::cout << " oi = " << oi << " (*pooling_map)[oi] = " << (*pooling_map)[oi] << std::endl;
170  (*batch_dx)[(size_t)(*pooling_map)[oi]] = (*batch_dy)[oi];
171 
172  }//: for batch
173 
174  LOG(LTRACE) << "MaxPooling::backward end\n";
175  }
176 
177 
183  void update(eT alpha_, eT decay_ = 0.0f) { }
184 
185  // Unhide the overloaded methods inherited from the template class Layer fields via "using" statement.
186  using Layer<eT>::forward;
187  using Layer<eT>::backward;
188 
189 protected:
190  // Unhide the fields inherited from the template class Layer via "using" statement.
191  using Layer<eT>::g;
192  using Layer<eT>::s;
193  using Layer<eT>::p;
194  using Layer<eT>::m;
195 
196  // Uncover "sizes" for visualization.
203  using Layer<eT>::batch_size;
204 
209 
213  size_t window_size;
214 
215 private:
216  // Friend class - required for using boost serialization.
217  template<typename tmp> friend class mic::mlnn::MultiLayerNeuralNetwork;
218 
219 
224 
225 };
226 
227 } /* namespace convolution */
228 } /* namespace mlnn */
229 } /* namespace mic */
230 
231 #endif /* SRC_MLNN_POOLING_HPP_ */
size_t inputSize()
Returns size (length) of inputs.
Definition: Layer.hpp:255
mic::types::MatrixPtr< eT > lazyReturnInputChannel(mic::types::MatrixPtr< eT > sample_ptr_, size_t sample_number_, size_t channel_number_)
Definition: Layer.hpp:519
Layer performing max pooling.
Definition: MaxPooling.hpp:39
size_t input_depth
Number of channels of the input (e.g. 3 for RGB images).
Definition: Layer.hpp:732
void update(eT alpha_, eT decay_=0.0f)
Definition: MaxPooling.hpp:183
size_t batch_size
Size (length) of (mini)batch.
Definition: Layer.hpp:744
size_t outputSize()
Returns size (length) of outputs.
Definition: Layer.hpp:260
void forward(bool test_=false)
Definition: MaxPooling.hpp:82
virtual void resizeBatch(size_t batch_size_)
Definition: Layer.hpp:199
size_t input_height
Height of the input (e.g. 28 for MNIST).
Definition: Layer.hpp:726
Class representing a multi-layer neural network.
Definition: Layer.hpp:86
LayerTypes
Enumeration of possible layer types.
Definition: Layer.hpp:58
mic::types::MatrixArray< eT > s
States - contains input [x] and output [y] matrices.
Definition: Layer.hpp:753
mic::types::MatrixArray< eT > g
Gradients - contains input [x] and output [y] matrices.
Definition: Layer.hpp:756
virtual void resizeBatch(size_t batch_size_)
Definition: MaxPooling.hpp:72
mic::types::MatrixPtr< eT > lazyReturnInputSample(mic::types::MatrixPtr< eT > batch_ptr_, size_t sample_number_)
Definition: Layer.hpp:460
size_t input_width
Width of the input (e.g. 28 for MNIST).
Definition: Layer.hpp:729
size_t output_height
Number of receptive fields in a single channel - vertical direction.
Definition: Layer.hpp:735
MaxPooling(size_t input_height_, size_t input_width_, size_t depth_, size_t window_size_, std::string name_="MaxPooling")
Definition: MaxPooling.hpp:51
size_t output_width
Number of receptive fields in a single channel - horizontal direction.
Definition: Layer.hpp:738
Contains a template class representing a layer.
mic::types::MatrixArray< eT > m
Memory - a list of temporal parameters, to be used by the derived classes.
Definition: Layer.hpp:762