|| (!pool_param.has_stride_h() && !pool_param.has_stride_w()))
<< "Stride is stride OR stride_h and stride_w are required.";
global_pooling_ = pool_param.global_pooling();
+ round_mode_ = pool_param.round_mode();
if (global_pooling_) {
kernel_h_ = bottom[0]->height();
kernel_w_ = bottom[0]->width();
kernel_h_ = bottom[0]->height();
kernel_w_ = bottom[0]->width();
}
- 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;
+ switch (round_mode_) {
+ case PoolingParameter_RoundMode_CEIL:
+ 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;
+ break;
+ case PoolingParameter_RoundMode_FLOOR:
+ pooled_height_ = static_cast<int>(floor(static_cast<float>(
+ height_ + 2 * pad_h_ - kernel_h_) / stride_h_)) + 1;
+ pooled_width_ = static_cast<int>(floor(static_cast<float>(
+ width_ + 2 * pad_w_ - kernel_w_) / stride_w_)) + 1;
+ break;
+ default:
+ LOG(FATAL) << "Unknown rounding mode.";
+ }
if (pad_h_ || pad_w_) {
// If we have padding, ensure that the last pooling starts strictly
// inside the image (instead of at the padding); otherwise clip the last.
// If global_pooling then it will pool over the size of the bottom by doing
// kernel_h = bottom->height and kernel_w = bottom->width
optional bool global_pooling = 12 [default = false];
+ // How to calculate the output size - using ceil (default) or floor rounding.
+ enum RoundMode {
+ CEIL = 0;
+ FLOOR = 1;
+ }
+ optional RoundMode round_mode = 13 [default = CEIL];
}
message PowerParameter {