提交 d6a9018a authored 作者: Vikram's avatar Vikram

Same changes for GPU. cuDNN disabled. More tests

上级 5726f9ab
...@@ -480,11 +480,11 @@ class BaseGpuCorrMM(CGpuKernelBase): ...@@ -480,11 +480,11 @@ class BaseGpuCorrMM(CGpuKernelBase):
'tuple of length 2'.format(border_mode)) 'tuple of length 2'.format(border_mode))
border = () border = ()
for mode in border_mode: for mode in border_mode:
if isinstance(mode, integer_types) and mode >= 0: if isinstance(mode, tuple) and len(mode) == 2 and \
border += ((mode, mode),)
elif isinstance(mode, tuple) and len(mode) == 2 and \
min(mode) >= 0: min(mode) >= 0:
border += ((int(mode[0]), int(mode[1])),) border += ((int(mode[0]), int(mode[1])),)
elif mode >= 0:
border += ((int(mode), int(mode)),)
else: else:
raise ValueError( raise ValueError(
'invalid border mode {}. The tuple can only contain ' 'invalid border mode {}. The tuple can only contain '
...@@ -630,13 +630,13 @@ class BaseGpuCorrMM(CGpuKernelBase): ...@@ -630,13 +630,13 @@ class BaseGpuCorrMM(CGpuKernelBase):
if height: if height:
height = '(*(npy_int*)(PyArray_DATA(%s)))' % height height = '(*(npy_int*)(PyArray_DATA(%s)))' % height
else: else:
if ((direction != 0) and (dH != 1)) or ((direction == 1) and (padH_l == -1)): if ((direction != 0) and (dH != 1)) or ((direction == 1) and (padH_l == -1 or padH_r == -1)):
raise ValueError("height must be given for backprop with vertical sampling or pad='half'") raise ValueError("height must be given for backprop with vertical sampling or pad='half'")
height = '-1' height = '-1'
if width: if width:
width = '(*(npy_int*)(PyArray_DATA(%s)))' % width width = '(*(npy_int*)(PyArray_DATA(%s)))' % width
else: else:
if ((direction != 0) and (dW != 1)) or ((direction == 1) and (padW_l == -1)): if ((direction != 0) and (dW != 1)) or ((direction == 1) and (padW_l == -1 or padW_r == -1)):
raise ValueError("width must be given for backprop with horizontal sampling or pad='half'") raise ValueError("width must be given for backprop with horizontal sampling or pad='half'")
width = '-1' width = '-1'
......
...@@ -3038,6 +3038,9 @@ def local_abstractconv_cudnn_graph(op, context_name, inputs, outputs): ...@@ -3038,6 +3038,9 @@ def local_abstractconv_cudnn_graph(op, context_name, inputs, outputs):
if op.unshared: if op.unshared:
return None return None
if isinstance(op.border_mode, tuple) and any(isinstance(p, tuple) for p in op.border_mode):
return None
inp1 = inputs[0] inp1 = inputs[0]
inp2 = inputs[1] inp2 = inputs[1]
...@@ -3134,6 +3137,8 @@ def local_abstractconv_cudnn(node): ...@@ -3134,6 +3137,8 @@ def local_abstractconv_cudnn(node):
return return
if node.op.unshared: if node.op.unshared:
return None return None
if isinstance(node.op.border_mode, tuple) and any(isinstance(p, tuple) for p in node.op.border_mode):
return None
if isinstance(node.op, AbstractConv2d): if isinstance(node.op, AbstractConv2d):
return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs) return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs)
elif isinstance(node.op, AbstractConv3d): elif isinstance(node.op, AbstractConv3d):
...@@ -3150,6 +3155,8 @@ def local_abstractconv_cudnn_alt(node): ...@@ -3150,6 +3155,8 @@ def local_abstractconv_cudnn_alt(node):
return None return None
if node.op.unshared: if node.op.unshared:
return None return None
if isinstance(node.op.border_mode, tuple) and any(isinstance(p, tuple) for p in node.op.border_mode):
return None
inp1 = node.inputs[0] inp1 = node.inputs[0]
inp2 = node.inputs[1] inp2 = node.inputs[1]
...@@ -3358,6 +3365,8 @@ def local_abstractconv_gw_cudnn(node): ...@@ -3358,6 +3365,8 @@ def local_abstractconv_gw_cudnn(node):
return return
if node.op.unshared: if node.op.unshared:
return None return None
if isinstance(node.op.border_mode, tuple) and any(isinstance(p, tuple) for p in node.op.border_mode):
return None
if isinstance(node.op, AbstractConv2d_gradWeights): if isinstance(node.op, AbstractConv2d_gradWeights):
return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs) return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs)
elif isinstance(node.op, AbstractConv3d_gradWeights): elif isinstance(node.op, AbstractConv3d_gradWeights):
...@@ -3371,6 +3380,8 @@ def local_abstractconv_gi_cudnn(node): ...@@ -3371,6 +3380,8 @@ def local_abstractconv_gi_cudnn(node):
return return
if node.op.unshared: if node.op.unshared:
return None return None
if isinstance(node.op.border_mode, tuple) and any(isinstance(p, tuple) for p in node.op.border_mode):
return None
if isinstance(node.op, AbstractConv2d_gradInputs): if isinstance(node.op, AbstractConv2d_gradInputs):
return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs) return local_abstractconv_cudnn_graph(node.op, ctx, node.inputs, node.outputs)
elif isinstance(node.op, AbstractConv3d_gradInputs): elif isinstance(node.op, AbstractConv3d_gradInputs):
......
...@@ -12,7 +12,7 @@ from ..type import gpuarray_shared_constructor ...@@ -12,7 +12,7 @@ from ..type import gpuarray_shared_constructor
from ..blas import GpuCorrMM, GpuCorrMM_gradWeights, GpuCorrMM_gradInputs from ..blas import GpuCorrMM, GpuCorrMM_gradWeights, GpuCorrMM_gradInputs
from .config import mode_with_gpu, mode_without_gpu, ref_cast from .config import mode_with_gpu, mode_without_gpu, ref_cast
from theano.tensor.nnet.tests.test_abstract_conv import Grouped_conv_noOptim, TestUnsharedConv from theano.tensor.nnet.tests.test_abstract_conv import Grouped_conv_noOptim, TestUnsharedConv
from theano.tensor.nnet.tests.test_abstract_conv import TestAsymmetricPadding from theano.tensor.nnet.tests.test_abstract_conv import TestAsymmetricPadding, TestCausalConv
class TestCorrMM(unittest.TestCase): class TestCorrMM(unittest.TestCase):
...@@ -280,3 +280,7 @@ class TestAsymmetricGpu(TestAsymmetricPadding): ...@@ -280,3 +280,7 @@ class TestAsymmetricGpu(TestAsymmetricPadding):
conv2d_op = GpuCorrMM conv2d_op = GpuCorrMM
conv2d_gradw_op = GpuCorrMM_gradWeights conv2d_gradw_op = GpuCorrMM_gradWeights
conv2d_gradi_op = GpuCorrMM_gradInputs conv2d_gradi_op = GpuCorrMM_gradInputs
class TestCausalGpuCorr(TestCausalConv):
mode = mode_with_gpu.excluding('cudnn')
...@@ -1908,138 +1908,144 @@ class TestAsymmetricPadding(unittest.TestCase): ...@@ -1908,138 +1908,144 @@ class TestAsymmetricPadding(unittest.TestCase):
mode = theano.compile.mode.Mode(optimizer='None') mode = theano.compile.mode.Mode(optimizer='None')
imshp = (3, 2, 4, 4) img_shape = [(2, 2, 4, 4), (3, 2, 4, 2), (3, 3, 5, 3)]
kshp = (4, 2, 2, 2) kern_shape = [(4, 2, 2, 2), (2, 2, 4, 2), (2, 3, 3, 3)]
topshp = (3, 4, 6, 6) topgrad_shape = [(2, 4, 6, 6), (3, 2, 3, 4), (3, 2, 6, 1)]
pad = ((1, 2), (2, 1)) border_mode = [((1, 2), (2, 1)), ((1, 1), (0, 3)), ((2, 1), (0, 0))]
def test_fwd(self): def test_fwd(self):
img_sym = theano.tensor.tensor4('img') img_sym = theano.tensor.tensor4('img')
kern_sym = theano.tensor.tensor4('kern') kern_sym = theano.tensor.tensor4('kern')
img = np.random.random(self.imshp).astype(theano.config.floatX) for imshp, kshp, pad in zip(self.img_shape, self.kern_shape, self.border_mode):
kern = np.random.random(self.kshp).astype(theano.config.floatX) img = np.random.random(imshp).astype(theano.config.floatX)
kern = np.random.random(kshp).astype(theano.config.floatX)
asymmetric_conv_op = self.conv2d(border_mode=self.pad, subsample=(1, 1), asymmetric_conv_op = self.conv2d(border_mode=pad, subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
asymmetric_out_sym = asymmetric_conv_op(img_sym, kern_sym) asymmetric_out_sym = asymmetric_conv_op(img_sym, kern_sym)
asymmetric_func = theano.function([img_sym, kern_sym], asymmetric_out_sym, mode=self.mode) asymmetric_func = theano.function([img_sym, kern_sym], asymmetric_out_sym, mode=self.mode)
assert any([isinstance(node.op, self.conv2d_op) assert any([isinstance(node.op, self.conv2d_op)
for node in asymmetric_func.maker.fgraph.toposort()]) for node in asymmetric_func.maker.fgraph.toposort()])
asymmetric_output = asymmetric_func(img, kern) asymmetric_output = asymmetric_func(img, kern)
ref_conv_op = self.conv2d(border_mode="valid", subsample=(1, 1), ref_conv_op = self.conv2d(border_mode="valid", subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
ref_out_sym = ref_conv_op(img_sym, kern_sym) ref_out_sym = ref_conv_op(img_sym, kern_sym)
ref_func = theano.function([img_sym, kern_sym], ref_out_sym, mode=self.mode) ref_func = theano.function([img_sym, kern_sym], ref_out_sym, mode=self.mode)
exp_imshp = (self.imshp[0], self.imshp[1], exp_imshp = (imshp[0], imshp[1],
self.imshp[2] + self.pad[0][0] + self.pad[0][1], imshp[2] + pad[0][0] + pad[0][1],
self.imshp[3] + self.pad[1][0] + self.pad[1][1]) imshp[3] + pad[1][0] + pad[1][1])
exp_img = np.zeros(exp_imshp, dtype=theano.config.floatX) exp_img = np.zeros(exp_imshp, dtype=theano.config.floatX)
exp_img[:, :, self.pad[0][0]:self.imshp[2] + self.pad[0][0], exp_img[:, :, pad[0][0]:imshp[2] + pad[0][0],
self.pad[1][0]:self.imshp[3] + self.pad[1][0]] = img pad[1][0]:imshp[3] + pad[1][0]] = img
ref_output = ref_func(exp_img, kern) ref_output = ref_func(exp_img, kern)
utt.assert_allclose(asymmetric_output, ref_output) utt.assert_allclose(asymmetric_output, ref_output)
utt.verify_grad(asymmetric_conv_op, [img, kern], mode=self.mode, eps=1) utt.verify_grad(asymmetric_conv_op, [img, kern], mode=self.mode, eps=1)
def test_gradweight(self): def test_gradweight(self):
img_sym = theano.tensor.tensor4('img') img_sym = theano.tensor.tensor4('img')
top_sym = theano.tensor.tensor4('top') top_sym = theano.tensor.tensor4('top')
img = np.random.random(self.imshp).astype(theano.config.floatX) for imshp, kshp, topshp, pad in zip(self.img_shape, self.kern_shape, self.topgrad_shape, self.border_mode):
top = np.random.random(self.topshp).astype(theano.config.floatX) img = np.random.random(imshp).astype(theano.config.floatX)
top = np.random.random(topshp).astype(theano.config.floatX)
asymmetric_conv_op = self.conv2d_gradw(border_mode=self.pad, subsample=(1, 1), asymmetric_conv_op = self.conv2d_gradw(border_mode=pad, subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
asymmetric_out_sym = asymmetric_conv_op(img_sym, top_sym, self.kshp[-2:]) asymmetric_out_sym = asymmetric_conv_op(img_sym, top_sym, kshp[-2:])
asymmetric_func = theano.function([img_sym, top_sym], asymmetric_out_sym, mode=self.mode) asymmetric_func = theano.function([img_sym, top_sym], asymmetric_out_sym, mode=self.mode)
assert any([isinstance(node.op, self.conv2d_gradw_op) assert any([isinstance(node.op, self.conv2d_gradw_op)
for node in asymmetric_func.maker.fgraph.toposort()]) for node in asymmetric_func.maker.fgraph.toposort()])
asymmetric_output = asymmetric_func(img, top) asymmetric_output = asymmetric_func(img, top)
ref_conv_op = self.conv2d_gradw(border_mode="valid", subsample=(1, 1), ref_conv_op = self.conv2d_gradw(border_mode="valid", subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
ref_out_sym = ref_conv_op(img_sym, top_sym, self.kshp[-2:]) ref_out_sym = ref_conv_op(img_sym, top_sym, kshp[-2:])
ref_func = theano.function([img_sym, top_sym], ref_out_sym, mode=self.mode) ref_func = theano.function([img_sym, top_sym], ref_out_sym, mode=self.mode)
exp_imshp = (self.imshp[0], self.imshp[1], exp_imshp = (imshp[0], imshp[1],
self.imshp[2] + self.pad[0][0] + self.pad[0][1], imshp[2] + pad[0][0] + pad[0][1],
self.imshp[3] + self.pad[1][0] + self.pad[1][1]) imshp[3] + pad[1][0] + pad[1][1])
exp_img = np.zeros(exp_imshp, dtype=theano.config.floatX) exp_img = np.zeros(exp_imshp, dtype=theano.config.floatX)
exp_img[:, :, self.pad[0][0]:self.imshp[2] + self.pad[0][0], exp_img[:, :, pad[0][0]:imshp[2] + pad[0][0],
self.pad[1][0]:self.imshp[3] + self.pad[1][0]] = img pad[1][0]:imshp[3] + pad[1][0]] = img
ref_output = ref_func(exp_img, top) ref_output = ref_func(exp_img, top)
utt.assert_allclose(asymmetric_output, ref_output) utt.assert_allclose(asymmetric_output, ref_output)
def conv_gradweight(inputs_val, output_val): def conv_gradweight(inputs_val, output_val):
return asymmetric_conv_op(inputs_val, output_val, tensor.as_tensor_variable(self.kshp[-2:])) return asymmetric_conv_op(inputs_val, output_val, tensor.as_tensor_variable(kshp[-2:]))
utt.verify_grad(conv_gradweight, [img, top], mode=self.mode, eps=1) utt.verify_grad(conv_gradweight, [img, top], mode=self.mode, eps=1)
def test_gradinput(self): def test_gradinput(self):
kern_sym = theano.tensor.tensor4('kern') kern_sym = theano.tensor.tensor4('kern')
top_sym = theano.tensor.tensor4('top') top_sym = theano.tensor.tensor4('top')
kern = np.random.random(self.kshp).astype(theano.config.floatX) for imshp, kshp, topshp, pad in zip(self.img_shape, self.kern_shape, self.topgrad_shape, self.border_mode):
top = np.random.random(self.topshp).astype(theano.config.floatX) kern = np.random.random(kshp).astype(theano.config.floatX)
top = np.random.random(topshp).astype(theano.config.floatX)
asymmetric_conv_op = self.conv2d_gradi(border_mode=self.pad, subsample=(1, 1), asymmetric_conv_op = self.conv2d_gradi(border_mode=pad, subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
asymmetric_out_sym = asymmetric_conv_op(kern_sym, top_sym, self.imshp[-2:]) asymmetric_out_sym = asymmetric_conv_op(kern_sym, top_sym, imshp[-2:])
asymmetric_func = theano.function([kern_sym, top_sym], asymmetric_out_sym, mode=self.mode) asymmetric_func = theano.function([kern_sym, top_sym], asymmetric_out_sym, mode=self.mode)
assert any([isinstance(node.op, self.conv2d_gradi_op) assert any([isinstance(node.op, self.conv2d_gradi_op)
for node in asymmetric_func.maker.fgraph.toposort()]) for node in asymmetric_func.maker.fgraph.toposort()])
asymmetric_output = asymmetric_func(kern, top) asymmetric_output = asymmetric_func(kern, top)
ref_conv_op = self.conv2d_gradi(border_mode="valid", subsample=(1, 1), ref_conv_op = self.conv2d_gradi(border_mode="valid", subsample=(1, 1),
filter_dilation=(1, 1)) filter_dilation=(1, 1))
exp_imshp = [self.imshp[2] + self.pad[0][0] + self.pad[0][1], exp_imshp = [imshp[2] + pad[0][0] + pad[0][1],
self.imshp[3] + self.pad[1][0] + self.pad[1][1]] imshp[3] + pad[1][0] + pad[1][1]]
ref_out_sym = ref_conv_op(kern_sym, top_sym, exp_imshp) ref_out_sym = ref_conv_op(kern_sym, top_sym, exp_imshp)
ref_func = theano.function([kern_sym, top_sym], ref_out_sym, mode=self.mode) ref_func = theano.function([kern_sym, top_sym], ref_out_sym, mode=self.mode)
ref_output = ref_func(kern, top) ref_output = ref_func(kern, top)
ref_output = ref_output[:, :, self.pad[0][0]:self.imshp[2] + self.pad[0][0], ref_output = ref_output[:, :, pad[0][0]:imshp[2] + pad[0][0],
self.pad[1][0]:self.imshp[3] + self.pad[1][0]] pad[1][0]:imshp[3] + pad[1][0]]
utt.assert_allclose(asymmetric_output, ref_output) utt.assert_allclose(asymmetric_output, ref_output)
def conv_gradinputs(filters_val, output_val): def conv_gradinputs(filters_val, output_val):
return asymmetric_conv_op(filters_val, output_val, tensor.as_tensor_variable(self.imshp[-2:])) return asymmetric_conv_op(filters_val, output_val, tensor.as_tensor_variable(imshp[-2:]))
utt.verify_grad(conv_gradinputs, [kern, top], mode=self.mode, eps=1) utt.verify_grad(conv_gradinputs, [kern, top], mode=self.mode, eps=1)
class TestCausalConv(unittest.TestCase): class TestCausalConv(unittest.TestCase):
mode = theano.compile.mode.Mode(optimizer='None') mode = theano.compile.mode.Mode(optimizer='None')
imshp = (3, 2, 5) img = np.array([[[2, 4, 9, 5, 8], [0, 0, 4, 0, 5]],
kshp = (2, 2, 3) [[2, 5, 8, 5, 5], [1, 3, 0, 7, 9]],
topshp = (3, 2, 5) [[7, 0, 7, 1, 0], [0, 1, 4, 7, 2]]]).astype(theano.config.floatX)
kern = np.array([[[5, 3, 1], [3, 1, 0]],
[[6, 4, 9], [2, 2, 7]]]).astype(theano.config.floatX)
dilation = 2
precomp_top = np.array([[[10, 20, 63, 37, 88], [12, 24, 70, 46, 120]],
[[13, 34, 47, 64, 78], [14, 36, 58, 70, 105]],
[[35, 3, 68, 27, 38], [42, 2, 78, 22, 103]]]).astype(theano.config.floatX)
def test_interface(self): def test_interface(self):
img_sym = theano.tensor.tensor3('img') img_sym = theano.tensor.tensor3('img')
kern_sym = theano.tensor.tensor3('kern') kern_sym = theano.tensor.tensor3('kern')
img = np.random.random(self.imshp).astype(theano.config.floatX) sym_out = causal_conv(img_sym, kern_sym, self.kern.shape, filter_dilation=self.dilation)
kern = np.random.random(self.kshp).astype(theano.config.floatX)
sym_out = causal_conv(img_sym, kern_sym, self.kshp, filter_dilation=1)
causal_func = theano.function([img_sym, kern_sym], sym_out, mode=self.mode) causal_func = theano.function([img_sym, kern_sym], sym_out, mode=self.mode)
output = causal_func(img, kern) output = causal_func(self.img, self.kern)
assert output.shape == self.topshp utt.assert_allclose(output, self.precomp_top)
# def causal_conv(inputs_val, filters_val): def causal_conv_fn(inputs_val, filters_val):
# return dilated_causal_conv(inputs_val, filters_val, self.kshp, filter_dilation=1) return causal_conv(inputs_val, filters_val, self.kern.shape, filter_dilation=1)
# utt.verify_grad(causal_conv, [img, kern], mode=self.mode, eps=1) utt.verify_grad(causal_conv_fn, [self.img, self.kern], mode=self.mode, eps=1)
...@@ -11,7 +11,7 @@ import theano.tensor as T ...@@ -11,7 +11,7 @@ import theano.tensor as T
from theano.tests import unittest_tools as utt from theano.tests import unittest_tools as utt
from theano.tensor.nnet import corr, conv from theano.tensor.nnet import corr, conv
from theano.tensor.nnet.tests.test_abstract_conv import Grouped_conv_noOptim, TestUnsharedConv from theano.tensor.nnet.tests.test_abstract_conv import Grouped_conv_noOptim, TestUnsharedConv
from theano.tensor.nnet.tests.test_abstract_conv import TestAsymmetricPadding from theano.tensor.nnet.tests.test_abstract_conv import TestAsymmetricPadding, TestCausalConv
class TestCorr2D(utt.InferShapeTester): class TestCorr2D(utt.InferShapeTester):
...@@ -473,6 +473,13 @@ class TestAsymmetricCorr(TestAsymmetricPadding): ...@@ -473,6 +473,13 @@ class TestAsymmetricCorr(TestAsymmetricPadding):
conv2d_gradi_op = corr.CorrMM_gradInputs conv2d_gradi_op = corr.CorrMM_gradInputs
class TestCausalCorr(TestCausalConv):
if theano.config.mode == "FAST_COMPILE":
mode = theano.compile.get_mode("FAST_RUN").excluding('gpuarray')
else:
mode = None
if __name__ == '__main__': if __name__ == '__main__':
t = TestCorr2D('setUp') t = TestCorr2D('setUp')
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论