glimpse.hpp
Go to the documentation of this file.
1 
26 #ifndef MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP
27 #define MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP
28 
29 #include <mlpack/prereqs.hpp>
30 
31 #include "layer_types.hpp"
32 #include <algorithm>
33 
34 namespace mlpack {
35 namespace ann {
36 
37 
38 /*
39  * The mean pooling rule for convolution neural networks. Average all values
40  * within the receptive block.
41  */
43 {
44  public:
45  /*
46  * Return the average value within the receptive block.
47  *
48  * @param input Input used to perform the pooling operation.
49  */
50  template<typename MatType>
51  double Pooling(const MatType& input)
52  {
53  return arma::mean(arma::mean(input));
54  }
55 
56  /*
57  * Set the average value within the receptive block.
58  *
59  * @param input Input used to perform the pooling operation.
60  * @param value The unpooled value.
61  * @param output The unpooled output data.
62  */
63  template<typename MatType>
64  void Unpooling(const MatType& input, const double value, MatType& output)
65  {
66  output = arma::zeros<MatType>(input.n_rows, input.n_cols);
67  const double mean = arma::mean(arma::mean(input));
68 
69  output.elem(arma::find(mean == input, 1)).fill(value);
70  }
71 };
72 
83 template <
84  typename InputDataType = arma::mat,
85  typename OutputDataType = arma::mat
86 >
87 class Glimpse
88 {
89  public:
102  Glimpse(const size_t inSize = 0,
103  const size_t size = 0,
104  const size_t depth = 3,
105  const size_t scale = 2,
106  const size_t inputWidth = 0,
107  const size_t inputHeight = 0);
108 
115  template<typename eT>
116  void Forward(const arma::Mat<eT>&& input, arma::Mat<eT>&& output);
117 
125  template<typename eT>
126  void Backward(const arma::Mat<eT>&& /* input */,
127  arma::Mat<eT>&& gy,
128  arma::Mat<eT>&& g);
129 
131  InputDataType& InputParameter() const {return inputParameter; }
133  InputDataType& InputParameter() { return inputParameter; }
134 
136  OutputDataType& OutputParameter() const {return outputParameter; }
138  OutputDataType& OutputParameter() { return outputParameter; }
139 
141  OutputDataType& Delta() const { return delta; }
143  OutputDataType& Delta() { return delta; }
144 
147  void Location(const arma::mat& location)
148  {
149  this->location = location;
150  }
151 
153  size_t const& InputWidth() const { return inputWidth; }
155  size_t& InputWidth() { return inputWidth; }
156 
158  size_t const& InputHeight() const { return inputHeight; }
160  size_t& InputHeight() { return inputHeight; }
161 
163  size_t const& OutputWidth() const { return outputWidth; }
165  size_t& OutputWidth() { return outputWidth; }
166 
168  size_t const& OutputHeight() const { return outputHeight; }
170  size_t& OutputHeight() { return outputHeight; }
171 
173  bool Deterministic() const { return deterministic; }
175  bool& Deterministic() { return deterministic; }
176 
180  template<typename Archive>
181  void serialize(Archive& ar, const unsigned int /* version */);
182 
183  private:
184  /*
185  * Transform the given input by changing rows to columns.
186  *
187  * @param w The input matrix used to perform the transformation.
188  */
189  void Transform(arma::mat& w)
190  {
191  arma::mat t = w;
192 
193  for (size_t i = 0, k = 0; i < w.n_elem; k++)
194  {
195  for (size_t j = 0; j < w.n_cols; j++, i++)
196  {
197  w(k, j) = t(i);
198  }
199  }
200  }
201 
202  /*
203  * Transform the given input by changing rows to columns.
204  *
205  * @param w The input matrix used to perform the transformation.
206  */
207  void Transform(arma::cube& w)
208  {
209  for (size_t i = 0; i < w.n_slices; i++)
210  {
211  arma::mat t = w.slice(i);
212  Transform(t);
213  w.slice(i) = t;
214  }
215  }
216 
224  template<typename eT>
225  void Pooling(const size_t kSize,
226  const arma::Mat<eT>& input,
227  arma::Mat<eT>& output)
228  {
229  const size_t rStep = kSize;
230  const size_t cStep = kSize;
231 
232  for (size_t j = 0; j < input.n_cols; j += cStep)
233  {
234  for (size_t i = 0; i < input.n_rows; i += rStep)
235  {
236  output(i / rStep, j / cStep) += pooling.Pooling(
237  input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)));
238  }
239  }
240  }
241 
249  template<typename eT>
250  void Unpooling(const arma::Mat<eT>& input,
251  const arma::Mat<eT>& error,
252  arma::Mat<eT>& output)
253  {
254  const size_t rStep = input.n_rows / error.n_rows;
255  const size_t cStep = input.n_cols / error.n_cols;
256 
257  arma::Mat<eT> unpooledError;
258  for (size_t j = 0; j < input.n_cols; j += cStep)
259  {
260  for (size_t i = 0; i < input.n_rows; i += rStep)
261  {
262  const arma::Mat<eT>& inputArea = input(arma::span(i, i + rStep - 1),
263  arma::span(j, j + cStep - 1));
264 
265  pooling.Unpooling(inputArea, error(i / rStep, j / cStep),
266  unpooledError);
267 
268  output(arma::span(i, i + rStep - 1),
269  arma::span(j, j + cStep - 1)) += unpooledError;
270  }
271  }
272  }
273 
281  template<typename eT>
282  void ReSampling(const arma::Mat<eT>& input, arma::Mat<eT>& output)
283  {
284  double wRatio = (double) (input.n_rows - 1) / (size - 1);
285  double hRatio = (double) (input.n_cols - 1) / (size - 1);
286 
287  double iWidth = input.n_rows - 1;
288  double iHeight = input.n_cols - 1;
289 
290  for (size_t y = 0; y < size; y++)
291  {
292  for (size_t x = 0; x < size; x++)
293  {
294  double ix = wRatio * x;
295  double iy = hRatio * y;
296 
297  // Get the 4 nearest neighbors.
298  double ixNw = std::floor(ix);
299  double iyNw = std::floor(iy);
300  double ixNe = ixNw + 1;
301  double iySw = iyNw + 1;
302 
303  // Get surfaces to each neighbor.
304  double se = (ix - ixNw) * (iy - iyNw);
305  double sw = (ixNe - ix) * (iy - iyNw);
306  double ne = (ix - ixNw) * (iySw - iy);
307  double nw = (ixNe - ix) * (iySw - iy);
308 
309  // Calculate the weighted sum.
310  output(y, x) = input(iyNw, ixNw) * nw +
311  input(iyNw, std::min(ixNe, iWidth)) * ne +
312  input(std::min(iySw, iHeight), ixNw) * sw +
313  input(std::min(iySw, iHeight), std::min(ixNe, iWidth)) * se;
314  }
315  }
316  }
317 
326  template<typename eT>
327  void DownwardReSampling(const arma::Mat<eT>& input,
328  const arma::Mat<eT>& error,
329  arma::Mat<eT>& output)
330  {
331  double iWidth = input.n_rows - 1;
332  double iHeight = input.n_cols - 1;
333 
334  double wRatio = iWidth / (size - 1);
335  double hRatio = iHeight / (size - 1);
336 
337  for (size_t y = 0; y < size; y++)
338  {
339  for (size_t x = 0; x < size; x++)
340  {
341  double ix = wRatio * x;
342  double iy = hRatio * y;
343 
344  // Get the 4 nearest neighbors.
345  double ixNw = std::floor(ix);
346  double iyNw = std::floor(iy);
347  double ixNe = ixNw + 1;
348  double iySw = iyNw + 1;
349 
350  // Get surfaces to each neighbor.
351  double se = (ix - ixNw) * (iy - iyNw);
352  double sw = (ixNe - ix) * (iy - iyNw);
353  double ne = (ix - ixNw) * (iySw - iy);
354  double nw = (ixNe - ix) * (iySw - iy);
355 
356  double ograd = error(y, x);
357 
358  output(iyNw, ixNw) = output(iyNw, ixNw) + nw * ograd;
359  output(iyNw, std::min(ixNe, iWidth)) = output(iyNw,
360  std::min(ixNe, iWidth)) + ne * ograd;
361  output(std::min(iySw, iHeight), ixNw) = output(std::min(iySw, iHeight),
362  ixNw) + sw * ograd;
363  output(std::min(iySw, iHeight), std::min(ixNe, iWidth)) = output(
364  std::min(iySw, iHeight), std::min(ixNe, iWidth)) + se * ograd;
365  }
366  }
367  }
368 
370  size_t inSize;
371 
373  size_t size;
374 
376  size_t depth;
377 
379  size_t scale;
380 
382  size_t inputWidth;
383 
385  size_t inputHeight;
386 
388  size_t outputWidth;
389 
391  size_t outputHeight;
392 
394  OutputDataType delta;
395 
397  InputDataType inputParameter;
398 
400  OutputDataType outputParameter;
401 
403  size_t inputDepth;
404 
406  arma::cube inputTemp;
407 
409  arma::cube outputTemp;
410 
412  arma::mat location;
413 
415  MeanPoolingRule pooling;
416 
418  std::vector<arma::mat> locationParameter;
419 
421  arma::cube gTemp;
422 
424  bool deterministic;
425 }; // class GlimpseLayer
426 
427 } // namespace ann
428 } // namespace mlpack
429 
430 // Include implementation.
431 #include "glimpse_impl.hpp"
432 
433 #endif
InputDataType & InputParameter() const
Get the input parameter.
Definition: glimpse.hpp:131
size_t & InputHeight()
Modify the input height.
Definition: glimpse.hpp:160
size_t const & OutputHeight() const
Get the output height.
Definition: glimpse.hpp:168
.hpp
Definition: add_to_po.hpp:21
double Pooling(const MatType &input)
Definition: glimpse.hpp:51
The core includes that mlpack expects; standard C++ includes and Armadillo.
OutputDataType & OutputParameter() const
Get the output parameter.
Definition: glimpse.hpp:136
size_t & InputWidth()
Modify input the width.
Definition: glimpse.hpp:155
OutputDataType & Delta() const
Get the detla.
Definition: glimpse.hpp:141
void Unpooling(const MatType &input, const double value, MatType &output)
Definition: glimpse.hpp:64
InputDataType & InputParameter()
Modify the input parameter.
Definition: glimpse.hpp:133
size_t & OutputWidth()
Modify the output width.
Definition: glimpse.hpp:165
size_t const & InputWidth() const
Get the input width.
Definition: glimpse.hpp:153
OutputDataType & Delta()
Modify the delta.
Definition: glimpse.hpp:143
OutputDataType & OutputParameter()
Modify the output parameter.
Definition: glimpse.hpp:138
size_t const & InputHeight() const
Get the input height.
Definition: glimpse.hpp:158
bool & Deterministic()
Modify the value of the deterministic parameter.
Definition: glimpse.hpp:175
void Location(const arma::mat &location)
Set the locationthe x and y coordinate of the center of the output glimpse.
Definition: glimpse.hpp:147
The glimpse layer returns a retina-like representation (down-scaled cropped images) of increasing sca...
Definition: glimpse.hpp:87
size_t const & OutputWidth() const
Get the output width.
Definition: glimpse.hpp:163
bool Deterministic() const
Get the value of the deterministic parameter.
Definition: glimpse.hpp:173
size_t & OutputHeight()
Modify the output height.
Definition: glimpse.hpp:170