提交 6aacf213 authored 作者: Dustin Webb's avatar Dustin Webb

Finished infer_shape on dnn ops and wrote tests.

Conflicts: theano/sandbox/cuda/tests/test_dnn.py
上级 bb3fe454
...@@ -377,15 +377,12 @@ class GpuDnnConv(DnnBase, COp): ...@@ -377,15 +377,12 @@ class GpuDnnConv(DnnBase, COp):
kw = shape[1][3] # Width of each filter kw = shape[1][3] # Width of each filter
padh = 0 padh = 0
padw = 0 padw = 0
sh = 1
sw = 1
desc = node.inputs[2].owner.op desc = node.inputs[2].owner.op
sh, sw = desc.subsample
if desc.border_mode == 'full': if desc.border_mode == 'full':
padh = kh - 1 padh = kh - 1
padw = kw - 1 padw = kw - 1
sh = desc.subsample[0]
sw = desc.subsample[1]
return [( return [(
b, nb, b, nb,
...@@ -448,6 +445,30 @@ class GpuDnnConvGradW(DnnBase, COp): ...@@ -448,6 +445,30 @@ class GpuDnnConvGradW(DnnBase, COp):
return Apply(self, [img, topgrad, desc, h, w], return Apply(self, [img, topgrad, desc, h, w],
[CudaNdarrayType(broadcastable)()]) [CudaNdarrayType(broadcastable)()])
def infer_shape(self, node, shape):
h = shape[0][2] # Height of input feature maps
w = shape[0][3] # Width of input feature maps
kh = shape[1][2] # Height of each filter
kw = shape[1][3] # Width of each filter
desc = node.inputs[2].owner.op
sh, sw = desc.subsample
if desc.border_mode == 'full':
kh = 2 - h + (kh - 1) * sh
kw = 2 - w + (kw - 1) * sw
else:
# border_mode is 'valid'
assert(desc.border_mode == 'valid')
kh = h - (kh - 1) * sh
kw = w - (kw - 1) * sw
return [(
shape[1][1],
shape[0][1],
kh,
kw
)]
class GpuDnnConvGradI(DnnBase, COp): class GpuDnnConvGradI(DnnBase, COp):
""" """
...@@ -502,6 +523,29 @@ class GpuDnnConvGradI(DnnBase, COp): ...@@ -502,6 +523,29 @@ class GpuDnnConvGradI(DnnBase, COp):
return Apply(self, [kern, topgrad, desc, h, w], return Apply(self, [kern, topgrad, desc, h, w],
[CudaNdarrayType(broadcastable)()]) [CudaNdarrayType(broadcastable)()])
def infer_shape(self, node, shape):
b = shape[0][0] # Number of inputs
h = shape[0][2] # Height of input feature maps
w = shape[0][3] # Width of input feature maps
nb = shape[1][0] # Number of output feature maps
kh = shape[1][2] # Height of each filter
kw = shape[1][3] # Width of each filter
padh = 0
padw = 0
desc = node.inputs[2].owner.op
sh, sw = desc.subsample
if desc.border_mode == 'full':
padh = h - 1
padw = w - 1
return [(
shape[1][0],
shape[0][1],
(kh - 1) * sh + h - 2*padh,
(kw - 1) * sw + w - 2*padw
)]
def dnn_conv(img, kerns, border_mode='valid', subsample=(1, 1), def dnn_conv(img, kerns, border_mode='valid', subsample=(1, 1),
conv_mode='conv', direction_hint=None): conv_mode='conv', direction_hint=None):
...@@ -1070,7 +1114,7 @@ class GpuDnnSoftmaxBase(DnnBase): ...@@ -1070,7 +1114,7 @@ class GpuDnnSoftmaxBase(DnnBase):
if isinstance(shape, list): if isinstance(shape, list):
return [shape[0]] return [shape[0]]
else: else:
return shape return shape*2
def _define_tensor4d_desc(self, name, id): def _define_tensor4d_desc(self, name, id):
return """ return """
......
...@@ -3,6 +3,7 @@ import unittest ...@@ -3,6 +3,7 @@ import unittest
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
import numpy import numpy
from itertools import product
import theano import theano
from theano.compat.six import StringIO from theano.compat.six import StringIO
...@@ -12,7 +13,7 @@ import theano.tests.unittest_tools as utt ...@@ -12,7 +13,7 @@ import theano.tests.unittest_tools as utt
from theano.sandbox.neighbours import images2neibs, neibs2images from theano.sandbox.neighbours import images2neibs, neibs2images
from theano.tensor.signal.downsample import max_pool_2d from theano.tensor.signal.downsample import max_pool_2d
from theano.tensor.signal.downsample import DownsampleFactorMaxGrad from theano.tensor.signal.downsample import DownsampleFactorMaxGrad
import theano.sandbox.cuda.dnn as dnn
# Skip test if cuda_ndarray is not available. # Skip test if cuda_ndarray is not available.
import theano.sandbox.cuda as cuda import theano.sandbox.cuda as cuda
...@@ -194,6 +195,84 @@ def test_dnn_tag(): ...@@ -194,6 +195,84 @@ def test_dnn_tag():
for n in f.maker.fgraph.toposort()]) for n in f.maker.fgraph.toposort()])
class TestDnnInferShapes(utt.InferShapeTester):
def setUp(self):
super(TestDnnInferShapes, self).setUp()
def test_softmax(self):
t = T.tensor4('t')
rand_tensor = numpy.asarray(
numpy.random.rand(5, 4, 3, 2),
dtype=theano.config.floatX
)
self._compile_and_check(
[t],
[dnn.GpuDnnSoftmax('bc01', 'accurate', 'channel')(t)],
[rand_tensor],
dnn.GpuDnnSoftmax
)
self._compile_and_check(
[t],
[
T.grad(
dnn.GpuDnnSoftmax(
'bc01',
'accurate',
'channel'
)(t).mean(),
t
)
],
[rand_tensor],
dnn.GpuDnnSoftmaxGrad
)
def test_conv(self):
img = T.tensor4('img')
kerns = T.tensor4('kerns')
img_val = numpy.asarray(
numpy.random.rand(2, 3, 4, 5),
dtype=theano.config.floatX
)
kern_vals = numpy.asarray(
numpy.random.rand(2, 3, 4, 5),
dtype=theano.config.floatX
)
for params in product(
['valid', 'full'],
[(1, 1), (2, 2)],
['conv', 'cross']
):
conv = dnn.dnn_conv(img, kerns, params[0], params[1], params[2])
softmax = dnn.GpuDnnSoftmax(
'bc01',
'accurate',
'channel'
)
self._compile_and_check(
[img, kerns],
[conv],
[img_val, kern_vals],
dnn.GpuDnnConv
)
self._compile_and_check(
[img, kerns],
[T.grad(softmax(conv).mean(), img)],
[img_val, kern_vals],
dnn.GpuDnnConvGradI
)
self._compile_and_check(
[img, kerns],
[T.grad(softmax(conv).mean(), kerns)],
[img_val, kern_vals],
dnn.GpuDnnConvGradW
)
def test_version(): def test_version():
if not cuda.dnn.dnn_available(): if not cuda.dnn.dnn_available():
raise SkipTest(cuda.dnn.dnn_available.msg) raise SkipTest(cuda.dnn.dnn_available.msg)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论