12 #ifndef MLPACK_METHODS_ANN_LAYER_CONVOLUTION_IMPL_HPP 13 #define MLPACK_METHODS_ANN_LAYER_CONVOLUTION_IMPL_HPP 22 typename ForwardConvolutionRule,
23 typename BackwardConvolutionRule,
24 typename GradientConvolutionRule,
25 typename InputDataType,
26 typename OutputDataType
29 ForwardConvolutionRule,
30 BackwardConvolutionRule,
31 GradientConvolutionRule,
40 typename ForwardConvolutionRule,
41 typename BackwardConvolutionRule,
42 typename GradientConvolutionRule,
43 typename InputDataType,
44 typename OutputDataType
47 ForwardConvolutionRule,
48 BackwardConvolutionRule,
49 GradientConvolutionRule,
55 const size_t kernelWidth,
56 const size_t kernelHeight,
57 const size_t strideWidth,
58 const size_t strideHeight,
61 const size_t inputWidth,
62 const size_t inputHeight,
63 const std::string& paddingType) :
71 std::tuple<size_t, size_t>(padW, padW),
72 std::tuple<size_t, size_t>(padH, padH),
81 typename ForwardConvolutionRule,
82 typename BackwardConvolutionRule,
83 typename GradientConvolutionRule,
84 typename InputDataType,
85 typename OutputDataType
88 ForwardConvolutionRule,
89 BackwardConvolutionRule,
90 GradientConvolutionRule,
96 const size_t kernelWidth,
97 const size_t kernelHeight,
98 const size_t strideWidth,
99 const size_t strideHeight,
100 const std::tuple<size_t, size_t>& padW,
101 const std::tuple<size_t, size_t>& padH,
102 const size_t inputWidth,
103 const size_t inputHeight,
104 const std::string& paddingType) :
107 kernelWidth(kernelWidth),
108 kernelHeight(kernelHeight),
109 strideWidth(strideWidth),
110 strideHeight(strideHeight),
111 padWLeft(
std::get<0>(padW)),
112 padWRight(
std::get<1>(padW)),
113 padHBottom(
std::get<1>(padH)),
114 padHTop(
std::get<0>(padH)),
115 inputWidth(inputWidth),
116 inputHeight(inputHeight),
123 const std::string paddingTypeLow = util::ToLower(paddingType);
125 if (paddingTypeLow ==
"valid")
132 else if (paddingTypeLow ==
"same")
134 InitializeSamePadding();
137 padding =
ann::Padding<>(padWLeft, padWRight, padHTop, padHBottom);
141 typename ForwardConvolutionRule,
142 typename BackwardConvolutionRule,
143 typename GradientConvolutionRule,
144 typename InputDataType,
145 typename OutputDataType
148 ForwardConvolutionRule,
149 BackwardConvolutionRule,
150 GradientConvolutionRule,
155 weight = arma::cube(weights.memptr(), kernelWidth, kernelHeight,
156 outSize * inSize,
false,
false);
157 bias = arma::mat(weights.memptr() + weight.n_elem,
158 outSize, 1,
false,
false);
162 typename ForwardConvolutionRule,
163 typename BackwardConvolutionRule,
164 typename GradientConvolutionRule,
165 typename InputDataType,
166 typename OutputDataType
168 template<
typename eT>
170 ForwardConvolutionRule,
171 BackwardConvolutionRule,
172 GradientConvolutionRule,
175 >
::Forward(
const arma::Mat<eT>& input, arma::Mat<eT>& output)
177 batchSize = input.n_cols;
178 arma::cube inputTemp(
const_cast<arma::Mat<eT>&
>(input).memptr(),
179 inputWidth, inputHeight, inSize * batchSize,
false,
false);
181 if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
183 inputPaddedTemp.set_size(inputTemp.n_rows + padWLeft + padWRight,
184 inputTemp.n_cols + padHTop + padHBottom, inputTemp.n_slices);
186 for (
size_t i = 0; i < inputTemp.n_slices; ++i)
188 padding.
Forward(inputTemp.slice(i), inputPaddedTemp.slice(i));
192 size_t wConv = ConvOutSize(inputWidth, kernelWidth, strideWidth, padWLeft,
194 size_t hConv = ConvOutSize(inputHeight, kernelHeight, strideHeight, padHTop,
197 output.set_size(wConv * hConv * outSize, batchSize);
198 outputTemp = arma::Cube<eT>(output.memptr(), wConv, hConv,
199 outSize * batchSize,
false,
false);
202 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
203 outSize * batchSize; outMap++)
205 if (outMap != 0 && outMap % outSize == 0)
211 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
213 arma::Mat<eT> convOutput;
215 if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
217 ForwardConvolutionRule::Convolution(inputPaddedTemp.slice(inMap +
218 batchCount * inSize), weight.slice(outMapIdx), convOutput,
219 strideWidth, strideHeight);
223 ForwardConvolutionRule::Convolution(inputTemp.slice(inMap +
224 batchCount * inSize), weight.slice(outMapIdx), convOutput,
225 strideWidth, strideHeight);
228 outputTemp.slice(outMap) += convOutput;
231 outputTemp.slice(outMap) += bias(outMap % outSize);
234 outputWidth = outputTemp.n_rows;
235 outputHeight = outputTemp.n_cols;
239 typename ForwardConvolutionRule,
240 typename BackwardConvolutionRule,
241 typename GradientConvolutionRule,
242 typename InputDataType,
243 typename OutputDataType
245 template<
typename eT>
247 ForwardConvolutionRule,
248 BackwardConvolutionRule,
249 GradientConvolutionRule,
253 const arma::Mat<eT>& ,
const arma::Mat<eT>& gy, arma::Mat<eT>& g)
255 arma::cube mappedError(((arma::Mat<eT>&) gy).memptr(), outputWidth,
256 outputHeight, outSize * batchSize,
false,
false);
258 g.set_size(inputWidth * inputHeight * inSize, batchSize);
259 gTemp = arma::Cube<eT>(g.memptr(), inputWidth, inputHeight,
260 inSize * batchSize,
false,
false);
263 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
264 outSize * batchSize; outMap++)
266 if (outMap != 0 && outMap % outSize == 0)
272 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
274 arma::Mat<eT> output, rotatedFilter;
275 Rotate180(weight.slice(outMapIdx), rotatedFilter);
277 BackwardConvolutionRule::Convolution(mappedError.slice(outMap),
278 rotatedFilter, output, strideWidth, strideHeight);
280 if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
282 gTemp.slice(inMap + batchCount * inSize) += output.submat(padWLeft,
283 padHTop, padWLeft + gTemp.n_rows - 1, padHTop + gTemp.n_cols - 1);
287 gTemp.slice(inMap + batchCount * inSize) += output;
294 typename ForwardConvolutionRule,
295 typename BackwardConvolutionRule,
296 typename GradientConvolutionRule,
297 typename InputDataType,
298 typename OutputDataType
300 template<
typename eT>
302 ForwardConvolutionRule,
303 BackwardConvolutionRule,
304 GradientConvolutionRule,
308 const arma::Mat<eT>& input,
309 const arma::Mat<eT>& error,
310 arma::Mat<eT>& gradient)
312 arma::cube mappedError(((arma::Mat<eT>&) error).memptr(), outputWidth,
313 outputHeight, outSize * batchSize,
false,
false);
314 arma::cube inputTemp(((arma::Mat<eT>&) input).memptr(), inputWidth,
315 inputHeight, inSize * batchSize,
false,
false);
317 gradient.set_size(weights.n_elem, 1);
318 gradientTemp = arma::Cube<eT>(gradient.memptr(), weight.n_rows,
319 weight.n_cols, weight.n_slices,
false,
false);
320 gradientTemp.zeros();
322 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
323 outSize * batchSize; outMap++)
325 if (outMap != 0 && outMap % outSize == 0)
331 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
333 arma::Mat<eT> inputSlice;
334 if (padWLeft != 0 || padWRight != 0 || padHTop != 0 || padHBottom != 0)
336 inputSlice = inputPaddedTemp.slice(inMap + batchCount * inSize);
340 inputSlice = inputTemp.slice(inMap + batchCount * inSize);
343 arma::Mat<eT> deltaSlice = mappedError.slice(outMap);
345 arma::Mat<eT> output;
346 GradientConvolutionRule::Convolution(inputSlice, deltaSlice,
347 output, strideWidth, strideHeight);
349 if (gradientTemp.n_rows < output.n_rows ||
350 gradientTemp.n_cols < output.n_cols)
352 gradientTemp.slice(outMapIdx) += output.submat(0, 0,
353 gradientTemp.n_rows - 1, gradientTemp.n_cols - 1);
355 else if (gradientTemp.n_rows > output.n_rows ||
356 gradientTemp.n_cols > output.n_cols)
358 gradientTemp.slice(outMapIdx).submat(0, 0, output.n_rows - 1,
359 output.n_cols - 1) += output;
363 gradientTemp.slice(outMapIdx) += output;
367 gradient.submat(weight.n_elem + (outMap % outSize), 0, weight.n_elem +
368 (outMap % outSize), 0) = arma::accu(mappedError.slice(outMap));
373 typename ForwardConvolutionRule,
374 typename BackwardConvolutionRule,
375 typename GradientConvolutionRule,
376 typename InputDataType,
377 typename OutputDataType
379 template<
typename Archive>
381 ForwardConvolutionRule,
382 BackwardConvolutionRule,
383 GradientConvolutionRule,
388 ar(CEREAL_NVP(inSize));
389 ar(CEREAL_NVP(outSize));
390 ar(CEREAL_NVP(batchSize));
391 ar(CEREAL_NVP(kernelWidth));
392 ar(CEREAL_NVP(kernelHeight));
393 ar(CEREAL_NVP(strideWidth));
394 ar(CEREAL_NVP(strideHeight));
395 ar(CEREAL_NVP(padWLeft));
396 ar(CEREAL_NVP(padWRight));
397 ar(CEREAL_NVP(padHBottom));
398 ar(CEREAL_NVP(padHTop));
399 ar(CEREAL_NVP(inputWidth));
400 ar(CEREAL_NVP(inputHeight));
401 ar(CEREAL_NVP(outputWidth));
402 ar(CEREAL_NVP(outputHeight));
403 ar(CEREAL_NVP(padding));
405 if (cereal::is_loading<Archive>())
407 weights.set_size((outSize * inSize * kernelWidth * kernelHeight) + outSize,
413 typename ForwardConvolutionRule,
414 typename BackwardConvolutionRule,
415 typename GradientConvolutionRule,
416 typename InputDataType,
417 typename OutputDataType
420 ForwardConvolutionRule,
421 BackwardConvolutionRule,
422 GradientConvolutionRule,
425 >::InitializeSamePadding()
430 size_t totalVerticalPadding = (strideWidth - 1) * inputWidth + kernelWidth -
432 size_t totalHorizontalPadding = (strideHeight - 1) * inputHeight +
433 kernelHeight - strideHeight;
435 padWLeft = totalVerticalPadding / 2;
436 padWRight = totalVerticalPadding - totalVerticalPadding / 2;
437 padHTop = totalHorizontalPadding / 2;
438 padHBottom = totalHorizontalPadding - totalHorizontalPadding / 2;
Linear algebra utility functions, generally performed on matrices or vectors.
Definition: cv.hpp:1
Implementation of the Padding module class.
Definition: layer_types.hpp:87
size_t WeightSize() const
Get size of weights for the layer.
Definition: convolution.hpp:286
Definition: pointer_wrapper.hpp:23
Implementation of the Convolution class.
Definition: convolution.hpp:77
OutputDataType const & Gradient() const
Get the gradient.
Definition: convolution.hpp:215
void serialize(Archive &ar, const uint32_t)
Serialize the layer.
Definition: convolution_impl.hpp:386
void Forward(const arma::Mat< eT > &input, arma::Mat< eT > &output)
Ordinary feed forward pass of a neural network, evaluating the function f(x) by propagating the activ...
Definition: convolution_impl.hpp:175
Convolution()
Create the Convolution object.
Definition: convolution_impl.hpp:34
void Forward(const arma::Mat< eT > &input, arma::Mat< eT > &output)
Ordinary feed forward pass of a neural network, evaluating the function f(x) by propagating the activ...
Definition: padding_impl.hpp:44
void Backward(const arma::Mat< eT > &, const arma::Mat< eT > &gy, arma::Mat< eT > &g)
Ordinary feed backward pass of a neural network, calculating the function f(x) by propagating x backw...
Definition: convolution_impl.hpp:252