提交 b3203222 authored 作者: Frederic Bastien's avatar Frederic Bastien

implemented mode wrap_centered in Images2Neibs in cpu mode. Make gpu raise NotImplementedError

上级 98d2a0c3
...@@ -11,12 +11,17 @@ if cuda_available: ...@@ -11,12 +11,17 @@ if cuda_available:
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 Images2Neibs(Op): class Images2Neibs(Op):
def __init__(self, mode='valid'):
if mode not in ['valid','wrap_centered']:
raise NotImplementedError("Only the mode valid and wrap_centered have been implemented for the op Images2Neibs")
self.mode = mode
def __eq__(self, other): def __eq__(self, other):
return type(self) == type(other) return type(self) == type(other) and self.mode==other.mode
def __hash__(self): def __hash__(self):
return hash(type(self)) return hash(type(self))^hash(self.mode)
def __str__(self): def __str__(self):
return self.__class__.__name__ return self.__class__.__name__+"{%s}"%self.mode
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 skip between patch
...@@ -45,7 +50,10 @@ class Images2Neibs(Op): ...@@ -45,7 +50,10 @@ class Images2Neibs(Op):
def c_code(self, node, name, (ten4, neib_shape, neib_step), (z,), sub): def c_code(self, node, name, (ten4, neib_shape, neib_step), (z,), sub):
fail = sub['fail'] fail = sub['fail']
mode=self.mode
return """ return """
int grid_c; //number of patch in height
int grid_d; //number of patch in width
{ {
if (%(ten4)s->nd != 4) if (%(ten4)s->nd != 4)
{ {
...@@ -80,6 +88,22 @@ class Images2Neibs(Op): ...@@ -80,6 +88,22 @@ class Images2Neibs(Op):
const npy_intp step_x = (npy_intp) *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 0); 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 npy_intp step_y = (npy_intp) *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 1);
if ( "%(mode)s" == "wrap_centered") {
if (c%%2!=1 || d%%2!=1){
PyErr_Format(PyExc_TypeError, "Images2Neibs: in mode wrap_centered need patch with odd shapes");
%(fail)s;
}
if ( (%(ten4)s->dimensions)[2] < c || (%(ten4)s->dimensions)[3] < d)
{
PyErr_Format(PyExc_TypeError, "Images2Neibs: in wrap_centered mode, don't support image shapes smaller then the patch shapes: neib_shape=(%%d,%%d), ten4[2:]=[%%d,%%d]",
c, d,%(ten4)s->dimensions[2], %(ten4)s->dimensions[3]);
%(fail)s;
}
//grid_c = CEIL_INTDIV(((%(ten4)s->dimensions)[2]),step_x)
//grid_d = CEIL_INTDIV(((%(ten4)s->dimensions)[3]),step_y)
grid_c = ((%(ten4)s->dimensions)[2])/step_x + ((((%(ten4)s->dimensions)[2])%%step_x)? 1:0);
grid_d = ((%(ten4)s->dimensions)[3])/step_y + ((((%(ten4)s->dimensions)[3])%%step_y)? 1:0);
}else if ( "%(mode)s" == "valid") {
if ( ((%(ten4)s->dimensions)[2] < c) ||( (((%(ten4)s->dimensions)[2]-c) %% step_x)!=0)) if ( ((%(ten4)s->dimensions)[2] < c) ||( (((%(ten4)s->dimensions)[2]-c) %% step_x)!=0))
{ {
PyErr_Format(PyExc_TypeError, "neib_shape[0]=%%d, neib_step[0]=%%d and ten4.shape[2]=%%d not consistent", PyErr_Format(PyExc_TypeError, "neib_shape[0]=%%d, neib_step[0]=%%d and ten4.shape[2]=%%d not consistent",
...@@ -92,9 +116,12 @@ class Images2Neibs(Op): ...@@ -92,9 +116,12 @@ class Images2Neibs(Op):
d, step_y, %(ten4)s->dimensions[3]); d, step_y, %(ten4)s->dimensions[3]);
%(fail)s; %(fail)s;
} }
grid_c = 1+(((%(ten4)s->dimensions)[2]-c)/step_x); //number of patch in height
const int grid_c = 1+(((%(ten4)s->dimensions)[2]-c)/step_x); //number of patch in height grid_d = 1+(((%(ten4)s->dimensions)[3]-d)/step_y); //number of patch in width
const int grid_d = 1+(((%(ten4)s->dimensions)[3]-d)/step_y); //number of patch in width }else{
PyErr_Format(PyExc_TypeError, "Images2Neibs: unknow mode '%(mode)s'");
%(fail)s;
}
// new dimensions for z // new dimensions for z
const npy_intp z_dim1 = c * d; const npy_intp z_dim1 = c * d;
...@@ -139,10 +166,9 @@ class Images2Neibs(Op): ...@@ -139,10 +166,9 @@ class Images2Neibs(Op):
// (step_x,step_y) = neib_step // (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_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 npy_intp step_y = (npy_intp) *(dtype_%(neib_step)s*) PyArray_GETPTR1(%(neib_step)s, 1);
const int grid_c = 1+(((%(ten4)s->dimensions)[2]-c)/step_x); //number of patch in height
const int grid_d = 1+(((%(ten4)s->dimensions)[3]-d)/step_y); //number of patch in width
const int wrap_centered_idx_shift_x = c/2;
const int wrap_centered_idx_shift_y = d/2;
// Oh this is messed up... // Oh this is messed up...
for (int n = 0; n < nb_batch; n++) // loop over batches for (int n = 0; n < nb_batch; n++) // loop over batches
for (int s = 0; s < nb_stack; s++) // loop over stacks for (int s = 0; s < nb_stack; s++) // loop over stacks
...@@ -153,10 +179,20 @@ class Images2Neibs(Op): ...@@ -153,10 +179,20 @@ class Images2Neibs(Op):
for (int i = 0; i < c; i++) // loop over c for (int i = 0; i < c; i++) // loop over c
{ {
int ten4_2 = i + a * step_x; int ten4_2 = i + a * step_x;
if ( "%(mode)s" == "wrap_centered" ){
ten4_2 -= wrap_centered_idx_shift_x;
if ( ten4_2 < 0 ) ten4_2 += height;
else if (ten4_2 >= height) ten4_2 -= height;
}
for (int j = 0; j < d; j++) // loop over d for (int j = 0; j < d; j++) // loop over d
{ {
int ten4_3 = j + b * step_y; int ten4_3 = j + b * step_y;
if ( "%(mode)s" == "wrap_centered" ){
ten4_3 -= wrap_centered_idx_shift_y;
if ( ten4_3 < 0 ) ten4_3 += width;
else if (ten4_3 >= width) ten4_3 -= width;
}
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);
...@@ -169,7 +205,9 @@ class Images2Neibs(Op): ...@@ -169,7 +205,9 @@ class Images2Neibs(Op):
} }
} // END NESTED SCOPE } // END NESTED SCOPE
""" % locals() """ % locals()
images2neibs = Images2Neibs()
def images2neibs(ten4, neib_shape, neib_step=None, mode='valid'):
return Images2Neibs(mode)(ten4, neib_shape, neib_step)
def neibs2images(neibs, neib_shape, original_shape): def neibs2images(neibs, neib_shape, original_shape):
""" """
...@@ -191,6 +229,10 @@ def neibs2images(neibs, neib_shape, original_shape): ...@@ -191,6 +229,10 @@ def neibs2images(neibs, neib_shape, original_shape):
# This is work in progress # This is work in progress
class GpuImages2Neibs(Images2Neibs): class GpuImages2Neibs(Images2Neibs):
def __init__(self, mode='valid'):
if mode not in ['valid']:
raise NotImplementedError("Only the mode valid have been implemented for the op GpuImages2Neibs")
self.mode = mode
def make_node(self, ten4, neib_shape, neib_step): def make_node(self, ten4, neib_shape, neib_step):
if neib_shape!=neib_step: if neib_shape!=neib_step:
...@@ -402,12 +444,13 @@ class GpuImages2Neibs(Images2Neibs): ...@@ -402,12 +444,13 @@ class GpuImages2Neibs(Images2Neibs):
} // END NESTED SCOPE } // END NESTED SCOPE
""" % locals() """ % locals()
gpu_images2neibs = GpuImages2Neibs() def gpu_images2neibs(ten4, neib_shape, neib_step=None, mode='valid'):
return GpuImages2Neibs(mode)(ten4, neib_shape, neib_step)
@local_optimizer() @local_optimizer()
def use_gpu_images2neibs(node): def use_gpu_images2neibs(node):
if node.op == 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]]))] 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)
......
...@@ -54,6 +54,63 @@ def test_neibs_bad_shape(): ...@@ -54,6 +54,63 @@ def test_neibs_bad_shape():
except TypeError: except TypeError:
pass pass
def test_neibs_bad_shape_warp_centered():
shape = (2,3,10,10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,2))
try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu)
neibs = f()
#print neibs
assert False,"An error was expected"
except TypeError:
pass
shape = (2,3,10,10)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((2,3))
try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu)
neibs = f()
#print neibs
assert False,"An error was expected"
except TypeError:
pass
shape = (2,3,2,3)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3))
try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu)
neibs = f()
#print neibs
assert False,"An error was expected"
except TypeError:
pass
shape = (2,3,3,2)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3))
try:
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu)
neibs = f()
#print neibs
assert False,"An error was expected"
except TypeError,e:
pass
shape = (2,3,3,3)
images = shared(numpy.arange(numpy.prod(shape)).reshape(shape))
neib_shape = T.as_tensor_variable((3,3))
f = function([], images2neibs(images, neib_shape, mode="wrap_centered"), mode=mode_without_gpu)
neibs = f()
#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))
...@@ -94,7 +151,7 @@ def test_neibs_manual(): ...@@ -94,7 +151,7 @@ def test_neibs_manual():
assert numpy.allclose(images.value,g()) assert numpy.allclose(images.value,g())
def test_neibs_manual_step(): 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(shape)).reshape(shape),dtype='float32'))
neib_shape = T.as_tensor_variable((3,3)) neib_shape = T.as_tensor_variable((3,3))
...@@ -138,6 +195,43 @@ def test_neibs_manual_step(): ...@@ -138,6 +195,43 @@ def test_neibs_manual_step():
#print g() #print g()
#assert numpy.allclose(images.value,g()) #assert numpy.allclose(images.value,g())
def test_neibs_wrap_centered_step_manual():
shape = (2,3,5,5)
images = shared(numpy.asarray(numpy.arange(numpy.prod(shape)).reshape(shape),dtype='float32'))
neib_shape = T.as_tensor_variable((3,3))
neib_step = T.as_tensor_variable((2,2))
modes = [mode_without_gpu]
if cuda.cuda_available:
modes.append(mode_with_gpu)
for mode in modes:
f = function([], images2neibs(images, neib_shape, neib_step, mode="wrap_centered"), mode=mode)
neibs = f()
print repr(neibs)
print neibs.shape
print images.value
expected = numpy.asarray([[24, 20, 21, 4, 0, 1, 9, 5, 6],
[21, 22, 23, 1, 2, 3, 6, 7, 8],
[23, 24, 20, 3, 4, 0, 8, 9, 5],
[ 9, 5, 6, 14, 10, 11, 19, 15, 16],
[ 6, 7, 8, 11, 12, 13, 16, 17, 18],
[ 8, 9, 5, 13, 14, 10, 18, 19, 15],
[19, 15, 16, 24, 20, 21, 4, 0, 1],
[16, 17, 18, 21, 22, 23, 1, 2, 3],
[18, 19, 15, 23, 24, 20, 3, 4, 0]])
assert numpy.allclose(neibs[0:9,:],expected)
assert numpy.allclose(neibs[9:18,:],expected+25)
assert numpy.allclose(neibs[18:27,:],expected+50)
assert numpy.allclose(neibs[27:36,:],expected+75)
assert numpy.allclose(neibs[36:45,:],expected+100)
assert numpy.allclose(neibs[45:,:],expected+125)
#g = function([], neibs2images(neibs, neib_shape, images.shape), mode=mode_without_gpu)
#print g()
#assert numpy.allclose(images.value,g())
def test_neibs_gpu(): def test_neibs_gpu():
if cuda.cuda_available == False: if cuda.cuda_available == False:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论