13 #ifndef MLPACK_METHODS_ANN_LAYER_ATROUS_CONVOLUTION_IMPL_HPP 14 #define MLPACK_METHODS_ANN_LAYER_ATROUS_CONVOLUTION_IMPL_HPP 23 typename ForwardConvolutionRule,
24 typename BackwardConvolutionRule,
25 typename GradientConvolutionRule,
26 typename InputDataType,
27 typename OutputDataType
30 ForwardConvolutionRule,
31 BackwardConvolutionRule,
32 GradientConvolutionRule,
41 typename ForwardConvolutionRule,
42 typename BackwardConvolutionRule,
43 typename GradientConvolutionRule,
44 typename InputDataType,
45 typename OutputDataType
48 ForwardConvolutionRule,
49 BackwardConvolutionRule,
50 GradientConvolutionRule,
56 const size_t kernelWidth,
57 const size_t kernelHeight,
58 const size_t strideWidth,
59 const size_t strideHeight,
62 const size_t inputWidth,
63 const size_t inputHeight,
64 const size_t dilationWidth,
65 const size_t dilationHeight,
66 const std::string& paddingType) :
74 std::tuple<size_t, size_t>(padW, padW),
75 std::tuple<size_t, size_t>(padH, padH),
86 typename ForwardConvolutionRule,
87 typename BackwardConvolutionRule,
88 typename GradientConvolutionRule,
89 typename InputDataType,
90 typename OutputDataType
93 ForwardConvolutionRule,
94 BackwardConvolutionRule,
95 GradientConvolutionRule,
100 const size_t outSize,
101 const size_t kernelWidth,
102 const size_t kernelHeight,
103 const size_t strideWidth,
104 const size_t strideHeight,
105 const std::tuple<size_t, size_t>& padW,
106 const std::tuple<size_t, size_t>& padH,
107 const size_t inputWidth,
108 const size_t inputHeight,
109 const size_t dilationWidth,
110 const size_t dilationHeight,
111 const std::string& paddingType) :
114 kernelWidth(kernelWidth),
115 kernelHeight(kernelHeight),
116 strideWidth(strideWidth),
117 strideHeight(strideHeight),
118 inputWidth(inputWidth),
119 inputHeight(inputHeight),
122 dilationWidth(dilationWidth),
123 dilationHeight(dilationHeight)
128 const std::string paddingTypeLow = util::ToLower(paddingType);
130 size_t padWLeft = std::get<0>(padW);
131 size_t padWRight = std::get<1>(padW);
132 size_t padHTop = std::get<0>(padH);
133 size_t padHBottom = std::get<1>(padH);
134 if (paddingTypeLow ==
"valid")
141 else if (paddingTypeLow ==
"same")
143 InitializeSamePadding(padWLeft, padWRight, padHTop, padHBottom);
146 padding =
ann::Padding<>(padWLeft, padWRight, padHTop, padHBottom);
150 typename ForwardConvolutionRule,
151 typename BackwardConvolutionRule,
152 typename GradientConvolutionRule,
153 typename InputDataType,
154 typename OutputDataType
157 ForwardConvolutionRule,
158 BackwardConvolutionRule,
159 GradientConvolutionRule,
164 weight = arma::cube(weights.memptr(), kernelWidth, kernelHeight,
165 outSize * inSize,
false,
false);
166 bias = arma::mat(weights.memptr() + weight.n_elem,
167 outSize, 1,
false,
false);
171 typename ForwardConvolutionRule,
172 typename BackwardConvolutionRule,
173 typename GradientConvolutionRule,
174 typename InputDataType,
175 typename OutputDataType
177 template<
typename eT>
179 ForwardConvolutionRule,
180 BackwardConvolutionRule,
181 GradientConvolutionRule,
184 >
::Forward(
const arma::Mat<eT>& input, arma::Mat<eT>& output)
186 batchSize = input.n_cols;
187 arma::cube inputTemp(
const_cast<arma::Mat<eT>&
>(input).memptr(),
188 inputWidth, inputHeight, inSize * batchSize,
false,
false);
193 inputPaddedTemp.set_size(
198 for (
size_t i = 0; i < inputTemp.n_slices; ++i)
200 padding.
Forward(inputTemp.slice(i), inputPaddedTemp.slice(i));
204 size_t wConv = ConvOutSize(inputWidth, kernelWidth, strideWidth,
206 size_t hConv = ConvOutSize(inputHeight, kernelHeight, strideHeight,
209 output.set_size(wConv * hConv * outSize, batchSize);
210 outputTemp = arma::Cube<eT>(output.memptr(), wConv, hConv,
211 outSize * batchSize,
false,
false);
214 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
215 outSize * batchSize; outMap++)
217 if (outMap != 0 && outMap % outSize == 0)
223 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
225 arma::Mat<eT> convOutput;
230 ForwardConvolutionRule::Convolution(inputPaddedTemp.slice(inMap +
231 batchCount * inSize), weight.slice(outMapIdx), convOutput,
232 strideWidth, strideHeight, dilationWidth, dilationHeight);
236 ForwardConvolutionRule::Convolution(inputTemp.slice(inMap +
237 batchCount * inSize), weight.slice(outMapIdx), convOutput,
238 strideWidth, strideHeight, dilationWidth, dilationHeight);
241 outputTemp.slice(outMap) += convOutput;
244 outputTemp.slice(outMap) += bias(outMap % outSize);
247 outputWidth = outputTemp.n_rows;
248 outputHeight = outputTemp.n_cols;
252 typename ForwardConvolutionRule,
253 typename BackwardConvolutionRule,
254 typename GradientConvolutionRule,
255 typename InputDataType,
256 typename OutputDataType
258 template<
typename eT>
260 ForwardConvolutionRule,
261 BackwardConvolutionRule,
262 GradientConvolutionRule,
266 const arma::Mat<eT>& ,
const arma::Mat<eT>& gy, arma::Mat<eT>& g)
268 arma::cube mappedError(((arma::Mat<eT>&) gy).memptr(), outputWidth,
269 outputHeight, outSize * batchSize,
false,
false);
271 g.set_size(inputWidth * inputHeight * inSize, batchSize);
272 gTemp = arma::Cube<eT>(g.memptr(), inputWidth, inputHeight,
273 inSize * batchSize,
false,
false);
276 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
277 outSize * batchSize; outMap++)
279 if (outMap != 0 && outMap % outSize == 0)
285 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
287 arma::Mat<eT> output, rotatedFilter;
288 Rotate180(weight.slice(outMapIdx), rotatedFilter);
290 BackwardConvolutionRule::Convolution(mappedError.slice(outMap),
291 rotatedFilter, output, strideWidth, strideHeight, dilationWidth,
297 gTemp.slice(inMap + batchCount * inSize) +=
299 padding.
PadWLeft() + gTemp.n_rows - 1,
300 padding.
PadHTop() + gTemp.n_cols - 1);
304 gTemp.slice(inMap + batchCount * inSize) += output;
311 typename ForwardConvolutionRule,
312 typename BackwardConvolutionRule,
313 typename GradientConvolutionRule,
314 typename InputDataType,
315 typename OutputDataType
317 template<
typename eT>
319 ForwardConvolutionRule,
320 BackwardConvolutionRule,
321 GradientConvolutionRule,
325 const arma::Mat<eT>& input,
326 const arma::Mat<eT>& error,
327 arma::Mat<eT>& gradient)
329 arma::cube mappedError(((arma::Mat<eT>&) error).memptr(), outputWidth,
330 outputHeight, outSize * batchSize,
false,
false);
331 arma::cube inputTemp(
const_cast<arma::Mat<eT>&
>(input).memptr(),
332 inputWidth, inputHeight, inSize * batchSize,
false,
false);
334 gradient.set_size(weights.n_elem, 1);
335 gradientTemp = arma::Cube<eT>(gradient.memptr(), weight.n_rows,
336 weight.n_cols, weight.n_slices,
false,
false);
337 gradientTemp.zeros();
339 for (
size_t outMap = 0, outMapIdx = 0, batchCount = 0; outMap <
340 outSize * batchSize; outMap++)
342 if (outMap != 0 && outMap % outSize == 0)
348 for (
size_t inMap = 0; inMap < inSize; inMap++, outMapIdx++)
350 arma::Mat<eT> inputSlice;
354 inputSlice = inputPaddedTemp.slice(inMap + batchCount * inSize);
358 inputSlice = inputTemp.slice(inMap + batchCount * inSize);
361 arma::Mat<eT> deltaSlice = mappedError.slice(outMap);
363 arma::Mat<eT> output;
364 GradientConvolutionRule::Convolution(inputSlice, deltaSlice,
365 output, strideWidth, strideHeight, 1, 1);
367 if (dilationHeight > 1)
369 for (
size_t i = 1; i < output.n_cols; ++i){
370 output.shed_cols(i, i + dilationHeight - 2);
373 if (dilationWidth > 1)
375 for (
size_t i = 1; i < output.n_rows; ++i){
376 output.shed_rows(i, i + dilationWidth - 2);
380 if (gradientTemp.n_rows < output.n_rows ||
381 gradientTemp.n_cols < output.n_cols)
383 gradientTemp.slice(outMapIdx) += output.submat(0, 0,
384 gradientTemp.n_rows - 1, gradientTemp.n_cols - 1);
386 else if (gradientTemp.n_rows > output.n_rows ||
387 gradientTemp.n_cols > output.n_cols)
389 gradientTemp.slice(outMapIdx).submat(0, 0, output.n_rows - 1,
390 output.n_cols - 1) += output;
394 gradientTemp.slice(outMapIdx) += output;
398 gradient.submat(weight.n_elem + (outMap % outSize), 0, weight.n_elem +
399 (outMap % outSize), 0) = arma::accu(mappedError.slice(outMap));
404 typename ForwardConvolutionRule,
405 typename BackwardConvolutionRule,
406 typename GradientConvolutionRule,
407 typename InputDataType,
408 typename OutputDataType
410 template<
typename Archive>
412 ForwardConvolutionRule,
413 BackwardConvolutionRule,
414 GradientConvolutionRule,
419 ar(CEREAL_NVP(inSize));
420 ar(CEREAL_NVP(outSize));
421 ar(CEREAL_NVP(batchSize));
422 ar(CEREAL_NVP(kernelWidth));
423 ar(CEREAL_NVP(kernelHeight));
424 ar(CEREAL_NVP(strideWidth));
425 ar(CEREAL_NVP(strideHeight));
426 ar(CEREAL_NVP(inputWidth));
427 ar(CEREAL_NVP(inputHeight));
428 ar(CEREAL_NVP(outputWidth));
429 ar(CEREAL_NVP(outputHeight));
430 ar(CEREAL_NVP(dilationWidth));
431 ar(CEREAL_NVP(dilationHeight));
432 ar(CEREAL_NVP(padding));
434 if (cereal::is_loading<Archive>())
436 weights.set_size((outSize * inSize * kernelWidth * kernelHeight) + outSize,
442 typename ForwardConvolutionRule,
443 typename BackwardConvolutionRule,
444 typename GradientConvolutionRule,
445 typename InputDataType,
446 typename OutputDataType
449 ForwardConvolutionRule,
450 BackwardConvolutionRule,
451 GradientConvolutionRule,
454 >::InitializeSamePadding(
size_t& padWLeft,
457 size_t& padHBottom)
const 462 size_t totalVerticalPadding = (strideWidth - 1) * inputWidth + kernelWidth -
463 strideWidth + (dilationWidth - 1) * (kernelWidth - 1);
464 size_t totalHorizontalPadding = (strideHeight - 1) * inputHeight +
465 kernelHeight - strideHeight + (dilationHeight - 1) * (kernelHeight - 1);
467 padWLeft = totalVerticalPadding / 2;
468 padWRight = totalVerticalPadding - totalVerticalPadding / 2;
469 padHTop = totalHorizontalPadding / 2;
470 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
AtrousConvolution()
Create the AtrousConvolution object.
Definition: atrous_convolution_impl.hpp:35
Definition: pointer_wrapper.hpp:23
void serialize(Archive &ar, const uint32_t)
Serialize the layer.
Definition: atrous_convolution_impl.hpp:417
OutputDataType const & Gradient() const
Get the gradient.
Definition: atrous_convolution.hpp:197
size_t PadWLeft() const
Get the left padding width.
Definition: padding.hpp:89
size_t PadWRight() const
Get the right padding width.
Definition: padding.hpp:94
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: atrous_convolution_impl.hpp:184
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
size_t PadHTop() const
Get the top padding width.
Definition: padding.hpp:99
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: atrous_convolution_impl.hpp:265
size_t PadHBottom() const
Get the bottom padding width.
Definition: padding.hpp:104
size_t WeightSize() const
Get size of the weight matrix.
Definition: atrous_convolution.hpp:263
Implementation of the Atrous Convolution class.
Definition: atrous_convolution.hpp:52