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

Make some tests pass

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