1/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations 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
23namespace tensorflow {
24
25// Shuffle a container randomly, copied from random_shuffle_op.cc
26template <class Iter, class Random>
27static 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.
73std::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