提交 2bcae301 authored 作者: Frédéric Bastien's avatar Frédéric Bastien 提交者: GitHub

Merge pull request #5616 from lamblin/fix_5613

Explicitly specify the output ndim in reshape
......@@ -152,7 +152,7 @@ class Images2Neibs(Op):
grad_undefined(self, 2, neib_step)]
def c_code_cache_version(self):
return (5,)
return (7,)
def perform(self, node, inp, out_):
ten4, neib_shape, neib_step = inp
......@@ -177,6 +177,12 @@ class Images2Neibs(Op):
c, d = neib_shape
step_x, step_y = neib_step
mode = self.mode
if step_x <= 0 or step_y <= 0:
raise ValueError(
"neib_step wrong step ; values <= 0. Got " + str(neib_step))
if c <= 0 or d <= 0:
raise ValueError(
"neib_shape values <=0. Got " + str(neib_shape))
if mode == "wrap_centered":
if (c % 2 != 1) or (d % 2 != 1):
......@@ -317,8 +323,24 @@ class Images2Neibs(Op):
const npy_intp c = (npy_intp) *(dtype_%(neib_shape)s*) PyArray_GETPTR1(%(neib_shape)s, 0);
const npy_intp d = (npy_intp) *(dtype_%(neib_shape)s*) PyArray_GETPTR1(%(neib_shape)s, 1);
// (step_x,step_y) = neib_step
const npy_intp step_x = (npy_intp) *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 0);
const npy_intp step_y = (npy_intp) *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 1);
const dtype_%(neib_step)s step_x = *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 0);
const dtype_%(neib_step)s step_y = *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 1);
if (step_x <=0 || step_y <=0)
{
PyErr_Format(PyExc_ValueError,
"neib_step wrong step ; values <= 0. Got %%lld %%lld.",
(long long) step_x, (long long) step_y);
%(fail)s;
}
if (c <=0 || d <=0)
{
PyErr_Format(PyExc_ValueError,
"neib_shape values <= 0. Got %%lld %%lld.",
(long long)c, (long long)d);
%(fail)s;
}
if ( "%(mode)s" == "wrap_centered") {
if (c%%2!=1 || d%%2!=1){
......@@ -617,10 +639,17 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'):
new_neib_shape, mode=mode)
if mode == 'ignore_borders':
valid_shape = list(original_shape)
valid_shape[2] = (valid_shape[2] // neib_shape[0]) * neib_shape[0]
valid_shape[3] = (valid_shape[3] // neib_shape[1]) * neib_shape[1]
output_4d = output_2d.reshape(valid_shape)
# We use set_subtensor to accept original_shape we can't infer
# the shape and still raise error when it don't have the right
# shape.
valid_shape = original_shape
valid_shape = T.set_subtensor(
valid_shape[2],
(valid_shape[2] // neib_shape[0]) * neib_shape[0])
valid_shape = T.set_subtensor(
valid_shape[3],
(valid_shape[3] // neib_shape[1]) * neib_shape[1])
output_4d = output_2d.reshape(valid_shape, ndim=4)
# padding the borders with zeros
for d in [2, 3]:
pad_shape = list(output_4d.shape)
......@@ -629,7 +658,7 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'):
elif mode == 'valid':
# TODO: we do not implement all mode with this code.
# Add a check for the good cases.
output_4d = output_2d.reshape(original_shape)
output_4d = output_2d.reshape(original_shape, ndim=4)
else:
raise NotImplementedError("neibs2images do not support mode=%s" % mode)
......
......@@ -144,8 +144,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
shape = (2, 3, 10, 10)
for dtype in self.dtypes:
images = shared(numpy.arange(
numpy.prod(shape), dtype=dtype
).reshape(shape))
numpy.prod(shape), dtype=dtype).reshape(shape))
for neib_shape in [(3, 2), (2, 3)]:
neib_shape = T.as_tensor_variable(neib_shape)
......@@ -340,6 +339,33 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
mode=self.mode)
self.assertRaises(TypeError, f, images_val)
def test_can_not_infer_nb_dim(self):
# Was reported in gh-5613. Test that we do not crash
# or that we crash in a few other case found while
# investigating that case
img = T.tensor4('img')
patches = T.nnet.neighbours.images2neibs(img, [16, 16])
extractPatches = theano.function([img], patches)
patsRecovery = T.matrix('patsRecovery')
original_size = T.ivector('original_size')
for mode in ['valid', 'ignore_borders']:
out = neibs2images(patsRecovery, (16, 16),
original_size, mode=mode)
f = theano.function([patsRecovery, original_size], out)
im_val = numpy.ones((1, 3, 320, 320), dtype=numpy.float32)
neibs = extractPatches(im_val)
f(neibs, im_val.shape)
# Wrong number of dimensions
self.assertRaises(ValueError, f, neibs,
(1, 1, 3, 320, 320))
# End up with a step of 0
self.assertRaises(ValueError, f, neibs,
(3, 320, 320, 1))
def speed_neibs(self):
shape = (100, 40, 18, 18)
images = shared(numpy.arange(numpy.prod(shape),
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论