setParamsFrom(params);
ceilMode = params.get<bool>("ceil_mode", true);
spatialScale = params.get<float>("spatial_scale", 1);
+ avePoolPaddedArea = params.get<bool>("ave_pool_padded_area", true);
}
#ifdef HAVE_OPENCL
const Mat* src, *rois;
Mat *dst, *mask;
Size kernel, stride, pad;
- String padMode;
+ bool avePoolPaddedArea;
int nstripes;
bool computeMaxIdx;
std::vector<int> ofsbuf;
computeMaxIdx(0), poolingType(MAX), spatialScale(0) {}
static void run(const Mat& src, const Mat& rois, Mat& dst, Mat& mask, Size kernel,
- Size stride, Size pad, String padMode, int poolingType, float spatialScale,
+ Size stride, Size pad, bool avePoolPaddedArea, int poolingType, float spatialScale,
bool computeMaxIdx, int nstripes)
{
CV_Assert(src.isContinuous(), dst.isContinuous(),
p.kernel = kernel;
p.stride = stride;
p.pad = pad;
- p.padMode = padMode;
+ p.avePoolPaddedArea = avePoolPaddedArea;
p.nstripes = nstripes;
p.computeMaxIdx = computeMaxIdx;
p.poolingType = poolingType;
yend = min(ystart + kernel_h, inp_height + pad_h);
srcData = src->ptr<float>(n, c);
}
+ int ydelta = yend - ystart;
ystart = max(ystart, 0);
yend = min(yend, inp_height);
float *dstData = dst->ptr<float>(n, c, y0);
}
else if (poolingType == AVE)
{
- bool isSamePad = padMode == "SAME";
for( ; x0 < x1; x0++ )
{
int xstart = x0 * stride_w - pad_w;
int xend = min(xstart + kernel_w, inp_width + pad_w);
+ int xdelta = xend - xstart;
xstart = max(xstart, 0);
xend = min(xend, inp_width);
- float inv_kernel_area = isSamePad ? (yend - ystart) * (xend - xstart) : kernel.area();
+ float inv_kernel_area = avePoolPaddedArea ? xdelta * ydelta : ((yend - ystart) * (xend - xstart));
inv_kernel_area = 1.0 / inv_kernel_area;
#if CV_SIMD128
if( xstart > 0 && x0 + 7 < x1 && (x0 + 7) * stride_w - pad_w + kernel_w < inp_width )
{
const int nstripes = getNumThreads();
Mat rois;
- PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, padMode, type, spatialScale, computeMaxIdx, nstripes);
+ PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
void avePooling(Mat &src, Mat &dst)
{
const int nstripes = getNumThreads();
Mat rois, mask;
- PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, padMode, type, spatialScale, computeMaxIdx, nstripes);
+ PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
void roiPooling(const Mat &src, const Mat &rois, Mat &dst)
{
const int nstripes = getNumThreads();
Mat mask;
- PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, padMode, type, spatialScale, computeMaxIdx, nstripes);
+ PoolingInvoker::run(src, rois, dst, mask, kernel, stride, pad, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
}
virtual Ptr<BackendNode> initMaxPoolingHalide(const std::vector<Ptr<BackendWrapper> > &inputs)
/*offset value*/ Values(3, 4)
));
+// Check that by default average pooling layer should not count zero padded values
+// into the normalization area.
+TEST(Layer_Test_Average_pooling_kernel_area, Accuracy)
+{
+ LayerParams lp;
+ lp.name = "testAvePool";
+ lp.type = "Pooling";
+ lp.set("kernel_size", 2);
+ lp.set("stride", 2);
+ lp.set("pool", "AVE");
+
+ Net net;
+ net.addLayerToPrev(lp.name, lp.type, lp);
+ // 1 2 | 3
+ // 4 5 | 6
+ // ----+--
+ // 7 8 | 9
+ Mat inp = (Mat_<float>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ Mat target = (Mat_<float>(2, 2) << (1 + 2 + 4 + 5) / 4.f, (3 + 6) / 2.f, (7 + 8) / 2.f, 9);
+ Mat tmp = blobFromImage(inp);
+ net.setInput(blobFromImage(inp));
+ Mat out = net.forward();
+ normAssert(out, blobFromImage(target));
+}
+
}} // namespace