提交 be3fee10 authored 作者: Olivier Delalleau's avatar Olivier Delalleau

Merge pull request #225 from nouiz/fix_neibs

Fix neibs
import theano import theano
from theano import Op, Apply from theano import Op, Apply
import theano.tensor as T import theano.tensor as T
from theano.tensor.opt import register_specialize
from theano.gof import local_optimizer from theano.gof import local_optimizer
from theano.sandbox.cuda import cuda_available from theano.sandbox.cuda import cuda_available
...@@ -10,6 +9,13 @@ if cuda_available: ...@@ -10,6 +9,13 @@ if cuda_available:
from theano.sandbox.cuda.basic_ops import host_from_gpu, gpu_from_host from theano.sandbox.cuda.basic_ops import host_from_gpu, gpu_from_host
from theano.sandbox.cuda.opt import register_opt as register_gpu_opt from theano.sandbox.cuda.opt import register_opt as register_gpu_opt
class BadOldCode(Exception):
""" We create a specific Exception to be sure it don't get caught
by mistake"""
pass
class Images2Neibs(Op): class Images2Neibs(Op):
def __init__(self, mode='valid'): def __init__(self, mode='valid'):
""" """
...@@ -20,26 +26,32 @@ class Images2Neibs(Op): ...@@ -20,26 +26,32 @@ class Images2Neibs(Op):
is not a multiple of the pooling factor(s) is not a multiple of the pooling factor(s)
wrap_centered : ?? TODO comment wrap_centered : ?? TODO comment
""" """
if mode not in ['valid','wrap_centered','ignore_borders']: if mode not in ['valid', 'wrap_centered', 'ignore_borders']:
raise NotImplementedError("Only the mode valid, ignore_borders and wrap_centered have been implemented for the op Images2Neibs") raise NotImplementedError("Only the mode valid, ignore_borders"
" and wrap_centered have been"
" implemented for the op Images2Neibs")
self.mode = mode self.mode = mode
def __eq__(self, other): def __eq__(self, other):
return type(self) == type(other) and self.mode==other.mode return type(self) == type(other) and self.mode == other.mode
def __hash__(self): def __hash__(self):
return hash(type(self))^hash(self.mode) return hash(type(self)) ^ hash(self.mode)
def __str__(self): def __str__(self):
return self.__class__.__name__+"{%s}"%self.mode return self.__class__.__name__ + "{%s}" % self.mode
def __setstate__(self, d): def __setstate__(self, d):
self.__dict__.update(d) self.__dict__.update(d)
if not hasattr(self,"mode"): if not hasattr(self, "mode"):
self.mode = 'valid' self.mode = 'valid'
def make_node(self, ten4, neib_shape, neib_step=None): def make_node(self, ten4, neib_shape, neib_step=None):
""" """
:param neib_step: (dx,dy) where dx is the number of rows to skip between patch :param neib_step: (dx,dy) where dx is the number of rows to
and dy is the number of columns. When None, this is the same skip between patch and dy is the number of
as neib_shape(patch are disjoint) columns. When None, this is the same as
neib_shape(patch are disjoint)
""" """
ten4 = T.as_tensor_variable(ten4) ten4 = T.as_tensor_variable(ten4)
neib_shape = T.as_tensor_variable(neib_shape) neib_shape = T.as_tensor_variable(neib_shape)
...@@ -48,17 +60,23 @@ class Images2Neibs(Op): ...@@ -48,17 +60,23 @@ class Images2Neibs(Op):
else: else:
neib_step = T.as_tensor_variable(neib_step) neib_step = T.as_tensor_variable(neib_step)
assert ten4.ndim==4 assert ten4.ndim == 4
assert neib_shape.ndim==1 assert neib_shape.ndim == 1
assert neib_step.ndim==1 assert neib_step.ndim == 1
return Apply(self, [ten4, neib_shape,neib_step], [T.matrix(dtype=ten4.type.dtype)]) return Apply(self, [ten4, neib_shape, neib_step],
[T.matrix(dtype=ten4.type.dtype)])
def grad(self, inp, grads): def grad(self, inp, grads):
x, neib_shape, neib_step = inp x, neib_shape, neib_step = inp
gz, = grads gz, = grads
if self.mode in ['valid','ignore_borders']: if self.mode in ['valid', 'ignore_borders']:
return [neibs2images(gz, neib_shape, x.shape, mode=self.mode), None, None] raise BadOldCode("The Images2Neibs grad is not implemented."
" It was in the past, but returned the wrong"
" answer!")
# This is the reverse of the op, not the grad!
return [neibs2images(gz, neib_shape, x.shape, mode=self.mode),
None, None]
else: else:
raise NotImplementedError() raise NotImplementedError()
...@@ -70,7 +88,7 @@ class Images2Neibs(Op): ...@@ -70,7 +88,7 @@ class Images2Neibs(Op):
z, = out z, = out
fail = sub['fail'] fail = sub['fail']
mode=self.mode mode = self.mode
return """ return """
int grid_c = -1; //number of patch in height int grid_c = -1; //number of patch in height
int grid_d = -1; //number of patch in width int grid_d = -1; //number of patch in width
...@@ -87,7 +105,8 @@ class Images2Neibs(Op): ...@@ -87,7 +105,8 @@ class Images2Neibs(Op):
} }
if ( (%(neib_shape)s->dimensions)[0] != 2) if ( (%(neib_shape)s->dimensions)[0] != 2)
{ {
PyErr_Format(PyExc_TypeError, "neib_shape wrong shape ; has to contain 2 elements"); PyErr_Format(PyExc_TypeError, "neib_shape wrong shape ; has to"
" contain 2 elements");
%(fail)s; %(fail)s;
} }
if (%(neib_step)s->nd != 1) if (%(neib_step)s->nd != 1)
...@@ -97,7 +116,8 @@ class Images2Neibs(Op): ...@@ -97,7 +116,8 @@ class Images2Neibs(Op):
} }
if ( (%(neib_step)s->dimensions)[0] != 2) if ( (%(neib_step)s->dimensions)[0] != 2)
{ {
PyErr_Format(PyExc_TypeError, "neib_step wrong step ; has to contain 2 elements"); PyErr_Format(PyExc_TypeError,
"neib_step wrong step ; has to contain 2 elements");
%(fail)s; %(fail)s;
} }
...@@ -229,9 +249,11 @@ class Images2Neibs(Op): ...@@ -229,9 +249,11 @@ class Images2Neibs(Op):
} // END NESTED SCOPE } // END NESTED SCOPE
""" % locals() """ % locals()
def images2neibs(ten4, neib_shape, neib_step=None, mode='valid'): def images2neibs(ten4, neib_shape, neib_step=None, mode='valid'):
return Images2Neibs(mode)(ten4, neib_shape, neib_step) return Images2Neibs(mode)(ten4, neib_shape, neib_step)
def neibs2images(neibs, neib_shape, original_shape, mode='valid'): def neibs2images(neibs, neib_shape, original_shape, mode='valid'):
""" """
Inverse of images2neib. Inverse of images2neib.
...@@ -246,19 +268,21 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'): ...@@ -246,19 +268,21 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'):
neib_shape = T.as_tensor_variable(neib_shape) neib_shape = T.as_tensor_variable(neib_shape)
original_shape = T.as_tensor_variable(original_shape) original_shape = T.as_tensor_variable(original_shape)
new_neib_shape = T.stack(original_shape[-1] // neib_shape[1], neib_shape[1]) new_neib_shape = T.stack(original_shape[-1] // neib_shape[1],
output_2d = images2neibs(neibs.dimshuffle('x','x',0,1), new_neib_shape, mode=mode) neib_shape[1])
output_2d = images2neibs(neibs.dimshuffle('x', 'x', 0, 1),
new_neib_shape, mode=mode)
if mode == 'ignore_borders': if mode == 'ignore_borders':
valid_shape = list(original_shape) valid_shape = list(original_shape)
valid_shape[2] = (valid_shape[2] // neib_shape[0]) * neib_shape[0] valid_shape[2] = (valid_shape[2] // neib_shape[0]) * neib_shape[0]
valid_shape[3] = (valid_shape[3] // neib_shape[1]) * neib_shape[1] valid_shape[3] = (valid_shape[3] // neib_shape[1]) * neib_shape[1]
output_4d = output_2d.reshape(valid_shape) output_4d = output_2d.reshape(valid_shape)
#padding the borders with zeros #padding the borders with zeros
for d in [2,3]: for d in [2, 3]:
pad_shape = list(output_4d.shape) pad_shape = list(output_4d.shape)
pad_shape[d] = original_shape[d] - valid_shape[d] pad_shape[d] = original_shape[d] - valid_shape[d]
output_4d = T.concatenate([output_4d,T.zeros(pad_shape)],axis=d) output_4d = T.concatenate([output_4d, T.zeros(pad_shape)], axis=d)
else: else:
output_4d = output_2d.reshape(original_shape) output_4d = output_2d.reshape(original_shape)
...@@ -269,7 +293,9 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'): ...@@ -269,7 +293,9 @@ def neibs2images(neibs, neib_shape, original_shape, mode='valid'):
class GpuImages2Neibs(Images2Neibs): class GpuImages2Neibs(Images2Neibs):
def __init__(self, mode='valid'): def __init__(self, mode='valid'):
if mode not in ['valid', 'wrap_centered']: if mode not in ['valid', 'wrap_centered']:
raise NotImplementedError("Only the mode valid and wrap_centered have been implemented for the op GpuImages2Neibs") raise NotImplementedError("Only the mode valid and wrap_centered"
" have been implemented for the op"
" GpuImages2Neibs")
self.mode = mode self.mode = mode
def make_node(self, ten4, neib_shape, neib_step): def make_node(self, ten4, neib_shape, neib_step):
...@@ -277,12 +303,13 @@ class GpuImages2Neibs(Images2Neibs): ...@@ -277,12 +303,13 @@ class GpuImages2Neibs(Images2Neibs):
if not isinstance(ten4.type, CudaNdarrayType): if not isinstance(ten4.type, CudaNdarrayType):
raise TypeError('ten4 must be cudandarray', ten4) raise TypeError('ten4 must be cudandarray', ten4)
assert ten4.ndim==4 assert ten4.ndim == 4
assert neib_shape.ndim==1 assert neib_shape.ndim == 1
assert neib_step.ndim==1 assert neib_step.ndim == 1
return Apply(self, [ten4, neib_shape, neib_step], [CudaNdarrayType(broadcastable=(False,False), return Apply(self, [ten4, neib_shape, neib_step],
dtype=ten4.type.dtype)()]) [CudaNdarrayType(broadcastable=(False, False),
dtype=ten4.type.dtype)()])
def c_code_cache_version(self): def c_code_cache_version(self):
return (7,) return (7,)
...@@ -502,7 +529,8 @@ class GpuImages2Neibs(Images2Neibs): ...@@ -502,7 +529,8 @@ class GpuImages2Neibs(Images2Neibs):
%(z)s = (CudaNdarray*)CudaNdarray_NewDims(2, dims); %(z)s = (CudaNdarray*)CudaNdarray_NewDims(2, dims);
if (!%(z)s) if (!%(z)s)
{ {
PyErr_SetString(PyExc_MemoryError, "failed to alloc z output"); PyErr_SetString(PyExc_MemoryError,
"failed to alloc z output");
%(fail)s; %(fail)s;
} }
} }
...@@ -567,7 +595,9 @@ class GpuImages2Neibs(Images2Neibs): ...@@ -567,7 +595,9 @@ class GpuImages2Neibs(Images2Neibs):
cudaError_t sts = cudaGetLastError(); cudaError_t sts = cudaGetLastError();
if (cudaSuccess != sts) if (cudaSuccess != sts)
{ {
PyErr_Format(PyExc_RuntimeError, "Cuda error: %%s: %%s. (grid: %%i x %%i; block: %%i x %%i x %%i; shared: %%i)\\n", PyErr_Format(PyExc_RuntimeError,
"Cuda error: %%s: %%s. (grid: %%i x %%i;"
" block: %%i x %%i x %%i; shared: %%i)\\n",
"k_multi_warp_%(name)s", "k_multi_warp_%(name)s",
cudaGetErrorString(sts), cudaGetErrorString(sts),
n_blocks.x, n_blocks.x,
...@@ -581,13 +611,18 @@ class GpuImages2Neibs(Images2Neibs): ...@@ -581,13 +611,18 @@ class GpuImages2Neibs(Images2Neibs):
} // END NESTED SCOPE } // END NESTED SCOPE
""" % locals() """ % locals()
def gpu_images2neibs(ten4, neib_shape, neib_step=None, mode='valid'): def gpu_images2neibs(ten4, neib_shape, neib_step=None, mode='valid'):
return GpuImages2Neibs(mode)(ten4, neib_shape, neib_step) return GpuImages2Neibs(mode)(ten4, neib_shape, neib_step)
@local_optimizer() @local_optimizer()
def use_gpu_images2neibs(node): def use_gpu_images2neibs(node):
if type(node.op) is Images2Neibs: if type(node.op) is Images2Neibs:
return [host_from_gpu(gpu_images2neibs(gpu_from_host(node.inputs[0]),node.inputs[1],node.inputs[2],mode=node.op.mode))] return [host_from_gpu(gpu_images2neibs(gpu_from_host(node.inputs[0]),
node.inputs[1], node.inputs[2],
mode=node.op.mode))]
if cuda_available: if cuda_available:
register_gpu_opt()(use_gpu_images2neibs) register_gpu_opt()(use_gpu_images2neibs)
import numpy import numpy
import numpy.random
import theano import theano
from theano import shared, function from theano import shared, function
import theano.tensor as T import theano.tensor as T
from neighbours import images2neibs, neibs2images, Images2Neibs, GpuImages2Neibs from neighbours import (images2neibs, neibs2images,
Images2Neibs, GpuImages2Neibs)
# Skip test if cuda_ndarray is not available. # Skip test if cuda_ndarray is not available.
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
import theano.sandbox.cuda as cuda import theano.sandbox.cuda as cuda
from theano.tests import unittest_tools from theano.tests import unittest_tools
if theano.config.mode=='FAST_COMPILE': if theano.config.mode == 'FAST_COMPILE':
mode_with_gpu = theano.compile.mode.get_mode('FAST_RUN').including('gpu') mode_with_gpu = theano.compile.mode.get_mode('FAST_RUN').including('gpu')
mode_without_gpu = theano.compile.mode.get_mode('FAST_RUN').excluding('gpu') mode_without_gpu = theano.compile.mode.get_mode(
'FAST_RUN').excluding('gpu')
else: else:
mode_with_gpu = theano.compile.mode.get_default_mode().including('gpu') mode_with_gpu = theano.compile.mode.get_default_mode().including('gpu')
mode_without_gpu = theano.compile.mode.get_default_mode().excluding('gpu') mode_without_gpu = theano.compile.mode.get_default_mode().excluding('gpu')
def test_neibs(): def test_neibs():
shape = (100,40,18,18) shape = (100, 40, 18, 18)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((2,2))#(array((2,2), dtype='float32')) neib_shape = T.as_tensor_variable((2, 2))
f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu)
#print images.get_value(borrow=True) #print images.get_value(borrow=True)
neibs = f() neibs = f()
#print neibs #print neibs
g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_without_gpu) g = function([], neibs2images(neibs, neib_shape, images.shape),
mode=mode_without_gpu)
#print g() #print g()
assert numpy.allclose(images.get_value(borrow=True),g()) assert numpy.allclose(images.get_value(borrow=True), g())
def test_neibs_bad_shape(): def test_neibs_bad_shape():
shape = (2,3,10,10) shape = (2, 3, 10, 10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,2)) neib_shape = T.as_tensor_variable((3, 2))
try: try:
f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError:
pass pass
shape = (2,3,10,10) shape = (2, 3, 10, 10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((2,3)) neib_shape = T.as_tensor_variable((2, 3))
try: try:
f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError:
pass pass
def test_neibs_bad_shape_warp_centered(): def test_neibs_bad_shape_warp_centered():
shape = (2,3,10,10) shape = (2, 3, 10, 10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,2)) neib_shape = T.as_tensor_variable((3, 2))
try: try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape,
mode="wrap_centered"),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError:
pass pass
shape = (2,3,10,10) shape = (2, 3, 10, 10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((2,3)) neib_shape = T.as_tensor_variable((2, 3))
try: try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape,
mode="wrap_centered"),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError:
pass pass
shape = (2,3,2,3) shape = (2, 3, 2, 3)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3)) neib_shape = T.as_tensor_variable((3, 3))
try: try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape,
mode="wrap_centered"),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError:
pass pass
shape = (2,3,3,2) shape = (2, 3, 3, 2)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3)) neib_shape = T.as_tensor_variable((3, 3))
try: try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape,
mode="wrap_centered"),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
assert False,"An error was expected" assert False, "An error was expected"
except TypeError,e: except TypeError, e:
pass pass
shape = (2,3,3,3) shape = (2, 3, 3, 3)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3)) neib_shape = T.as_tensor_variable((3, 3))
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape, mode="wrap_centered"),
mode=mode_without_gpu)
neibs = f() neibs = f()
#print neibs #print neibs
def test_neibs_manual(): def test_neibs_manual():
shape = (2,3,4,4) shape = (2, 3, 4, 4)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape)) images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((2,2)) neib_shape = T.as_tensor_variable((2, 2))
f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape), mode=mode_without_gpu)
...@@ -148,29 +165,34 @@ def test_neibs_manual(): ...@@ -148,29 +165,34 @@ def test_neibs_manual():
[82, 83, 86, 87], [82, 83, 86, 87],
[88, 89, 92, 93], [88, 89, 92, 93],
[90, 91, 94, 95]]) [90, 91, 94, 95]])
g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_without_gpu) g = function([], neibs2images(neibs, neib_shape, images.shape),
mode=mode_without_gpu)
#print g() #print g()
assert numpy.allclose(images.get_value(borrow=True), g()) assert numpy.allclose(images.get_value(borrow=True), g())
def test_neibs_step_manual(): def test_neibs_step_manual():
shape = (2,3,5,5) shape = (2, 3, 5, 5)
images = shared(numpy.asarray(numpy.arange(numpy.prod(shape)).reshape(shape),dtype='float32')) images = shared(numpy.asarray(numpy.arange(numpy.prod(
neib_shape = T.as_tensor_variable((3,3)) shape)).reshape(shape), dtype='float32'))
neib_step = T.as_tensor_variable((2,2)) neib_shape = T.as_tensor_variable((3, 3))
neib_step = T.as_tensor_variable((2, 2))
modes = [mode_without_gpu] modes = [mode_without_gpu]
if cuda.cuda_available: if cuda.cuda_available:
modes.append(mode_with_gpu) modes.append(mode_with_gpu)
for mode_idx,mode in enumerate(modes): for mode_idx, mode in enumerate(modes):
f = function([], images2neibs(images, neib_shape, neib_step), mode=mode) f = function([], images2neibs(images, neib_shape, neib_step),
mode=mode)
#print images.get_value(borrow=True) #print images.get_value(borrow=True)
neibs = f() neibs = f()
if mode_idx==0: if mode_idx == 0:
assert Images2Neibs in [type(node.op) for node in f.maker.env.toposort()] assert Images2Neibs in [type(node.op)
elif mode_idx==1: for node in f.maker.env.toposort()]
assert GpuImages2Neibs in [type(node.op) for node in f.maker.env.toposort()] elif mode_idx == 1:
assert GpuImages2Neibs in [type(node.op)
for node in f.maker.env.toposort()]
assert numpy.allclose(neibs, assert numpy.allclose(neibs,
[[ 0, 1, 2, 5, 6, 7, 10, 11, 12], [[ 0, 1, 2, 5, 6, 7, 10, 11, 12],
...@@ -202,6 +224,7 @@ def test_neibs_step_manual(): ...@@ -202,6 +224,7 @@ def test_neibs_step_manual():
#print g() #print g()
#assert numpy.allclose(images.get_value(borrow=True),g()) #assert numpy.allclose(images.get_value(borrow=True),g())
def test_neibs_wrap_centered_step_manual(): def test_neibs_wrap_centered_step_manual():
modes = [mode_without_gpu] modes = [mode_without_gpu]
...@@ -221,57 +244,63 @@ def test_neibs_wrap_centered_step_manual(): ...@@ -221,57 +244,63 @@ def test_neibs_wrap_centered_step_manual():
[ 22, 23, 24, 2, 3, 4, 7, 8, 9], [ 22, 23, 24, 2, 3, 4, 7, 8, 9],
[ 14, 10, 11, 19, 15, 16, 24, 20, 21], [ 14, 10, 11, 19, 15, 16, 24, 20, 21],
[ 12, 13, 14, 17, 18, 19, 22, 23, 24]] [ 12, 13, 14, 17, 18, 19, 22, 23, 24]]
expected3 = [[ 19, 15, 16, 24, 20, 21, 4, 0, 1, 9, 5, 6, 14, 10, 11], expected3 = [[19, 15, 16, 24, 20, 21, 4, 0, 1, 9, 5, 6, 14, 10, 11],
[ 17, 18, 19, 22, 23, 24, 2, 3, 4, 7, 8, 9, 12, 13, 14], [17, 18, 19, 22, 23, 24, 2, 3, 4, 7, 8, 9, 12, 13, 14],
[ 9, 5, 6, 14, 10, 11, 19, 15, 16, 24, 20, 21, 4, 0, 1], [ 9, 5, 6, 14, 10, 11, 19, 15, 16, 24, 20, 21, 4, 0, 1],
[ 7, 8, 9, 12, 13, 14, 17, 18, 19, 22, 23, 24, 2, 3, 4]] [ 7, 8, 9, 12, 13, 14, 17, 18, 19, 22, 23, 24, 2, 3, 4]]
expected4 = [[ 23, 24, 20, 21, 22, 3, 4, 0, 1, 2, 8, 9, 5, 6, 7], expected4 = [[23, 24, 20, 21, 22, 3, 4, 0, 1, 2, 8, 9, 5, 6, 7],
[ 21, 22, 23, 24, 20, 1, 2, 3, 4, 0, 6, 7, 8, 9, 5], [21, 22, 23, 24, 20, 1, 2, 3, 4, 0, 6, 7, 8, 9, 5],
[ 13, 14, 10, 11, 12, 18, 19, 15, 16, 17, 23, 24, 20, 21, 22], [13, 14, 10, 11, 12, 18, 19, 15, 16, 17, 23, 24, 20, 21, 22],
[ 11, 12, 13, 14, 10, 16, 17, 18, 19, 15, 21, 22, 23, 24, 20]] [11, 12, 13, 14, 10, 16, 17, 18, 19, 15, 21, 22, 23, 24, 20]]
expected5 = [[ 24, 20, 21, 4, 0, 1, 9, 5, 6], expected5 = [[24, 20, 21, 4, 0, 1, 9, 5, 6],
[ 22, 23, 24, 2, 3, 4, 7, 8, 9], [22, 23, 24, 2, 3, 4, 7, 8, 9],
[ 9, 5, 6, 14, 10, 11, 19, 15, 16], [ 9, 5, 6, 14, 10, 11, 19, 15, 16],
[ 7, 8, 9, 12, 13, 14, 17, 18, 19], [ 7, 8, 9, 12, 13, 14, 17, 18, 19],
[ 19, 15, 16, 24, 20, 21, 4, 0, 1], [19, 15, 16, 24, 20, 21, 4, 0, 1],
[ 17, 18, 19, 22, 23, 24, 2, 3, 4]] [17, 18, 19, 22, 23, 24, 2, 3, 4]]
expected6 = [[ 24, 20, 21, 4, 0, 1, 9, 5, 6], expected6 = [[24, 20, 21, 4, 0, 1, 9, 5, 6],
[ 21, 22, 23, 1, 2, 3, 6, 7, 8], [21, 22, 23, 1, 2, 3, 6, 7, 8],
[ 23, 24, 20, 3, 4, 0, 8, 9, 5], [23, 24, 20, 3, 4, 0, 8, 9, 5],
[ 14, 10, 11, 19, 15, 16, 24, 20, 21], [14, 10, 11, 19, 15, 16, 24, 20, 21],
[ 11, 12, 13, 16, 17, 18, 21, 22, 23], [11, 12, 13, 16, 17, 18, 21, 22, 23],
[ 13, 14, 10, 18, 19, 15, 23, 24, 20]] [13, 14, 10, 18, 19, 15, 23, 24, 20]]
#TODO test discontinous image #TODO test discontinous image
for shp_idx,(shape,neib_shape,neib_step,expected) in enumerate([ for shp_idx, (shape, neib_shape, neib_step, expected) in enumerate([
[(7,8,5,5),(3,3),(2,2),expected1], [(7, 8, 5, 5), (3, 3), (2, 2), expected1],
[(7,8,5,5),(3,3),(3,3),expected2], [(7, 8, 5, 5), (3, 3), (3, 3), expected2],
[(7,8,5,5),(5,3),(3,3),expected3], [(7, 8, 5, 5), (5, 3), (3, 3), expected3],
[(7,8,5,5),(3,5),(3,3),expected4], [(7, 8, 5, 5), (3, 5), (3, 3), expected4],
[(80,90,5,5),(3,3),(2,3),expected5], [(80, 90, 5, 5), (3, 3), (2, 3), expected5],
[(1025,9,5,5),(3,3),(3,2),expected6], [(1025, 9, 5, 5), (3, 3), (3, 2), expected6],
[(1,1,5,1035),(3,3),(3,3),None], [(1, 1, 5, 1035), (3, 3), (3, 3), None],
[(1,1,1045,5),(3,3),(3,3),None], [(1, 1, 1045, 5), (3, 3), (3, 3), None],
]): ]):
images = shared(numpy.asarray(numpy.arange(numpy.prod(shape)).reshape(shape),dtype='float32')) images = shared(numpy.asarray(numpy.arange(numpy.prod(
shape)).reshape(shape), dtype='float32'))
neib_shape = T.as_tensor_variable(neib_shape) neib_shape = T.as_tensor_variable(neib_shape)
neib_step = T.as_tensor_variable(neib_step) neib_step = T.as_tensor_variable(neib_step)
expected = numpy.asarray(expected) expected = numpy.asarray(expected)
for mode_idx,mode in enumerate(modes): for mode_idx, mode in enumerate(modes):
f = function([], images2neibs(images, neib_shape, neib_step, mode="wrap_centered"), mode=mode) f = function([], images2neibs(images, neib_shape, neib_step,
mode="wrap_centered"), mode=mode)
neibs = f() neibs = f()
if expected.size>1: if expected.size > 1:
for i in range(shape[0]*shape[1]): for i in range(shape[0] * shape[1]):
assert numpy.allclose(neibs[i*expected.shape[0]:(i+1)*expected.shape[0],:],expected+25*i), mode_idx assert numpy.allclose(neibs[i * expected.shape[0]:
(i + 1) * expected.shape[0], :],
expected + 25 * i), mode_idx
if mode_idx==0: if mode_idx == 0:
assert Images2Neibs in [type(node.op) for node in f.maker.env.toposort()] assert Images2Neibs in [type(node.op)
elif mode_idx==1: for node in f.maker.env.toposort()]
assert GpuImages2Neibs in [type(node.op) for node in f.maker.env.toposort()] elif mode_idx == 1:
assert GpuImages2Neibs in [type(node.op)
for node in f.maker.env.toposort()]
#g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_without_gpu) #g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_without_gpu)
...@@ -281,123 +310,82 @@ def test_neibs_wrap_centered_step_manual(): ...@@ -281,123 +310,82 @@ def test_neibs_wrap_centered_step_manual():
def test_neibs_gpu(): def test_neibs_gpu():
if cuda.cuda_available == False: if cuda.cuda_available == False:
raise SkipTest('Optional package cuda disabled') raise SkipTest('Optional package cuda disabled')
for shape, pshape in [((100,40,18,18),(2,2)), for shape, pshape in [((100, 40, 18, 18), (2, 2)),
((100,40,6,18),(3,2)), ((100, 40, 6, 18), (3, 2)),
((10,40,66,66),(33,33)), ((10, 40, 66, 66), (33, 33)),
((10,40,68,66),(34,33)) ((10, 40, 68, 66), (34, 33))
]: ]:
images = shared(numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape)) images = shared(numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape))
neib_shape = T.as_tensor_variable(pshape) neib_shape = T.as_tensor_variable(pshape)
from theano.sandbox.cuda.basic_ops import gpu_from_host f = function([], images2neibs(images, neib_shape),
f = function([], images2neibs(images,neib_shape),
mode=mode_with_gpu) mode=mode_with_gpu)
f_gpu = function([], images2neibs(images,neib_shape), f_gpu = function([], images2neibs(images, neib_shape),
mode=mode_with_gpu) mode=mode_with_gpu)
assert any([isinstance(node.op,GpuImages2Neibs) for node in f_gpu.maker.env.toposort()]) assert any([isinstance(node.op, GpuImages2Neibs)
for node in f_gpu.maker.env.toposort()])
#print images.get_value(borrow=True) #print images.get_value(borrow=True)
neibs = numpy.asarray(f_gpu()) neibs = numpy.asarray(f_gpu())
assert numpy.allclose(neibs,f()) assert numpy.allclose(neibs, f())
#print neibs #print neibs
g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_with_gpu) g = function([], neibs2images(neibs, neib_shape, images.shape),
assert any([isinstance(node.op,GpuImages2Neibs) for node in f.maker.env.toposort()]) mode=mode_with_gpu)
assert any([isinstance(node.op, GpuImages2Neibs)
for node in f.maker.env.toposort()])
#print numpy.asarray(g()) #print numpy.asarray(g())
assert numpy.allclose(images.get_value(borrow=True), g()) assert numpy.allclose(images.get_value(borrow=True), g())
def speed_neibs(): def speed_neibs():
shape = (100,40,18,18) shape = (100, 40, 18, 18)
images = shared(numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape)) images = shared(numpy.arange(numpy.prod(shape),
neib_shape = T.as_tensor_variable((3,3)) dtype='float32').reshape(shape))
neib_shape = T.as_tensor_variable((3, 3))
from theano.sandbox.cuda.basic_ops import gpu_from_host
f = function([], images2neibs(images,neib_shape))#, mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape))
for i in range(1000): for i in range(1000):
f() f()
def speed_neibs_wrap_centered():
shape = (100,40,18,18)
images = shared(numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape))
neib_shape = T.as_tensor_variable((3,3))
from theano.sandbox.cuda.basic_ops import gpu_from_host def speed_neibs_wrap_centered():
shape = (100, 40, 18, 18)
images = shared(numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape))
neib_shape = T.as_tensor_variable((3, 3))
f = function([], images2neibs(images,neib_shape,mode="wrap_centered"))#, mode=mode_without_gpu) f = function([], images2neibs(images, neib_shape, mode="wrap_centered"))
for i in range(1000): for i in range(1000):
f() f()
def test_neibs_grad(): # Disable the test as the grad is wrongly implemented
shape = (2,3,4,4) def tes_neibs_grad_verify_grad():
images = shared(numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape)) shape = (2, 3, 4, 4)
cost = T.sum(T.sqr(images2neibs(images, (2,2))), axis=[0,1])
grad = T.grad(cost, images)
f = theano.function([], [cost, grad], mode=mode_without_gpu)
got = f()
should_get = [numpy.asarray(290320.0, dtype=numpy.float32),
numpy.asarray([[[[ 0., 2., 4., 6.],
[ 8., 10., 12., 14.],
[ 16., 18., 20., 22.],
[ 24., 26., 28., 30.]],
[[ 32., 34., 36., 38.],
[ 40., 42., 44., 46.],
[ 48., 50., 52., 54.],
[ 56., 58., 60., 62.]],
[[ 64., 66., 68., 70.],
[ 72., 74., 76., 78.],
[ 80., 82., 84., 86.],
[ 88., 90., 92., 94.]]],
[[[ 96., 98., 100., 102.],
[ 104., 106., 108., 110.],
[ 112., 114., 116., 118.],
[ 120., 122., 124., 126.]],
[[ 128., 130., 132., 134.],
[ 136., 138., 140., 142.],
[ 144., 146., 148., 150.],
[ 152., 154., 156., 158.]],
[[ 160., 162., 164., 166.],
[ 168., 170., 172., 174.],
[ 176., 178., 180., 182.],
[ 184., 186., 188., 190.]]]], dtype=numpy.float32)]
assert numpy.allclose(got[0], should_get[0])
assert numpy.allclose(got[1], should_get[1])
def test_neibs_grad_verify_grad():
shape = (2,3,4,4)
images = T.dtensor4() images = T.dtensor4()
images_val = numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape) images_val = numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape)
def fn(images): def fn(images):
return T.sum(T.sqr(images2neibs(images, (2,2))), axis=[0,1]) return T.sum(T.sqr(images2neibs(images, (2, 2))), axis=[0, 1])
unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu) unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu)
if cuda.cuda_available: if cuda.cuda_available:
unittest_tools.verify_grad(fn, [images_val], mode=mode_with_gpu) unittest_tools.verify_grad(fn, [images_val], mode=mode_with_gpu)
def test_neibs_grad_verify_grad_warp_centered(): def test_neibs_grad_verify_grad_warp_centered():
# It is not implemented for now. So test that we raise an error. # It is not implemented for now. So test that we raise an error.
shape = (2,3,6,6) shape = (2, 3, 6, 6)
images = T.dtensor4() images = T.dtensor4()
images_val = numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape) images_val = numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape)
def fn(images): def fn(images):
return T.sum(T.sqr(images2neibs(images, (3,3),mode='wrap_centered')), axis=[0,1]) return T.sum(T.sqr(images2neibs(images, (3, 3), mode='wrap_centered')),
axis=[0, 1])
try: try:
unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu) unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu)
raise Exception("Expected an error") raise Exception("Expected an error")
...@@ -411,42 +399,52 @@ def test_neibs_grad_verify_grad_warp_centered(): ...@@ -411,42 +399,52 @@ def test_neibs_grad_verify_grad_warp_centered():
except NotImplementedError: except NotImplementedError:
pass pass
def test_neibs_ignore_border(): def test_neibs_ignore_border():
shape = (2,3,5,5) shape = (2, 3, 5, 5)
images = T.dtensor4() images = T.dtensor4()
images_val = numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape) images_val = numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape)
def fn(images): def fn(images):
return T.sum(T.sqr(images2neibs(images, (2,2), mode='ignore_borders')), axis=[0,1]) return T.sum(T.sqr(images2neibs(images, (2, 2),
mode='ignore_borders')), axis=[0, 1])
# Disable the test as the grad is wrongly implemented
#unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu)
unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu)
# not implemented for gpu # not implemented for gpu
# if cuda.cuda_available: # if cuda.cuda_available:
# unittest_tools.verify_grad(fn, [images_val], mode=mode_with_gpu) # unittest_tools.verify_grad(fn, [images_val], mode=mode_with_gpu)
def test_neibs_valid_with_inconsistent_borders(): def test_neibs_valid_with_inconsistent_borders():
shape = (2,3,5,5) shape = (2, 3, 5, 5)
images = T.dtensor4() images = T.dtensor4()
images_val = numpy.arange(numpy.prod(shape), dtype='float32').reshape(shape) images_val = numpy.arange(numpy.prod(shape),
dtype='float32').reshape(shape)
def fn(images): def fn(images):
return T.sum(T.sqr(images2neibs(images, (2,2), mode='valid')), axis=[0,1]) return T.sum(T.sqr(images2neibs(images, (2, 2), mode='valid')),
axis=[0, 1])
f = theano.function([images],
T.sqr(images2neibs(images, (2, 2), mode='valid')))
try: try:
unittest_tools.verify_grad(fn, [images_val], mode=mode_without_gpu) f(images_val)
assert False,"An error was expected" assert False, "An error was expected"
except TypeError: except TypeError, e:
# This is expected if the assert is there # This is expected if the assert is there
pass pass
def test_neibs2images_crash_on_grad(): # Disable the test as the grad is wrongly implemented
# say we had images of size (2,3,20,20) def tes_neibs2images_crash_on_grad():
# then we extracted 2x2 neighbors on this, we get (2*3*10*10, 4) # say we had images of size (2, 3, 20, 20)
# then we extracted 2x2 neighbors on this, we get (2 * 3 * 10 * 10, 4)
neibs = T.dmatrix() neibs = T.dmatrix()
neibs_val = numpy.random.rand(600,4) neibs_val = numpy.random.rand(600, 4)
to_images = T.sum(neibs2images(neibs, (2,2), (2,3,20,20))) to_images = T.sum(neibs2images(neibs, (2, 2), (2, 3, 20, 20)))
g = T.grad(to_images, neibs) g = T.grad(to_images, neibs)
fn = theano.function([neibs], to_images, mode=mode_without_gpu) fn = theano.function([neibs], to_images, mode=mode_without_gpu)
print "Compiled" print "Compiled"
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论