cxx11_tensor_image_patch.cpp
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #include "main.h"
11 
12 #include <Eigen/CXX11/Tensor>
13 
14 using Eigen::Tensor;
15 
17 {
18  Tensor<float, 4> tensor(2,3,5,7);
19  tensor.setRandom();
20  Tensor<float, 4, RowMajor> tensor_row_major = tensor.swap_layout();
21  VERIFY_IS_EQUAL(tensor.dimension(0), tensor_row_major.dimension(3));
22  VERIFY_IS_EQUAL(tensor.dimension(1), tensor_row_major.dimension(2));
23  VERIFY_IS_EQUAL(tensor.dimension(2), tensor_row_major.dimension(1));
24  VERIFY_IS_EQUAL(tensor.dimension(3), tensor_row_major.dimension(0));
25 
26  // Single pixel patch: ColMajor
27  Tensor<float, 5> single_pixel_patch;
28  single_pixel_patch = tensor.extract_image_patches(1, 1);
29  VERIFY_IS_EQUAL(single_pixel_patch.dimension(0), 2);
30  VERIFY_IS_EQUAL(single_pixel_patch.dimension(1), 1);
31  VERIFY_IS_EQUAL(single_pixel_patch.dimension(2), 1);
32  VERIFY_IS_EQUAL(single_pixel_patch.dimension(3), 3*5);
33  VERIFY_IS_EQUAL(single_pixel_patch.dimension(4), 7);
34 
35  // Single pixel patch: RowMajor
36  Tensor<float, 5, RowMajor> single_pixel_patch_row_major;
37  single_pixel_patch_row_major = tensor_row_major.extract_image_patches(1, 1);
38  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(0), 7);
39  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(1), 3*5);
40  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(2), 1);
41  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(3), 1);
42  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(4), 2);
43 
44  for (int i = 0; i < tensor.size(); ++i) {
45  // ColMajor
46  if (tensor.data()[i] != single_pixel_patch.data()[i]) {
47  std::cout << "Mismatch detected at index " << i << " : "
48  << tensor.data()[i] << " vs " << single_pixel_patch.data()[i]
49  << std::endl;
50  }
51  VERIFY_IS_EQUAL(single_pixel_patch.data()[i], tensor.data()[i]);
52  // RowMajor
53  if (tensor_row_major.data()[i] != single_pixel_patch_row_major.data()[i]) {
54  std::cout << "Mismatch detected at index " << i << " : "
55  << tensor.data()[i] << " vs "
56  << single_pixel_patch_row_major.data()[i] << std::endl;
57  }
58  VERIFY_IS_EQUAL(single_pixel_patch_row_major.data()[i],
59  tensor_row_major.data()[i]);
60  VERIFY_IS_EQUAL(tensor.data()[i], tensor_row_major.data()[i]);
61  VERIFY_IS_EQUAL(single_pixel_patch.data()[i],
62  single_pixel_patch_row_major.data()[i]);
63  }
64 
65  // Entire image patch: ColMajor
66  Tensor<float, 5> entire_image_patch;
67  entire_image_patch = tensor.extract_image_patches(3, 5);
68  VERIFY_IS_EQUAL(entire_image_patch.dimension(0), 2);
69  VERIFY_IS_EQUAL(entire_image_patch.dimension(1), 3);
70  VERIFY_IS_EQUAL(entire_image_patch.dimension(2), 5);
71  VERIFY_IS_EQUAL(entire_image_patch.dimension(3), 3*5);
72  VERIFY_IS_EQUAL(entire_image_patch.dimension(4), 7);
73 
74  // Entire image patch: RowMajor
75  Tensor<float, 5, RowMajor> entire_image_patch_row_major;
76  entire_image_patch_row_major = tensor_row_major.extract_image_patches(3, 5);
77  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(0), 7);
78  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(1), 3*5);
79  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(2), 5);
80  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(3), 3);
81  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(4), 2);
82 
83  for (int i = 0; i < 3; ++i) {
84  for (int j = 0; j < 5; ++j) {
85  int patchId = i+3*j;
86  for (int r = 0; r < 3; ++r) {
87  for (int c = 0; c < 5; ++c) {
88  for (int d = 0; d < 2; ++d) {
89  for (int b = 0; b < 7; ++b) {
90  float expected = 0.0f;
91  float expected_row_major = 0.0f;
92  if (r-1+i >= 0 && c-2+j >= 0 && r-1+i < 3 && c-2+j < 5) {
93  expected = tensor(d, r-1+i, c-2+j, b);
94  expected_row_major = tensor_row_major(b, c-2+j, r-1+i, d);
95  }
96  // ColMajor
97  if (entire_image_patch(d, r, c, patchId, b) != expected) {
98  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
99  }
100  VERIFY_IS_EQUAL(entire_image_patch(d, r, c, patchId, b), expected);
101  // RowMajor
102  if (entire_image_patch_row_major(b, patchId, c, r, d) !=
103  expected_row_major) {
104  std::cout << "Mismatch detected at index i=" << i << " j=" << j
105  << " r=" << r << " c=" << c << " d=" << d << " b=" << b
106  << std::endl;
107  }
108  VERIFY_IS_EQUAL(entire_image_patch_row_major(b, patchId, c, r, d),
109  expected_row_major);
110  // Check that ColMajor and RowMajor agree.
111  VERIFY_IS_EQUAL(expected, expected_row_major);
112  }
113  }
114  }
115  }
116  }
117  }
118 
119  // 2D patch: ColMajor
120  Tensor<float, 5> twod_patch;
121  twod_patch = tensor.extract_image_patches(2, 2);
122  VERIFY_IS_EQUAL(twod_patch.dimension(0), 2);
123  VERIFY_IS_EQUAL(twod_patch.dimension(1), 2);
124  VERIFY_IS_EQUAL(twod_patch.dimension(2), 2);
125  VERIFY_IS_EQUAL(twod_patch.dimension(3), 3*5);
126  VERIFY_IS_EQUAL(twod_patch.dimension(4), 7);
127 
128  // 2D patch: RowMajor
129  Tensor<float, 5, RowMajor> twod_patch_row_major;
130  twod_patch_row_major = tensor_row_major.extract_image_patches(2, 2);
131  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(0), 7);
132  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(1), 3*5);
133  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(2), 2);
134  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(3), 2);
135  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(4), 2);
136 
137 
138  // Based on the calculation described in TensorTraits.h, padding happens to be 0.
139  int row_padding = 0;
140  int col_padding = 0;
141  int stride = 1;
142 
143  for (int i = 0; i < 3; ++i) {
144  for (int j = 0; j < 5; ++j) {
145  int patchId = i+3*j;
146  for (int r = 0; r < 2; ++r) {
147  for (int c = 0; c < 2; ++c) {
148  for (int d = 0; d < 2; ++d) {
149  for (int b = 0; b < 7; ++b) {
150  float expected = 0.0f;
151  float expected_row_major = 0.0f;
152  int row_offset = r*stride + i - row_padding;
153  int col_offset = c*stride + j - col_padding;
154  // ColMajor
155  if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor.dimension(1) && col_offset < tensor.dimension(2)) {
156  expected = tensor(d, row_offset, col_offset, b);
157  }
158  if (twod_patch(d, r, c, patchId, b) != expected) {
159  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
160  }
161  VERIFY_IS_EQUAL(twod_patch(d, r, c, patchId, b), expected);
162 
163  // RowMajor
164  if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_row_major.dimension(2) && col_offset < tensor_row_major.dimension(1)) {
165  expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
166 
167  }
168  if (twod_patch_row_major(b, patchId, c, r, d) != expected_row_major) {
169  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
170  }
171  VERIFY_IS_EQUAL(twod_patch_row_major(b, patchId, c, r, d), expected_row_major);
172  // Check that ColMajor and RowMajor agree.
173  VERIFY_IS_EQUAL(expected, expected_row_major);
174  }
175  }
176  }
177  }
178  }
179  }
180 }
181 
182 // Verifies VALID padding (no padding) with incrementing values.
184 {
185  int input_depth = 3;
186  int input_rows = 3;
187  int input_cols = 3;
188  int input_batches = 1;
189  int ksize = 2; // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
190  int stride = 2; // Only same stride is supported.
191  Tensor<float, 4> tensor(input_depth, input_rows, input_cols, input_batches);
192  // Initializes tensor with incrementing numbers.
193  for (int i = 0; i < tensor.size(); ++i) {
194  tensor.data()[i] = i + 1;
195  }
196  // ColMajor
197  Tensor<float, 5> result = tensor.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
198 
199  VERIFY_IS_EQUAL(result.dimension(0), input_depth); // depth
200  VERIFY_IS_EQUAL(result.dimension(1), ksize); // kernel rows
201  VERIFY_IS_EQUAL(result.dimension(2), ksize); // kernel cols
202  VERIFY_IS_EQUAL(result.dimension(3), 1); // number of patches
203  VERIFY_IS_EQUAL(result.dimension(4), input_batches); // number of batches
204 
205  // RowMajor
206  Tensor<float, 4, RowMajor> tensor_row_major = tensor.swap_layout();
207  VERIFY_IS_EQUAL(tensor.dimension(0), tensor_row_major.dimension(3));
208  VERIFY_IS_EQUAL(tensor.dimension(1), tensor_row_major.dimension(2));
209  VERIFY_IS_EQUAL(tensor.dimension(2), tensor_row_major.dimension(1));
210  VERIFY_IS_EQUAL(tensor.dimension(3), tensor_row_major.dimension(0));
211 
212  Tensor<float, 5, RowMajor> result_row_major = tensor_row_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
213  VERIFY_IS_EQUAL(result.dimension(0), result_row_major.dimension(4));
214  VERIFY_IS_EQUAL(result.dimension(1), result_row_major.dimension(3));
215  VERIFY_IS_EQUAL(result.dimension(2), result_row_major.dimension(2));
216  VERIFY_IS_EQUAL(result.dimension(3), result_row_major.dimension(1));
217  VERIFY_IS_EQUAL(result.dimension(4), result_row_major.dimension(0));
218 
219  // No padding is carried out.
220  int row_padding = 0;
221  int col_padding = 0;
222 
223  for (int i = 0; (i+stride+ksize-1) < input_rows; i += stride) { // input rows
224  for (int j = 0; (j+stride+ksize-1) < input_cols; j += stride) { // input cols
225  int patchId = i+input_rows*j;
226  for (int r = 0; r < ksize; ++r) { // patch rows
227  for (int c = 0; c < ksize; ++c) { // patch cols
228  for (int d = 0; d < input_depth; ++d) { // depth
229  for (int b = 0; b < input_batches; ++b) { // batch
230  float expected = 0.0f;
231  float expected_row_major = 0.0f;
232  int row_offset = r + i - row_padding;
233  int col_offset = c + j - col_padding;
234  if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
235  expected = tensor(d, row_offset, col_offset, b);
236  expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
237  }
238  // ColMajor
239  if (result(d, r, c, patchId, b) != expected) {
240  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
241  }
242  VERIFY_IS_EQUAL(result(d, r, c, patchId, b), expected);
243  // RowMajor
244  if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
245  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
246  }
247  VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
248  // Check that ColMajor and RowMajor agree.
249  VERIFY_IS_EQUAL(expected, expected_row_major);
250  }
251  }
252  }
253  }
254  }
255  }
256 }
257 
258 // Verifies VALID padding (no padding) with the same value.
260 {
261  int input_depth = 1;
262  int input_rows = 5;
263  int input_cols = 5;
264  int input_batches = 2;
265  int ksize = 3; // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
266  int stride = 2; // Only same stride is supported.
267  // ColMajor
268  Tensor<float, 4> tensor(input_depth, input_rows, input_cols, input_batches);
269  tensor = tensor.constant(11.0f);
270  Tensor<float, 5> result = tensor.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
271 
272  VERIFY_IS_EQUAL(result.dimension(0), input_depth); // depth
273  VERIFY_IS_EQUAL(result.dimension(1), ksize); // kernel rows
274  VERIFY_IS_EQUAL(result.dimension(2), ksize); // kernel cols
275  VERIFY_IS_EQUAL(result.dimension(3), 4); // number of patches
276  VERIFY_IS_EQUAL(result.dimension(4), input_batches); // number of batches
277 
278  // RowMajor
279  Tensor<float, 4, RowMajor> tensor_row_major = tensor.swap_layout();
280  VERIFY_IS_EQUAL(tensor.dimension(0), tensor_row_major.dimension(3));
281  VERIFY_IS_EQUAL(tensor.dimension(1), tensor_row_major.dimension(2));
282  VERIFY_IS_EQUAL(tensor.dimension(2), tensor_row_major.dimension(1));
283  VERIFY_IS_EQUAL(tensor.dimension(3), tensor_row_major.dimension(0));
284 
285  Tensor<float, 5, RowMajor> result_row_major = tensor_row_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
286  VERIFY_IS_EQUAL(result.dimension(0), result_row_major.dimension(4));
287  VERIFY_IS_EQUAL(result.dimension(1), result_row_major.dimension(3));
288  VERIFY_IS_EQUAL(result.dimension(2), result_row_major.dimension(2));
289  VERIFY_IS_EQUAL(result.dimension(3), result_row_major.dimension(1));
290  VERIFY_IS_EQUAL(result.dimension(4), result_row_major.dimension(0));
291 
292  // No padding is carried out.
293  int row_padding = 0;
294  int col_padding = 0;
295 
296  for (int i = 0; (i+stride+ksize-1) <= input_rows; i += stride) { // input rows
297  for (int j = 0; (j+stride+ksize-1) <= input_cols; j += stride) { // input cols
298  int patchId = i+input_rows*j;
299  for (int r = 0; r < ksize; ++r) { // patch rows
300  for (int c = 0; c < ksize; ++c) { // patch cols
301  for (int d = 0; d < input_depth; ++d) { // depth
302  for (int b = 0; b < input_batches; ++b) { // batch
303  float expected = 0.0f;
304  float expected_row_major = 0.0f;
305  int row_offset = r + i - row_padding;
306  int col_offset = c + j - col_padding;
307  if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
308  expected = tensor(d, row_offset, col_offset, b);
309  expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
310  }
311  // ColMajor
312  if (result(d, r, c, patchId, b) != expected) {
313  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
314  }
315  VERIFY_IS_EQUAL(result(d, r, c, patchId, b), expected);
316  // RowMajor
317  if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
318  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
319  }
320  VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
321  // Check that ColMajor and RowMajor agree.
322  VERIFY_IS_EQUAL(expected, expected_row_major);
323  }
324  }
325  }
326  }
327  }
328  }
329 }
330 
331 // Verifies SAME padding.
333 {
334  int input_depth = 3;
335  int input_rows = 4;
336  int input_cols = 2;
337  int input_batches = 1;
338  int ksize = 2; // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
339  int stride = 2; // Only same stride is supported.
340  // ColMajor
341  Tensor<float, 4> tensor(input_depth, input_rows, input_cols, input_batches);
342  // Initializes tensor with incrementing numbers.
343  for (int i = 0; i < tensor.size(); ++i) {
344  tensor.data()[i] = i + 1;
345  }
346  Tensor<float, 5> result = tensor.extract_image_patches(ksize, ksize, stride, stride, PADDING_SAME);
347 
348  VERIFY_IS_EQUAL(result.dimension(0), input_depth); // depth
349  VERIFY_IS_EQUAL(result.dimension(1), ksize); // kernel rows
350  VERIFY_IS_EQUAL(result.dimension(2), ksize); // kernel cols
351  VERIFY_IS_EQUAL(result.dimension(3), 2); // number of patches
352  VERIFY_IS_EQUAL(result.dimension(4), input_batches); // number of batches
353 
354  // RowMajor
355  Tensor<float, 4, RowMajor> tensor_row_major = tensor.swap_layout();
356  VERIFY_IS_EQUAL(tensor.dimension(0), tensor_row_major.dimension(3));
357  VERIFY_IS_EQUAL(tensor.dimension(1), tensor_row_major.dimension(2));
358  VERIFY_IS_EQUAL(tensor.dimension(2), tensor_row_major.dimension(1));
359  VERIFY_IS_EQUAL(tensor.dimension(3), tensor_row_major.dimension(0));
360 
361  Tensor<float, 5, RowMajor> result_row_major = tensor_row_major.extract_image_patches(ksize, ksize, stride, stride, PADDING_SAME);
362  VERIFY_IS_EQUAL(result.dimension(0), result_row_major.dimension(4));
363  VERIFY_IS_EQUAL(result.dimension(1), result_row_major.dimension(3));
364  VERIFY_IS_EQUAL(result.dimension(2), result_row_major.dimension(2));
365  VERIFY_IS_EQUAL(result.dimension(3), result_row_major.dimension(1));
366  VERIFY_IS_EQUAL(result.dimension(4), result_row_major.dimension(0));
367 
368  // Based on the calculation described in TensorTraits.h, padding happens to be
369  // 0.
370  int row_padding = 0;
371  int col_padding = 0;
372 
373  for (int i = 0; (i+stride+ksize-1) <= input_rows; i += stride) { // input rows
374  for (int j = 0; (j+stride+ksize-1) <= input_cols; j += stride) { // input cols
375  int patchId = i+input_rows*j;
376  for (int r = 0; r < ksize; ++r) { // patch rows
377  for (int c = 0; c < ksize; ++c) { // patch cols
378  for (int d = 0; d < input_depth; ++d) { // depth
379  for (int b = 0; b < input_batches; ++b) { // batch
380  float expected = 0.0f;
381  float expected_row_major = 0.0f;
382  int row_offset = r*stride + i - row_padding;
383  int col_offset = c*stride + j - col_padding;
384  if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
385  expected = tensor(d, row_offset, col_offset, b);
386  expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
387  }
388  // ColMajor
389  if (result(d, r, c, patchId, b) != expected) {
390  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
391  }
392  VERIFY_IS_EQUAL(result(d, r, c, patchId, b), expected);
393  // RowMajor
394  if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
395  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
396  }
397  VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
398  // Check that ColMajor and RowMajor agree.
399  VERIFY_IS_EQUAL(expected, expected_row_major);
400  }
401  }
402  }
403  }
404  }
405  }
406 }
407 
409 {
410  Tensor<float, 3> tensor(2,3,5);
411  tensor.setRandom();
412  Tensor<float, 3, RowMajor> tensor_row_major = tensor.swap_layout();
413  VERIFY_IS_EQUAL(tensor.dimension(0), tensor_row_major.dimension(2));
414  VERIFY_IS_EQUAL(tensor.dimension(1), tensor_row_major.dimension(1));
415  VERIFY_IS_EQUAL(tensor.dimension(2), tensor_row_major.dimension(0));
416 
417  // Single pixel patch: ColMajor
418  Tensor<float, 4> single_pixel_patch;
419  single_pixel_patch = tensor.extract_image_patches(1, 1);
420  VERIFY_IS_EQUAL(single_pixel_patch.dimension(0), 2);
421  VERIFY_IS_EQUAL(single_pixel_patch.dimension(1), 1);
422  VERIFY_IS_EQUAL(single_pixel_patch.dimension(2), 1);
423  VERIFY_IS_EQUAL(single_pixel_patch.dimension(3), 3*5);
424 
425  // Single pixel patch: RowMajor
426  Tensor<float, 4, RowMajor> single_pixel_patch_row_major;
427  single_pixel_patch_row_major = tensor_row_major.extract_image_patches(1, 1);
428  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(0), 3*5);
429  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(1), 1);
430  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(2), 1);
431  VERIFY_IS_EQUAL(single_pixel_patch_row_major.dimension(3), 2);
432 
433  for (int i = 0; i < tensor.size(); ++i) {
434  // ColMajor
435  if (tensor.data()[i] != single_pixel_patch.data()[i]) {
436  std::cout << "Mismatch detected at index " << i << " : " << tensor.data()[i] << " vs " << single_pixel_patch.data()[i] << std::endl;
437  }
438  VERIFY_IS_EQUAL(single_pixel_patch.data()[i], tensor.data()[i]);
439  // RowMajor
440  if (tensor_row_major.data()[i] != single_pixel_patch_row_major.data()[i]) {
441  std::cout << "Mismatch detected at index " << i << " : "
442  << tensor.data()[i] << " vs "
443  << single_pixel_patch_row_major.data()[i] << std::endl;
444  }
445  VERIFY_IS_EQUAL(single_pixel_patch_row_major.data()[i],
446  tensor_row_major.data()[i]);
447  VERIFY_IS_EQUAL(tensor.data()[i], tensor_row_major.data()[i]);
448  VERIFY_IS_EQUAL(single_pixel_patch.data()[i],
449  single_pixel_patch_row_major.data()[i]);
450  }
451 
452  // Entire image patch: ColMajor
453  Tensor<float, 4> entire_image_patch;
454  entire_image_patch = tensor.extract_image_patches(3, 5);
455  VERIFY_IS_EQUAL(entire_image_patch.dimension(0), 2);
456  VERIFY_IS_EQUAL(entire_image_patch.dimension(1), 3);
457  VERIFY_IS_EQUAL(entire_image_patch.dimension(2), 5);
458  VERIFY_IS_EQUAL(entire_image_patch.dimension(3), 3*5);
459 
460  // Entire image patch: RowMajor
461  Tensor<float, 4, RowMajor> entire_image_patch_row_major;
462  entire_image_patch_row_major = tensor_row_major.extract_image_patches(3, 5);
463  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(0), 3*5);
464  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(1), 5);
465  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(2), 3);
466  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(3), 2);
467 
468  for (int i = 0; i < 3; ++i) {
469  for (int j = 0; j < 5; ++j) {
470  int patchId = i+3*j;
471  for (int r = 0; r < 3; ++r) {
472  for (int c = 0; c < 5; ++c) {
473  for (int d = 0; d < 2; ++d) {
474  float expected = 0.0f;
475  float expected_row_major = 0.0f;
476  if (r-1+i >= 0 && c-2+j >= 0 && r-1+i < 3 && c-2+j < 5) {
477  expected = tensor(d, r-1+i, c-2+j);
478  expected_row_major = tensor_row_major(c-2+j, r-1+i, d);
479  }
480  // ColMajor
481  if (entire_image_patch(d, r, c, patchId) != expected) {
482  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << std::endl;
483  }
484  VERIFY_IS_EQUAL(entire_image_patch(d, r, c, patchId), expected);
485  // RowMajor
486  if (entire_image_patch_row_major(patchId, c, r, d) !=
487  expected_row_major) {
488  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << std::endl;
489  }
490  VERIFY_IS_EQUAL(entire_image_patch_row_major(patchId, c, r, d),
491  expected_row_major);
492  // Check that ColMajor and RowMajor agree.
493  VERIFY_IS_EQUAL(expected, expected_row_major);
494  }
495  }
496  }
497  }
498  }
499 
500  // 2D patch: ColMajor
501  Tensor<float, 4> twod_patch;
502  twod_patch = tensor.extract_image_patches(2, 2);
503  VERIFY_IS_EQUAL(twod_patch.dimension(0), 2);
504  VERIFY_IS_EQUAL(twod_patch.dimension(1), 2);
505  VERIFY_IS_EQUAL(twod_patch.dimension(2), 2);
506  VERIFY_IS_EQUAL(twod_patch.dimension(3), 3*5);
507 
508  // 2D patch: RowMajor
509  Tensor<float, 4, RowMajor> twod_patch_row_major;
510  twod_patch_row_major = tensor_row_major.extract_image_patches(2, 2);
511  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(0), 3*5);
512  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(1), 2);
513  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(2), 2);
514  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(3), 2);
515 
516  // Based on the calculation described in TensorTraits.h, padding happens to be 0.
517  int row_padding = 0;
518  int col_padding = 0;
519  int stride = 1;
520 
521  for (int i = 0; i < 3; ++i) {
522  for (int j = 0; j < 5; ++j) {
523  int patchId = i+3*j;
524  for (int r = 0; r < 2; ++r) {
525  for (int c = 0; c < 2; ++c) {
526  for (int d = 0; d < 2; ++d) {
527  float expected = 0.0f;
528  float expected_row_major = 0.0f;
529  int row_offset = r*stride + i - row_padding;
530  int col_offset = c*stride + j - col_padding;
531  // ColMajor
532  if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor.dimension(1) && col_offset < tensor.dimension(2)) {
533  expected = tensor(d, row_offset, col_offset);
534  }
535  if (twod_patch(d, r, c, patchId) != expected) {
536  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << std::endl;
537  }
538  VERIFY_IS_EQUAL(twod_patch(d, r, c, patchId), expected);
539  // RowMajor
540  if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_row_major.dimension(1) && col_offset < tensor_row_major.dimension(0)) {
541  expected_row_major = tensor_row_major(col_offset, row_offset, d);
542  }
543  if (twod_patch_row_major(patchId, c, r, d) != expected_row_major) {
544  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << std::endl;
545  }
546  VERIFY_IS_EQUAL(twod_patch_row_major(patchId, c, r, d), expected_row_major);
547  // Check that ColMajor and RowMajor agree.
548  VERIFY_IS_EQUAL(expected, expected_row_major);
549  }
550  }
551  }
552  }
553  }
554 }
555 
557 {
558  // Test the code on typical configurations used by the 'imagenet' benchmarks at
559  // https://github.com/soumith/convnet-benchmarks
560  // ColMajor
561  Tensor<float, 4> l_in(3, 128, 128, 16);
562  l_in.setRandom();
563  Tensor<float, 5> l_out = l_in.extract_image_patches(11, 11);
564  VERIFY_IS_EQUAL(l_out.dimension(0), 3);
565  VERIFY_IS_EQUAL(l_out.dimension(1), 11);
566  VERIFY_IS_EQUAL(l_out.dimension(2), 11);
567  VERIFY_IS_EQUAL(l_out.dimension(3), 128*128);
568  VERIFY_IS_EQUAL(l_out.dimension(4), 16);
569 
570  // RowMajor
571  Tensor<float, 5, RowMajor> l_out_row_major = l_in.swap_layout().extract_image_patches(11, 11);
572  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 16);
573  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 128*128);
574  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 11);
575  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 11);
576  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 3);
577 
578  for (int b = 0; b < 16; ++b) {
579  for (int i = 0; i < 128; ++i) {
580  for (int j = 0; j < 128; ++j) {
581  int patchId = i+128*j;
582  for (int c = 0; c < 11; ++c) {
583  for (int r = 0; r < 11; ++r) {
584  for (int d = 0; d < 3; ++d) {
585  float expected = 0.0f;
586  if (r-5+i >= 0 && c-5+j >= 0 && r-5+i < 128 && c-5+j < 128) {
587  expected = l_in(d, r-5+i, c-5+j, b);
588  }
589  // ColMajor
590  if (l_out(d, r, c, patchId, b) != expected) {
591  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
592  }
593  VERIFY_IS_EQUAL(l_out(d, r, c, patchId, b), expected);
594  // RowMajor
595  if (l_out_row_major(b, patchId, c, r, d) !=
596  expected) {
597  std::cout << "Mismatch detected at index i=" << i << " j=" << j
598  << " r=" << r << " c=" << c << " d=" << d << " b=" << b
599  << std::endl;
600  }
601  VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d),
602  expected);
603  }
604  }
605  }
606  }
607  }
608  }
609 
610  // ColMajor
611  l_in.resize(16, 64, 64, 32);
612  l_in.setRandom();
613  l_out = l_in.extract_image_patches(9, 9);
614  VERIFY_IS_EQUAL(l_out.dimension(0), 16);
615  VERIFY_IS_EQUAL(l_out.dimension(1), 9);
616  VERIFY_IS_EQUAL(l_out.dimension(2), 9);
617  VERIFY_IS_EQUAL(l_out.dimension(3), 64*64);
618  VERIFY_IS_EQUAL(l_out.dimension(4), 32);
619 
620  // RowMajor
621  l_out_row_major = l_in.swap_layout().extract_image_patches(9, 9);
622  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
623  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 64*64);
624  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 9);
625  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 9);
626  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 16);
627 
628  for (int b = 0; b < 32; ++b) {
629  for (int i = 0; i < 64; ++i) {
630  for (int j = 0; j < 64; ++j) {
631  int patchId = i+64*j;
632  for (int c = 0; c < 9; ++c) {
633  for (int r = 0; r < 9; ++r) {
634  for (int d = 0; d < 16; ++d) {
635  float expected = 0.0f;
636  if (r-4+i >= 0 && c-4+j >= 0 && r-4+i < 64 && c-4+j < 64) {
637  expected = l_in(d, r-4+i, c-4+j, b);
638  }
639  // ColMajor
640  if (l_out(d, r, c, patchId, b) != expected) {
641  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
642  }
643  VERIFY_IS_EQUAL(l_out(d, r, c, patchId, b), expected);
644  // RowMajor
645  if (l_out_row_major(b, patchId, c, r, d) != expected) {
646  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
647  }
648  VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
649  }
650  }
651  }
652  }
653  }
654  }
655 
656  // ColMajor
657  l_in.resize(32, 16, 16, 32);
658  l_in.setRandom();
659  l_out = l_in.extract_image_patches(7, 7);
660  VERIFY_IS_EQUAL(l_out.dimension(0), 32);
661  VERIFY_IS_EQUAL(l_out.dimension(1), 7);
662  VERIFY_IS_EQUAL(l_out.dimension(2), 7);
663  VERIFY_IS_EQUAL(l_out.dimension(3), 16*16);
664  VERIFY_IS_EQUAL(l_out.dimension(4), 32);
665 
666  // RowMajor
667  l_out_row_major = l_in.swap_layout().extract_image_patches(7, 7);
668  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
669  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 16*16);
670  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 7);
671  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 7);
672  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 32);
673 
674  for (int b = 0; b < 32; ++b) {
675  for (int i = 0; i < 16; ++i) {
676  for (int j = 0; j < 16; ++j) {
677  int patchId = i+16*j;
678  for (int c = 0; c < 7; ++c) {
679  for (int r = 0; r < 7; ++r) {
680  for (int d = 0; d < 32; ++d) {
681  float expected = 0.0f;
682  if (r-3+i >= 0 && c-3+j >= 0 && r-3+i < 16 && c-3+j < 16) {
683  expected = l_in(d, r-3+i, c-3+j, b);
684  }
685  // ColMajor
686  if (l_out(d, r, c, patchId, b) != expected) {
687  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
688  }
689  VERIFY_IS_EQUAL(l_out(d, r, c, patchId, b), expected);
690  // RowMajor
691  if (l_out_row_major(b, patchId, c, r, d) != expected) {
692  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
693  }
694  VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
695  }
696  }
697  }
698  }
699  }
700  }
701 
702  // ColMajor
703  l_in.resize(64, 13, 13, 32);
704  l_in.setRandom();
705  l_out = l_in.extract_image_patches(3, 3);
706  VERIFY_IS_EQUAL(l_out.dimension(0), 64);
707  VERIFY_IS_EQUAL(l_out.dimension(1), 3);
708  VERIFY_IS_EQUAL(l_out.dimension(2), 3);
709  VERIFY_IS_EQUAL(l_out.dimension(3), 13*13);
710  VERIFY_IS_EQUAL(l_out.dimension(4), 32);
711 
712  // RowMajor
713  l_out_row_major = l_in.swap_layout().extract_image_patches(3, 3);
714  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
715  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 13*13);
716  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 3);
717  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 3);
718  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 64);
719 
720  for (int b = 0; b < 32; ++b) {
721  for (int i = 0; i < 13; ++i) {
722  for (int j = 0; j < 13; ++j) {
723  int patchId = i+13*j;
724  for (int c = 0; c < 3; ++c) {
725  for (int r = 0; r < 3; ++r) {
726  for (int d = 0; d < 64; ++d) {
727  float expected = 0.0f;
728  if (r-1+i >= 0 && c-1+j >= 0 && r-1+i < 13 && c-1+j < 13) {
729  expected = l_in(d, r-1+i, c-1+j, b);
730  }
731  // ColMajor
732  if (l_out(d, r, c, patchId, b) != expected) {
733  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
734  }
735  VERIFY_IS_EQUAL(l_out(d, r, c, patchId, b), expected);
736  // RowMajor
737  if (l_out_row_major(b, patchId, c, r, d) != expected) {
738  std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d << " b=" << b << std::endl;
739  }
740  VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
741  }
742  }
743  }
744  }
745  }
746  }
747 }
748 
750 {
751  CALL_SUBTEST_1(test_simple_patch());
752  CALL_SUBTEST_2(test_patch_no_extra_dim());
753  CALL_SUBTEST_3(test_patch_padding_valid());
754  CALL_SUBTEST_4(test_patch_padding_valid_same_value());
755  CALL_SUBTEST_5(test_patch_padding_same());
756  CALL_SUBTEST_6(test_imagenet_patches());
757 }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const
Definition: Tensor.h:101
Scalar * b
Definition: benchVecAdd.cpp:17
void test_patch_no_extra_dim()
Matrix expected
Definition: testMatrix.cpp:974
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor< Scalar_, NumIndices_, Options_, IndexType_ > & setRandom()
Definition: TensorBase.h:850
#define VERIFY_IS_EQUAL(a, b)
Definition: main.h:331
Values result
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorLayoutSwapOp< const Tensor< Scalar_, NumIndices_, Options_, IndexType_ > > swap_layout() const
Definition: TensorBase.h:887
void test_cxx11_tensor_image_patch()
void test_patch_padding_valid_same_value()
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
void test_patch_padding_valid()
EIGEN_DEVICE_FUNC void resize(const array< Index, NumIndices > &dimensions)
Definition: Tensor.h:432
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar * data()
Definition: Tensor.h:104
void test_patch_padding_same()
void test_simple_patch()
void test_imagenet_patches()
std::ptrdiff_t j
The tensor class.
Definition: Tensor.h:63
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const
Definition: Tensor.h:103


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:41:55