提交 94fb4d03 authored 作者: Arnaud Bergeron's avatar Arnaud Bergeron

Add tests for grad shape.

Some improvements to the gradient, but it's still transposed and partially wrong.
上级 bcb902e9
...@@ -69,7 +69,7 @@ def bptr(a): ...@@ -69,7 +69,7 @@ def bptr(a):
dtype=cublas.ctypes.c_void_p) dtype=cublas.ctypes.c_void_p)
class SparseBlockGemvDS(GpuOp): class SparseBlockGemvSS(GpuOp):
def __init__(self, inplace): def __init__(self, inplace):
self.inplace = inplace self.inplace = inplace
if self.inplace: if self.inplace:
...@@ -112,9 +112,10 @@ class SparseBlockGemvDS(GpuOp): ...@@ -112,9 +112,10 @@ class SparseBlockGemvDS(GpuOp):
go = grads[0] go = grads[0]
# might revise that interface to not have a huge output # might revise that interface to not have a huge output
Wgrad = sparse_block_outer_ss(W.zeros_like().dimshuffle((1, 0, 3, 2)), Wgrad = sparse_block_outer_ss(W.zeros_like(),
go, h, outputIdx, inputIdx) h, go, inputIdx, outputIdx)
hgrad = sparse_block_gemv_ds(h.zeros_like(), W.dimshuffle((1, 0, 3, 2)), hgrad = sparse_block_gemv_ss(h.zeros_like(),
W.dimshuffle((1, 0, 3, 2)),
go, go,
outputIdx, inputIdx) outputIdx, inputIdx)
return [go, Wgrad, hgrad, return [go, Wgrad, hgrad,
...@@ -124,7 +125,7 @@ class SparseBlockGemvDS(GpuOp): ...@@ -124,7 +125,7 @@ class SparseBlockGemvDS(GpuOp):
"grad of outputIdx makes no sense")] "grad of outputIdx makes no sense")]
sparse_block_gemv_ds = SparseBlockGemvDS(False) sparse_block_gemv_ss = SparseBlockGemvSS(False)
class SparseBlockOuterSS(GpuOp): class SparseBlockOuterSS(GpuOp):
...@@ -145,10 +146,10 @@ class SparseBlockOuterSS(GpuOp): ...@@ -145,10 +146,10 @@ class SparseBlockOuterSS(GpuOp):
if not self.inplace: if not self.inplace:
o = o.copy() o = o.copy()
for i in range(x.shape[0]):
inp_id = xIdx[i]
for j in range(y.shape[0]): for j in range(y.shape[0]):
out_id = yIdx[j] out_id = yIdx[j]
for i in range(x.shape[0]):
inp_id = xIdx[i]
ger(numpy.float32(1.0), x[i], ger(numpy.float32(1.0), x[i],
y[j], o[inp_id, out_id]) y[j], o[inp_id, out_id])
...@@ -161,7 +162,7 @@ sparse_block_outer_ss = SparseBlockOuterSS() ...@@ -161,7 +162,7 @@ sparse_block_outer_ss = SparseBlockOuterSS()
# All code above this line is unused (except for the imports) # All code above this line is unused (except for the imports)
def sparse_block_dot_DS(W, h, inputIdx, b, outputIdx): def sparse_block_dot_SS(W, h, inputIdx, b, outputIdx):
""" """
var: shape, comment var: shape, comment
W: (iBlocks, oBlocks, iSize, oSize), weight matrix W: (iBlocks, oBlocks, iSize, oSize), weight matrix
......
...@@ -5,8 +5,8 @@ import theano.tests.unittest_tools as utt ...@@ -5,8 +5,8 @@ import theano.tests.unittest_tools as utt
import numpy import numpy
from numpy.random import randn from numpy.random import randn
from theano.sandbox.cuda.blocksparse import (sparse_block_dot_DS, from theano.sandbox.cuda.blocksparse import (sparse_block_dot_SS,
sparse_block_gemv_ds) sparse_block_gemv_ss)
def blocksparse_data(): def blocksparse_data():
nInputBlock = 128 nInputBlock = 128
...@@ -45,7 +45,7 @@ def test_blocksparse(): ...@@ -45,7 +45,7 @@ def test_blocksparse():
iIdx = tensor.lvector() iIdx = tensor.lvector()
oIdx = tensor.lvector() oIdx = tensor.lvector()
o = sparse_block_dot_DS(W, h, iIdx, b, oIdx) o = sparse_block_dot_SS(W, h, iIdx, b, oIdx)
f = theano.function([W, h, iIdx, b, oIdx], o) f = theano.function([W, h, iIdx, b, oIdx], o)
...@@ -64,7 +64,7 @@ def test_blocksparse_op(): ...@@ -64,7 +64,7 @@ def test_blocksparse_op():
iIdx = tensor.lvector() iIdx = tensor.lvector()
oIdx = tensor.lvector() oIdx = tensor.lvector()
o = sparse_block_gemv_ds(b.take(oIdx, axis=0), W, h, iIdx, oIdx) o = sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
f = theano.function([W, h, iIdx, b, oIdx], o) f = theano.function([W, h, iIdx, b, oIdx], o)
...@@ -80,16 +80,16 @@ def test_blocksparse_op_grad(): ...@@ -80,16 +80,16 @@ def test_blocksparse_op_grad():
h_val = randn(2, 3).astype('float32') h_val = randn(2, 3).astype('float32')
iIdx_val = numpy.random.permutation(3)[:2] iIdx_val = numpy.random.permutation(3)[:2]
oIdx_val = numpy.random.permutation(3)[:2] oIdx_val = numpy.random.permutation(3)[:2]
W_val = randn(3, 3, 3, 3).astype('float32') W_val = randn(3, 3, 4, 3).astype('float32')
b_val = randn(3, 3).astype('float32') b_val = randn(3, 4).astype('float32')
iIdx = theano.tensor.constant(iIdx_val) iIdx = theano.tensor.constant(iIdx_val)
oIdx = theano.tensor.constant(oIdx_val) oIdx = theano.tensor.constant(oIdx_val)
def f(b, W, h): def f(b, h, W):
return sparse_block_gemv_ds(b.take(oIdx, axis=0), W, h, iIdx, oIdx) return sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
utt.verify_grad(f, [b_val, W_val, h_val]) utt.verify_grad(f, [b_val, h_val, W_val])
def test_blocksparse_op_grad2(): def test_blocksparse_op_grad2():
...@@ -99,7 +99,7 @@ def test_blocksparse_op_grad2(): ...@@ -99,7 +99,7 @@ def test_blocksparse_op_grad2():
iIdx = tensor.lvector() iIdx = tensor.lvector()
oIdx = tensor.lvector() oIdx = tensor.lvector()
o = sparse_block_gemv_ds(b.take(oIdx, axis=0), W, h, iIdx, oIdx) o = sparse_block_gemv_ss(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
go = theano.grad(o.sum(), [b, W, h]) go = theano.grad(o.sum(), [b, W, h])
f = theano.function([W, h, iIdx, b, oIdx], go) f = theano.function([W, h, iIdx, b, oIdx], go)
...@@ -107,4 +107,8 @@ def test_blocksparse_op_grad2(): ...@@ -107,4 +107,8 @@ def test_blocksparse_op_grad2():
W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data() W_val, h_val, iIdx_val, b_val, oIdx_val = blocksparse_data()
# just make sure that it runs correcly and all the shapes are ok. # just make sure that it runs correcly and all the shapes are ok.
f(W_val, h_val, iIdx_val, b_val, oIdx_val) b_g, W_g, h_g = f(W_val, h_val, iIdx_val, b_val, oIdx_val)
assert b_g.shape == b_val.shape
assert h_g.shape == h_val.shape
assert W_g.shape == W_val.shape
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论