提交 2dc471fc authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Merge pull request #3903 from matthias-k/AbstractConv2d_R_op

R_op for AbstractConv2d
...@@ -308,6 +308,17 @@ class AbstractConv2d(BaseAbstractConv2d): ...@@ -308,6 +308,17 @@ class AbstractConv2d(BaseAbstractConv2d):
'Did you exclude both "conv_dnn" and "conv_gemm" from ' 'Did you exclude both "conv_dnn" and "conv_gemm" from '
'the optimizer? Is cudnn available and does the GPU support it?') 'the optimizer? Is cudnn available and does the GPU support it?')
def R_op(self, inputs, eval_points):
rval = None
if eval_points[0] is not None:
rval = self.make_node(eval_points[0], inputs[1]).outputs[0]
if eval_points[1] is not None:
if rval is None:
rval = self.make_node(inputs[0], eval_points[1]).outputs[0]
else:
rval += self.make_node(inputs[0], eval_points[1]).outputs[0]
return [rval]
def grad(self, inp, grads): def grad(self, inp, grads):
bottom, weights = inp bottom, weights = inp
top, = grads top, = grads
......
...@@ -22,7 +22,7 @@ from theano.gof import Op, Apply ...@@ -22,7 +22,7 @@ from theano.gof import Op, Apply
from theano.gradient import grad_undefined from theano.gradient import grad_undefined
from theano.tests.unittest_tools import SkipTest from theano.tests.unittest_tools import SkipTest
from theano.tensor.signal.pool import Pool from theano.tensor.signal.pool import Pool
from theano.tensor.nnet import conv from theano.tensor.nnet import conv, conv2d
''' '''
Special Op created to test what happens when you have one op that is not Special Op created to test what happens when you have one op that is not
...@@ -260,50 +260,51 @@ class test_RopLop(RopLop_checker): ...@@ -260,50 +260,51 @@ class test_RopLop(RopLop_checker):
(1,)) (1,))
def test_conv(self): def test_conv(self):
for border_mode in ['valid', 'full']: for conv_op in [conv.conv2d, conv2d]:
image_shape = (2, 2, 4, 5) for border_mode in ['valid', 'full']:
filter_shape = (2, 2, 2, 3) image_shape = (2, 2, 4, 5)
image_dim = len(image_shape) filter_shape = (2, 2, 2, 3)
filter_dim = len(filter_shape) image_dim = len(image_shape)
input = tensor.TensorType( filter_dim = len(filter_shape)
theano.config.floatX, input = tensor.TensorType(
[False] * image_dim)(name='input') theano.config.floatX,
filters = tensor.TensorType( [False] * image_dim)(name='input')
theano.config.floatX, filters = tensor.TensorType(
[False] * filter_dim)(name='filter') theano.config.floatX,
ev_input = tensor.TensorType( [False] * filter_dim)(name='filter')
theano.config.floatX, ev_input = tensor.TensorType(
[False] * image_dim)(name='ev_input') theano.config.floatX,
ev_filters = tensor.TensorType( [False] * image_dim)(name='ev_input')
theano.config.floatX, ev_filters = tensor.TensorType(
[False] * filter_dim)(name='ev_filters') theano.config.floatX,
[False] * filter_dim)(name='ev_filters')
def sym_conv2d(input, filters):
return conv.conv2d(input, filters, border_mode=border_mode) def sym_conv2d(input, filters):
output = sym_conv2d(input, filters).flatten() return conv_op(input, filters, border_mode=border_mode)
yv = tensor.Rop(output, [input, filters], [ev_input, ev_filters]) output = sym_conv2d(input, filters).flatten()
rop_f = function([input, filters, ev_input, ev_filters], yv = tensor.Rop(output, [input, filters], [ev_input, ev_filters])
yv, on_unused_input='ignore') rop_f = function([input, filters, ev_input, ev_filters],
sy, _ = theano.scan( yv, on_unused_input='ignore')
lambda i, y, x1, x2, v1, v2: sy, _ = theano.scan(
(tensor.grad(y[i], x1) * v1).sum() + \ lambda i, y, x1, x2, v1, v2:
(tensor.grad(y[i], x2) * v2).sum(), (tensor.grad(y[i], x1) * v1).sum() + \
sequences=tensor.arange(output.shape[0]), (tensor.grad(y[i], x2) * v2).sum(),
non_sequences=[output, input, filters, sequences=tensor.arange(output.shape[0]),
ev_input, ev_filters]) non_sequences=[output, input, filters,
scan_f = function([input, filters, ev_input, ev_filters], sy, ev_input, ev_filters])
on_unused_input='ignore') scan_f = function([input, filters, ev_input, ev_filters], sy,
on_unused_input='ignore')
dtype = theano.config.floatX
image_data = numpy.random.random(image_shape).astype(dtype) dtype = theano.config.floatX
filter_data = numpy.random.random(filter_shape).astype(dtype) image_data = numpy.random.random(image_shape).astype(dtype)
ev_image_data = numpy.random.random(image_shape).astype(dtype) filter_data = numpy.random.random(filter_shape).astype(dtype)
ev_filter_data = numpy.random.random(filter_shape).astype(dtype) ev_image_data = numpy.random.random(image_shape).astype(dtype)
v1 = rop_f(image_data, filter_data, ev_image_data, ev_filter_data = numpy.random.random(filter_shape).astype(dtype)
ev_filter_data) v1 = rop_f(image_data, filter_data, ev_image_data,
v2 = scan_f(image_data, filter_data, ev_image_data,
ev_filter_data) ev_filter_data)
assert numpy.allclose(v1, v2), ("Rop mismatch: %s %s" % v2 = scan_f(image_data, filter_data, ev_image_data,
ev_filter_data)
assert numpy.allclose(v1, v2), ("Rop mismatch: %s %s" %
(v1, v2)) (v1, v2))
def test_join(self): def test_join(self):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论