1 | /* Copyright 2016 The TensorFlow Authors. All Rights Reserved. |
2 | |
3 | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | you may not use this file except in compliance with the License. |
5 | You may obtain a copy of the License at |
6 | |
7 | http://www.apache.org/licenses/LICENSE-2.0 |
8 | |
9 | Unless required by applicable law or agreed to in writing, software |
10 | distributed under the License is distributed on an "AS IS" BASIS, |
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | See the License for the specific language governing permissions and |
13 | limitations under the License. |
14 | ==============================================================================*/ |
15 | #ifndef TENSORFLOW_CORE_KERNELS_FRACTIONAL_POOL_COMMON_H_ |
16 | #define TENSORFLOW_CORE_KERNELS_FRACTIONAL_POOL_COMMON_H_ |
17 | |
18 | #include <algorithm> |
19 | #include <vector> |
20 | |
21 | #include "tensorflow/core/util/guarded_philox_random.h" |
22 | |
23 | namespace tensorflow { |
24 | |
25 | // Shuffle a container randomly, copied from random_shuffle_op.cc |
26 | template <class Iter, class Random> |
27 | static inline void RandomShuffle(Iter first, Iter last, const Random& uniform) { |
28 | if (first == last) { |
29 | return; |
30 | } |
31 | const auto stop = last - 1; |
32 | for (auto i = first; i != stop; ++i) { |
33 | using std::iter_swap; |
34 | iter_swap(i, i + uniform(last - i)); |
35 | } |
36 | } |
37 | |
38 | // Generate pooling sequence for fractional pooling along one dimension. |
39 | // |
40 | // Regular max/avg pooling can be viewed as a special case, in which given the |
41 | // * input_length: e.g. 10 |
42 | // * output_length: e.g. 5 |
43 | // it will generate pooling sequence as |
44 | // diff sequence: [2, 2, 2, 2, 2] |
45 | // or as |
46 | // cumulative sequence: [0, 2, 4, 6, 8, 10] |
47 | // |
48 | // In the case of fractional pooling, input_length is not an integer multiple of |
49 | // output_length, randomness plays a role when generating pooling sequence. |
50 | // There are two type of randomness (random vs pseudo-random) defined in paper: |
51 | // http://arxiv.org/abs/1412.6071 |
52 | // You can check the paper for the difference between these two types. |
53 | // |
54 | // In summary, the generated diff sequence satisfy the following properties for |
55 | // both types of randomness: |
56 | // * length(generated_diff_pooling_sequence) = output_length |
57 | // * sum(generated_diff_pooling_sequence) = input_length |
58 | // * Let's define floor(input_length / output_length) = K, then |
59 | // K <= generated_diff_pooling_sequence[i] <= K+1 |
60 | // For example, when input_length = 10, output_length = 6, the following are |
61 | // valid pooling sequence: |
62 | // * [1, 2, 2, 1, 2, 2] |
63 | // * [1, 1, 2, 2, 2, 2] |
64 | // [1, 3, 2, 2, 2, 2] is not valid. |
65 | // |
66 | // Args: |
67 | // input_length: See above explanation |
68 | // output_length: See above explanation |
69 | // generator: Parallel version of random number generator |
70 | // pseudo_random: Whether or not use pseudo-random |
71 | // Returns: |
72 | // pooling_sequence: This is the cumulative pooling sequence. |
73 | std::vector<int64_t> GeneratePoolingSequence(int input_length, |
74 | int output_length, |
75 | GuardedPhiloxRandom* generator, |
76 | bool pseudo_random); |
77 | } // namespace tensorflow |
78 | |
79 | #endif // TENSORFLOW_CORE_KERNELS_FRACTIONAL_POOL_COMMON_H_ |
80 | |