From b3a76f7d632c76e7302655f72a017c64ddb5c976 Mon Sep 17 00:00:00 2001 From: Sina Honari Date: Mon, 17 Nov 2014 22:24:47 -0500 Subject: [PATCH] fixing the pooling with stride plus adding a test. --- theano/tensor/signal/downsample.py | 68 ++++++------------- theano/tensor/signal/tests/test_downsample.py | 64 ++++++++++------- 2 files changed, 57 insertions(+), 75 deletions(-) diff --git a/theano/tensor/signal/downsample.py b/theano/tensor/signal/downsample.py index 87d2cd1eb7e..488d2b50677 100644 --- a/theano/tensor/signal/downsample.py +++ b/theano/tensor/signal/downsample.py @@ -78,10 +78,11 @@ def out_shape(imgshape, ds, ignore_border=False, st=None): scalar Theano variable. :param ds: downsample factor over rows and columns - this parameter indicates the pooling region + this parameter indicates the size of the pooling region :type ds: list or tuple of two ints - :param st: the stride size + :param st: the stride size. This is the distance between the pooling + regions. If it's set to None, in which case it equlas ds. :type st: list or tuple of two ints :param ignore_border: if ds doesn't divide imgshape, do we include an @@ -97,42 +98,27 @@ def out_shape(imgshape, ds, ignore_border=False, st=None): raise TypeError('imgshape must have at least two elements ' '(rows, cols)') - if st == None: + if st is None: st = ds r, c = imgshape[-2:] - if st[0] >= ds[0]: - nr = r // st[0] - else: - nr = (r - ds[0]) // st[0] + 1 - if st[1] >= ds[1]: - nc = c // st[1] - else: - nc = (c - ds[1]) // st[1] + 1 + nr = (r - ds[0]) // st[0] + 1 + nc = (c - ds[1]) // st[1] + 1 + rval = list(imgshape[:-2]) + [nr, nc] if not ignore_border: - if st[0] >= ds[0]: - if isinstance(r, theano.Variable): - rval[-2] = tensor.switch(r % st[0], rval[-2] + 1, rval[-2]) - elif r % ds[0]: - rval[-2] += 1 - else: - if isinstance(r, theano.Variable): - rval[-2] = tensor.switch((r - ds[0]) % st[0], rval[-2] + 1, rval[-2]) - elif (r - ds[0]) % st[0]: - rval[-2] += 1 - - if st[1] >= ds[1]: - if isinstance(c, theano.Variable): - rval[-1] = tensor.switch(c % st[1], rval[-1] + 1, rval[-1]) - elif c % ds[1]: - rval[-1] += 1 - else: - if isinstance(c, theano.Variable): - rval[-1] = tensor.switch((c - ds[1]) % st[1], rval[-1] + 1, rval[-1]) - elif (c - ds[1]) % st[1]: - rval[-1] += 1 + if isinstance(r, theano.Variable): + rr = r % st[0] + rval[-2] = tensor.switch(tensor.and_((rr % ds[0]), tensor.eq(rr // ds[0], 0)), rval[-2] + 1, rval[-2]) + elif (r % st[0]) % ds[0]: + rval[-2] += 1 + if isinstance(c, theano.Variable): + cr = c % st[1] + crn = cr - ds[1] + rval[-1] = tensor.switch(tensor.lt(crn, 0), rval[-1] + 1, rval[-1]) + elif (c % st[1]) % ds[1]: + rval[-1] += 1 return rval def __init__(self, ds, ignore_border=False, st=None): @@ -158,7 +144,7 @@ def __init__(self, ds, ignore_border=False, st=None): raise ValueError( "DownsampleFactorMax downsample parameters must be ints." " Got %s" % str(ds)) - if st == None: + if st is None: st = ds self.st = tuple(st) self.ignore_border = ignore_border @@ -206,22 +192,6 @@ def perform(self, node, inp, out): img_rows = x.shape[-2] img_cols = x.shape[-1] - if self.ignore_border: - if st0 >= ds0: - x_usable2 = (x.shape[2] // ds0 * ds0) - else: - x_usable2 = (x.shape[2] - ds0) // st0 * st0 + ds0 - else: - x_usable2 = x.shape[2] - - if self.ignore_border: - if st1 >= ds1: - x_usable3 = (x.shape[3] // ds1 * ds1) - else: - x_usable3 = (x.shape[3] - ds1) // st1 * st1 + ds1 - else: - x_usable3 = x.shape[3] - for n in xrange(x.shape[0]): for k in xrange(x.shape[1]): for r in xrange(pr): diff --git a/theano/tensor/signal/tests/test_downsample.py b/theano/tensor/signal/tests/test_downsample.py index 38eb2957542..8aa2dbb51fa 100644 --- a/theano/tensor/signal/tests/test_downsample.py +++ b/theano/tensor/signal/tests/test_downsample.py @@ -52,41 +52,29 @@ def numpy_max_pool_2d_stride(input, ds, ignore_border=False, st=None): st = ds xi = 0 yi = 0 + img_rows = input.shape[-2] + img_cols = input.shape[-1] + if not ignore_border: - if st[0] >= ds[0]: - if input.shape[-2] % st[0]: - xi += 1 - else: - if (input.shape[-2] - ds[0]) % st[0]: - xi += 1 - if st[1] >= ds[1]: - if input.shape[-1] % st[1]: - yi += 1 - else: - if (input.shape[-1] % - ds[1]) % st[1]: - yi += 1 + rr = (img_rows) % st[0] + cr = (img_cols) % st[1] + if rr > 0 and rr < ds[0]: + xi += 1 + if cr > 0 and cr < ds[1]: + yi += 1 + out_shp = list(input.shape[:-2]) - if st[0] >= ds[0]: - out_shp.append(input.shape[-2] / ds[0] + xi) - else: - out_shp.append((input.shape[-2] - ds[0]) / st[0] + 1 + xi) - - if st[1] >= ds[1]: - out_shp.append(input.shape[-1] / ds[1] + yi) - else: - out_shp.append((input.shape[-1] - ds[1]) / st[1] + 1 + yi) + out_shp.append((img_rows - ds[0]) / st[0] + 1 + xi) + out_shp.append((img_cols - ds[1]) / st[1] + 1 + yi) output_val = numpy.zeros(out_shp) - img_rows = input.shape[-2] - img_cols = input.shape[-1] - for k in numpy.ndindex(*input.shape[:-2]): for i in range(output_val.shape[-2]): - ii_st = i * ds[0] + ii_st = i * st[0] ii_end = __builtin__.min(ii_st + ds[0], img_rows) for j in range(output_val.shape[-1]): - jj_st = j * ds[1] + jj_st = j * st[1] jj_end = __builtin__.min(jj_st + ds[1], img_cols) patch = input[k][ii_st:ii_end, jj_st:jj_end] output_val[k][i, j] = numpy.max(patch) @@ -119,6 +107,30 @@ def test_DownsampleFactorMax(self): output_val = f(imval) assert (numpy.abs(output_val - numpy_output_val) < 1e-5).all() + def test_DownsampleFactorMaxStride(self): + rng = numpy.random.RandomState(utt.fetch_seed()) + # generate random images + maxpoolshps = ((1, 1), (2, 2), (3, 3), (2, 3)) + stridesizes = ((1, 1), (2, 2), (3, 1), (2, 5), (5, 7)) + imval = rng.rand(4, 10, 64, 64) + images = tensor.dtensor4() + + for maxpoolshp in maxpoolshps: + for ignore_border in [True, False]: + for stride in stridesizes: + print 'maxpoolshp =', maxpoolshp + print 'ignore_border =', ignore_border + print 'stride =', stride + + #DownsampleFactorMax op + numpy_output_val = self.numpy_max_pool_2d_stride(imval, maxpoolshp, + ignore_border, stride) + maxpool_op = DownsampleFactorMax(maxpoolshp, + ignore_border=ignore_border, st=stride)(images) + f = function([images], maxpool_op) + output_val = f(imval) + assert (numpy.abs(output_val - numpy_output_val) < 1e-5).all() + def test_DownsampleFactorMax_grad(self): rng = numpy.random.RandomState(utt.fetch_seed()) maxpoolshps = ((1, 1), (3, 2), (2, 3))