glimpse.hpp
Go to the documentation of this file.
1 
27 #ifndef MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP
28 #define MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP
29 
30 #include <mlpack/prereqs.hpp>
31 
32 #include "layer_types.hpp"
33 #include <algorithm>
34 
35 namespace mlpack {
36 namespace ann {
37 
38 
39 /*
40  * The mean pooling rule for convolution neural networks. Average all values
41  * within the receptive block.
42  */
44 {
45  public:
46  /*
47  * Return the average value within the receptive block.
48  *
49  * @param input Input used to perform the pooling operation.
50  */
51  template<typename MatType>
52  double Pooling(const MatType& input)
53  {
54  return arma::mean(arma::mean(input));
55  }
56 
57  /*
58  * Set the average value within the receptive block.
59  *
60  * @param input Input used to perform the pooling operation.
61  * @param value The unpooled value.
62  * @param output The unpooled output data.
63  */
64  template<typename MatType>
65  void Unpooling(const MatType& input, const double value, MatType& output)
66  {
67  output = arma::zeros<MatType>(input.n_rows, input.n_cols);
68  const double mean = arma::mean(arma::mean(input));
69 
70  output.elem(arma::find(mean == input, 1)).fill(value);
71  }
72 };
73 
84 template <
85  typename InputDataType = arma::mat,
86  typename OutputDataType = arma::mat
87 >
88 class Glimpse
89 {
90  public:
103  Glimpse(const size_t inSize = 0,
104  const size_t size = 0,
105  const size_t depth = 3,
106  const size_t scale = 2,
107  const size_t inputWidth = 0,
108  const size_t inputHeight = 0);
109 
116  template<typename eT>
117  void Forward(const arma::Mat<eT>& input, arma::Mat<eT>& output);
118 
126  template<typename eT>
127  void Backward(const arma::Mat<eT>& /* input */,
128  const arma::Mat<eT>& gy,
129  arma::Mat<eT>& g);
130 
132  OutputDataType& OutputParameter() const {return outputParameter; }
134  OutputDataType& OutputParameter() { return outputParameter; }
135 
137  OutputDataType& Delta() const { return delta; }
139  OutputDataType& Delta() { return delta; }
140 
143  void Location(const arma::mat& location)
144  {
145  this->location = location;
146  }
147 
149  size_t const& InputWidth() const { return inputWidth; }
151  size_t& InputWidth() { return inputWidth; }
152 
154  size_t const& InputHeight() const { return inputHeight; }
156  size_t& InputHeight() { return inputHeight; }
157 
159  size_t const& OutputWidth() const { return outputWidth; }
161  size_t& OutputWidth() { return outputWidth; }
162 
164  size_t const& OutputHeight() const { return outputHeight; }
166  size_t& OutputHeight() { return outputHeight; }
167 
169  bool Deterministic() const { return deterministic; }
171  bool& Deterministic() { return deterministic; }
172 
174  size_t const& Depth() const { return depth; }
175 
177  size_t const& Scale() const { return scale; }
178 
180  size_t InSize() const { return inSize; }
181 
183  size_t GlimpseSize() const { return size;}
184 
186  size_t InputShape() const
187  {
188  return inSize;
189  }
190 
194  template<typename Archive>
195  void serialize(Archive& ar, const uint32_t /* version */);
196 
197  private:
198  /*
199  * Transform the given input by changing rows to columns.
200  *
201  * @param w The input matrix used to perform the transformation.
202  */
203  void Transform(arma::mat& w)
204  {
205  arma::mat t = w;
206 
207  for (size_t i = 0, k = 0; i < w.n_elem; ++k)
208  {
209  for (size_t j = 0; j < w.n_cols; ++j, ++i)
210  {
211  w(k, j) = t(i);
212  }
213  }
214  }
215 
216  /*
217  * Transform the given input by changing rows to columns.
218  *
219  * @param w The input matrix used to perform the transformation.
220  */
221  void Transform(arma::cube& w)
222  {
223  for (size_t i = 0; i < w.n_slices; ++i)
224  {
225  arma::mat t = w.slice(i);
226  Transform(t);
227  w.slice(i) = t;
228  }
229  }
230 
238  template<typename eT>
239  void Pooling(const size_t kSize,
240  const arma::Mat<eT>& input,
241  arma::Mat<eT>& output)
242  {
243  const size_t rStep = kSize;
244  const size_t cStep = kSize;
245 
246  for (size_t j = 0; j < input.n_cols; j += cStep)
247  {
248  for (size_t i = 0; i < input.n_rows; i += rStep)
249  {
250  output(i / rStep, j / cStep) += pooling.Pooling(
251  input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)));
252  }
253  }
254  }
255 
263  template<typename eT>
264  void Unpooling(const arma::Mat<eT>& input,
265  const arma::Mat<eT>& error,
266  arma::Mat<eT>& output)
267  {
268  const size_t rStep = input.n_rows / error.n_rows;
269  const size_t cStep = input.n_cols / error.n_cols;
270 
271  arma::Mat<eT> unpooledError;
272  for (size_t j = 0; j < input.n_cols; j += cStep)
273  {
274  for (size_t i = 0; i < input.n_rows; i += rStep)
275  {
276  const arma::Mat<eT>& inputArea = input(arma::span(i, i + rStep - 1),
277  arma::span(j, j + cStep - 1));
278 
279  pooling.Unpooling(inputArea, error(i / rStep, j / cStep),
280  unpooledError);
281 
282  output(arma::span(i, i + rStep - 1),
283  arma::span(j, j + cStep - 1)) += unpooledError;
284  }
285  }
286  }
287 
295  template<typename eT>
296  void ReSampling(const arma::Mat<eT>& input, arma::Mat<eT>& output)
297  {
298  double wRatio = (double) (input.n_rows - 1) / (size - 1);
299  double hRatio = (double) (input.n_cols - 1) / (size - 1);
300 
301  double iWidth = input.n_rows - 1;
302  double iHeight = input.n_cols - 1;
303 
304  for (size_t y = 0; y < size; y++)
305  {
306  for (size_t x = 0; x < size; x++)
307  {
308  double ix = wRatio * x;
309  double iy = hRatio * y;
310 
311  // Get the 4 nearest neighbors.
312  double ixNw = std::floor(ix);
313  double iyNw = std::floor(iy);
314  double ixNe = ixNw + 1;
315  double iySw = iyNw + 1;
316 
317  // Get surfaces to each neighbor.
318  double se = (ix - ixNw) * (iy - iyNw);
319  double sw = (ixNe - ix) * (iy - iyNw);
320  double ne = (ix - ixNw) * (iySw - iy);
321  double nw = (ixNe - ix) * (iySw - iy);
322 
323  // Calculate the weighted sum.
324  output(y, x) = input(iyNw, ixNw) * nw +
325  input(iyNw, std::min(ixNe, iWidth)) * ne +
326  input(std::min(iySw, iHeight), ixNw) * sw +
327  input(std::min(iySw, iHeight), std::min(ixNe, iWidth)) * se;
328  }
329  }
330  }
331 
340  template<typename eT>
341  void DownwardReSampling(const arma::Mat<eT>& input,
342  const arma::Mat<eT>& error,
343  arma::Mat<eT>& output)
344  {
345  double iWidth = input.n_rows - 1;
346  double iHeight = input.n_cols - 1;
347 
348  double wRatio = iWidth / (size - 1);
349  double hRatio = iHeight / (size - 1);
350 
351  for (size_t y = 0; y < size; y++)
352  {
353  for (size_t x = 0; x < size; x++)
354  {
355  double ix = wRatio * x;
356  double iy = hRatio * y;
357 
358  // Get the 4 nearest neighbors.
359  double ixNw = std::floor(ix);
360  double iyNw = std::floor(iy);
361  double ixNe = ixNw + 1;
362  double iySw = iyNw + 1;
363 
364  // Get surfaces to each neighbor.
365  double se = (ix - ixNw) * (iy - iyNw);
366  double sw = (ixNe - ix) * (iy - iyNw);
367  double ne = (ix - ixNw) * (iySw - iy);
368  double nw = (ixNe - ix) * (iySw - iy);
369 
370  double ograd = error(y, x);
371 
372  output(iyNw, ixNw) = output(iyNw, ixNw) + nw * ograd;
373  output(iyNw, std::min(ixNe, iWidth)) = output(iyNw,
374  std::min(ixNe, iWidth)) + ne * ograd;
375  output(std::min(iySw, iHeight), ixNw) = output(std::min(iySw, iHeight),
376  ixNw) + sw * ograd;
377  output(std::min(iySw, iHeight), std::min(ixNe, iWidth)) = output(
378  std::min(iySw, iHeight), std::min(ixNe, iWidth)) + se * ograd;
379  }
380  }
381  }
382 
384  size_t inSize;
385 
387  size_t size;
388 
390  size_t depth;
391 
393  size_t scale;
394 
396  size_t inputWidth;
397 
399  size_t inputHeight;
400 
402  size_t outputWidth;
403 
405  size_t outputHeight;
406 
408  OutputDataType delta;
409 
411  OutputDataType outputParameter;
412 
414  size_t inputDepth;
415 
417  arma::cube inputTemp;
418 
420  arma::cube outputTemp;
421 
423  arma::mat location;
424 
426  MeanPoolingRule pooling;
427 
429  std::vector<arma::mat> locationParameter;
430 
432  arma::cube gTemp;
433 
435  bool deterministic;
436 }; // class GlimpseLayer
437 
438 } // namespace ann
439 } // namespace mlpack
440 
441 // Include implementation.
442 #include "glimpse_impl.hpp"
443 
444 #endif
size_t & InputHeight()
Modify the input height.
Definition: glimpse.hpp:156
size_t const & OutputHeight() const
Get the output height.
Definition: glimpse.hpp:164
constexpr auto size(Container const &container) noexcept -> decltype(container.size())
Definition: iterator.hpp:29
Linear algebra utility functions, generally performed on matrices or vectors.
double Pooling(const MatType &input)
Definition: glimpse.hpp:52
The core includes that mlpack expects; standard C++ includes and Armadillo.
size_t GlimpseSize() const
Get the used glimpse size (height = width).
Definition: glimpse.hpp:183
size_t InputShape() const
Get the shape of the input.
Definition: glimpse.hpp:186
typename impl::find< T, U >::type find
Definition: meta.hpp:238
OutputDataType & OutputParameter() const
Get the output parameter.
Definition: glimpse.hpp:132
size_t & InputWidth()
Modify input the width.
Definition: glimpse.hpp:151
OutputDataType & Delta() const
Get the detla.
Definition: glimpse.hpp:137
void Unpooling(const MatType &input, const double value, MatType &output)
Definition: glimpse.hpp:65
size_t & OutputWidth()
Modify the output width.
Definition: glimpse.hpp:161
size_t const & InputWidth() const
Get the input width.
Definition: glimpse.hpp:149
OutputDataType & Delta()
Modify the delta.
Definition: glimpse.hpp:139
size_t InSize() const
Get the size of the input units.
Definition: glimpse.hpp:180
size_t const & Scale() const
Get the scale fraction.
Definition: glimpse.hpp:177
OutputDataType & OutputParameter()
Modify the output parameter.
Definition: glimpse.hpp:134
size_t const & InputHeight() const
Get the input height.
Definition: glimpse.hpp:154
bool & Deterministic()
Modify the value of the deterministic parameter.
Definition: glimpse.hpp:171
void Location(const arma::mat &location)
Set the locationthe x and y coordinate of the center of the output glimpse.
Definition: glimpse.hpp:143
The glimpse layer returns a retina-like representation (down-scaled cropped images) of increasing sca...
Definition: glimpse.hpp:88
size_t const & OutputWidth() const
Get the output width.
Definition: glimpse.hpp:159
bool Deterministic() const
Get the value of the deterministic parameter.
Definition: glimpse.hpp:169
size_t & OutputHeight()
Modify the output height.
Definition: glimpse.hpp:166
constexpr T const & min(T const &lhs, T const &rhs)
Definition: algorithm.hpp:69
size_t const & Depth() const
Get the number of patches to crop per glimpse.
Definition: glimpse.hpp:174