提交 3805415a authored 作者: botev's avatar botev

Merge remote-tracking branch 'origin/master'

...@@ -23,17 +23,14 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -23,17 +23,14 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
""" """
def __init__(self, mode='valid'): def __init__(self, mode='valid'):
if mode not in ['valid', 'ignore_borders', 'wrap_centered', 'half']: if mode not in ['valid', 'half', 'full',
raise NotImplementedError("Only the mode valid, ignore_borders" 'ignore_borders', 'wrap_centered']:
", wrap_centered and half" raise NotImplementedError("Only the mode valid, half, full, "
" have been implemented for the op" "ignore_borders and wrap_centered have "
" GpuImages2Neibs") "been implemented for GpuImages2Neibs")
self.mode = mode self.mode = mode
def make_node(self, ten4, neib_shape, neib_step=None): def make_node(self, ten4, neib_shape, neib_step=None):
# TODO: I don't know why, but without this the tests fail?
neib_shape.eval()
####
ten4 = as_gpuarray_variable(ten4, infer_context_name(ten4)) ten4 = as_gpuarray_variable(ten4, infer_context_name(ten4))
neib_shape = T.as_tensor_variable(neib_shape) neib_shape = T.as_tensor_variable(neib_shape)
if neib_step is None: if neib_step is None:
...@@ -56,7 +53,7 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -56,7 +53,7 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
return node.inputs[0].type.context return node.inputs[0].type.context
def c_code_cache_version(self): def c_code_cache_version(self):
return (12, ) return (12,)
def c_headers(self): def c_headers(self):
return ['<numpy_compat.h>', '<gpuarray/types.h>'] return ['<numpy_compat.h>', '<gpuarray/types.h>']
...@@ -124,6 +121,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -124,6 +121,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
ten4_2 -= height; ten4_2 -= height;
} else if ("%(mode)s"=="half"){ } else if ("%(mode)s"=="half"){
ten4_2 -= wrap_centered_half_idx_shift_x; ten4_2 -= wrap_centered_half_idx_shift_x;
} else if ("%(mode)s"=="full"){
ten4_2 -= c - 1;
} }
ga_int j = LID_0; // loop over d ga_int j = LID_0; // loop over d
{ {
...@@ -136,6 +135,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -136,6 +135,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
ten4_3 -= width; ten4_3 -= width;
} else if ("%(mode)s"=="half"){ } else if ("%(mode)s"=="half"){
ten4_3 -= wrap_centered_half_idx_shift_y; ten4_3 -= wrap_centered_half_idx_shift_y;
} else if ("%(mode)s"=="full"){
ten4_3 -= d - 1;
} }
ga_int z_col = j + d * i; ga_int z_col = j + d * i;
...@@ -219,6 +220,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -219,6 +220,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
ten4_2 -= height; ten4_2 -= height;
} else if ("%(mode)s"=="half"){ } else if ("%(mode)s"=="half"){
ten4_2 -= wrap_centered_half_idx_shift_x; ten4_2 -= wrap_centered_half_idx_shift_x;
} else if ("%(mode)s"=="full"){
ten4_2 -= c - 1;
} }
// loop over d // loop over d
for (ga_int j = LID_0; j < d; j+=LDIM_0) for (ga_int j = LID_0; j < d; j+=LDIM_0)
...@@ -232,6 +235,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -232,6 +235,8 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
ten4_3 -= width; ten4_3 -= width;
} else if ("%(mode)s"=="half"){ } else if ("%(mode)s"=="half"){
ten4_3 -= wrap_centered_half_idx_shift_y; ten4_3 -= wrap_centered_half_idx_shift_y;
} else if ("%(mode)s"=="full"){
ten4_3 -= d - 1;
} }
ga_int z_col = j + d * i; ga_int z_col = j + d * i;
...@@ -333,6 +338,22 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -333,6 +338,22 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
const npy_intp step_y = (npy_intp) *(npy_%(dtype_neib_step)s*) const npy_intp step_y = (npy_intp) *(npy_%(dtype_neib_step)s*)
PyArray_GETPTR1(%(neib_step)s, 1); 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 ( "%(mode)s" == "wrap_centered") {
if (c%%2!=1 || d%%2!=1){ if (c%%2!=1 || d%%2!=1){
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
...@@ -412,6 +433,31 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -412,6 +433,31 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
grid_c = 1+(((PyGpuArray_DIMS(%(ten4)s))[2]-(c%%2))/step_x); grid_c = 1+(((PyGpuArray_DIMS(%(ten4)s))[2]-(c%%2))/step_x);
//number of patch in width //number of patch in width
grid_d = 1+(((PyGpuArray_DIMS(%(ten4)s))[3]-(d%%2))/step_y); grid_d = 1+(((PyGpuArray_DIMS(%(ten4)s))[3]-(d%%2))/step_y);
}else if ( "%(mode)s" == "full") {
if ( ((PyGpuArray_DIMS(%(ten4)s))[2] < c) ||
( (((PyGpuArray_DIMS(%(ten4)s))[2]+c-2) %% step_x)!=0))
{
PyErr_Format(PyExc_TypeError,
"neib_shape[0]=%%ld, neib_step[0]=%%ld and"
" ten4.shape[2]=%%ld not consistent",
(long int)c, (long int)step_x,
(long int)(PyGpuArray_DIMS(%(ten4)s)[2]));
%(fail)s;
}
if ( ((PyGpuArray_DIMS(%(ten4)s))[3] < d) ||
( (((PyGpuArray_DIMS(%(ten4)s))[3]+d-2) %% step_y)!=0))
{
PyErr_Format(PyExc_TypeError,
"neib_shape[1]=%%ld, neib_step[1]=%%ld and"
" ten4.shape[3]=%%ld not consistent",
(long int)d, (long int)step_y,
(long int)(PyGpuArray_DIMS(%(ten4)s)[3]));
%(fail)s;
}
//number of patch in height
grid_c = 1+(((PyGpuArray_DIMS(%(ten4)s))[2]+c-2)/step_x);
//number of patch in width
grid_d = 1+(((PyGpuArray_DIMS(%(ten4)s))[3]+d-2)/step_y);
}else{ }else{
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"GpuImages2Neibs:: unknown mode '%(mode)s'"); "GpuImages2Neibs:: unknown mode '%(mode)s'");
...@@ -530,5 +576,5 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op): ...@@ -530,5 +576,5 @@ class GpuImages2Neibs(GpuKernelBase, Images2Neibs, Op):
@op_lifter([Images2Neibs]) @op_lifter([Images2Neibs])
@register_opt2([Images2Neibs], 'fast_compile') @register_opt2([Images2Neibs], 'fast_compile')
def local_gpua_images2neibs(op, context_name, inputs, outputs): def local_gpua_images2neibs(op, context_name, inputs, outputs):
if op.mode in ['valid', 'ignore_borders', 'wrap_centered', 'half']: if op.mode in ['valid', 'half', 'full', 'ignore_borders', 'wrap_centered']:
return GpuImages2Neibs(op.mode) return GpuImages2Neibs(op.mode)
...@@ -24,24 +24,28 @@ class Images2Neibs(Op): ...@@ -24,24 +24,28 @@ class Images2Neibs(Op):
- 'valid' : - 'valid' :
Requires an input that is a multiple of the pooling factor Requires an input that is a multiple of the pooling factor
(in each direction). (in each direction).
- 'half' :
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0]//2, neib_shape[1]//2)
- 'full' :
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0] - 1, neib_shape[1] - 1)
- 'ignore_borders' : - 'ignore_borders' :
Same as valid, but will ignore the borders if the shape(s) Same as valid, but will ignore the borders if the shape(s)
of the input is not a multiple of the pooling factor(s). of the input is not a multiple of the pooling factor(s).
- 'wrap_centered' : - 'wrap_centered' :
?? TODO comment ?? TODO comment
- 'half' :
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0]//2, neib_shape[1]//2)
""" """
__props__ = ("mode",) __props__ = ("mode",)
def __init__(self, mode='valid'): def __init__(self, mode='valid'):
if mode not in ['valid', 'wrap_centered', 'ignore_borders', 'half']: if mode not in ['valid', 'half', 'full',
raise NotImplementedError("Only the mode valid, ignore_borders" 'wrap_centered', 'ignore_borders']:
",wrap_centered and half have been" raise NotImplementedError("Only the mode valid, half, full, "
" implemented for the op Images2Neibs") "ignore_borders and wrap_centered have "
"been implemented for Images2Neibs")
self.mode = mode self.mode = mode
def __str__(self): def __str__(self):
...@@ -155,7 +159,7 @@ class Images2Neibs(Op): ...@@ -155,7 +159,7 @@ class Images2Neibs(Op):
grad_undefined(self, 2, neib_step)] grad_undefined(self, 2, neib_step)]
def c_code_cache_version(self): def c_code_cache_version(self):
return (7,) return (8,)
def perform(self, node, inp, out_): def perform(self, node, inp, out_):
ten4, neib_shape, neib_step = inp ten4, neib_shape, neib_step = inp
...@@ -241,9 +245,28 @@ class Images2Neibs(Op): ...@@ -241,9 +245,28 @@ class Images2Neibs(Op):
grid_c = 1 + ((ten4.shape[2] - (c % 2)) // step_x) grid_c = 1 + ((ten4.shape[2] - (c % 2)) // step_x)
# number of patch in width # number of patch in width
grid_d = 1 + ((ten4.shape[3] - (d % 2)) // step_y) grid_d = 1 + ((ten4.shape[3] - (d % 2)) // step_y)
elif mode == "full":
# This is equivalent to 'valid' with padding (c - 1, d - 1) on both sides
# Thus the expanded image will have size (h + 2 * (c - 1), w + 2 * (d - 1))
# Plugging these in the equation for 'valid' we get
# h + 2 * (c - 1) - c = h + c - 2
# w + 2 * (d - 1) - c = w + d - 2
if (ten4.shape[2] < c) or (((ten4.shape[2] + c - 2) % step_x) != 0):
raise TypeError(
"neib_shape[0]=%d, neib_step[0]=%d and"
" ten4.shape[2]=%d not consistent" %
(c, step_x, ten4.shape[2]))
if (ten4.shape[3] < d) or (((ten4.shape[3] + d - 2) % step_y) != 0):
raise TypeError(
"neib_shape[1]=%d, neib_step[1]=%d and"
" ten4.shape[3]=%d not consistent" %
(d, step_y, ten4.shape[3]))
# number of patch in height
grid_c = 1 + ((ten4.shape[2] + c - 2) // step_x)
# number of patch in width
grid_d = 1 + ((ten4.shape[3] + d - 2) // step_y)
else: else:
raise TypeError("Images2Neibs: unknow mode '%s'" % mode) raise TypeError("Images2Neibs: unknow mode '%s'" % mode)
z_dim0 = grid_c * grid_d * ten4.shape[1] * ten4.shape[0] z_dim0 = grid_c * grid_d * ten4.shape[1] * ten4.shape[0]
z_dim1 = c * d z_dim1 = c * d
z[0] = np.empty((z_dim0, z_dim1), dtype=node.outputs[0].dtype) z[0] = np.empty((z_dim0, z_dim1), dtype=node.outputs[0].dtype)
...@@ -272,6 +295,8 @@ class Images2Neibs(Op): ...@@ -272,6 +295,8 @@ class Images2Neibs(Op):
ten4_2 -= height ten4_2 -= height
elif mode == "half": elif mode == "half":
ten4_2 -= wrap_centered_half_idx_shift_x ten4_2 -= wrap_centered_half_idx_shift_x
elif mode == "full":
ten4_2 -= c - 1
if ten4_2 < 0 or ten4_2 >= height: if ten4_2 < 0 or ten4_2 >= height:
z[0][z_row, d * i: d * i + d] = 0 z[0][z_row, d * i: d * i + d] = 0
else: else:
...@@ -285,6 +310,8 @@ class Images2Neibs(Op): ...@@ -285,6 +310,8 @@ class Images2Neibs(Op):
ten4_3 -= width ten4_3 -= width
elif mode == "half": elif mode == "half":
ten4_3 -= wrap_centered_half_idx_shift_y ten4_3 -= wrap_centered_half_idx_shift_y
elif mode == "full":
ten4_3 -= d - 1
z_col = j + d * i z_col = j + d * i
if ten4_3 < 0 or ten4_3 >= width: if ten4_3 < 0 or ten4_3 >= width:
z[0][z_row, z_col] = 0 z[0][z_row, z_col] = 0
...@@ -307,6 +334,11 @@ class Images2Neibs(Op): ...@@ -307,6 +334,11 @@ class Images2Neibs(Op):
elif self.mode == 'half': elif self.mode == 'half':
grid_c = 1 + ((in_shape[2] - (c % 2)) // step_x) grid_c = 1 + ((in_shape[2] - (c % 2)) // step_x)
grid_d = 1 + ((in_shape[3] - (d % 2)) // step_y) grid_d = 1 + ((in_shape[3] - (d % 2)) // step_y)
elif self.mode == 'full':
grid_c = 1 + ((in_shape[2] + c - 2) // step_x)
grid_d = 1 + ((in_shape[3] + d - 2) // step_y)
else:
raise TypeError("Images2Neibs: unknow mode '%s'" % self.mode)
z_dim0 = grid_c * grid_d * in_shape[1] * in_shape[0] z_dim0 = grid_c * grid_d * in_shape[1] * in_shape[0]
z_dim1 = c * d z_dim1 = c * d
return [(z_dim0, z_dim1)] return [(z_dim0, z_dim1)]
...@@ -453,7 +485,32 @@ class Images2Neibs(Op): ...@@ -453,7 +485,32 @@ class Images2Neibs(Op):
grid_c = 1+(((PyArray_DIMS(%(ten4)s))[2]-(c%%2))/step_x); grid_c = 1+(((PyArray_DIMS(%(ten4)s))[2]-(c%%2))/step_x);
//number of patch in width //number of patch in width
grid_d = 1+(((PyArray_DIMS(%(ten4)s))[3]-(d%%2))/step_y); grid_d = 1+(((PyArray_DIMS(%(ten4)s))[3]-(d%%2))/step_y);
}else{ }else if ( "%(mode)s" == "full") {
if ( ((PyArray_DIMS(%(ten4)s))[2] < c) ||
( (((PyArray_DIMS(%(ten4)s))[2]+c-2) %% step_x)!=0))
{
PyErr_Format(PyExc_TypeError,
"neib_shape[0]=%%ld, neib_step[0]=%%ld and"
" ten4.shape[2]=%%ld not consistent",
(long int)c, (long int)step_x,
(long int)(PyArray_DIMS(%(ten4)s)[2]));
%(fail)s;
}
if ( ((PyArray_DIMS(%(ten4)s))[3] < d) ||
( (((PyArray_DIMS(%(ten4)s))[3]+d-2) %% step_y)!=0))
{
PyErr_Format(PyExc_TypeError,
"neib_shape[1]=%%ld, neib_step[1]=%%ld and"
" ten4.shape[3]=%%ld not consistent",
(long int)d, (long int)step_y,
(long int)(PyArray_DIMS(%(ten4)s)[3]));
%(fail)s;
}
//number of patch in height
grid_c = 1+(((PyArray_DIMS(%(ten4)s))[2]+c-2)/step_x);
//number of patch in width
grid_d = 1+(((PyArray_DIMS(%(ten4)s))[3]+d-2)/step_y);
}else {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"Images2Neibs: unknow mode '%(mode)s'"); "Images2Neibs: unknow mode '%(mode)s'");
%(fail)s; %(fail)s;
...@@ -521,6 +578,8 @@ class Images2Neibs(Op): ...@@ -521,6 +578,8 @@ class Images2Neibs(Op):
else if (ten4_2 >= height) ten4_2 -= height; else if (ten4_2 >= height) ten4_2 -= height;
} else if ( "%(mode)s" == "half" ){ } else if ( "%(mode)s" == "half" ){
ten4_2 -= wrap_centered_half_idx_shift_x; ten4_2 -= wrap_centered_half_idx_shift_x;
} else if ( "%(mode)s" == "full" ){
ten4_2 -= c - 1;
} }
if (ten4_2 < 0 | ten4_2 >= height) { if (ten4_2 < 0 | ten4_2 >= height) {
dtype_%(z)s* curr_z = (dtype_%(z)s*) PyArray_GETPTR2(%(z)s, z_row, d * i); dtype_%(z)s* curr_z = (dtype_%(z)s*) PyArray_GETPTR2(%(z)s, z_row, d * i);
...@@ -535,6 +594,8 @@ class Images2Neibs(Op): ...@@ -535,6 +594,8 @@ class Images2Neibs(Op):
else if (ten4_3 >= width) ten4_3 -= width; else if (ten4_3 >= width) ten4_3 -= width;
} else if ( "%(mode)s" == "half" ){ } else if ( "%(mode)s" == "half" ){
ten4_3 -= wrap_centered_half_idx_shift_y; ten4_3 -= wrap_centered_half_idx_shift_y;
} else if ( "%(mode)s" == "full" ){
ten4_3 -= d - 1;
} }
int z_col = j + d * i; int z_col = j + d * i;
dtype_%(z)s* curr_z = (dtype_%(z)s*) PyArray_GETPTR2(%(z)s, z_row, z_col); dtype_%(z)s* curr_z = (dtype_%(z)s*) PyArray_GETPTR2(%(z)s, z_row, z_col);
...@@ -583,14 +644,17 @@ def images2neibs(ten4, neib_shape, neib_step=None, mode='valid'): ...@@ -583,14 +644,17 @@ def images2neibs(ten4, neib_shape, neib_step=None, mode='valid'):
``valid`` ``valid``
Requires an input that is a multiple of the Requires an input that is a multiple of the
pooling factor (in each direction). pooling factor (in each direction).
``half``
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0]//2, neib_shape[1]//2)
``full``
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0] - 1, neib_shape[1] - 1)
``ignore_borders`` ``ignore_borders``
Same as valid, but will ignore the borders if the shape(s) of Same as valid, but will ignore the borders if the shape(s) of
the input is not a multiple of the pooling factor(s). the input is not a multiple of the pooling factor(s).
``wrap_centered`` ``wrap_centered``
?? TODO comment ?? TODO comment
``half``
Equivalent to 'valid' if we pre-pad with zeros the input on
each side by (neib_shape[0]//2, neib_shape[1]//2)
Returns Returns
------- -------
......
...@@ -237,6 +237,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -237,6 +237,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
# assert numpy.allclose(images.get_value(borrow=True), g()) # assert numpy.allclose(images.get_value(borrow=True), g())
def test_neibs_half_step_by_valid(self): def test_neibs_half_step_by_valid(self):
neib_shapes = ((3, 3), (3, 5), (5, 3))
for shp_idx, (shape, neib_step) in enumerate([ for shp_idx, (shape, neib_step) in enumerate([
[(7, 8, 5, 5), (1, 1)], [(7, 8, 5, 5), (1, 1)],
[(7, 8, 5, 5), (2, 2)], [(7, 8, 5, 5), (2, 2)],
...@@ -248,7 +249,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -248,7 +249,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
[(1, 1, 5, 1037), (2, 4)], [(1, 1, 5, 1037), (2, 4)],
[(1, 1, 1045, 5), (4, 2)]] [(1, 1, 1045, 5), (4, 2)]]
): ):
for neib_shape in [(3, 3), (3, 5), (5, 3)]: for neib_shape in neib_shapes:
for dtype in self.dtypes: for dtype in self.dtypes:
x = theano.shared(np.random.randn(*shape).astype(dtype)) x = theano.shared(np.random.randn(*shape).astype(dtype))
extra = (neib_shape[0] // 2, neib_shape[1] // 2) extra = (neib_shape[0] // 2, neib_shape[1] // 2)
...@@ -261,6 +262,31 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -261,6 +262,31 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
f = theano.function([], close, mode=self.mode) f = theano.function([], close, mode=self.mode)
assert f() assert f()
def test_neibs_full_step_by_valid(self):
for shp_idx, (shape, neib_step, neib_shapes) in enumerate([
[(7, 8, 5, 5), (1, 1), ((3, 3), (3, 5), (5, 3))],
[(7, 8, 5, 5), (2, 2), ((3, 3), (3, 5), (5, 3))],
[(7, 8, 6, 6), (3, 3), ((2, 2), (2, 5), (5, 2))],
[(7, 8, 6, 6), (1, 3), ((2, 2), (2, 5), (5, 2))],
[(7, 8, 6, 6), (3, 1), ((2, 2), (2, 5), (5, 2))],
[(80, 90, 5, 5), (1, 2), ((3, 3), (3, 5), (5, 3))],
[(1025, 9, 5, 5), (2, 1), ((3, 3), (3, 5), (5, 3))],
[(1, 1, 11, 1037), (2, 3), ((3, 3), (5, 3))],
[(1, 1, 1043, 11), (3, 2), ((3, 3), (3, 5))]]
):
for neib_shape in neib_shapes:
for dtype in self.dtypes:
x = theano.shared(np.random.randn(*shape).astype(dtype))
extra = (neib_shape[0] - 1, neib_shape[1] - 1)
padded_shape = (x.shape[0], x.shape[1], x.shape[2] + 2 * extra[0], x.shape[3] + 2 * extra[1])
padded_x = T.zeros(padded_shape)
padded_x = T.set_subtensor(padded_x[:, :, extra[0]:-extra[0], extra[1]:-extra[1]], x)
x_using_valid = images2neibs(padded_x, neib_shape, neib_step, mode="valid")
x_using_full = images2neibs(x, neib_shape, neib_step, mode="full")
close = T.allclose(x_using_valid, x_using_full)
f = theano.function([], close, mode=self.mode)
assert f()
def test_neibs_bad_shape_wrap_centered(self): def test_neibs_bad_shape_wrap_centered(self):
shape = (2, 3, 10, 10) shape = (2, 3, 10, 10)
...@@ -317,6 +343,17 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -317,6 +343,17 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
self.assertRaises(TypeError, unittest_tools.verify_grad, self.assertRaises(TypeError, unittest_tools.verify_grad,
fn, [images_val], mode=self.mode) fn, [images_val], mode=self.mode)
def test_grad_full(self):
# It is not implemented for now. So test that we raise an error.
shape = (2, 3, 6, 6)
images_val = np.random.rand(*shape).astype('float32')
def fn(images):
return images2neibs(images, (3, 3), mode='full')
self.assertRaises(TypeError, unittest_tools.verify_grad,
fn, [images_val], mode=self.mode)
def test_grad_valid(self): def test_grad_valid(self):
shape = (2, 3, 6, 6) shape = (2, 3, 6, 6)
images_val = np.random.rand(*shape).astype('float32') images_val = np.random.rand(*shape).astype('float32')
...@@ -382,6 +419,17 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -382,6 +419,17 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
mode=self.mode) mode=self.mode)
self.assertRaises(TypeError, f, images_val) self.assertRaises(TypeError, f, images_val)
def test_neibs_full_with_inconsistent_borders(self):
shape = (2, 3, 5, 5)
images = T.dtensor4()
images_val = np.arange(np.prod(shape),
dtype='float32').reshape(shape)
f = theano.function([images],
T.sqr(images2neibs(images, (2, 2), mode='full')),
mode=self.mode)
self.assertRaises(TypeError, f, images_val)
def test_can_not_infer_nb_dim(self): def test_can_not_infer_nb_dim(self):
# Was reported in gh-5613. Test that we do not crash # Was reported in gh-5613. Test that we do not crash
# or that we crash in a few other case found while # or that we crash in a few other case found while
...@@ -389,8 +437,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -389,8 +437,7 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
img = T.tensor4('img') img = T.tensor4('img')
patches = T.nnet.neighbours.images2neibs(img, [16, 16]) patches = T.nnet.neighbours.images2neibs(img, [16, 16])
extractPatches = theano.function([img], patches, extractPatches = theano.function([img], patches, mode=self.mode)
mode=self.mode)
patsRecovery = T.matrix('patsRecovery') patsRecovery = T.matrix('patsRecovery')
original_size = T.ivector('original_size') original_size = T.ivector('original_size')
...@@ -450,6 +497,19 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -450,6 +497,19 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
for i in range(1000): for i in range(1000):
f() f()
def speed_neibs_full(self):
shape = (100, 40, 18, 18)
images = shared(np.arange(np.prod(shape),
dtype='float32').reshape(shape))
neib_shape = T.as_tensor_variable((3, 3))
f = function([],
images2neibs(images, neib_shape, mode="full"),
mode=self.mode)
for i in range(1000):
f()
def test_infer_shape(self): def test_infer_shape(self):
shape = (100, 40, 6, 3) shape = (100, 40, 6, 3)
images = np.ones(shape).astype('float32') images = np.ones(shape).astype('float32')
...@@ -498,6 +558,15 @@ class T_Images2Neibs(unittest_tools.InferShapeTester): ...@@ -498,6 +558,15 @@ class T_Images2Neibs(unittest_tools.InferShapeTester):
self._compile_and_check( self._compile_and_check(
[x], [images2neibs(x, neib_shape=(2, 3), mode='half')], [x], [images2neibs(x, neib_shape=(2, 3), mode='half')],
[images], Images2Neibs) [images], Images2Neibs)
shape = (100, 40, 6, 5)
images = np.ones(shape).astype('float32')
x = T.ftensor4()
self._compile_and_check(
[x], [images2neibs(x, neib_shape=(2, 1), mode='full')],
[images], Images2Neibs)
self._compile_and_check(
[x], [images2neibs(x, neib_shape=(2, 3), mode='full')],
[images], Images2Neibs)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论