| 233 | } |
| 234 | |
| 235 | void Pooling::ForwardAvgPooling(const float* bottom, const int num, |
| 236 | const int channels, |
| 237 | const int height, const int width, |
| 238 | const int pooled_h, const int pooled_w, |
| 239 | const int kernel_h, const int kernel_w, |
| 240 | const int pad_h, const int pad_w, |
| 241 | const int stride_h, const int stride_w, |
| 242 | float* top) { |
| 243 | int top_count = num * pooled_h * pooled_w * channels; |
| 244 | for (int i = 0; i < top_count; i++) { |
| 245 | top[i] = 0; |
| 246 | } |
| 247 | const int bottom_offset = height * width; |
| 248 | const int top_offset = pooled_h * pooled_w; |
| 249 | // The main loop |
| 250 | for (int n = 0; n < num; ++n) { |
| 251 | for (int c = 0; c < channels; ++c) { |
| 252 | for (int ph = 0; ph < pooled_h; ++ph) { |
| 253 | for (int pw = 0; pw < pooled_w; ++pw) { |
| 254 | int hstart = ph * stride_h - pad_h; |
| 255 | int wstart = pw * stride_w - pad_w; |
| 256 | int hend = std::min(hstart + kernel_h, height + pad_h); |
| 257 | int wend = std::min(wstart + kernel_w, width + pad_w); |
| 258 | int pool_size = (hend - hstart) * (wend - wstart); |
| 259 | hstart = std::max(hstart, 0); |
| 260 | wstart = std::max(wstart, 0); |
| 261 | hend = std::min(hend, height); |
| 262 | wend = std::min(wend, width); |
| 263 | const int top_index = ph * pooled_w + pw; |
| 264 | for (int h = hstart; h < hend; ++h) { |
| 265 | for (int w = wstart; w < wend; ++w) { |
| 266 | const int index = h * width + w; |
| 267 | top[top_index] += bottom[index]; |
| 268 | } |
| 269 | } |
| 270 | top[top_index] /= pool_size; |
| 271 | } |
| 272 | } |
| 273 | // compute offset |
| 274 | bottom += bottom_offset; |
| 275 | top += top_offset; |
| 276 | } |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | void Pooling::BackwardAvgPooling(const float* top, const int num, |
| 281 | const int channels, |