提交 1ddd6c38 authored 作者: Olivier Breuleux's avatar Olivier Breuleux

doc, small fixes to tests, defined more gradients

上级 2d60d3e3
...@@ -7,6 +7,7 @@ import gof ...@@ -7,6 +7,7 @@ import gof
from scalar import * from scalar import *
import tensor
from elemwise import * from elemwise import *
...@@ -40,13 +41,6 @@ class _test_DimShuffle(unittest.TestCase): ...@@ -40,13 +41,6 @@ class _test_DimShuffle(unittest.TestCase):
self.with_linker(gof.PerformLinker) self.with_linker(gof.PerformLinker)
# def test_straightforward(self):
# x, y, z = inputs()
# e0 = DimShuffle(x, [1, 'x', 0]).out
# f = gof.PerformLinker(env([x], [e0])).make_function(inplace=True)
# assert f(numpy.ones((2, 3))).shape == (3, 1, 2)
class _test_Broadcast(unittest.TestCase): class _test_Broadcast(unittest.TestCase):
def with_linker(self, linker): def with_linker(self, linker):
...@@ -164,27 +158,42 @@ class _test_CAReduce(unittest.TestCase): ...@@ -164,27 +158,42 @@ class _test_CAReduce(unittest.TestCase):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
# x = modes.build(Tensor('int32', [0, 0], name = 'x'))
# y = modes.build(Tensor('int32', [0, 0], name = 'y')) # # x = modes.build(Tensor('int32', [0, 0], name = 'x'))
# # x = modes.build(Tensor('float64', [0, 0], name = 'x')) # # y = modes.build(Tensor('int32', [0, 0], name = 'y'))
# # y = modes.build(Tensor('float64', [0, 0], name = 'y')) # from scalar import Scalar, composite
# e = Broadcast(Pow, (x, y)).out # x = modes.build(Tensor('float64', [0, 0], name = 'x'))
# y = modes.build(Tensor('float64', [0, 0], name = 'y'))
# xs, ys = Scalar('float64'), Scalar('float64')
# e = Broadcast(composite([xs, ys], [(xs * ys) + (xs / ys) * 7.0]), (x, y)).out
# f = gof.CLinker(env([x, y], [e])).make_function(inplace = False) # f = gof.CLinker(env([x, y], [e])).make_function(inplace = False)
# # xv = numpy.random.rand(1000, 1000) # size = 2000
# # yv = numpy.random.rand(1000, 1000) # xv = numpy.random.rand(size, size)
# # zv = numpy.random.rand(1000, 1000) # yv = numpy.random.rand(size, size)
# xv = numpy.random.randint(1, 5, (1000, 1000)) # zv = numpy.random.rand(size, size)
# yv = numpy.random.randint(1, 5, (1000, 1000)) # # xv = numpy.random.randint(1, 5, (1000, 1000))
# add = numpy.frompyfunc(lambda x, y: x + y, 2, 1) # # yv = numpy.random.randint(1, 5, (1000, 1000))
# # t0 = time.time() # # t0 = time.time()
# # for i in xrange(100): # # for i in xrange(100):
# # xv / yv # # xv / yv
# # print time.time() - t0 # # print time.time() - t0
# # t0 = time.time()
# # for i in xrange(10):
# # f(xv, yv)
# # print time.time() - t0
# # t0 = time.time()
# # for i in xrange(10):
# # (xv * yv) + (xv / yv) * 7.0
# # print time.time() - t0
# from scipy import weave
# import numpy
# t0 = time.time() # t0 = time.time()
# for i in xrange(100): # for i in xrange(10):
# f(xv, yv) # weave.blitz("zv = dot(xv, yv)", locals())
# print time.time() - t0 # print time.time() - t0
# speed ratios: # speed ratios:
......
...@@ -281,18 +281,18 @@ PowTester = make_broadcast_tester(op_class = Pow, ...@@ -281,18 +281,18 @@ PowTester = make_broadcast_tester(op_class = Pow,
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))) column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))))
) )
PowTester = make_broadcast_tester(op_class = PowInplace, PowInplaceTester = make_broadcast_tester(op_class = PowInplace,
expected = lambda x, y: x ** y, expected = lambda x, y: x ** y,
good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))), column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))),
dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))), dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))),
grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))), column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))),
inplace = True) inplace = True)
...@@ -417,28 +417,36 @@ CosInplaceTester = make_broadcast_tester(op_class = CosInplace, ...@@ -417,28 +417,36 @@ CosInplaceTester = make_broadcast_tester(op_class = CosInplace,
TanTester = make_broadcast_tester(op_class = Tan, TanTester = make_broadcast_tester(op_class = Tan,
expected = numpy.tan, expected = numpy.tan,
good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),))) shifted = (rand_ranged(3.15, 6.28, (2, 3)),)))
TanInplaceTester = make_broadcast_tester(op_class = CosInplace, TanInplaceTester = make_broadcast_tester(op_class = TanInplace,
expected = numpy.cos, expected = numpy.tan,
good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)), shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
inplace = True) inplace = True)
CoshTester = make_broadcast_tester(op_class = Cosh, CoshTester = make_broadcast_tester(op_class = Cosh,
expected = numpy.cosh, expected = numpy.cosh,
good = _good_broadcast_unary_normal) good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal)
CoshInplaceTester = make_broadcast_tester(op_class = CoshInplace, CoshInplaceTester = make_broadcast_tester(op_class = CoshInplace,
expected = numpy.cosh, expected = numpy.cosh,
good = _good_broadcast_unary_normal, good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal,
inplace = True) inplace = True)
SinhTester = make_broadcast_tester(op_class = Sinh, SinhTester = make_broadcast_tester(op_class = Sinh,
expected = numpy.sinh, expected = numpy.sinh,
good = _good_broadcast_unary_normal) good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal)
SinhInplaceTester = make_broadcast_tester(op_class = SinhInplace, SinhInplaceTester = make_broadcast_tester(op_class = SinhInplace,
expected = numpy.sinh, expected = numpy.sinh,
good = _good_broadcast_unary_normal, good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal,
inplace = True) inplace = True)
TanhTester = make_broadcast_tester(op_class = Tanh, TanhTester = make_broadcast_tester(op_class = Tanh,
......
差异被折叠。
...@@ -16,7 +16,7 @@ __all__ = ['Op', ...@@ -16,7 +16,7 @@ __all__ = ['Op',
] ]
def constructor(op_cls): def constructor(op_cls, name = None):
"""Make an Op look like a L{Result}-valued function.""" """Make an Op look like a L{Result}-valued function."""
def f(*args, **kwargs): def f(*args, **kwargs):
op = op_cls(*args, **kwargs) op = op_cls(*args, **kwargs)
...@@ -24,6 +24,17 @@ def constructor(op_cls): ...@@ -24,6 +24,17 @@ def constructor(op_cls):
return op.outputs return op.outputs
else: else:
return op.outputs[0] return op.outputs[0]
opname = op_cls.__name__
if name is None:
name = "constructor{%s}" % opname
f.__name__ = name
doc = op_cls.__doc__
f.__doc__ = """
Constructor for %(opname)s:
%(doc)s
""" % locals()
return f return f
class Op(object): class Op(object):
......
...@@ -246,6 +246,8 @@ class FloatUnaryScalarOp(UnaryScalarOp): ...@@ -246,6 +246,8 @@ class FloatUnaryScalarOp(UnaryScalarOp):
class Add(ScalarOp): class Add(ScalarOp):
identity = 0 identity = 0
commutative = True
associative = True
def impl(self, *inputs): def impl(self, *inputs):
return sum(inputs) return sum(inputs)
def c_code(self, inputs, (z, ), sub): def c_code(self, inputs, (z, ), sub):
...@@ -258,6 +260,8 @@ class Add(ScalarOp): ...@@ -258,6 +260,8 @@ class Add(ScalarOp):
class Mul(ScalarOp): class Mul(ScalarOp):
identity = 1 identity = 1
commutative = True
associative = True
def impl(self, *inputs): def impl(self, *inputs):
return numpy.product(inputs) return numpy.product(inputs)
def c_code(self, inputs, (z, ), sub): def c_code(self, inputs, (z, ), sub):
...@@ -424,27 +428,37 @@ class Tan(FloatUnaryScalarOp): ...@@ -424,27 +428,37 @@ class Tan(FloatUnaryScalarOp):
def impl(self, x): def impl(self, x):
return math.tan(x) return math.tan(x)
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
raise NotImplementedError() return gz / (cos(x) ** 2),
def c_code(self, (x, ), (z, ), sub): def c_code(self, (x, ), (z, ), sub):
return "%(z)s = tan(%(x)s);" % locals() return "%(z)s = tan(%(x)s);" % locals()
class Cosh(FloatUnaryScalarOp): class Cosh(FloatUnaryScalarOp):
"""
sinh(x) = (exp(x) + exp(-x)) / 2
"""
def impl(self, x): def impl(self, x):
return math.cosh(x) return math.cosh(x)
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
raise NotImplementedError() return gz * sinh(x),
def c_code(self, (x, ), (z, ), sub): def c_code(self, (x, ), (z, ), sub):
return "%(z)s = cosh(%(x)s);" % locals() return "%(z)s = cosh(%(x)s);" % locals()
class Sinh(FloatUnaryScalarOp): class Sinh(FloatUnaryScalarOp):
"""
sinh(x) = (exp(x) - exp(-x)) / 2
"""
def impl(self, x): def impl(self, x):
return math.sinh(x) return math.sinh(x)
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
raise NotImplementedError() return gz * cosh(x),
def c_code(self, (x, ), (z, ), sub): def c_code(self, (x, ), (z, ), sub):
return "%(z)s = sinh(%(x)s);" % locals() return "%(z)s = sinh(%(x)s);" % locals()
class Tanh(FloatUnaryScalarOp): class Tanh(FloatUnaryScalarOp):
"""
tanh(x) = sinh(x) / cosh(x)
= (exp(2*x) - 1) / (exp(2*x) + 1)
"""
def impl(self, x): def impl(self, x):
return math.tanh(x) return math.tanh(x)
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
......
...@@ -218,15 +218,14 @@ TensorCopy, tensor_copy = broadcast(scal.Identity, 'TensorCopy', False) ...@@ -218,15 +218,14 @@ TensorCopy, tensor_copy = broadcast(scal.Identity, 'TensorCopy', False)
# View Operations # View Operations
########################## ##########################
class TransposeInplace(_Op, Viewer): class TransposeInplace(s2t.DimShuffle):
def view_map(self):
return {self.out: [self.inputs[0]]} def __init__(self, input):
def propagate_broadcastable(self, x): s2t.DimShuffle.__init__(self, input, range(len(input.broadcastable)-1, -1, -1), True)
rval = list(x)
rval.reverse() def perform(self):
return [rval] self.outputs[0].data = self.inputs[0].data.T
def impl(self, x):
return x.T #numpy's transpose
def grad(self, (x,), (gz,)): def grad(self, (x,), (gz,)):
return transpose(gz), return transpose(gz),
...@@ -238,6 +237,7 @@ class TransposeInplace(_Op, Viewer): ...@@ -238,6 +237,7 @@ class TransposeInplace(_Op, Viewer):
} }
%(z)s = transposed; %(z)s = transposed;
""" % locals() """ % locals()
transpose_inplace = gof.op.constructor(TransposeInplace) transpose_inplace = gof.op.constructor(TransposeInplace)
def transpose(x, **kwargs): def transpose(x, **kwargs):
return transpose_inplace(tensor_copy(x), **kwargs) return transpose_inplace(tensor_copy(x), **kwargs)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论