void Pooling::Setup()

in src/model/layer/pooling.cc [26:84]


void Pooling::Setup(const Shape& in_sample, const LayerConf& conf) {
  Layer::Setup(in_sample, conf);
  PoolingConf pool_conf = conf.pooling_conf();
  if (pool_conf.has_kernel_size()) {
    kernel_w_ = kernel_h_ = pool_conf.kernel_size();
  } else {
    kernel_w_ = pool_conf.kernel_w();
    kernel_h_ = pool_conf.kernel_h();
  }
  CHECK_GT(kernel_w_, 0u);
  CHECK_GT(kernel_h_, 0u);

  if (pool_conf.has_pad()) {
    pad_w_ = pad_h_ = pool_conf.pad();
  } else {
    pad_w_ = pool_conf.pad_w();
    pad_h_ = pool_conf.pad_h();
  }
  CHECK_GE(pad_w_, 0u);
  CHECK_GE(pad_h_, 0u);

  if (pool_conf.has_stride()) {
    stride_w_ = stride_h_ = pool_conf.stride();
  } else {
    stride_w_ = pool_conf.stride_w();
    stride_h_ = pool_conf.stride_h();
  }
  CHECK_GT(stride_w_, 0u);
  CHECK_GE(stride_h_, 0u);  // 0 for 1D pooling

  pool_ = pool_conf.pool();
  CHECK(pool_ == PoolingConf_PoolMethod_AVE ||
        pool_ == PoolingConf_PoolMethod_MAX ||
        pool_ == PoolingConf_PoolMethod_STOCHASTIC)
      << "Padding implemented only for average and max pooling.";

  CHECK_EQ(in_sample.size(), 3u);
  channels_ = in_sample.at(0);
  height_ = in_sample.at(1);
  width_ = in_sample.at(2);
  pooled_height_ = 1;
  if (pool_conf.ceil()) {
    // TODO(wangwei): caffe also ensures the last pooling window starts strictly
    // within the original area
    if (stride_h_ > 0)
      pooled_height_ = static_cast<int>(ceil(static_cast<float>(
              height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
    pooled_width_ = static_cast<int>(ceil(static_cast<float>(
        width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
  }
  else {
    if (stride_h_ > 0)
      pooled_height_ =
          static_cast<size_t>((height_ + 2 * pad_h_ - kernel_h_) / stride_h_) + 1;
    pooled_width_ =
        static_cast<size_t>((width_ + 2 * pad_w_ - kernel_w_) / stride_w_) + 1;
  }
  out_sample_shape_ = vector<size_t>{channels_, pooled_height_, pooled_width_};
}