提交 77ecf5c6 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Make some tests pass

上级 33d35144
......@@ -158,9 +158,9 @@ class Conv3D(theano.Op):
vidDur = V_shape[3]
filterDur = W_shape[3]
output_height = T.floor((vidHeight - filterHeight) // dr) + 1
output_width = T.floor((vidWidth - filterWidth) // dc) + 1
output_dur = T.floor((vidDur - filterDur) // dt) + 1
output_height = ((vidHeight - filterHeight) // dr) + 1
output_width = ((vidWidth - filterWidth) // dc) + 1
output_dur = ((vidDur - filterDur) // dt) + 1
rval = (batch_size, output_height, output_width, output_dur, output_channels)
......
......@@ -566,6 +566,9 @@ def local_conv2d_gradweight_cpu(node):
if node.op.border_mode not in ['full', 'valid']:
return None
if not node.op.filter_flip:
# Not tested yet
return
if node.op.border_mode == 'valid' and \
(node.op.subsample != (1, 1) or node.op.imshp is None or node.op.kshp is None):
......@@ -574,20 +577,20 @@ def local_conv2d_gradweight_cpu(node):
# slower than it could be), nad incorrect when subsample > 2.
# build a "node", that should be equivalent to the one given by
# self.make_node, but using convGrad3D instead.
if not node.op.filter_flip:
topgrad = topgrad[:, :, ::-1, ::-1] # flip them
shuffled_img = img.dimshuffle(0, 2, 3, 'x', 1)
shuffled_topgrad = topgrad.dimshuffle(0, 2, 3, 'x', 1)
rval = convGrad3D(V=shuffled_img,
d=(node.op.subsample[0], node.op.subsample[1], 1),
WShape=(shape[0], shape[2], shape[3], 1, shape[1]),
WShape=(shuffled_topgrad.shape[4],
shape[0], shape[1], 1,
shuffled_img.shape[4]),
dCdH=shuffled_topgrad)
rval = theano.tensor.addbroadcast(rval, 3)
return [rval.dimshuffle(0, 4, 1, 2)]
rval = rval.dimshuffle(0, 4, 1, 2)
rval = rval[:, :, ::-1, ::-1]
rval = patternbroadcast(rval, node.outputs[0].broadcastable)
return [rval]
if node.op.imshp is None or node.op.kshp is None:
return None
......@@ -602,7 +605,6 @@ def local_conv2d_gradweight_cpu(node):
node.op.kshp[2:], (1, 1),
node.op.border_mode)
newimg = img.dimshuffle((1, 0, 2, 3))
newtopgrad = topgrad.dimshuffle((1, 0, 2, 3))
......@@ -630,6 +632,7 @@ def local_conv2d_gradweight_cpu(node):
if node.op.filter_flip:
filters = filters[:, :, ::-1, ::-1] # flip them
dw = ConvOp(imshp, kshp, nkern, bsize, 1, 1, output_mode='valid',
unroll_batch=None, unroll_kern=None, unroll_patch=None,
imshp_logical=imshp_logical,
......@@ -638,16 +641,16 @@ def local_conv2d_gradweight_cpu(node):
direction_hint='bprop weights')
res = dw(img, filters)
res = res.dimshuffle((1, 0, 2, 3))
res = res[:, :, ::-1, ::-1]
res = patternbroadcast(res, node.outputs[0].broadcastable)
return [res]
register_specialize_device(local_conv2d_gradweight_cpu)
@local_optimizer([AbstractConv2d_gradInputs])
def local_conv2d_gradinputs_cpu(node):
kern, topgrad, shape = node.inputs
if isinstance(kern.type, CudaNdarrayType) or \
isinstance(topgrad.type, CudaNdarrayType):
return None
......@@ -655,20 +658,25 @@ def local_conv2d_gradinputs_cpu(node):
if node.op.border_mode not in ['full', 'valid']:
return None
if not node.op.filter_flip:
# Not tested yet
return None
### Conv 3d implementation, needed when subsample > 2
if node.op.border_mode == 'valid' and \
(node.op.subsample != (1, 1) or node.op.imshp is None or node.op.kshp is None):
if node.op.filter_flip:
kern = kern[:, :, ::-1, ::-1]
kern = kern[:, :, ::-1, ::-1]
shuffled_kern = kern.dimshuffle(0, 2, 3, 'x', 1)
shuffled_topgrad = topgrad.dimshuffle(0, 2, 3, 'x', 1)
b = theano.tensor.zeros_like(shuffled_kern[0, 0, 0, 0, :])
rval = convTransp3D(W=shuffled_kern, b=b,
d=(node.op.subsample[0], node.op.subsample[1], 1),
H=shuffled_topgrad,
RShape=(shape[2], shape[3], 1))
RShape=(shape[0], shape[1], 1))
rval = theano.tensor.addbroadcast(rval, 3)
return [rval.dimshuffle(0, 4, 1, 2)]
rval = rval.dimshuffle(0, 4, 1, 2)
rval = patternbroadcast(rval, node.outputs[0].broadcastable)
return [rval]
### Conv2d Implementation
if node.op.imshp is None or node.op.kshp is None:
......@@ -677,8 +685,7 @@ def local_conv2d_gradinputs_cpu(node):
if not node.op.border_mode == 'full':
mode = 'full'
filters = kern.dimshuffle((1, 0, 2, 3))
if node.op.filter_flip:
filters = filters[:, :, ::-1, ::-1]
filters = filters[:, :, ::-1, ::-1]
outshp = ConvOp.getOutputShape(node.op.imshp[2:],
node.op.kshp[2:], node.op.subsample,
......@@ -701,5 +708,6 @@ def local_conv2d_gradinputs_cpu(node):
version=-1,
direction_hint='bprop inputs')
din = din(topgrad, filters)
din = patternbroadcast(din, node.outputs[0].broadcastable)
return [din]
register_specialize_device(local_conv2d_gradinputs_cpu)
......@@ -105,11 +105,11 @@ class TestConv2d(unittest.TestCase):
c = conv.AbstractConv2d_gradWeights(border_mode=border_mode,
subsample=subsample,
imshp = imshp, kshp = kshp)
c = c(inputs, output, filters_shape)
c = c(inputs, output, filters_shape[-2:])
f = theano.function([], c, mode)
res_ref = py_conv(inputs_val.transpose((1, 0, 2, 3)),
output_val.transpose((1, 0, 2, 3))[:, :, ::-1, ::-1],
'valid', subsample).transpose((1, 0, 2, 3))
'valid', subsample).transpose((1, 0, 2, 3))[:, :, ::-1, ::-1]
res = numpy.array(f())
print res_ref.shape, res.shape
......@@ -151,7 +151,7 @@ class TestConv2d(unittest.TestCase):
c = conv.AbstractConv2d_gradInputs(border_mode="valid",
subsample=subsample,
imshp = imshp, kshp = kshp)
c = c(filters, output, inputs_shape)
c = c(filters, output, inputs_shape[-2:])
f = theano.function([], c, mode)
res_ref = py_conv(output_val,
filters_val.transpose(1, 0, 2, 3)[:, :, ::-1, ::-1],
......@@ -161,11 +161,15 @@ class TestConv2d(unittest.TestCase):
print "2, ", res_ref.shape, res.shape
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(conv.AbstractConv2d_gradInputs(border_mode=border_mode,
subsample=subsample),
[filters_val, output_val,
numpy.array(inputs_shape).astype('float32')])
utt.verify_grad(abstract_conv2d_gradinputs,
[filters_val, output_val])
......@@ -193,7 +197,7 @@ class TestConv2d(unittest.TestCase):
border_mode= 'valid'
for i, f, o, s in zip(inputs_shapes[0:1], filters_shapes[0:1], output_shapes[0:1], subsamples[0:1]):
for provide_shape in [True]:
for provide_shape in [False, True]:
self.run_fwd(inputs_shape=i, filters_shape=f, subsample=s,
verify_grad=True, mode=mode_without_gpu, device='cpu',
provide_shape=provide_shape, border_mode=border_mode)
......@@ -224,7 +228,7 @@ class TestConv2d(unittest.TestCase):
for provide_shape in [False, True]:
self.run_gradweight(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode_without_gpu, device='cpu',
verify_grad=True, mode=mode_without_gpu, device='cpu',
provide_shape=provide_shape, border_mode=border_mode)
return
### No reference implementation of full available yet
......@@ -251,7 +255,7 @@ class TestConv2d(unittest.TestCase):
for provide_shape in [True, False]:
self.run_gradinput(inputs_shape=i, filters_shape=f,
output_shape=o, subsample=s,
verify_grad=False, mode=mode_without_gpu, device='cpu',
verify_grad=True, mode=mode_without_gpu, device='cpu',
provide_shape=provide_shape, border_mode=border_mode)
return
### No reference implementation of full available yet
......@@ -261,7 +265,6 @@ class TestConv2d(unittest.TestCase):
filters_shape=(10, 1, 2, 2),
output_shape=(16, 10, 3, 3),
subsample=(1, 1),
verify_grad=False, mode=mode_without_gpu, device='cpu',
verify_grad=True, mode=mode_without_gpu, device='cpu',
provide_shape=provide_shape, border_mode=border_mode)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论