提交 1d2eec53 authored 作者: Sina Honari's avatar Sina Honari

applying the changes for the case of ignore_border plus the changes for pep8 for issue #2196

上级 26c105c9
...@@ -29,8 +29,8 @@ def max_pool_2d(input, ds, ignore_border=False): ...@@ -29,8 +29,8 @@ def max_pool_2d(input, ds, ignore_border=False):
:param input: input images. Max pooling will be done over the 2 last :param input: input images. Max pooling will be done over the 2 last
dimensions. dimensions.
:type ds: tuple of length 2 :type ds: tuple of length 2
:param ds: factor by which to downscale (vertical ds, horizontal ds). :param ds: factor by which to downscale (vertical ds, horizontal ds).
(2,2) will halve the image in each dimension. (2,2) will halve the image in each dimension.
:param ignore_border: boolean value. When True, (5,5) input with ds=(2,2) :param ignore_border: boolean value. When True, (5,5) input with ds=(2,2)
will generate a (2,2) output. (3,3) otherwise. will generate a (2,2) output. (3,3) otherwise.
""" """
...@@ -81,7 +81,7 @@ class DownsampleFactorMax(Op): ...@@ -81,7 +81,7 @@ class DownsampleFactorMax(Op):
this parameter indicates the size of the pooling region this parameter indicates the size of the pooling region
:type ds: list or tuple of two ints :type ds: list or tuple of two ints
:param st: the stride size. This is the distance between the pooling :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. regions. If it's set to None, in which case it equlas ds.
:type st: list or tuple of two ints :type st: list or tuple of two ints
...@@ -102,29 +102,34 @@ class DownsampleFactorMax(Op): ...@@ -102,29 +102,34 @@ class DownsampleFactorMax(Op):
st = ds st = ds
r, c = imgshape[-2:] r, c = imgshape[-2:]
out_r = (r - ds[0]) // st[0] + 1 if ignore_border:
out_c = (c - ds[1]) // st[1] + 1 out_r = (r - ds[0]) // st[0] + 1
out_c = (c - ds[1]) // st[1] + 1
if isinstance(r, theano.Variable): if isinstance(r, theano.Variable):
nr = tensor.maximum(out_r, 0) nr = tensor.maximum(out_r, 0)
else: else:
nr = numpy.maximum(out_r, 0) nr = numpy.maximum(out_r, 0)
if isinstance(c, theano.Variable): if isinstance(c, theano.Variable):
nc = tensor.maximum(out_c, 0) nc = tensor.maximum(out_c, 0)
else:
nc = numpy.maximum(out_c, 0)
else: else:
nc = numpy.maximum(out_c, 0)
if not ignore_border:
if isinstance(r, theano.Variable): if isinstance(r, theano.Variable):
nr = tensor.switch(tensor.ge(st[0], ds[0]), (r - 1) // st[0] + 1, tensor.maximum(0, (r - 1 - ds[0]) // st[0] + 1) + 1) nr = tensor.switch(tensor.ge(st[0], ds[0]),
elif st[0] >= ds[0]: (r - 1) // st[0] + 1,
tensor.maximum(0, (r - 1 - ds[0])
// st[0] + 1) + 1)
elif st[0] >= ds[0]:
nr = (r - 1) // st[0] + 1 nr = (r - 1) // st[0] + 1
else: else:
nr = max(0, (r - 1 - ds[0]) // st[0] + 1) + 1 nr = max(0, (r - 1 - ds[0]) // st[0] + 1) + 1
if isinstance(c, theano.Variable): if isinstance(c, theano.Variable):
nc = tensor.switch(tensor.ge(st[1], ds[1]), (c - 1) // st[1] + 1, tensor.maximum(0, (c - 1 - ds[1]) // st[1] + 1) + 1) nc = tensor.switch(tensor.ge(st[1], ds[1]),
elif st[1] >= ds[1]: (c - 1) // st[1] + 1,
tensor.maximum(0, (c - 1 - ds[1])
// st[1] + 1) + 1)
elif st[1] >= ds[1]:
nc = (c - 1) // st[1] + 1 nc = (c - 1) // st[1] + 1
else: else:
nc = max(0, (c - 1 - ds[1]) // st[1] + 1) + 1 nc = max(0, (c - 1 - ds[1]) // st[1] + 1) + 1
...@@ -134,14 +139,15 @@ class DownsampleFactorMax(Op): ...@@ -134,14 +139,15 @@ class DownsampleFactorMax(Op):
def __init__(self, ds, ignore_border=False, st=None): def __init__(self, ds, ignore_border=False, st=None):
""" """
:param ds: downsample factor over rows and column. ds indicates the pool region size :param ds: downsample factor over rows and column.
ds indicates the pool region size.
:type ds: list or tuple of two ints :type ds: list or tuple of two ints
: param st: stride size, which is the number of shifts : param st: stride size, which is the number of shifts
over rows/cols to get the the next pool region. over rows/cols to get the the next pool region.
if st is None, it is considered equal to ds if st is None, it is considered equal to ds
(no overlap on pooling regions) (no overlap on pooling regions)
: type st: list or tuple of two ints : type st: list or tuple of two ints
:param ignore_border: if ds doesn't divide imgshape, do we include :param ignore_border: if ds doesn't divide imgshape, do we include
an extra row/col of partial downsampling (False) or an extra row/col of partial downsampling (False) or
...@@ -167,11 +173,12 @@ class DownsampleFactorMax(Op): ...@@ -167,11 +173,12 @@ class DownsampleFactorMax(Op):
self.ignore_border == other.ignore_border) self.ignore_border == other.ignore_border)
def __hash__(self): def __hash__(self):
return hash(type(self)) ^ hash(self.ds) ^ hash(self.st) ^ hash(self.ignore_border) return hash(type(self)) ^ hash(self.ds) ^ \
hash(self.st) ^ hash(self.ignore_border)
def __str__(self): def __str__(self):
return '%s{%s,%s,%s}' % (self.__class__.__name__, return '%s{%s,%s,%s}' % (self.__class__.__name__,
self.ds, self.st, self.ignore_border) self.ds, self.st, self.ignore_border)
def make_node(self, x): def make_node(self, x):
if x.type.ndim != 4: if x.type.ndim != 4:
...@@ -196,8 +203,10 @@ class DownsampleFactorMax(Op): ...@@ -196,8 +203,10 @@ class DownsampleFactorMax(Op):
## zz needs to be initialized with -inf for the following to work ## zz needs to be initialized with -inf for the following to work
zz -= numpy.inf zz -= numpy.inf
pr = zz.shape[-2] # number of pooling output rows #number of pooling output rows
pc = zz.shape[-1] # number of pooling output cols pr = zz.shape[-2]
#number of pooling output cols
pc = zz.shape[-1]
ds0, ds1 = self.ds ds0, ds1 = self.ds
st0, st1 = self.st st0, st1 = self.st
img_rows = x.shape[-2] img_rows = x.shape[-2]
...@@ -213,11 +222,13 @@ class DownsampleFactorMax(Op): ...@@ -213,11 +222,13 @@ class DownsampleFactorMax(Op):
col_end = __builtin__.min(col_st + ds1, img_cols) col_end = __builtin__.min(col_st + ds1, img_cols)
for row_ind in xrange(row_st, row_end): for row_ind in xrange(row_st, row_end):
for col_ind in xrange(col_st, col_end): for col_ind in xrange(col_st, col_end):
zz[n, k, r, c] = __builtin__.max(zz[n, k, r, c], zz[n, k, r, c] = \
x[n, k, row_ind, col_ind]) __builtin__.max(zz[n, k, r, c],
x[n, k, row_ind, col_ind])
def infer_shape(self, node, in_shapes): def infer_shape(self, node, in_shapes):
shp = self.out_shape(in_shapes[0], self.ds, self.ignore_border, self.st) shp = self.out_shape(in_shapes[0], self.ds,
self.ignore_border, self.st)
return [shp] return [shp]
def grad(self, inp, grads): def grad(self, inp, grads):
......
...@@ -15,8 +15,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -15,8 +15,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
'''Helper function, implementing max_pool_2d in pure numpy''' '''Helper function, implementing max_pool_2d in pure numpy'''
if len(input.shape) < 2: if len(input.shape) < 2:
raise NotImplementedError('input should have at least 2 dim,' raise NotImplementedError('input should have at least 2 dim,'
' shape is %s'\ ' shape is %s'
% str(input.shape)) % str(input.shape))
xi = 0 xi = 0
yi = 0 yi = 0
if not ignore_border: if not ignore_border:
...@@ -45,10 +45,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -45,10 +45,10 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
for the pooling regions. if not indicated, st == sd.''' for the pooling regions. if not indicated, st == sd.'''
if len(input.shape) < 2: if len(input.shape) < 2:
raise NotImplementedError('input should have at least 2 dim,' raise NotImplementedError('input should have at least 2 dim,'
' shape is %s'\ ' shape is %s'
% str(input.shape)) % str(input.shape))
if st == None: if st is None:
st = ds st = ds
xi = 0 xi = 0
yi = 0 yi = 0
...@@ -58,25 +58,24 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -58,25 +58,24 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
out_r = 0 out_r = 0
out_c = 0 out_c = 0
if img_rows - ds[0] >= 0: if img_rows - ds[0] >= 0:
out_r = (img_rows - ds[0]) // st[0] + 1 out_r = (img_rows - ds[0]) // st[0] + 1
if img_cols - ds[1] >= 0: if img_cols - ds[1] >= 0:
out_c = (img_cols - ds[1]) // st[1] + 1 out_c = (img_cols - ds[1]) // st[1] + 1
if not ignore_border: if not ignore_border:
if out_r > 0: if out_r > 0:
if img_rows - ((out_r - 1) * st[0] + ds[0]) > 0 : if img_rows - ((out_r - 1) * st[0] + ds[0]) > 0:
rr = img_rows - out_r * st[0] rr = img_rows - out_r * st[0]
if rr > 0: if rr > 0:
out_r += 1 out_r += 1
else: else:
if img_rows > 0: if img_rows > 0:
out_r += 1 out_r += 1
if out_c > 0: if out_c > 0:
if img_cols - ((out_c - 1) * st[1] + ds[1]) > 0 : if img_cols - ((out_c - 1) * st[1] + ds[1]) > 0:
cr = img_cols - out_c * st[1] cr = img_cols - out_c * st[1]
if cr > 0: if cr > 0:
out_c +=1 out_c += 1
else: else:
if img_cols > 0: if img_cols > 0:
out_c += 1 out_c += 1
...@@ -119,7 +118,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -119,7 +118,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
#DownsampleFactorMax op #DownsampleFactorMax op
maxpool_op = DownsampleFactorMax(maxpoolshp, maxpool_op = DownsampleFactorMax(maxpoolshp,
ignore_border=ignore_border)(images) ignore_border=
ignore_border)(images)
f = function([images], maxpool_op) f = function([images], maxpool_op)
output_val = f(imval) output_val = f(imval)
utt.assert_allclose(output_val, numpy_output_val) utt.assert_allclose(output_val, numpy_output_val)
...@@ -130,11 +130,12 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -130,11 +130,12 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
stridesizes = ((1, 1), (3, 3), (5, 7)) stridesizes = ((1, 1), (3, 3), (5, 7))
# generate random images # generate random images
imval = rng.rand(4, 10, 16, 16) imval = rng.rand(4, 10, 16, 16)
outputshps = ((4, 10, 16, 16), (4, 10, 6, 6), (4, 10, 4, 3), (4, 10, 16, 16), \ outputshps = ((4, 10, 16, 16), (4, 10, 6, 6), (4, 10, 4, 3),
(4, 10, 6, 6), (4, 10, 4, 3), (4, 10, 14, 14), (4, 10, 5, 5), \ (4, 10, 16, 16), (4, 10, 6, 6), (4, 10, 4, 3),
(4, 10, 3, 2), (4, 10, 14, 14), (4, 10, 6, 6), (4, 10, 4, 3), \ (4, 10, 14, 14), (4, 10, 5, 5), (4, 10, 3, 2),
(4, 10, 12, 14), (4, 10, 4, 5), (4, 10, 3, 2), (4, 10, 12, 14), \ (4, 10, 14, 14), (4, 10, 6, 6), (4, 10, 4, 3),
(4, 10, 5, 6), (4, 10, 4, 3)) (4, 10, 12, 14), (4, 10, 4, 5), (4, 10, 3, 2),
(4, 10, 12, 14), (4, 10, 5, 6), (4, 10, 4, 3))
images = tensor.dtensor4() images = tensor.dtensor4()
indx = 0 indx = 0
for maxpoolshp in maxpoolshps: for maxpoolshp in maxpoolshps:
...@@ -143,13 +144,16 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -143,13 +144,16 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
outputshp = outputshps[indx] outputshp = outputshps[indx]
indx += 1 indx += 1
#DownsampleFactorMax op #DownsampleFactorMax op
numpy_output_val = self.numpy_max_pool_2d_stride(imval, maxpoolshp, numpy_output_val = \
ignore_border, stride) self.numpy_max_pool_2d_stride(imval, maxpoolshp,
ignore_border, stride)
assert numpy_output_val.shape == outputshp, ( assert numpy_output_val.shape == outputshp, (
"outshape is %s, calculated shape is %s" "outshape is %s, calculated shape is %s"
%(outputshp, numpy_output_val.shape)) % (outputshp, numpy_output_val.shape))
maxpool_op = DownsampleFactorMax(maxpoolshp, maxpool_op = \
ignore_border=ignore_border, st=stride)(images) DownsampleFactorMax(maxpoolshp,
ignore_border=ignore_border,
st=stride)(images)
f = function([images], maxpool_op) f = function([images], maxpool_op)
output_val = f(imval) output_val = f(imval)
utt.assert_allclose(output_val, numpy_output_val) utt.assert_allclose(output_val, numpy_output_val)
...@@ -157,16 +161,19 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -157,16 +161,19 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
def test_DownsampleFactorMaxStrideExtra(self): def test_DownsampleFactorMaxStrideExtra(self):
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
maxpoolshps = ((5, 3), (5, 3), (5, 3), (5, 5), (3, 2), (7, 7), (9, 9)) maxpoolshps = ((5, 3), (5, 3), (5, 3), (5, 5), (3, 2), (7, 7), (9, 9))
stridesizes = ((3, 2), (7, 5), (10, 6), (1, 1), (2, 3), (10, 10), (1, 1)) stridesizes = ((3, 2), (7, 5), (10, 6), (1, 1),
imvsizs = ((16, 16), (16, 16), (16, 16), (8, 5), (8, 5), (8, 5), (8, 5)) (2, 3), (10, 10), (1, 1))
outputshps = ((4, 10, 4, 7), (4, 10, 5, 8), (4, 10, 2, 3), (4, 10, 3, 4), \ imvsizs = ((16, 16), (16, 16), (16, 16), (8, 5),
(4, 10, 2, 3), (4, 10, 2, 3), (4, 10, 4, 1), (4, 10, 4, 1), \ (8, 5), (8, 5), (8, 5))
(4, 10, 3, 2), (4, 10, 4, 2), (4, 10, 1, 0), (4, 10, 1, 1), \ outputshps = ((4, 10, 4, 7), (4, 10, 5, 8), (4, 10, 2, 3),
(4, 10, 3, 4), (4, 10, 2, 3), (4, 10, 2, 3),
(4, 10, 4, 1), (4, 10, 4, 1), (4, 10, 3, 2),
(4, 10, 4, 2), (4, 10, 1, 0), (4, 10, 1, 1),
(4, 10, 0, 0), (4, 10, 1, 1)) (4, 10, 0, 0), (4, 10, 1, 1))
images = tensor.dtensor4() images = tensor.dtensor4()
for indx in numpy.arange(len(maxpoolshps)): for indx in numpy.arange(len(maxpoolshps)):
imvsize = imvsizs[indx] imvsize = imvsizs[indx]
imval = rng.rand(4, 10 , imvsize[0], imvsize[1]) imval = rng.rand(4, 10, imvsize[0], imvsize[1])
stride = stridesizes[indx] stride = stridesizes[indx]
maxpoolshp = maxpoolshps[indx] maxpoolshp = maxpoolshps[indx]
for ignore_border in [True, False]: for ignore_border in [True, False]:
...@@ -175,13 +182,16 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -175,13 +182,16 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
indx_out += 1 indx_out += 1
outputshp = outputshps[indx_out] outputshp = outputshps[indx_out]
#DownsampleFactorMax op #DownsampleFactorMax op
numpy_output_val = self.numpy_max_pool_2d_stride(imval, maxpoolshp, numpy_output_val = \
ignore_border, stride) self.numpy_max_pool_2d_stride(imval, maxpoolshp,
ignore_border, stride)
assert numpy_output_val.shape == outputshp, ( assert numpy_output_val.shape == outputshp, (
"outshape is %s, calculated shape is %s" "outshape is %s, calculated shape is %s"
%(outputshp, numpy_output_val.shape)) % (outputshp, numpy_output_val.shape))
maxpool_op = DownsampleFactorMax(maxpoolshp, maxpool_op = \
ignore_border=ignore_border, st=stride)(images) DownsampleFactorMax(maxpoolshp,
ignore_border=ignore_border,
st=stride)(images)
f = function([images], maxpool_op) f = function([images], maxpool_op)
output_val = f(imval) output_val = f(imval)
utt.assert_allclose(output_val, numpy_output_val) utt.assert_allclose(output_val, numpy_output_val)
...@@ -198,7 +208,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -198,7 +208,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
#print 'ignore_border =', ignore_border #print 'ignore_border =', ignore_border
def mp(input): def mp(input):
return DownsampleFactorMax(maxpoolshp, return DownsampleFactorMax(maxpoolshp,
ignore_border=ignore_border)(input) ignore_border=
ignore_border)(input)
utt.verify_grad(mp, [imval], rng=rng) utt.verify_grad(mp, [imval], rng=rng)
def test_DownsampleFactorMaxGrad_grad(self): def test_DownsampleFactorMaxGrad_grad(self):
...@@ -257,7 +268,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -257,7 +268,8 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
output_val = function([images], output)(imval) output_val = function([images], output)(imval)
assert numpy.all(output_val == numpy_output_val), ( assert numpy.all(output_val == numpy_output_val), (
"output_val is %s, numpy_output_val is %s" "output_val is %s, numpy_output_val is %s"
%(output_val, numpy_output_val)) % (output_val, numpy_output_val))
def mp(input): def mp(input):
return max_pool_2d(input, maxpoolshp, ignore_border) return max_pool_2d(input, maxpoolshp, ignore_border)
utt.verify_grad(mp, [imval], rng=rng) utt.verify_grad(mp, [imval], rng=rng)
...@@ -278,15 +290,15 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -278,15 +290,15 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
output_val = function([images], output)(imval) output_val = function([images], output)(imval)
assert numpy.all(output_val == numpy_output_val), ( assert numpy.all(output_val == numpy_output_val), (
"output_val is %s, numpy_output_val is %s" "output_val is %s, numpy_output_val is %s"
%(output_val, numpy_output_val)) % (output_val, numpy_output_val))
c = tensor.sum(output) c = tensor.sum(output)
c_val = function([images], c)(imval) c_val = function([images], c)(imval)
g = tensor.grad(c, images) g = tensor.grad(c, images)
g_val = function([images], g_val = function([images],
[g.shape, [g.shape,
tensor.min(g, axis=(0, 1, 2)), tensor.min(g, axis=(0, 1, 2)),
tensor.max(g, axis=(0, 1, 2))] tensor.max(g, axis=(0, 1, 2))]
)(imval) )(imval)
#removed as already tested in test_max_pool_2d_2D #removed as already tested in test_max_pool_2d_2D
#This make test in debug mode too slow. #This make test in debug mode too slow.
...@@ -335,19 +347,20 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -335,19 +347,20 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
# checking shapes generated by DownsampleFactorMax # checking shapes generated by DownsampleFactorMax
self._compile_and_check([image], self._compile_and_check([image],
[DownsampleFactorMax(maxpoolshp, [DownsampleFactorMax(maxpoolshp,
ignore_border=ignore_border)(image)], ignore_border=ignore_border)(image)],
[image_val], DownsampleFactorMax) [image_val], DownsampleFactorMax)
# checking shapes generated by DownsampleFactorMaxGrad # checking shapes generated by DownsampleFactorMaxGrad
maxout_val = rng.rand(*out_shapes[i][j]) maxout_val = rng.rand(*out_shapes[i][j])
gz_val = rng.rand(*out_shapes[i][j]) gz_val = rng.rand(*out_shapes[i][j])
self._compile_and_check([image, maxout, gz], self._compile_and_check([image, maxout, gz],
[DownsampleFactorMaxGrad(maxpoolshp, [DownsampleFactorMaxGrad(maxpoolshp,
ignore_border=ignore_border)(image, maxout, gz)], ignore_border=ignore_border)
[image_val, maxout_val, gz_val], (image, maxout, gz)],
[image_val, maxout_val, gz_val],
DownsampleFactorMaxGrad, DownsampleFactorMaxGrad,
warn=False) warn=False)
if __name__ == '__main__': if __name__ == '__main__':
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论