提交 4e7913c2 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Accept arrays in AbstractConv make_node

We are not calling `as_tensor_variable` to avoid transfers when the inputs are on GPU, but the the cuda/numpy arrays should still be converted to Constant variables.
上级 121ec69a
import numpy
import theano import theano
from theano.tensor.nnet.tests import test_abstract_conv from theano.tensor.nnet.tests import test_abstract_conv
from theano.sandbox.cuda import float32_shared_constructor as gpu_shared from theano.sandbox.cuda import float32_shared_constructor as gpu_shared
...@@ -82,3 +84,5 @@ class TestDnnConvTypes(test_abstract_conv.TestConvTypes): ...@@ -82,3 +84,5 @@ class TestDnnConvTypes(test_abstract_conv.TestConvTypes):
self.input = cuda.ftensor4() self.input = cuda.ftensor4()
self.filters = cuda.ftensor4() self.filters = cuda.ftensor4()
self.topgrad = cuda.ftensor4() self.topgrad = cuda.ftensor4()
self.constant_tensor = cuda.CudaNdarray(
numpy.zeros((3, 5, 7, 11), dtype='float32'))
from nose.plugins.skip import SkipTest from nose.plugins.skip import SkipTest
import numpy
from theano.tensor.nnet.tests import test_abstract_conv from theano.tensor.nnet.tests import test_abstract_conv
from ..type import GpuArrayType, gpuarray_shared_constructor from ..type import GpuArrayType, gpuarray_shared_constructor, get_context
from ..dnn import dnn_available, GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI from ..dnn import dnn_available, GpuDnnConv, GpuDnnConvGradW, GpuDnnConvGradI
from .config import mode_with_gpu, test_ctx_name from .config import mode_with_gpu, test_ctx_name
from pygpu import gpuarray
gpu_ftensor4 = GpuArrayType(dtype='float32', broadcastable=(False,) * 4) gpu_ftensor4 = GpuArrayType(dtype='float32', broadcastable=(False,) * 4)
...@@ -43,3 +46,6 @@ class TestDnnConvTypes(test_abstract_conv.TestConvTypes): ...@@ -43,3 +46,6 @@ class TestDnnConvTypes(test_abstract_conv.TestConvTypes):
self.input = gpu_ftensor4() self.input = gpu_ftensor4()
self.filters = gpu_ftensor4() self.filters = gpu_ftensor4()
self.topgrad = gpu_ftensor4() self.topgrad = gpu_ftensor4()
self.constant_tensor = gpuarray.array(
numpy.zeros((3, 5, 7, 11), dtype='float32'),
context=get_context(test_ctx_name))
...@@ -510,7 +510,11 @@ class AbstractConv2d(BaseAbstractConv2d): ...@@ -510,7 +510,11 @@ class AbstractConv2d(BaseAbstractConv2d):
filter_flip) filter_flip)
def make_node(self, img, kern): def make_node(self, img, kern):
# Make sure both inputs have the same Type # Make sure both inputs are Variables with the same Type
if not isinstance(img, theano.Variable):
img = as_tensor_variable(img)
if not isinstance(kern, theano.Variable):
kern = as_tensor_variable(kern)
ktype = img.type.clone(dtype=kern.dtype, ktype = img.type.clone(dtype=kern.dtype,
broadcastable=kern.broadcastable) broadcastable=kern.broadcastable)
kern = ktype.filter_variable(kern) kern = ktype.filter_variable(kern)
...@@ -635,7 +639,11 @@ class AbstractConv2d_gradWeights(BaseAbstractConv2d): ...@@ -635,7 +639,11 @@ class AbstractConv2d_gradWeights(BaseAbstractConv2d):
# Update shape/height_width # Update shape/height_width
def make_node(self, img, topgrad, shape): def make_node(self, img, topgrad, shape):
# Make sure both inputs have the same Type # Make sure both inputs are Variables with the same Type
if not isinstance(img, theano.Variable):
img = as_tensor_variable(img)
if not isinstance(topgrad, theano.Variable):
topgrad = as_tensor_variable(topgrad)
gtype = img.type.clone(dtype=topgrad.dtype, gtype = img.type.clone(dtype=topgrad.dtype,
broadcastable=topgrad.broadcastable) broadcastable=topgrad.broadcastable)
topgrad = gtype.filter_variable(topgrad) topgrad = gtype.filter_variable(topgrad)
...@@ -766,7 +774,11 @@ class AbstractConv2d_gradInputs(BaseAbstractConv2d): ...@@ -766,7 +774,11 @@ class AbstractConv2d_gradInputs(BaseAbstractConv2d):
# Update shape/height_width # Update shape/height_width
def make_node(self, kern, topgrad, shape): def make_node(self, kern, topgrad, shape):
# Make sure both inputs have the same Type # Make sure both inputs are Variables with the same Type
if not isinstance(kern, theano.Variable):
kern = as_tensor_variable(kern)
if not isinstance(topgrad, theano.Variable):
topgrad = as_tensor_variable(topgrad)
gtype = kern.type.clone(dtype=topgrad.dtype, gtype = kern.type.clone(dtype=topgrad.dtype,
broadcastable=topgrad.broadcastable) broadcastable=topgrad.broadcastable)
topgrad = gtype.filter_variable(topgrad) topgrad = gtype.filter_variable(topgrad)
......
...@@ -441,6 +441,8 @@ class TestConvTypes(unittest.TestCase): ...@@ -441,6 +441,8 @@ class TestConvTypes(unittest.TestCase):
self.filters = tensor.ftensor4() self.filters = tensor.ftensor4()
self.topgrad = tensor.ftensor4() self.topgrad = tensor.ftensor4()
self.constant_tensor = numpy.zeros((3, 5, 7, 11), dtype='float32')
def test_grad_types(self): def test_grad_types(self):
# This function simply tests the behaviour of the AbstractConv # This function simply tests the behaviour of the AbstractConv
# Ops, not their optimizations # Ops, not their optimizations
...@@ -477,3 +479,48 @@ class TestConvTypes(unittest.TestCase): ...@@ -477,3 +479,48 @@ class TestConvTypes(unittest.TestCase):
grad_filters, grad_filters.type, filters, filters.type) grad_filters, grad_filters.type, filters, filters.type)
assert grad_topgrad.type == topgrad.type, ( assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type) grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
def test_constant_input(self):
# Check the AbstractConv Ops for constant inputs
input = self.input
filters = self.filters
topgrad = self.topgrad
constant_tensor = self.constant_tensor
out_shape = tensor.lvector()
# Check the forward Op
output = conv.conv2d(constant_tensor, filters)
grad_filters = theano.grad(output.sum(), wrt=filters)
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
output = conv.conv2d(input, constant_tensor)
grad_input = theano.grad(output.sum(), wrt=input)
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
# Check grad wrt weights
grad_filters = conv.AbstractConv2d_gradWeights()(
constant_tensor, topgrad, out_shape)
grad_topgrad = theano.grad(grad_filters.sum(), wrt=topgrad)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
grad_filters = conv.AbstractConv2d_gradWeights()(
input, constant_tensor, out_shape)
grad_input = theano.grad(grad_filters.sum(), wrt=input)
assert grad_input.type == input.type, (
grad_input, grad_input.type, input, input.type)
# Check grad wrt inputs
grad_input = conv.AbstractConv2d_gradInputs()(
constant_tensor, topgrad, out_shape)
grad_topgrad = theano.grad(grad_input.sum(), wrt=topgrad)
assert grad_topgrad.type == topgrad.type, (
grad_topgrad, grad_topgrad.type, topgrad, topgrad.type)
grad_input = conv.AbstractConv2d_gradInputs()(
filters, constant_tensor, out_shape)
grad_filters = theano.grad(grad_input.sum(), wrt=filters)
assert grad_filters.type == filters.type, (
grad_filters, grad_filters.type, filters, filters.type)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论