28 #ifndef MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP 29 #define MLPACK_METHODS_ANN_LAYER_GLIMPSE_HPP 52 template<
typename MatType>
55 return arma::mean(arma::mean(input));
65 template<
typename MatType>
66 void Unpooling(
const MatType& input,
const double value, MatType& output)
68 output = arma::zeros<MatType>(input.n_rows, input.n_cols);
69 const double mean = arma::mean(arma::mean(input));
71 output.elem(
arma::find(mean == input, 1)).fill(value);
86 typename InputType = arma::mat,
87 typename OutputType = arma::mat
105 const size_t size = 0,
106 const size_t depth = 3,
107 const size_t scale = 2,
108 const size_t inputWidth = 0,
109 const size_t inputHeight = 0);
117 void Forward(
const InputType& input, OutputType& output);
126 void Backward(
const InputType& ,
127 const OutputType& gy,
132 void Location(
const arma::mat& location) { this->location = location; }
155 size_t const&
Depth()
const {
return depth; }
158 size_t const&
Scale()
const {
return scale; }
168 std::vector<size_t> result(inputDimensions.size(), 0);
169 result[0] = outputWidth;
170 result[1] = outputHeight;
171 for (
size_t i = 2; i < inputDimensions.size(); ++i)
172 result[i] = inputDimensions[i];
179 template<
typename Archive>
180 void serialize(Archive& ar,
const uint32_t );
188 void Transform(arma::mat& w)
192 for (
size_t i = 0, k = 0; i < w.n_elem; ++k)
194 for (
size_t j = 0; j < w.n_cols; ++j, ++i)
206 void Transform(arma::cube& w)
208 for (
size_t i = 0; i < w.n_slices; ++i)
210 arma::mat t = w.slice(i);
223 void Pooling(
const size_t kSize,
224 const InputType& input,
227 const size_t rStep = kSize;
228 const size_t cStep = kSize;
230 for (
size_t j = 0; j < input.n_cols; j += cStep)
232 for (
size_t i = 0; i < input.n_rows; i += rStep)
234 output(i / rStep, j / cStep) += pooling.Pooling(
235 input(arma::span(i, i + rStep - 1), arma::span(j, j + cStep - 1)));
248 const OutputType& error,
251 const size_t rStep = input.n_rows / error.n_rows;
252 const size_t cStep = input.n_cols / error.n_cols;
254 OutputType unpooledError;
255 for (
size_t j = 0; j < input.n_cols; j += cStep)
257 for (
size_t i = 0; i < input.n_rows; i += rStep)
259 const InputType& inputArea = input(arma::span(i, i + rStep - 1),
260 arma::span(j, j + cStep - 1));
262 pooling.Unpooling(inputArea, error(i / rStep, j / cStep),
265 output(arma::span(i, i + rStep - 1),
266 arma::span(j, j + cStep - 1)) += unpooledError;
278 void ReSampling(
const InputType& input, OutputType& output)
280 double wRatio = (double) (input.n_rows - 1) / (
size - 1);
281 double hRatio = (double) (input.n_cols - 1) / (
size - 1);
283 double iWidth = input.n_rows - 1;
284 double iHeight = input.n_cols - 1;
286 for (
size_t y = 0; y <
size; y++)
288 for (
size_t x = 0; x <
size; x++)
290 double ix = wRatio * x;
291 double iy = hRatio * y;
294 double ixNw = std::floor(ix);
295 double iyNw = std::floor(iy);
296 double ixNe = ixNw + 1;
297 double iySw = iyNw + 1;
300 double se = (ix - ixNw) * (iy - iyNw);
301 double sw = (ixNe - ix) * (iy - iyNw);
302 double ne = (ix - ixNw) * (iySw - iy);
303 double nw = (ixNe - ix) * (iySw - iy);
306 output(y, x) = input(iyNw, ixNw) * nw +
307 input(iyNw,
std::min(ixNe, iWidth)) * ne +
308 input(
std::min(iySw, iHeight), ixNw) * sw +
322 void DownwardReSampling(
const InputType& input,
323 const OutputType& error,
326 double iWidth = input.n_rows - 1;
327 double iHeight = input.n_cols - 1;
329 double wRatio = iWidth / (
size - 1);
330 double hRatio = iHeight / (
size - 1);
332 for (
size_t y = 0; y <
size; y++)
334 for (
size_t x = 0; x <
size; x++)
336 double ix = wRatio * x;
337 double iy = hRatio * y;
340 double ixNw = std::floor(ix);
341 double iyNw = std::floor(iy);
342 double ixNe = ixNw + 1;
343 double iySw = iyNw + 1;
346 double se = (ix - ixNw) * (iy - iyNw);
347 double sw = (ixNe - ix) * (iy - iyNw);
348 double ne = (ix - ixNw) * (iySw - iy);
349 double nw = (ixNe - ix) * (iySw - iy);
351 double ograd = error(y, x);
353 output(iyNw, ixNw) = output(iyNw, ixNw) + nw * ograd;
354 output(iyNw,
std::min(ixNe, iWidth)) = output(iyNw,
355 std::min(ixNe, iWidth)) + ne * ograd;
392 arma::Cube<typename InputType::elem_type> inputTemp;
395 arma::Cube<typename OutputType::elem_type> outputTemp;
404 std::vector<OutputType> locationParameter;
407 arma::Cube<typename OutputType::elem_type> gTemp;
417 #include "glimpse_impl.hpp" constexpr auto size(Container const &container) noexcept -> decltype(container.size())
Linear algebra utility functions, generally performed on matrices or vectors.
size_t & OutputWidth()
Modify the output width.
size_t & InputHeight()
Modify the input height.
double Pooling(const MatType &input)
size_t & InputWidth()
Modify input the width.
size_t GlimpseSize() const
Get the used glimpse size (height = width).
The glimpse layer returns a retina-like representation (down-scaled cropped images) of increasing sca...
size_t const & OutputWidth() const
Get the output width.
The core includes that mlpack expects; standard C++ includes and Armadillo.
const std::vector< size_t > OutputDimensions() const
size_t const & OutputHeight() const
Get the output height.
size_t const & InputWidth() const
Get the input width.
size_t const & Scale() const
Get the scale fraction.
size_t const & InputHeight() const
Get the input height.
void Unpooling(const MatType &input, const double value, MatType &output)
size_t & OutputHeight()
Modify the output height.
void Location(const arma::mat &location)
Set the locationthe x and y coordinate of the center of the output glimpse.
GlimpseType< arma::mat, arma::mat > Glimpse
size_t const & Depth() const
Get the number of patches to crop per glimpse.
A layer is an abstract class implementing common neural networks operations, such as convolution...
constexpr T const & min(T const &lhs, T const &rhs)
size_t InSize() const
Get the size of the input units.