提交 84c51913 authored 作者: Sina Honari's avatar Sina Honari

resolving the conflict for git rebase

上级 1d2eec53
...@@ -236,7 +236,8 @@ class DownsampleFactorMax(Op): ...@@ -236,7 +236,8 @@ class DownsampleFactorMax(Op):
gz, = grads gz, = grads
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)(
x, maxout, gz)] x, maxout, gz)]
def c_code_tmp(self, node, name, inp, out, sub): def c_code_tmp(self, node, name, inp, out, sub):
...@@ -317,21 +318,26 @@ class DownsampleFactorMax(Op): ...@@ -317,21 +318,26 @@ class DownsampleFactorMax(Op):
class DownsampleFactorMaxGrad(Op): class DownsampleFactorMaxGrad(Op):
def __init__(self, ds, ignore_border): def __init__(self, ds, ignore_border, st=None):
self.ds = tuple(ds) self.ds = tuple(ds)
self.ignore_border = ignore_border self.ignore_border = ignore_border
if st is None:
st = ds
self.st = tuple(st)
def __eq__(self, other): def __eq__(self, other):
return (type(self) == type(other) and return (type(self) == type(other) and
self.ds == other.ds and self.ds == other.ds and
self.st == other.st and
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.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}' % (self.__class__.__name__, return '%s{%s,%s,%s}' % (self.__class__.__name__,
self.ds, self.ignore_border) self.ds, self.st, self.ignore_border)
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
...@@ -347,22 +353,27 @@ class DownsampleFactorMaxGrad(Op): ...@@ -347,22 +353,27 @@ class DownsampleFactorMaxGrad(Op):
gx_stg, = out gx_stg, = out
gx = numpy.zeros_like(x) gx = numpy.zeros_like(x)
#number of pooling output rows
pr = maxout.shape[-2]
#number of pooling output cols
pc = maxout.shape[-1]
ds0, ds1 = self.ds ds0, ds1 = self.ds
shape2 = (x.shape[2] // ds0 * ds0) st0, st1 = self.st
if not self.ignore_border: img_rows = x.shape[-2]
shape2 = x.shape[2] img_cols = x.shape[-1]
shape3 = (x.shape[3] // ds1 * ds1)
if not self.ignore_border:
shape3 = x.shape[3]
for n in xrange(x.shape[0]): for n in xrange(x.shape[0]):
for k in xrange(x.shape[1]): for k in xrange(x.shape[1]):
for i in xrange(shape2): for r in xrange(pr):
zi = i // ds0 row_st = r * st0
for j in xrange(shape3): row_end = __builtin__.min(row_st + ds0, img_rows)
zj = j // ds1 for c in xrange(pc):
if (maxout[n, k, zi, zj] == x[n, k, i, j]): col_st = c * st1
gx[n, k, i, j] = gz[n, k, zi, zj] col_end = __builtin__.min(col_st + ds1, img_cols)
# No else clause needed as it is allocated with zeros for row_ind in xrange(row_st, row_end):
for col_ind in xrange(col_st, col_end):
if (maxout[n, k, r, c] == x[n, k, row_ind, col_ind]):
gx[n, k, row_ind, col_ind] = gz[n, k, r, c]
gx_stg[0] = gx gx_stg[0] = gx
def infer_shape(self, node, in_shapes): def infer_shape(self, node, in_shapes):
...@@ -374,9 +385,9 @@ class DownsampleFactorMaxGrad(Op): ...@@ -374,9 +385,9 @@ 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)(x, maxout, ggx)] self.ds, ignore_border=self.ignore_border, st=self.st)(x, maxout, ggx)]
def c_code(self, node, name, inp, out, sub): def c_code_tmp(self, node, name, inp, out, sub):
x, z, gz = inp x, z, gz = inp
gx, = out gx, = out
fail = sub['fail'] fail = sub['fail']
...@@ -475,7 +486,7 @@ class DownsampleFactorMaxGrad(Op): ...@@ -475,7 +486,7 @@ class DownsampleFactorMaxGrad(Op):
class DownsampleFactorMaxGradGrad(Op): class DownsampleFactorMaxGradGrad(Op):
@staticmethod @staticmethod
def out_shape(imgshape, ds, ignore_border=False): def out_shape(imgshape, ds, ignore_border=False, st=None):
"""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.
...@@ -485,11 +496,15 @@ class DownsampleFactorMaxGradGrad(Op): ...@@ -485,11 +496,15 @@ class DownsampleFactorMaxGradGrad(Op):
scalar Theano variable. scalar Theano variable.
:param ds: downsample factor over rows and columns :param ds: downsample factor over rows and columns
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 ignore_border: if ds doesn't divide imgshape, do we include :param st: the stride size. This is the distance between the pooling
an extra row/col of partial downsampling (False) or ignore regions. If it's set to None, in which case it equlas ds.
it (True). :type st: list or tuple of two ints
:param ignore_border: if ds doesn't divide imgshape, do we include an
extra row/col of partial downsampling (False) or ignore it (True).
:type ignore_border: bool :type ignore_border: bool
:rtype: list :rtype: list
...@@ -500,35 +515,66 @@ class DownsampleFactorMaxGradGrad(Op): ...@@ -500,35 +515,66 @@ class DownsampleFactorMaxGradGrad(Op):
if len(imgshape) < 2: if len(imgshape) < 2:
raise TypeError('imgshape must have at least two elements ' raise TypeError('imgshape must have at least two elements '
'(rows, cols)') '(rows, cols)')
if st is None:
st = ds
r, c = imgshape[-2:] r, c = imgshape[-2:]
rval = list(imgshape[:-2]) + [r // ds[0], c // ds[1]]
if not ignore_border: if ignore_border:
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):
rval[-2] = tensor.switch(r % ds[0], rval[-2] + 1, rval[-2]) nr = tensor.maximum(out_r, 0)
elif r % ds[0]: else:
rval[-2] += 1 nr = numpy.maximum(out_r, 0)
if isinstance(c, theano.Variable): if isinstance(c, theano.Variable):
rval[-1] = tensor.switch(c % ds[1], rval[-1] + 1, rval[-1]) nc = tensor.maximum(out_c, 0)
elif c % ds[1]: else:
rval[-1] += 1 nc = numpy.maximum(out_c, 0)
else:
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)
elif st[0] >= ds[0]:
nr = (r - 1) // st[0] + 1
else:
nr = max(0, (r - 1 - ds[0]) // st[0] + 1) + 1
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)
elif st[1] >= ds[1]:
nc = (c - 1) // st[1] + 1
else:
nc = max(0, (c - 1 - ds[1]) // st[1] + 1) + 1
rval = list(imgshape[:-2]) + [nr, nc]
return rval return rval
def __init__(self, ds, ignore_border): def __init__(self, ds, ignore_border, st=None):
self.ds = tuple(ds) self.ds = tuple(ds)
self.ignore_border = ignore_border self.ignore_border = ignore_border
if st is None:
st = ds
self.st = tuple(st)
def __eq__(self, other): def __eq__(self, other):
return (type(self) == type(other) return (type(self) == type(other)
and self.ds == other.ds and self.ds == other.ds
and self.st == other.st
and self.ignore_border == other.ignore_border) and self.ignore_border == other.ignore_border)
def __hash__(self): def __hash__(self):
return hash(type(self)) ^ hash(self.ds) ^ 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}' % (self.__class__.__name__, self.ds, return '%s{%s,%s,%s}' % (self.__class__.__name__,
self.ignore_border) self.ds, self.st, self.ignore_border)
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
...@@ -540,38 +586,42 @@ class DownsampleFactorMaxGradGrad(Op): ...@@ -540,38 +586,42 @@ class DownsampleFactorMaxGradGrad(Op):
return Apply(self, [x, maxout, gz], [x.type()]) return Apply(self, [x, maxout, gz], [x.type()])
def perform(self, node, inp, out): def perform(self, node, inp, out):
x, maxout, ggx = inp x, maxout, ggx = inp
z, = out z, = out
if len(x.shape) != 4: if len(x.shape) != 4:
raise NotImplementedError( raise NotImplementedError(
'DownsampleFactorMaxGradGrad requires 4D input for now') 'DownsampleFactorMaxGradGrad requires 4D input for now')
z_shape = self.out_shape(x.shape, self.ds, self.ignore_border) z_shape = self.out_shape(x.shape, self.ds, self.ignore_border, self.st)
if (z[0] is None) or (z[0].shape != z_shape): if (z[0] is None) or (z[0].shape != z_shape):
z[0] = numpy.zeros( z[0] = numpy.zeros(self.out_shape(x.shape, self.ds,
self.out_shape(x.shape, self.ds, self.ignore_border)) self.ignore_border, self.st))
z[0] = theano._asarray(z[0], dtype=x.dtype) z[0] = theano._asarray(z[0], dtype=x.dtype)
ggz = z[0] ggz = z[0]
## zz needs to be initialized with -inf for the following to work
ggz -= numpy.inf
#number of pooling output rows
pr = ggz.shape[-2]
#number of pooling output cols
pc = ggz.shape[-1]
ds0, ds1 = self.ds ds0, ds1 = self.ds
if self.ignore_border: st0, st1 = self.st
x_usable2 = (x.shape[2] // ds0 * ds0) img_rows = x.shape[-2]
else: img_cols = x.shape[-1]
x_usable2 = x.shape[2]
if self.ignore_border:
x_usable3 = (x.shape[3] // ds1 * ds1)
else:
x_usable3 = x.shape[3]
for n in xrange(x.shape[0]): for n in xrange(x.shape[0]):
for k in xrange(x.shape[1]): for k in xrange(x.shape[1]):
for i in xrange(x_usable2): for r in xrange(pr):
zi = i // ds0 row_st = r * st0
for j in xrange(x_usable3): row_end = __builtin__.min(row_st + ds0, img_rows)
zj = j // ds1 for c in xrange(pc):
if (maxout[n, k, zi, zj] == x[n, k, i, j]): col_st = c * st1
ggz[n, k, zi, zj] = ggx[n, k, i, j] col_end = __builtin__.min(col_st + ds1, img_cols)
for row_ind in xrange(row_st, row_end):
for col_ind in xrange(col_st, col_end):
if (maxout[n, k, r, c] == x[n, k, row_ind, col_ind]):
ggz[n, k, r, c] = ggx[n, k, row_ind, col_ind]
def infer_shape(self, node, in_shapes): def infer_shape(self, node, in_shapes):
return [in_shapes[0]] return [in_shapes[0]]
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论