提交 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):
dtype=cublas.ctypes.c_void_p)
class SparseBlockGemvDS(GpuOp):
class SparseBlockGemvSS(GpuOp):
def __init__(self, inplace):
self.inplace = inplace
if self.inplace:
......@@ -112,9 +112,10 @@ class SparseBlockGemvDS(GpuOp):
go = grads[0]
# might revise that interface to not have a huge output
Wgrad = sparse_block_outer_ss(W.zeros_like().dimshuffle((1, 0, 3, 2)),
go, h, outputIdx, inputIdx)
hgrad = sparse_block_gemv_ds(h.zeros_like(), W.dimshuffle((1, 0, 3, 2)),
Wgrad = sparse_block_outer_ss(W.zeros_like(),
h, go, inputIdx, outputIdx)
hgrad = sparse_block_gemv_ss(h.zeros_like(),
W.dimshuffle((1, 0, 3, 2)),
go,
outputIdx, inputIdx)
return [go, Wgrad, hgrad,
......@@ -124,7 +125,7 @@ class SparseBlockGemvDS(GpuOp):
"grad of outputIdx makes no sense")]
sparse_block_gemv_ds = SparseBlockGemvDS(False)
sparse_block_gemv_ss = SparseBlockGemvSS(False)
class SparseBlockOuterSS(GpuOp):
......@@ -145,10 +146,10 @@ class SparseBlockOuterSS(GpuOp):
if not self.inplace:
o = o.copy()
for i in range(x.shape[0]):
inp_id = xIdx[i]
for j in range(y.shape[0]):
out_id = yIdx[j]
for j in range(y.shape[0]):
out_id = yIdx[j]
for i in range(x.shape[0]):
inp_id = xIdx[i]
ger(numpy.float32(1.0), x[i],
y[j], o[inp_id, out_id])
......@@ -161,7 +162,7 @@ sparse_block_outer_ss = SparseBlockOuterSS()
# 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
W: (iBlocks, oBlocks, iSize, oSize), weight matrix
......@@ -171,7 +172,7 @@ def sparse_block_dot_DS(W, h, inputIdx, b, outputIdx):
outputIdx: (oWin,), indexes of the output blocks
returns (oBlocks, oSize), dot(W[i, j], h[i]) + b[j]
but b[j] is only added once
but b[j] is only added once
"""
o = b.take(outputIdx, axis=0)
def outer_fn(out_id, W, h, b, iIdx):
......
......@@ -5,8 +5,8 @@ import theano.tests.unittest_tools as utt
import numpy
from numpy.random import randn
from theano.sandbox.cuda.blocksparse import (sparse_block_dot_DS,
sparse_block_gemv_ds)
from theano.sandbox.cuda.blocksparse import (sparse_block_dot_SS,
sparse_block_gemv_ss)
def blocksparse_data():
nInputBlock = 128
......@@ -45,7 +45,7 @@ def test_blocksparse():
iIdx = 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)
......@@ -64,7 +64,7 @@ def test_blocksparse_op():
iIdx = 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)
......@@ -80,16 +80,16 @@ def test_blocksparse_op_grad():
h_val = randn(2, 3).astype('float32')
iIdx_val = numpy.random.permutation(3)[:2]
oIdx_val = numpy.random.permutation(3)[:2]
W_val = randn(3, 3, 3, 3).astype('float32')
b_val = randn(3, 3).astype('float32')
W_val = randn(3, 3, 4, 3).astype('float32')
b_val = randn(3, 4).astype('float32')
iIdx = theano.tensor.constant(iIdx_val)
oIdx = theano.tensor.constant(oIdx_val)
def f(b, W, h):
return sparse_block_gemv_ds(b.take(oIdx, axis=0), W, h, iIdx, oIdx)
def f(b, h, W):
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():
......@@ -99,7 +99,7 @@ def test_blocksparse_op_grad2():
iIdx = 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])
f = theano.function([W, h, iIdx, b, oIdx], go)
......@@ -107,4 +107,8 @@ def test_blocksparse_op_grad2():
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.
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论