提交 bd5dc5a8 authored 作者: Li's avatar Li

pep8, and grad finally worked

上级 33551a31
...@@ -12,13 +12,14 @@ import numpy ...@@ -12,13 +12,14 @@ import numpy
import theano import theano
from theano import gof, Op, tensor, Variable, Apply from theano import gof, Op, tensor, Variable, Apply
def max_pool2D(*args, **kwargs): def max_pool2D(*args, **kwargs):
import sys import sys
print >> sys.stderr, "DEPRECATION: max_pool2D renamed to max_pool_2d" print >> sys.stderr, "DEPRECATION: max_pool2D renamed to max_pool_2d"
return max_pool_2d(*args, **kwargs) return max_pool_2d(*args, **kwargs)
def max_pool_2d(input, ds, ignore_border=False, st=None, padding=(0,0)): def max_pool_2d(input, ds, ignore_border=False, st=None, padding=(0, 0)):
""" """
Takes as input a N-D tensor, where N >= 2. It downscales the input image by Takes as input a N-D tensor, where N >= 2. It downscales the input image by
the specified factor, by keeping only the maximum value of non-overlapping the specified factor, by keeping only the maximum value of non-overlapping
...@@ -79,7 +80,7 @@ class DownsampleFactorMax(Op): ...@@ -79,7 +80,7 @@ class DownsampleFactorMax(Op):
__props__ = ('ds', 'ignore_border', 'st', 'padding') __props__ = ('ds', 'ignore_border', 'st', 'padding')
@staticmethod @staticmethod
def out_shape(imgshape, ds, ignore_border=False, st=None, padding=(0,0)): def out_shape(imgshape, ds, ignore_border=False, st=None, padding=(0, 0)):
"""Return the shape of the output from this op, for input of given """Return the shape of the output from this op, for input of given
shape and flags. shape and flags.
...@@ -100,8 +101,9 @@ class DownsampleFactorMax(Op): ...@@ -100,8 +101,9 @@ class DownsampleFactorMax(Op):
extra row/col of partial downsampling (False) or ignore it (True). extra row/col of partial downsampling (False) or ignore it (True).
:type ignore_border: bool :type ignore_border: bool
:param padding: pad zeros on four borders of the images :param padding: (pad_h, pad_w), pad zeros on four borders
:type padding: tuple of two ints of the images, pad_h for padding rows, and pad_w for columns.
:type padding: tuple of two ints
:rtype: list :rtype: list
:returns: the shape of the output from this op, for input of given :returns: the shape of the output from this op, for input of given
...@@ -117,7 +119,7 @@ class DownsampleFactorMax(Op): ...@@ -117,7 +119,7 @@ class DownsampleFactorMax(Op):
r, c = imgshape[-2:] r, c = imgshape[-2:]
r += padding[0] * 2 r += padding[0] * 2
c += padding[1] * 2 c += padding[1] * 2
if ignore_border: if ignore_border:
out_r = (r - ds[0]) // st[0] + 1 out_r = (r - ds[0]) // st[0] + 1
out_c = (c - ds[1]) // st[1] + 1 out_c = (c - ds[1]) // st[1] + 1
...@@ -153,7 +155,7 @@ class DownsampleFactorMax(Op): ...@@ -153,7 +155,7 @@ class DownsampleFactorMax(Op):
rval = list(imgshape[:-2]) + [nr, nc] rval = list(imgshape[:-2]) + [nr, nc]
return rval return rval
def __init__(self, ds, ignore_border=False, st=None, padding=(0,0)): def __init__(self, ds, ignore_border=False, st=None, padding=(0, 0)):
""" """
:param ds: downsample factor over rows and column. :param ds: downsample factor over rows and column.
ds indicates the pool region size. ds indicates the pool region size.
...@@ -170,8 +172,9 @@ class DownsampleFactorMax(Op): ...@@ -170,8 +172,9 @@ class DownsampleFactorMax(Op):
(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 padding: pad zeros on four borders of the images :param padding: (pad_h, pad_w), pad zeros on four borders
:type padding: tuple of two ints of the images, pad_h for padding rows, and pad_w for columns.
:type padding: tuple of two ints
""" """
self.ds = tuple(ds) self.ds = tuple(ds)
...@@ -185,13 +188,16 @@ class DownsampleFactorMax(Op): ...@@ -185,13 +188,16 @@ class DownsampleFactorMax(Op):
self.ignore_border = ignore_border self.ignore_border = ignore_border
self.padding = tuple(padding) self.padding = tuple(padding)
self.padding = padding self.padding = padding
if padding != (0,0) and not ignore_border: if padding != (0, 0) and not ignore_border:
raise NotImplementedError('padding works only with ignore_boarder=True') raise NotImplementedError(
'padding works only with ignore_boarder=True')
if self.padding[0] >= self.ds[0] or self.padding[1] >= self.ds[1]: if self.padding[0] >= self.ds[0] or self.padding[1] >= self.ds[1]:
raise NotImplementedError('padding_h and padding_w must be smaller than strides') raise NotImplementedError(
'padding_h and padding_w must be smaller than strides')
def __str__(self): def __str__(self):
return '%s{%s, %s, %s, %s}' % (self.__class__.__name__, return '%s{%s, %s, %s, %s}' % (self.__class__.__name__,
self.ds, self.st, self.ignore_border,self.padding) self.ds, self.st, self.ignore_border, self.padding)
def make_node(self, x): def make_node(self, x):
if x.type.ndim != 4: if x.type.ndim != 4:
...@@ -214,7 +220,6 @@ class DownsampleFactorMax(Op): ...@@ -214,7 +220,6 @@ class DownsampleFactorMax(Op):
self.ignore_border, self.st, self.padding), self.ignore_border, self.st, self.padding),
dtype=x.dtype) dtype=x.dtype)
zz = z[0] zz = z[0]
#number of pooling output rows #number of pooling output rows
pr = zz.shape[-2] pr = zz.shape[-2]
#number of pooling output cols #number of pooling output cols
...@@ -228,7 +233,9 @@ class DownsampleFactorMax(Op): ...@@ -228,7 +233,9 @@ class DownsampleFactorMax(Op):
# pad the image # pad the image
fill = x.min()-1. fill = x.min()-1.
y = numpy.zeros((x.shape[0], x.shape[1], img_rows, img_cols), dtype=x.dtype) + fill y = numpy.zeros(
(x.shape[0], x.shape[1], img_rows, img_cols),
dtype=x.dtype) + fill
y[:, :, pad_h:(img_rows-pad_h), pad_w:(img_cols-pad_w)] = x y[:, :, pad_h:(img_rows-pad_h), pad_w:(img_cols-pad_w)] = x
# max pooling # max pooling
for n in xrange(x.shape[0]): for n in xrange(x.shape[0]):
...@@ -253,7 +260,7 @@ class DownsampleFactorMax(Op): ...@@ -253,7 +260,7 @@ class DownsampleFactorMax(Op):
maxout = self(x) maxout = self(x)
return [DownsampleFactorMaxGrad(self.ds, return [DownsampleFactorMaxGrad(self.ds,
ignore_border=self.ignore_border, ignore_border=self.ignore_border,
st=self.st)( st=self.st, padding=self.padding)(
x, maxout, gz)] x, maxout, gz)]
def c_code(self, node, name, inp, out, sub): def c_code(self, node, name, inp, out, sub):
...@@ -261,7 +268,7 @@ class DownsampleFactorMax(Op): ...@@ -261,7 +268,7 @@ class DownsampleFactorMax(Op):
# the stride size and the pooling size are different. # the stride size and the pooling size are different.
# An exception is raised for such a case. # An exception is raised for such a case.
if self.ds != self.st: if self.ds != self.st:
raise theano.gof.utils.MethodNotDefined() raise theano.gof.utils.MethodNotDefined()
x, = inp x, = inp
z, = out z, = out
fail = sub['fail'] fail = sub['fail']
...@@ -340,7 +347,7 @@ class DownsampleFactorMax(Op): ...@@ -340,7 +347,7 @@ class DownsampleFactorMax(Op):
class DownsampleFactorMaxGrad(Op): class DownsampleFactorMaxGrad(Op):
__props__ = ('ds', 'ignore_border', 'st', 'padding') __props__ = ('ds', 'ignore_border', 'st', 'padding')
def __init__(self, ds, ignore_border, st=None, padding=(0,0)): def __init__(self, ds, ignore_border, st=None, padding=(0, 0)):
self.ds = tuple(ds) self.ds = tuple(ds)
self.ignore_border = ignore_border self.ignore_border = ignore_border
if st is None: if st is None:
...@@ -350,7 +357,7 @@ class DownsampleFactorMaxGrad(Op): ...@@ -350,7 +357,7 @@ class DownsampleFactorMaxGrad(Op):
def __str__(self): def __str__(self):
return '%s{%s, %s, %s, %s}' % (self.__class__.__name__, return '%s{%s, %s, %s, %s}' % (self.__class__.__name__,
self.ds, self.st, self.ignore_border,self.padding) self.ds, self.st, self.ignore_border, self.padding)
def make_node(self, x, maxout, gz): def make_node(self, x, maxout, gz):
# make_node should only be called by the grad function of # make_node should only be called by the grad function of
...@@ -364,7 +371,6 @@ class DownsampleFactorMaxGrad(Op): ...@@ -364,7 +371,6 @@ class DownsampleFactorMaxGrad(Op):
def perform(self, node, inp, out): def perform(self, node, inp, out):
x, maxout, gz = inp x, maxout, gz = inp
gx_stg, = out gx_stg, = out
#number of pooling output rows #number of pooling output rows
pr = maxout.shape[-2] pr = maxout.shape[-2]
#number of pooling output cols #number of pooling output cols
...@@ -375,11 +381,10 @@ class DownsampleFactorMaxGrad(Op): ...@@ -375,11 +381,10 @@ class DownsampleFactorMaxGrad(Op):
img_cols = x.shape[-1] + 2 * self.padding[1] img_cols = x.shape[-1] + 2 * self.padding[1]
pad_h = self.padding[0] pad_h = self.padding[0]
pad_w = self.padding[1] pad_w = self.padding[1]
# pad the image # pad the image
fill = x.min()-1 fill = x.min()-1
y = numpy.zeros((x.shape[0], x.shape[1], img_rows, img_cols), dtype=x.dtype) + fill y = numpy.zeros(
(x.shape[0], x.shape[1], img_rows, img_cols), dtype=x.dtype) + fill
y[:, :, pad_h:(img_rows-pad_h), pad_w:(img_cols-pad_w)] = x y[:, :, pad_h:(img_rows-pad_h), pad_w:(img_cols-pad_w)] = x
gx = numpy.zeros_like(y) gx = numpy.zeros_like(y)
for n in xrange(x.shape[0]): for n in xrange(x.shape[0]):
...@@ -408,15 +413,17 @@ class DownsampleFactorMaxGrad(Op): ...@@ -408,15 +413,17 @@ class DownsampleFactorMaxGrad(Op):
return [theano.tensor.zeros_like(x), return [theano.tensor.zeros_like(x),
theano.tensor.zeros_like(maxout), theano.tensor.zeros_like(maxout),
DownsampleFactorMaxGradGrad( DownsampleFactorMaxGradGrad(
self.ds, ignore_border=self.ignore_border, st=self.st)(x, maxout, ggx)] self.ds, ignore_border=self.ignore_border,
st=self.st)(x, maxout, ggx)]
else: else:
return [theano.tensor.zeros_like(x), return [theano.tensor.zeros_like(x),
theano.tensor.zeros_like(maxout), theano.tensor.zeros_like(maxout),
theano.gradients.grad_not_implemented( theano.gradients.grad_not_implemented(
self, 2, gz,'Hessian not implemented with padding')] self, 2, gz, 'Hessian not implemented with padding')]
def c_code(self, node, name, inp, out, sub): def c_code(self, node, name, inp, out, sub):
if self.ds != self.st: if self.ds != self.st:
raise theano.gof.utils.MethodNotDefined() raise theano.gof.utils.MethodNotDefined()
x, z, gz = inp x, z, gz = inp
gx, = out gx, = out
fail = sub['fail'] fail = sub['fail']
......
...@@ -37,22 +37,24 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -37,22 +37,24 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
patch = input[k][ii:ii + ds[0], jj:jj + ds[1]] patch = input[k][ii:ii + ds[0], jj:jj + ds[1]]
output_val[k][i, j] = numpy.max(patch) output_val[k][i, j] = numpy.max(patch)
return output_val return output_val
@staticmethod @staticmethod
def numpy_max_pool_2d_stride_padding( def numpy_max_pool_2d_stride_padding(
x, ds, ignore_border=True, st=None, padding=(0,0)): x, ds, ignore_border=True, st=None, padding=(0, 0)):
pad_h = padding[0] pad_h = padding[0]
pad_w = padding[1] pad_w = padding[1]
h = x.shape[-2] h = x.shape[-2]
w = x.shape[-1] w = x.shape[-1]
assert ds[0] > pad_h assert ds[0] > pad_h
assert ds[1] > pad_w assert ds[1] > pad_w
def pad_img(x): def pad_img(x):
fill = x.min()-1 fill = x.min()-1
t = numpy.ones((x.shape[0],x.shape[1],1,1)) t = numpy.ones((x.shape[0], x.shape[1], 1, 1))
ud_bar = (numpy.zeros((pad_h, w)) + fill)[ ud_bar = (numpy.zeros((pad_h, w)) + fill)[
numpy.newaxis, numpy.newaxis,:,:] * t numpy.newaxis, numpy.newaxis, :, :] * t
lr_bar = (numpy.zeros((pad_h * 2 + h, pad_w)) + fill)[ lr_bar = (numpy.zeros((pad_h * 2 + h, pad_w)) + fill)[
numpy.newaxis, numpy.newaxis,:,:] * t numpy.newaxis, numpy.newaxis, :, :] * t
y = numpy.concatenate([ud_bar, x, ud_bar], axis=2) y = numpy.concatenate([ud_bar, x, ud_bar], axis=2)
y = numpy.concatenate([lr_bar, y, lr_bar], axis=3) y = numpy.concatenate([lr_bar, y, lr_bar], axis=3)
return y return y
...@@ -64,7 +66,7 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -64,7 +66,7 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
out_shp.append(out_r) out_shp.append(out_r)
out_shp.append(out_c) out_shp.append(out_c)
ds0, ds1 = ds ds0, ds1 = ds
st0, st1 = st st0, st1 = st
output_val = numpy.zeros(out_shp) output_val = numpy.zeros(out_shp)
tt = [] tt = []
y = pad_img(x) y = pad_img(x)
...@@ -236,14 +238,14 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -236,14 +238,14 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
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)
def test_DownsampleFactorMaxPaddingStride(self): def test_DownsampleFactorMaxPaddingStride(self):
ignore_border = True # padding does not support ignore_border=False ignore_border = True # padding does not support ignore_border=False
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
maxpoolsizes = [(3, 3), (4,4), (3,4), (4,3)] maxpoolsizes = [(3, 3), (4, 4), (3, 4), (4, 3)]
stridesizes = [(2, 2), (2,2), (1,1), (1,2)] stridesizes = [(2, 2), (2, 2), (1, 1), (1, 2)]
paddingsizes = [(2, 2), (1,2), (2,1), (0,0)] paddingsizes = [(2, 2), (1, 2), (2, 1), (0, 0)]
imgsizes = [(5, 5), (5,5), (5,6), (6,5)] imgsizes = [(5, 5), (5, 5), (5, 6), (6, 5)]
m = 4 # minibatch m = 4 # minibatch
c = 10 # channel size c = 10 # channel size
images = tensor.dtensor4() images = tensor.dtensor4()
...@@ -254,21 +256,22 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -254,21 +256,22 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
maxpoolsize = maxpoolsizes[indx] maxpoolsize = maxpoolsizes[indx]
paddingsize = paddingsizes[indx] paddingsize = paddingsizes[indx]
numpy_output_val = self.numpy_max_pool_2d_stride_padding( numpy_output_val = self.numpy_max_pool_2d_stride_padding(
imval, maxpoolsize,ignore_border, stridesize, paddingsize) imval, maxpoolsize, ignore_border, stridesize, paddingsize)
maxpool_op = DownsampleFactorMax(
maxpool_op = DownsampleFactorMax(maxpoolsize, maxpoolsize,
ignore_border=ignore_border, ignore_border=ignore_border,
st=stridesize,padding=paddingsize)(images) st=stridesize, padding=paddingsize)(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)
def test_DownsampleFactorMaxPaddingStride_grad(self): def test_DownsampleFactorMaxPaddingStride_grad(self):
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
imval = rng.rand(1, 1, 10, 10) * 10.0 imval = rng.rand(1, 1, 10, 10) * 10.0
maxpoolsize = (5, 3) maxpoolsize = (5, 3)
stridesize = (3, 2) stridesize = (3, 2)
paddingsize = (2,2) paddingsize = (2, 2)
def mp(input): def mp(input):
return DownsampleFactorMax( return DownsampleFactorMax(
maxpoolsize, ignore_border=True, maxpoolsize, ignore_border=True,
...@@ -276,7 +279,7 @@ class TestDownsampleFactorMax(utt.InferShapeTester): ...@@ -276,7 +279,7 @@ class TestDownsampleFactorMax(utt.InferShapeTester):
padding=paddingsize, padding=paddingsize,
)(input) )(input)
utt.verify_grad(mp, [imval], rng=rng) utt.verify_grad(mp, [imval], rng=rng)
def test_DownsampleFactorMax_grad(self): def test_DownsampleFactorMax_grad(self):
rng = numpy.random.RandomState(utt.fetch_seed()) rng = numpy.random.RandomState(utt.fetch_seed())
maxpoolshps = ((1, 1), (3, 2), (2, 3)) maxpoolshps = ((1, 1), (3, 2), (2, 3))
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论