Pooling.h
Go to the documentation of this file.
1#ifndef SHARK_CORE_IMAGES_CPU_POOLING_2D_H
2#define SHARK_CORE_IMAGES_CPU_POOLING_2D_H
3
4#include <shark/LinAlg/Base.h>
6#include <shark/Core/Shape.h>
7namespace shark{
8namespace image{
9template<class T>
11 blas::dense_matrix_adaptor<T const, blas::row_major, blas::continuous_dense_tag, blas::cpu_tag> inputs,
12 Shape const& shape,
13 Shape const& patchSize,
14 blas::dense_matrix_adaptor<T, blas::row_major, blas::continuous_dense_tag, blas::cpu_tag> outputs
15){
16 std::size_t depth = shape[2];
17 std::size_t outputHeight = shape[0]/patchSize[0];
18 std::size_t outputWidth = shape[1]/patchSize[1];
19 std::size_t outputPixels = outputWidth * outputHeight;
20 SIZE_CHECK(outputs.size2() == outputPixels * depth);
21
22 //for all images
23 for(std::size_t img = 0; img != inputs.size1(); ++img){
24 //Extract single images and create matrices (pixels,channels)
25 auto imageIn = to_matrix(row(inputs,img), shape[0] * shape[1], depth);
26 auto imageOut = to_matrix(row(outputs,img), outputHeight * outputWidth, depth);
27 //traverse over all pixels of the output image
28 for(std::size_t p = 0; p != outputPixels; ++p){
29 auto pixel = row(imageOut,p);
30 //extract pixel coordinates in input image
31 std::size_t starti = (p / outputWidth) * patchSize[0];
32 std::size_t startj = (p % outputWidth) * patchSize[1];
33 std::size_t endi = starti + patchSize[0];
34 std::size_t endj = startj + patchSize[1];
35
36 //traverse the patch on the input image and compute maximum
37 noalias(pixel) = row(imageIn, starti * shape[1] + startj);
38 for(std::size_t i = starti; i != endi; ++i){
39 for(std::size_t j = startj; j != endj; ++j){
40 std::size_t index = i * shape[1] + j;
41 noalias(pixel) = max(pixel,row(imageIn, index));
42 }
43 }
44 }
45 }
46}
47
48template<class T>
50 blas::dense_matrix_adaptor<T const, blas::row_major, blas::continuous_dense_tag, blas::cpu_tag> inputs,
51 blas::dense_matrix_adaptor<T const, blas::row_major, blas::continuous_dense_tag, blas::cpu_tag> coefficients,
52 Shape const& shape,
53 Shape const& patchSize,
54 blas::dense_matrix_adaptor<T, blas::row_major, blas::continuous_dense_tag, blas::cpu_tag> derivatives
55){
56 std::size_t depth = shape[2];
57 std::size_t outputHeight = shape[0]/patchSize[0];
58 std::size_t outputWidth = shape[1]/patchSize[1];
59 std::size_t outputPixels = outputWidth * outputHeight;
60 SIZE_CHECK(coefficients.size2() == outputPixels * depth);
61 //for all images
62 for(std::size_t img = 0; img != inputs.size1(); ++img){
63 //Extract single images and create matrices (pixels,channels)
64 auto imageCoeffs = to_matrix(row(coefficients,img), outputHeight * outputWidth, depth);
65 auto imageIn = to_matrix(row(inputs,img), shape[0] * shape[1], depth);
66 auto imageDer = to_matrix(row(derivatives,img), shape[0] * shape[1], depth);
67 //traverse over all pixels of the output image
68 for(std::size_t p = 0; p != outputPixels; ++p){
69 std::size_t starti = (p / outputWidth) * patchSize[0];
70 std::size_t startj = (p % outputWidth) * patchSize[1];
71 std::size_t endi = starti + patchSize[0];
72 std::size_t endj = startj + patchSize[1];
73
74 //traverse the patch on the input image and compute arg-max for each channel
75 for(std::size_t c = 0; c != depth; ++c){
76 std::size_t maxIndex = starti * shape[1] + startj;
77 double maxVal = imageIn(maxIndex,c);
78 for(std::size_t i = starti; i != endi; ++i){
79 for(std::size_t j = startj; j != endj; ++j){
80 std::size_t index = i * shape[1] + j;
81 double val = imageIn(index,c);
82 if(val > maxVal){
83 maxVal = val;
84 maxIndex = index;
85 }
86 }
87 }
88 //after arg-max is obtained, update gradient
89 imageDer(maxIndex, c) += imageCoeffs(p,c);
90 }
91 }
92 }
93}
94
95
96}}
97
98#endif