14 #ifndef MLPACK_METHODS_ANN_LAYER_GLIMPSE_IMPL_HPP 15 #define MLPACK_METHODS_ANN_LAYER_GLIMPSE_IMPL_HPP 23 template <
typename InputDataType,
typename OutputDataType>
29 const size_t inputWidth,
30 const size_t inputHeight) :
35 inputWidth(inputWidth),
36 inputHeight(inputHeight),
45 template<
typename InputDataType,
typename OutputDataType>
48 const arma::Mat<eT>& input, arma::Mat<eT>& output)
50 inputTemp = arma::cube(input.colptr(0), inputWidth, inputHeight, inSize);
51 outputTemp = arma::Cube<eT>(size, size, depth * inputTemp.n_slices);
53 location = input.submat(0, 1, 1, 1);
57 locationParameter.push_back(location);
60 inputDepth = inputTemp.n_slices / inSize;
62 for (
size_t inputIdx = 0; inputIdx < inSize; inputIdx++)
64 for (
size_t depthIdx = 0, glimpseSize = size;
65 depthIdx < depth; depthIdx++, glimpseSize *= scale)
67 size_t padSize = std::floor((glimpseSize - 1) / 2);
69 arma::Cube<eT> inputPadded = arma::zeros<arma::Cube<eT> >(
70 inputTemp.n_rows + padSize * 2, inputTemp.n_cols + padSize * 2,
71 inputTemp.n_slices / inSize);
73 inputPadded.tube(padSize, padSize, padSize + inputTemp.n_rows - 1,
74 padSize + inputTemp.n_cols - 1) = inputTemp.subcube(0, 0,
75 inputIdx * inputDepth, inputTemp.n_rows - 1, inputTemp.n_cols - 1,
76 (inputIdx + 1) * inputDepth - 1);
78 size_t h = inputPadded.n_rows - glimpseSize;
79 size_t w = inputPadded.n_cols - glimpseSize;
81 size_t x = std::min(h, (
size_t) std::max(0.0,
82 (location(0, inputIdx) + 1) / 2.0 * h));
83 size_t y = std::min(w, (
size_t) std::max(0.0,
84 (location(1, inputIdx) + 1) / 2.0 * w));
88 for (
size_t j = (inputIdx + depthIdx), paddedSlice = 0;
89 j < outputTemp.n_slices; j += (inSize * depth), paddedSlice++)
91 outputTemp.slice(j) = inputPadded.subcube(x, y,
92 paddedSlice, x + glimpseSize - 1, y + glimpseSize - 1,
98 for (
size_t j = (inputIdx + depthIdx * (depth - 1)), paddedSlice = 0;
99 j < outputTemp.n_slices; j += (inSize * depth), paddedSlice++)
101 arma::Mat<eT> poolingInput = inputPadded.subcube(x, y,
102 paddedSlice, x + glimpseSize - 1, y + glimpseSize - 1,
107 Pooling(glimpseSize / size, poolingInput, outputTemp.slice(j));
111 ReSampling(poolingInput, outputTemp.slice(j));
118 for (
size_t i = 0; i < outputTemp.n_slices; ++i)
120 outputTemp.slice(i) = arma::trans(outputTemp.slice(i));
123 output = arma::Mat<eT>(outputTemp.memptr(), outputTemp.n_elem, 1);
125 outputWidth = outputTemp.n_rows;
126 outputHeight = outputTemp.n_cols;
129 template<
typename InputDataType,
typename OutputDataType>
130 template<
typename eT>
132 const arma::Mat<eT>& ,
const arma::Mat<eT>& gy, arma::Mat<eT>& g)
135 arma::Cube<eT> mappedError = arma::zeros<arma::cube>(outputWidth,
138 location = locationParameter.back();
139 locationParameter.pop_back();
141 for (
size_t s = 0, j = 0; s < mappedError.n_slices; s+= gy.n_cols, ++j)
143 for (
size_t i = 0; i < gy.n_cols; ++i)
145 mappedError.slice(s + i) = arma::Mat<eT>(gy.memptr(),
146 outputWidth, outputHeight);
150 gTemp = arma::zeros<arma::cube>(inputTemp.n_rows, inputTemp.n_cols,
153 for (
size_t inputIdx = 0; inputIdx < inSize; inputIdx++)
155 for (
size_t depthIdx = 0, glimpseSize = size;
156 depthIdx < depth; depthIdx++, glimpseSize *= scale)
158 size_t padSize = std::floor((glimpseSize - 1) / 2);
160 arma::Cube<eT> inputPadded = arma::zeros<arma::Cube<eT> >(
161 inputTemp.n_rows + padSize * 2, inputTemp.n_cols +
162 padSize * 2, inputTemp.n_slices / inSize);
164 size_t h = inputPadded.n_rows - glimpseSize;
165 size_t w = inputPadded.n_cols - glimpseSize;
167 size_t x = std::min(h, (
size_t) std::max(0.0,
168 (location(0, inputIdx) + 1) / 2.0 * h));
169 size_t y = std::min(w, (
size_t) std::max(0.0,
170 (location(1, inputIdx) + 1) / 2.0 * w));
174 for (
size_t j = (inputIdx + depthIdx), paddedSlice = 0;
175 j < mappedError.n_slices; j += (inSize * depth), paddedSlice++)
177 inputPadded.subcube(x, y,
178 paddedSlice, x + glimpseSize - 1, y + glimpseSize - 1,
179 paddedSlice) = mappedError.slice(j);
184 for (
size_t j = (inputIdx + depthIdx * (depth - 1)), paddedSlice = 0;
185 j < mappedError.n_slices; j += (inSize * depth), paddedSlice++)
187 arma::Mat<eT> poolingOutput = inputPadded.subcube(x, y,
188 paddedSlice, x + glimpseSize - 1, y + glimpseSize - 1,
193 Unpooling(inputTemp.slice(paddedSlice), mappedError.slice(j),
198 DownwardReSampling(inputTemp.slice(paddedSlice),
199 mappedError.slice(j), poolingOutput);
202 inputPadded.subcube(x, y,
203 paddedSlice, x + glimpseSize - 1, y + glimpseSize - 1,
204 paddedSlice) = poolingOutput;
208 gTemp += inputPadded.tube(padSize, padSize, padSize +
209 inputTemp.n_rows - 1, padSize + inputTemp.n_cols - 1);
214 g = arma::mat(gTemp.memptr(), gTemp.n_elem, 1);
217 template<
typename InputDataType,
typename OutputDataType>
218 template<
typename Archive>
220 Archive& ar,
const uint32_t )
222 ar(CEREAL_NVP(inSize));
223 ar(CEREAL_NVP(size));
224 ar(CEREAL_NVP(depth));
225 ar(CEREAL_NVP(scale));
226 ar(CEREAL_NVP(inputWidth));
227 ar(CEREAL_NVP(inputHeight));
228 ar(CEREAL_NVP(outputWidth));
229 ar(CEREAL_NVP(outputHeight));
230 ar(CEREAL_NVP(location));
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
void Backward(const arma::Mat< eT > &, const arma::Mat< eT > &gy, arma::Mat< eT > &g)
Ordinary feed backward pass of the glimpse layer.
Definition: glimpse_impl.hpp:131
void serialize(Archive &ar, const uint32_t)
Serialize the layer.
Definition: glimpse_impl.hpp:219
Glimpse(const size_t inSize=0, const size_t size=0, const size_t depth=3, const size_t scale=2, const size_t inputWidth=0, const size_t inputHeight=0)
Create the GlimpseLayer object using the specified ratio and rescale parameter.
Definition: glimpse_impl.hpp:24
void Forward(const arma::Mat< eT > &input, arma::Mat< eT > &output)
Ordinary feed forward pass of the glimpse layer.
Definition: glimpse_impl.hpp:47