提交 0aa5ff77 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Merge pull request #4018 from abergeron/fix_buildbot

Move the AbstractConv tests with the implementation
import unittest
import numpy
import itertools
import theano import theano
from theano import tensor from theano.tensor.nnet.tests import test_abstract_conv
from theano.tests import unittest_tools as utt
import theano.tensor.nnet.abstract_conv as conv
from theano.sandbox.cuda import float32_shared_constructor as gpu_shared from theano.sandbox.cuda import float32_shared_constructor as gpu_shared
from theano.compile import shared as cpu_shared
from theano.sandbox.cuda.dnn import ( from theano.sandbox.cuda.dnn import (
dnn_available, dnn_conv, dnn_gradweight, dnn_gradinput, dnn_available,
GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI) GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI)
from theano.sandbox.cuda.blas import ( from theano.sandbox.cuda.blas import (
GpuCorrMM, GpuCorrMM_gradWeights, GpuCorrMM_gradInputs) GpuCorrMM, GpuCorrMM_gradWeights, GpuCorrMM_gradInputs)
...@@ -21,237 +15,49 @@ if not cuda.cuda_available: ...@@ -21,237 +15,49 @@ if not cuda.cuda_available:
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')
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.get_default_mode().excluding('gpu')
class TestConv2d(unittest.TestCase): class TestDnnConv2d(test_abstract_conv.BaseTestConv2d):
def setUp(self): def setUp(self):
super(TestDnnConv2d, self).setUp()
# provide_shape is not used by the CuDNN impementation
self.provide_shape = [False]
self.shared = gpu_shared
super(TestConv2d, self).setUp() def tcase(self, i, f, s, b, flip, provide_shape):
self.inputs_shapes = [(8, 1, 12, 12), (8, 1, 18, 18), (2, 1, 4, 4),
(6, 1, 10, 11), (2, 1, 6, 5), (1, 5, 9, 9)]
self.filters_shapes = [(5, 1, 2, 2), (4, 1, 3, 3), (2, 1, 3, 3),
(1, 1, 2, 5), (4, 1, 2, 2), (4, 5, 2, 2)]
self.subsamples = [(1, 1), (2, 2), (2, 4)]
self.border_modes = ["valid", "full", "half",
(0, 0), (1, 1), (5, 5), (5, 2)]
self.filter_flip = [True, False]
def get_output_shape(self, inputs_shape, filters_shape,
subsample, border_mode):
if border_mode == "valid":
border_mode = (0, 0)
elif border_mode == "full":
border_mode = (filters_shape[2] - 1, filters_shape[3] - 1)
elif border_mode == "half":
border_mode = (filters_shape[2] // 2, filters_shape[3] // 2)
batch_size = inputs_shape[0]
num_filters = filters_shape[0]
return (batch_size, num_filters,) \
+ tuple(None if i is None or k is None
else ((i + 2 * pad - k) // d + 1)
for i, k, d, pad in zip(inputs_shape[2:], filters_shape[2:],
subsample, border_mode))
def run_fwd(self, inputs_shape, filters_shape, ref=dnn_conv,
subsample=(1, 1), verify_grad=True, mode=mode_without_gpu,
border_mode='valid', filter_flip=True, device='cpu', provide_shape=False,
target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
if device == 'gpu':
inputs = gpu_shared(inputs_val)
filters = gpu_shared(filters_val)
else:
inputs = theano.tensor.as_tensor_variable(cpu_shared(inputs_val))
filters = theano.tensor.as_tensor_variable(cpu_shared(filters_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c_ref = ref(inputs, filters,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
c = conv.conv2d(inputs, filters,
border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
input_shape=imshp,
filter_shape=kshp)
f_ref = theano.function([], c_ref, mode=mode)
f = theano.function([], c, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
if verify_grad:
utt.verify_grad(conv.AbstractConv2d(border_mode="valid", imshp=imshp, kshp=kshp,
subsample=subsample),
[inputs_val, filters_val],
mode=mode)
def run_gradweight(self, inputs_shape, filters_shape, output_shape,
ref=dnn_gradweight, subsample=(1, 1), filter_flip=True,
verify_grad=True, mode=mode_without_gpu, border_mode='valid',
device='cpu', provide_shape=False, target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
output_val = numpy.random.random(output_shape).astype('float32')
if device == 'gpu':
inputs = gpu_shared(inputs_val)
output = gpu_shared(output_val)
else:
inputs = theano.tensor.as_tensor_variable(cpu_shared(inputs_val))
output = theano.tensor.as_tensor_variable(cpu_shared(output_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradWeights(border_mode=border_mode,
filter_flip=filter_flip,
subsample=subsample,
imshp=imshp, kshp=kshp)
c = c(inputs, output, filters_shape[-2:])
c_ref = ref(inputs, output,
filters_shape,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode)
f_ref = theano.function([], c_ref, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradweight(inputs_val, output_val):
conv_op = conv.AbstractConv2d_gradWeights(border_mode=border_mode, subsample=subsample)
return conv_op(inputs_val, output_val, filters_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradweight, [inputs_val, output_val],
mode=mode, eps=1)
def run_gradinput(self, inputs_shape, filters_shape,
output_shape, ref=dnn_gradinput,
subsample=(1, 1), filter_flip=True,
verify_grad=True, mode=mode_without_gpu,
border_mode='valid', device='cpu', provide_shape=False,
target_op=None):
output_val = numpy.random.random(output_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
if device == 'gpu':
output = gpu_shared(output_val)
filters = gpu_shared(filters_val)
else:
output = theano.tensor.as_tensor_variable(cpu_shared(output_val))
filters = theano.tensor.as_tensor_variable(cpu_shared(filters_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradInputs(border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
imshp=imshp, kshp=kshp)
c = c(filters, output, inputs_shape[-2:])
c_ref = ref(filters, output, inputs_shape,
border_mode=border_mode, subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode)
f_ref = theano.function([], c_ref, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradinputs(filters_val, output_val):
conv_op = conv.AbstractConv2d_gradInputs(border_mode=border_mode, subsample=subsample)
return conv_op(filters_val, output_val, inputs_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradinputs, [filters_val, output_val],
mode=mode, eps=1)
def test_dnn_conv(self):
if not dnn_available(): if not dnn_available():
raise SkipTest(cuda.dnn.dnn_available.msg) raise SkipTest(cuda.dnn.dnn_available.msg)
mode = mode_with_gpu mode = mode_with_gpu
# provide_shape is not used by the CuDNN impementation
provide_shape = False
for (i, f), s, b, flip in itertools.product(
zip(self.inputs_shapes, self.filters_shapes),
self.subsamples,
self.border_modes,
self.filter_flip):
o = self.get_output_shape(i, f, s, b) o = self.get_output_shape(i, f, s, b)
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s, self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConv) filter_flip=flip, target_op=GpuDnnConv)
self.run_gradweight(inputs_shape=i, filters_shape=f, self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConvGradW) filter_flip=flip, target_op=GpuDnnConvGradW)
self.run_gradinput(inputs_shape=i, filters_shape=f, self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConvGradI) filter_flip=flip, target_op=GpuDnnConvGradI)
def test_gpucorrmm_conv(self):
if not dnn_available():
raise SkipTest(cuda.dnn.dnn_available.msg)
mode = mode_with_gpu.excluding('cudnn') class TestCorrMMConv2d(test_abstract_conv.TestConv2d):
for (i, f), s, b, flip, provide_shape in itertools.product( def setUp(self):
zip(self.inputs_shapes, self.filters_shapes), super(TestCorrMMConv2d, self).setUp()
self.subsamples, self.shared = gpu_shared
self.border_modes, self.mode = mode_with_gpu.excluding('cudnn')
self.filter_flip,
[False, True]):
def test_gpucorrmm_conv(self, i, f, s, b, flip, provide_shape):
mode = self.mode
o = self.get_output_shape(i, f, s, b) o = self.get_output_shape(i, f, s, b)
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s, self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, filter_flip=flip,
target_op=(GpuCorrMM, target_op=(GpuCorrMM,
...@@ -259,65 +65,20 @@ class TestConv2d(unittest.TestCase): ...@@ -259,65 +65,20 @@ class TestConv2d(unittest.TestCase):
GpuCorrMM_gradInputs)) GpuCorrMM_gradInputs))
self.run_gradweight(inputs_shape=i, filters_shape=f, self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, filter_flip=flip,
target_op=GpuCorrMM_gradWeights) target_op=GpuCorrMM_gradWeights)
self.run_gradinput(inputs_shape=i, filters_shape=f, self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, filter_flip=flip,
target_op=GpuCorrMM_gradInputs) target_op=GpuCorrMM_gradInputs)
def test_grad_types(self):
# This function simply tests the behaviour of the AbstractConv
# Ops, not their optimizations
cpu_input = tensor.ftensor4()
cpu_filters = tensor.ftensor4()
cpu_topgrad = tensor.ftensor4()
gpu_input = cuda.ftensor4()
gpu_filters = cuda.ftensor4()
gpu_topgrad = cuda.ftensor4()
out_shape = tensor.lvector()
# Check the gradient of the forward conv2d
for input, filters in itertools.product(
(cpu_input, gpu_input),
(cpu_filters, gpu_filters)):
output = conv.conv2d(input, filters)
grad_input, grad_filters = theano.grad(output.sum(),
wrt=(input, filters))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
# Check the gradient of gradweight class TestDnnConvTypes(test_abstract_conv.TestConvTypes):
for input, topgrad in itertools.product( def setUp(self):
(cpu_input, gpu_input), self.input = cuda.ftensor4()
(cpu_topgrad, gpu_topgrad)): self.filters = cuda.ftensor4()
grad_filters = conv.AbstractConv2d_gradWeights()( self.topgrad = cuda.ftensor4()
input, topgrad, out_shape)
grad_input, grad_topgrad = theano.grad(grad_filters.sum(),
wrt=(input, topgrad))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
# Check the gradient of gradinputs
for filters, topgrad in itertools.product(
(cpu_filters, gpu_filters),
(cpu_topgrad, gpu_topgrad)):
grad_input = conv.AbstractConv2d_gradInputs()(
filters, topgrad, out_shape)
grad_filters, grad_topgrad = theano.grad(grad_input.sum(),
wrt=(filters, topgrad))
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
import unittest
import numpy
import itertools
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
import theano from theano.tensor.nnet.tests import test_abstract_conv
from theano import tensor from ..type import GpuArrayType, gpuarray_shared_constructor
from theano.tests import unittest_tools as utt from ..dnn import dnn_available, GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI
import theano.tensor.nnet.abstract_conv as conv
from theano.compile import shared as cpu_shared
from ..type import gpuarray_shared_constructor as gpu_shared
from ..type import GpuArrayType
from ..dnn import (
dnn_available, dnn_conv, dnn_gradweight, dnn_gradinput,
GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI)
from theano.tensor.nnet.corr import (
CorrMM, CorrMM_gradWeights, CorrMM_gradInputs)
from theano.tensor.nnet.conv import ConvOp
from theano.tensor.nnet import ConvGrad3D, ConvTransp3D
from .config import mode_with_gpu, mode_without_gpu, test_ctx_name
from .config import mode_with_gpu, test_ctx_name
gpu_ftensor4 = GpuArrayType(dtype='float32', broadcastable=(False,) * 4) gpu_ftensor4 = GpuArrayType(dtype='float32', broadcastable=(False,) * 4)
class TestConv2d(unittest.TestCase): class TestDnnConv2d(test_abstract_conv.BaseTestConv2d):
def setUp(self): def setUp(self):
super(TestConv2d, self).setUp() super(TestDnnConv2d, self).setUp()
self.inputs_shapes = [(8, 1, 12, 12), (8, 1, 18, 18), (2, 1, 4, 4), self.shared = gpuarray_shared_constructor
(6, 1, 10, 11), (2, 1, 6, 5), (1, 5, 9, 9)] # provide_shape is not used by the CuDNN impementation
self.filters_shapes = [(5, 1, 2, 2), (4, 1, 3, 3), (2, 1, 3, 3), self.provide_shape = [False]
(1, 1, 2, 5), (4, 1, 2, 2), (4, 5, 2, 2)]
self.subsamples = [(1, 1), (2, 2), (2, 4)]
self.border_modes = ["valid", "full", (0, 0), (1, 1), (5, 5), (5, 2)]
self.filter_flip = [True, False]
def get_output_shape(self, inputs_shape, filters_shape, subsample,
border_mode):
if border_mode == "valid":
border_mode = (0, 0)
if border_mode == "full":
border_mode = (filters_shape[2] - 1, filters_shape[3] - 1)
batch_size = inputs_shape[0]
num_filters = filters_shape[0]
return ((batch_size, num_filters,) +
tuple(None if i is None or k is None
else ((i + 2 * pad - k) // d + 1)
for i, k, d, pad in zip(inputs_shape[2:],
filters_shape[2:],
subsample, border_mode)))
def run_fwd(self, inputs_shape, filters_shape, ref=dnn_conv,
subsample=(1, 1), verify_grad=True, mode=mode_without_gpu,
border_mode='valid', filter_flip=True, device='cpu',
provide_shape=False, target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
if device == 'gpu':
inputs = gpu_shared(inputs_val)
filters = gpu_shared(filters_val)
else:
inputs = theano.tensor.as_tensor_variable(cpu_shared(inputs_val))
filters = theano.tensor.as_tensor_variable(cpu_shared(filters_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c_ref = ref(inputs, filters,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
c = conv.conv2d(inputs, filters,
border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
input_shape=imshp,
filter_shape=kshp)
f_ref = theano.function([], c_ref, mode=mode)
f = theano.function([], c, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
if verify_grad:
utt.verify_grad(conv.AbstractConv2d(border_mode="valid",
imshp=imshp, kshp=kshp,
subsample=subsample),
[inputs_val, filters_val],
mode=mode)
def run_gradweight(self, inputs_shape, filters_shape, output_shape,
ref=dnn_gradweight, subsample=(1, 1), filter_flip=True,
verify_grad=True, mode=mode_without_gpu, border_mode='valid',
device='cpu', provide_shape=False, target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
output_val = numpy.random.random(output_shape).astype('float32')
if device == 'gpu':
inputs = gpu_shared(inputs_val)
output = gpu_shared(output_val)
else:
inputs = theano.tensor.as_tensor_variable(cpu_shared(inputs_val))
output = theano.tensor.as_tensor_variable(cpu_shared(output_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradWeights(border_mode=border_mode,
filter_flip=filter_flip,
subsample=subsample,
imshp=imshp, kshp=kshp)
c = c(inputs, output, filters_shape[-2:])
c_ref = ref(inputs, output,
filters_shape,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
f_ref = theano.function([], c_ref, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradweight(inputs_val, output_val):
conv_op = conv.AbstractConv2d_gradWeights(border_mode=border_mode, subsample=subsample)
return conv_op(inputs_val, output_val, filters_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradweight, [inputs_val, output_val],
mode=mode, eps=1)
def run_gradinput(self, inputs_shape, filters_shape, output_shape, ref=dnn_gradinput,
subsample=(1, 1), filter_flip=True, verify_grad=True, mode=mode_without_gpu,
border_mode='valid', device='cpu', provide_shape=False,
target_op=None):
output_val = numpy.random.random(output_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
if device == 'gpu':
output = gpu_shared(output_val)
filters = gpu_shared(filters_val)
else:
output = theano.tensor.as_tensor_variable(cpu_shared(output_val))
filters = theano.tensor.as_tensor_variable(cpu_shared(filters_val))
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradInputs(border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
imshp=imshp, kshp=kshp)
c = c(filters, output, inputs_shape[-2:])
c_ref = ref(filters, output, inputs_shape,
border_mode=border_mode, subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
f_ref = theano.function([], c_ref, mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradinputs(filters_val, output_val):
conv_op = conv.AbstractConv2d_gradInputs(border_mode=border_mode, subsample=subsample)
return conv_op(filters_val, output_val, inputs_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradinputs, [filters_val, output_val],
mode=mode, eps=1)
def test_dnn_conv(self): def tcase(self, i, f, s, b, flip, provide_shape):
if not dnn_available(test_ctx_name): if not dnn_available(test_ctx_name):
raise SkipTest(dnn_available.msg) raise SkipTest(dnn_available.msg)
mode = mode_with_gpu mode = mode_with_gpu
# provide_shape is not used by the CuDNN impementation
provide_shape = False
for (i, f), s, b, flip in itertools.product(
zip(self.inputs_shapes, self.filters_shapes),
self.subsamples,
self.border_modes,
self.filter_flip):
o = self.get_output_shape(i, f, s, b) o = self.get_output_shape(i, f, s, b)
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s, self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConv) filter_flip=flip, target_op=GpuDnnConv)
self.run_gradweight(inputs_shape=i, filters_shape=f, self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConvGradW) filter_flip=flip, target_op=GpuDnnConvGradW)
self.run_gradinput(inputs_shape=i, filters_shape=f, self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='gpu', verify_grad=True, mode=mode,
provide_shape=provide_shape, border_mode=b, provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=GpuDnnConvGradI) filter_flip=flip, target_op=GpuDnnConvGradI)
def test_cormm_conv(self):
if not dnn_available(test_ctx_name):
raise SkipTest(dnn_available.msg)
mode = mode_without_gpu
for (i, f), s, b, flip, provide_shape in itertools.product(
zip(self.inputs_shapes, self.filters_shapes),
self.subsamples,
self.border_modes,
self.filter_flip,
[False, True]):
o = self.get_output_shape(i, f, s, b) class TestDnnConvTypes(test_abstract_conv.TestConvTypes):
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s, def setUp(self):
verify_grad=True, mode=mode, device='cpu', self.input = gpu_ftensor4()
provide_shape=provide_shape, border_mode=b, self.filters = gpu_ftensor4()
filter_flip=flip, target_op=CorrMM) self.topgrad = gpu_ftensor4()
self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='cpu',
provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=CorrMM_gradWeights)
self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=True, mode=mode, device='cpu',
provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=CorrMM_gradInputs)
def test_cpu_conv(self):
if not dnn_available(test_ctx_name):
raise SkipTest(dnn_available.msg)
mode = mode_without_gpu.excluding('conv_gemm')
for (i, f), s, b, flip, provide_shape in itertools.product(
zip(self.inputs_shapes, self.filters_shapes),
self.subsamples,
self.border_modes,
self.filter_flip,
[False, True]):
o = self.get_output_shape(i, f, s, b)
fwd_OK = True
gradweight_OK = True
gradinput_OK = True
if not flip:
fwd_OK = False
gradweight_OK = False
gradinput_OK = False
if b not in ('valid', 'full'):
fwd_OK = False
gradweight_OK = False
gradinput_OK = False
if (not provide_shape) and (s != (1, 1)) and (b == 'full'):
gradweight_OK = False
gradinput_OK = False
if ((s[0] not in (1, 2)) or (s[1] not in (1, 2))) and (b == 'full'):
gradweight_OK = False
gradinput_OK = False
if fwd_OK:
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, mode=mode, device='cpu',
provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=ConvOp)
else:
self.assertRaises(NotImplementedError,
self.run_fwd,
inputs_shape=i,
filters_shape=f,
subsample=s,
verify_grad=False,
mode=mode,
device='cpu',
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
if gradweight_OK:
self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode, device='cpu',
provide_shape=provide_shape, border_mode=b,
filter_flip=flip,
target_op=(ConvOp, ConvGrad3D))
else:
self.assertRaises(NotImplementedError,
self.run_gradweight,
inputs_shape=i,
filters_shape=f,
output_shape=o,
subsample=s,
verify_grad=False,
mode=mode,
device='cpu',
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
if gradinput_OK:
self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode, device='cpu',
provide_shape=provide_shape, border_mode=b,
filter_flip=flip,
target_op=(ConvOp, ConvTransp3D))
else:
self.assertRaises(NotImplementedError,
self.run_gradinput,
inputs_shape=i,
filters_shape=f,
output_shape=o,
subsample=s,
verify_grad=False,
mode=mode,
device='cpu',
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
def test_grad_types(self):
# This function simply tests the behaviour of the AbstractConv
# Ops, not their optimizations
cpu_input = tensor.ftensor4()
cpu_filters = tensor.ftensor4()
cpu_topgrad = tensor.ftensor4()
gpu_input = gpu_ftensor4()
gpu_filters = gpu_ftensor4()
gpu_topgrad = gpu_ftensor4()
out_shape = tensor.lvector()
# Check the gradient of the forward conv2d
for input, filters in itertools.product(
(cpu_input, gpu_input),
(cpu_filters, gpu_filters)):
output = conv.conv2d(input, filters)
grad_input, grad_filters = theano.grad(output.sum(),
wrt=(input, filters))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
# Check the gradient of gradweight
for input, topgrad in itertools.product(
(cpu_input, gpu_input),
(cpu_topgrad, gpu_topgrad)):
grad_filters = conv.AbstractConv2d_gradWeights()(
input, topgrad, out_shape)
grad_input, grad_topgrad = theano.grad(grad_filters.sum(),
wrt=(input, topgrad))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
# Check the gradient of gradinputs
for filters, topgrad in itertools.product(
(cpu_filters, gpu_filters),
(cpu_topgrad, gpu_topgrad)):
grad_input = conv.AbstractConv2d_gradInputs()(
filters, topgrad, out_shape)
grad_filters, grad_topgrad = theano.grad(grad_input.sum(),
wrt=(filters, topgrad))
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
...@@ -31,6 +31,7 @@ from .bn import batch_normalization ...@@ -31,6 +31,7 @@ from .bn import batch_normalization
import warnings import warnings
from .abstract_conv import conv2d as abstract_conv2d from .abstract_conv import conv2d as abstract_conv2d
def conv2d(input, filters, input_shape=None, filter_shape=None, def conv2d(input, filters, input_shape=None, filter_shape=None,
border_mode='valid', subsample=(1, 1), filter_flip=True, border_mode='valid', subsample=(1, 1), filter_flip=True,
image_shape=None, **kwargs): image_shape=None, **kwargs):
...@@ -139,5 +140,3 @@ def conv2d(input, filters, input_shape=None, filter_shape=None, ...@@ -139,5 +140,3 @@ def conv2d(input, filters, input_shape=None, filter_shape=None,
return abstract_conv2d(input, filters, input_shape, filter_shape, return abstract_conv2d(input, filters, input_shape, filter_shape,
border_mode, subsample, filter_flip) border_mode, subsample, filter_flip)
...@@ -408,7 +408,7 @@ class BaseAbstractConv2d(Op): ...@@ -408,7 +408,7 @@ class BaseAbstractConv2d(Op):
if len(subsample) != 2: if len(subsample) != 2:
raise ValueError("subsample must have two elements") raise ValueError("subsample must have two elements")
self.subsample = subsample self.subsample = tuple(subsample)
def flops(self, inp, outp): def flops(self, inp, outp):
""" Useful with the hack in profilemode to print the MFlops""" """ Useful with the hack in profilemode to print the MFlops"""
......
...@@ -52,7 +52,7 @@ class BaseCorrMM(gof.Op): ...@@ -52,7 +52,7 @@ class BaseCorrMM(gof.Op):
self.border_mode = border_mode self.border_mode = border_mode
if len(subsample) != 2: if len(subsample) != 2:
raise ValueError("subsample must have two elements") raise ValueError("subsample must have two elements")
self.subsample = subsample self.subsample = tuple(subsample)
@property @property
def pad(self): def pad(self):
...@@ -177,13 +177,13 @@ class BaseCorrMM(gof.Op): ...@@ -177,13 +177,13 @@ class BaseCorrMM(gof.Op):
if ((direction != 0) and (dH != 1)) or ((direction == 1) and (padH == -1)): if ((direction != 0) and (dH != 1)) or ((direction == 1) and (padH == -1)):
if not height: if not height:
raise ValueError("height must be given for backprop with vertical sampling or border_mode='half'") raise ValueError("height must be given for backprop with vertical sampling or border_mode='half'")
height = '(*(npy_int*)(PyArray_DATA(%s)))' % height height = '(*(npy_int64 *)(PyArray_DATA(%s)))' % height
else: else:
height = '-1' height = '-1'
if ((direction != 0) and (dW != 1)) or ((direction == 1) and (padW == -1)): if ((direction != 0) and (dW != 1)) or ((direction == 1) and (padW == -1)):
if not width: if not width:
raise ValueError("width must be given for backprop with horizontal sampling or border_mode='half'") raise ValueError("width must be given for backprop with horizontal sampling or border_mode='half'")
width = '(*(npy_int*)(PyArray_DATA(%s)))' % width width = '(*(npy_int64 *)(PyArray_DATA(%s)))' % width
else: else:
width = '-1' width = '-1'
sub = sub.copy() sub = sub.copy()
...@@ -314,8 +314,8 @@ class BaseCorrMM(gof.Op): ...@@ -314,8 +314,8 @@ class BaseCorrMM(gof.Op):
if (NULL == %(out)s) if (NULL == %(out)s)
{ {
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"BaseCorrMM: Failed to allocate output of %%d x %%d x %%d x %%d", "BaseCorrMM: Failed to allocate output of %%lld x %%lld x %%lld x %%lld",
out_dim[0], out_dim[1], out_dim[2], out_dim[3]); (long long)out_dim[0], (long long)out_dim[1], (long long)out_dim[2], (long long)out_dim[3]);
%(fail)s %(fail)s
} }
} }
...@@ -424,7 +424,7 @@ class CorrMM_gradWeights(BaseCorrMM): ...@@ -424,7 +424,7 @@ class CorrMM_gradWeights(BaseCorrMM):
if shape is None: if shape is None:
raise ValueError('shape must be given if subsample != (1, 1)' raise ValueError('shape must be given if subsample != (1, 1)'
' or border_mode == "half"') ' or border_mode == "half"')
height_width = [shape[0], shape[1]] height_width = [as_tensor_variable(shape[0]).astype('int64'), as_tensor_variable(shape[1]).astype('int64')]
else: else:
height_width = [] height_width = []
...@@ -519,7 +519,7 @@ class CorrMM_gradInputs(BaseCorrMM): ...@@ -519,7 +519,7 @@ class CorrMM_gradInputs(BaseCorrMM):
raise TypeError('topgrad must be 4D tensor') raise TypeError('topgrad must be 4D tensor')
if self.subsample != (1, 1) and shape is None: if self.subsample != (1, 1) and shape is None:
raise ValueError('shape must be given if subsample != (1, 1)') raise ValueError('shape must be given if subsample != (1, 1)')
height_width = [shape[0], shape[1]] if self.subsample != (1, 1) else [] height_width = [as_tensor_variable(shape[0]).astype('int64'), as_tensor_variable(shape[1]).astype('int64')] if self.subsample != (1, 1) else []
broadcastable = [topgrad.type.broadcastable[0], kern.type.broadcastable[1], broadcastable = [topgrad.type.broadcastable[0], kern.type.broadcastable[1],
False, False] False, False]
......
...@@ -162,7 +162,7 @@ PyArrayObject* corrMM(PyArrayObject* bottom, ...@@ -162,7 +162,7 @@ PyArrayObject* corrMM(PyArrayObject* bottom,
"CorrMM shape inconsistency:\n" "CorrMM shape inconsistency:\n"
" bottom shape: %%d %%d %%d %%d\n" " bottom shape: %%d %%d %%d %%d\n"
" weight shape: %%d %%d %%d %%d\n" " weight shape: %%d %%d %%d %%d\n"
" top shape: %%d %%d %%d %%d (expected %%d %%d %%d %%d)\n", " top shape: %%ld %%ld %%ld %%ld (expected %%d %%d %%d %%d)\n",
batchSize, nChannels, bottomHeight, bottomWidth, batchSize, nChannels, bottomHeight, bottomWidth,
nFilters, nChannels, kH, kW, nFilters, nChannels, kH, kW,
PyArray_DIMS(top)[0], PyArray_DIMS(top)[1], PyArray_DIMS(top)[0], PyArray_DIMS(top)[1],
...@@ -182,7 +182,7 @@ PyArrayObject* corrMM(PyArrayObject* bottom, ...@@ -182,7 +182,7 @@ PyArrayObject* corrMM(PyArrayObject* bottom,
if (NULL == col) if (NULL == col)
{ {
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"CorrMM failed to allocate working memory of %%d x %%d\n", "CorrMM failed to allocate working memory of %%ld x %%ld\n",
col_dim[0], col_dim[1]); col_dim[0], col_dim[1]);
return NULL; return NULL;
} }
......
import numpy
import unittest import unittest
from nose.plugins.skip import SkipTest
import theano
from theano import tensor
from theano.tests import unittest_tools as utt
from theano.tensor.nnet import corr, abstract_conv as conv
from theano.tensor.nnet.abstract_conv import get_conv_output_shape from theano.tensor.nnet.abstract_conv import get_conv_output_shape
from theano.tensor.nnet.conv import ConvOp
from theano.tensor.nnet.corr import (CorrMM, CorrMM_gradWeights,
CorrMM_gradInputs)
from theano.tensor.nnet.ConvGrad3D import ConvGrad3D
from theano.tensor.nnet.ConvTransp3D import ConvTransp3D
class TestGetConvOutShape(unittest.TestCase): def conv_corr(inputs, filters, border_mode="valid", subsample=(1, 1),
conv_mode='conv'):
if conv_mode == 'conv':
filters = filters[:, :, ::-1, ::-1]
return corr.CorrMM(border_mode, subsample)(inputs, filters)
def conv_corr_gw(inputs, topgrad, filters_shape, border_mode="valid",
subsample=(1, 1), conv_mode='conv'):
rval = corr.CorrMM_gradWeights(border_mode, subsample)(inputs, topgrad,
filters_shape[2:])
if conv_mode == 'conv':
rval = rval[:, :, ::-1, ::-1]
return rval
def conv_corr_gi(filters, topgrad, inputs_shape, border_mode="valid",
subsample=(1, 1), conv_mode='conv'):
if conv_mode == 'conv':
filters = filters[:, :, ::-1, ::-1]
return corr.CorrMM_gradInputs(border_mode, subsample)(filters, topgrad,
inputs_shape[2:])
class TestGetConvOutShape(unittest.TestCase):
def test_basic(self): def test_basic(self):
image_shape, kernel_shape = (3, 2, 8, 9), (4, 2, 5, 6) image_shape, kernel_shape = (3, 2, 8, 9), (4, 2, 5, 6)
sub_sample = (1, 2) sub_sample = (1, 2)
...@@ -20,3 +56,353 @@ class TestGetConvOutShape(unittest.TestCase): ...@@ -20,3 +56,353 @@ class TestGetConvOutShape(unittest.TestCase):
self.assertTrue(test2_params == (3, 4, 8, 5)) self.assertTrue(test2_params == (3, 4, 8, 5))
self.assertTrue(test3_params == (3, 4, 12, 7)) self.assertTrue(test3_params == (3, 4, 12, 7))
self.assertTrue(test4_params == (3, 4, 6, 4)) self.assertTrue(test4_params == (3, 4, 6, 4))
class BaseTestConv2d(unittest.TestCase):
def setUp(self):
self.inputs_shapes = [(8, 1, 12, 12), (8, 1, 18, 18), (2, 1, 4, 4),
(6, 1, 10, 11), (2, 1, 6, 5), (1, 5, 9, 9)]
self.filters_shapes = [(5, 1, 2, 2), (4, 1, 3, 3), (2, 1, 3, 3),
(1, 1, 2, 5), (4, 1, 2, 2), (4, 5, 2, 2)]
self.subsamples = [(1, 1), (2, 2), (2, 4)]
self.border_modes = ["valid", "full", (0, 0), (1, 1), (5, 5), (5, 2)]
self.filter_flip = [True, False]
self.provide_shape = [True, False]
self.shared = theano.compile.shared
def get_output_shape(self, inputs_shape, filters_shape, subsample,
border_mode):
if border_mode == "valid":
border_mode = (0, 0)
if border_mode == "full":
border_mode = (filters_shape[2] - 1, filters_shape[3] - 1)
batch_size = inputs_shape[0]
num_filters = filters_shape[0]
return ((batch_size, num_filters,) +
tuple(None if i is None or k is None
else ((i + 2 * pad - k) // d + 1)
for i, k, d, pad in zip(inputs_shape[2:],
filters_shape[2:],
subsample, border_mode)))
def run_fwd(self, inputs_shape, filters_shape, ref=conv_corr,
subsample=(1, 1), verify_grad=True, mode=None,
border_mode='valid', filter_flip=True, provide_shape=False,
target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
inputs = self.shared(inputs_val)
filters = self.shared(filters_val)
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c_ref = ref(inputs, filters,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
c = conv.conv2d(inputs, filters,
border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
input_shape=imshp,
filter_shape=kshp)
f_ref = theano.function([], c_ref, mode='FAST_RUN')
f = theano.function([], c, mode=mode)
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
if verify_grad:
utt.verify_grad(conv.AbstractConv2d(border_mode=border_mode,
imshp=imshp, kshp=kshp,
subsample=subsample),
[inputs_val, filters_val],
mode=mode)
def run_gradweight(self, inputs_shape, filters_shape, output_shape,
ref=conv_corr_gw, subsample=(1, 1), filter_flip=True,
verify_grad=True, mode=None, border_mode='valid',
provide_shape=False, target_op=None):
inputs_val = numpy.random.random(inputs_shape).astype('float32')
output_val = numpy.random.random(output_shape).astype('float32')
inputs = self.shared(inputs_val)
output = self.shared(output_val)
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradWeights(border_mode=border_mode,
filter_flip=filter_flip,
subsample=subsample,
imshp=imshp, kshp=kshp)
c = c(inputs, output, filters_shape[-2:])
c_ref = ref(inputs, output,
filters_shape,
border_mode=border_mode,
subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
f_ref = theano.function([], c_ref, mode='FAST_RUN')
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradweight(inputs_val, output_val):
conv_op = conv.AbstractConv2d_gradWeights(border_mode=border_mode,
subsample=subsample)
return conv_op(inputs_val, output_val, filters_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradweight,
[inputs_val, output_val],
mode=mode, eps=1)
def run_gradinput(self, inputs_shape, filters_shape, output_shape,
ref=conv_corr_gi, subsample=(1, 1), filter_flip=True,
verify_grad=True, mode=None, border_mode='valid',
provide_shape=False, target_op=None):
output_val = numpy.random.random(output_shape).astype('float32')
filters_val = numpy.random.random(filters_shape).astype('float32')
output = self.shared(output_val)
filters = self.shared(filters_val)
if provide_shape:
imshp = inputs_shape
kshp = filters_shape
else:
imshp = None
kshp = None
if filter_flip:
conv_mode = 'conv'
else:
conv_mode = 'cross'
c = conv.AbstractConv2d_gradInputs(border_mode=border_mode,
subsample=subsample,
filter_flip=filter_flip,
imshp=imshp, kshp=kshp)
c = c(filters, output, inputs_shape[-2:])
c_ref = ref(filters, output, inputs_shape,
border_mode=border_mode, subsample=subsample,
conv_mode=conv_mode)
f = theano.function([], c, mode=mode)
self.assertTrue(hasattr(f.maker.fgraph.outputs[0].tag, 'trace'))
f_ref = theano.function([], c_ref, mode='FAST_RUN')
if target_op is not None:
assert any([isinstance(n.op, target_op) for n
in f.maker.fgraph.toposort()])
res_ref = numpy.array(f_ref())
res = numpy.array(f())
utt.assert_allclose(res_ref, res)
def abstract_conv2d_gradinputs(filters_val, output_val):
conv_op = conv.AbstractConv2d_gradInputs(border_mode=border_mode,
subsample=subsample)
return conv_op(filters_val, output_val, inputs_shape[-2:])
if verify_grad:
utt.verify_grad(abstract_conv2d_gradinputs,
[filters_val, output_val],
mode=mode, eps=1)
def test_all(self):
if type(self) is BaseTestConv2d:
raise SkipTest("base class")
ds = [1, 1]
db = (0, 0)
dflip = True in self.filter_flip
dprovide_shape = True in self.provide_shape
for (i, f) in zip(self.inputs_shapes, self.filters_shapes):
for provide_shape in self.provide_shape:
self.tcase(i, f, ds, db, dflip, provide_shape)
for s in self.subsamples:
for b in self.border_modes:
self.tcase(i, f, s, db, dflip, dprovide_shape)
for flip in self.filter_flip:
self.tcase(i, f, ds, db, flip, dprovide_shape)
class TestCorrConv2d(BaseTestConv2d):
def setUp(self):
if theano.config.blas.ldflags == "":
raise SkipTest()
return super(TestCorrConv2d, self).setUp()
def tcase(self, i, f, s, b, flip, provide_shape):
o = self.get_output_shape(i, f, s, b)
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, provide_shape=provide_shape,
border_mode=b, filter_flip=flip, target_op=CorrMM)
self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, verify_grad=True,
provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=CorrMM_gradWeights)
self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s, verify_grad=True,
provide_shape=provide_shape, border_mode=b,
filter_flip=flip, target_op=CorrMM_gradInputs)
class TestCpuConv2d(BaseTestConv2d):
def setUp(self):
super(TestCpuConv2d, self).setUp()
self.mode = theano.compile.mode.get_default_mode().excluding('conv_gemm')
def tcase(self, i, f, s, b, flip, provide_shape):
mode = self.mode
o = self.get_output_shape(i, f, s, b)
fwd_OK = True
gradweight_OK = True
gradinput_OK = True
if not flip:
fwd_OK = False
gradweight_OK = False
gradinput_OK = False
if b not in ((0, 0), 'valid', 'full'):
fwd_OK = False
gradweight_OK = False
gradinput_OK = False
if (not provide_shape) and (s != (1, 1)) and (b == 'full'):
gradweight_OK = False
gradinput_OK = False
if ((s[0] not in (1, 2)) or (s[1] not in (1, 2))) and (b == 'full'):
gradweight_OK = False
gradinput_OK = False
if fwd_OK:
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=(gradweight_OK and gradinput_OK),
mode=mode, provide_shape=provide_shape,
border_mode=b, filter_flip=flip, target_op=ConvOp)
else:
self.assertRaises(NotImplementedError,
self.run_fwd,
inputs_shape=i,
filters_shape=f,
subsample=s,
verify_grad=False,
mode=mode,
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
if gradweight_OK:
self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode,
provide_shape=provide_shape, border_mode=b,
filter_flip=flip,
target_op=(ConvOp, ConvGrad3D))
else:
self.assertRaises(NotImplementedError,
self.run_gradweight,
inputs_shape=i,
filters_shape=f,
output_shape=o,
subsample=s,
verify_grad=False,
mode=mode,
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
if gradinput_OK:
self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode,
provide_shape=provide_shape, border_mode=b,
filter_flip=flip,
target_op=(ConvOp, ConvTransp3D))
else:
self.assertRaises(NotImplementedError,
self.run_gradinput,
inputs_shape=i,
filters_shape=f,
output_shape=o,
subsample=s,
verify_grad=False,
mode=mode,
provide_shape=provide_shape,
border_mode=b,
filter_flip=flip)
class TestConvTypes(unittest.TestCase):
def setUp(self):
self.input = tensor.ftensor4()
self.filters = tensor.ftensor4()
self.topgrad = tensor.ftensor4()
def test_grad_types(self):
# This function simply tests the behaviour of the AbstractConv
# Ops, not their optimizations
input = self.input
filters = self.filters
topgrad = self.topgrad
out_shape = tensor.lvector()
output = conv.conv2d(input, filters)
grad_input, grad_filters = theano.grad(output.sum(),
wrt=(input, filters))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
grad_filters = conv.AbstractConv2d_gradWeights()(
input, topgrad, out_shape)
grad_input, grad_topgrad = theano.grad(grad_filters.sum(),
wrt=(input, topgrad))
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
grad_input = conv.AbstractConv2d_gradInputs()(
filters, topgrad, out_shape)
grad_filters, grad_topgrad = theano.grad(grad_input.sum(),
wrt=(filters, topgrad))
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论