| 160 | } |
| 161 | |
| 162 | void Pooling::ForwardMaxPooling(const float* bottom, const int num, |
| 163 | const int channels, |
| 164 | const int height, const int width, |
| 165 | const int pooled_h, const int pooled_w, |
| 166 | const int kernel_h, const int kernel_w, |
| 167 | const int pad_h, const int pad_w, |
| 168 | const int stride_h, const int stride_w, |
| 169 | float* top, float* mask) { |
| 170 | int top_count = num * pooled_h * pooled_w * channels; |
| 171 | for (int i = 0; i < top_count; i++) { |
| 172 | mask[i] = -1; |
| 173 | top[i] = -FLT_MAX; |
| 174 | } |
| 175 | const int bottom_offset = height * width; |
| 176 | const int top_offset = pooled_h * pooled_w; |
| 177 | // The main loop |
| 178 | for (int n = 0; n < num; ++n) { |
| 179 | for (int c = 0; c < channels; ++c) { |
| 180 | for (int ph = 0; ph < pooled_h; ++ph) { |
| 181 | for (int pw = 0; pw < pooled_w; ++pw) { |
| 182 | int hstart = ph * stride_h - pad_h; |
| 183 | int wstart = pw * stride_w - pad_w; |
| 184 | int hend = std::min(hstart + kernel_h, height); |
| 185 | int wend = std::min(wstart + kernel_w, width); |
| 186 | hstart = std::max(hstart, 0); |
| 187 | wstart = std::max(wstart, 0); |
| 188 | const int top_index = ph * pooled_w + pw; |
| 189 | for (int h = hstart; h < hend; ++h) { |
| 190 | for (int w = wstart; w < wend; ++w) { |
| 191 | const int index = h * width + w; |
| 192 | if (bottom[index] > top[top_index]) { |
| 193 | top[top_index] = bottom[index]; |
| 194 | mask[top_index] = (float) index; |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | } |
| 199 | } |
| 200 | // compute offset |
| 201 | bottom += bottom_offset; |
| 202 | top += top_offset; |
| 203 | mask += top_offset; |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | |
| 208 | void Pooling::BackwardMaxPooling(const float* top, const float* mask, |
| 209 | const int num, const int channels, |