Ejemplo n.º 1
0
    def test_import_var(self):

        var1 = MyVariable("var1")
        var2 = MyVariable("var2")
        var3 = op1(var2, var1)
        var4 = op2(var3, var2)
        var5 = op3(var4, var2, var2)
        fg = FunctionGraph([var1, var2], [var3, var5], clone=False)

        with pytest.raises(MissingInputError):
            var0 = MyVariable("var0")
            # We can't import a new `FunctionGraph` input (i.e. something
            # without an owner)
            fg.import_var(var0, "testing")

        var5 = op2()
        # We can import variables with owners
        fg.import_var(var5, "testing")
        assert var5 in fg.variables
        assert var5.owner in fg.apply_nodes

        with pytest.raises(TypeError, match="Computation graph contains.*"):
            from theano.gof.null_type import NullType

            fg.import_var(NullType()(), "testing")
Ejemplo n.º 2
0
def test_undefined_cost_grad():
    # Tests that if we say the cost is not differentiable via the
    # known_grads mechanism, it is treated as such by the rest of the
    # system.
    # This is so that Ops that are built around minigraphs like OpFromGraph
    # and scan can implement Op.grad by passing ograds to known_grads

    x = theano.tensor.iscalar()
    y = theano.tensor.iscalar()
    cost = x + y
    assert cost.dtype in theano.tensor.discrete_dtypes
    try:
        theano.tensor.grad(cost, [x, y], known_grads={cost: NullType()()})
    except theano.gradient.NullTypeGradError:
        return
    raise AssertionError("An undefined gradient has been ignored.")
Ejemplo n.º 3
0
 def grad(self, inputs, output_grads):
     return [inputs[0].zeros_like(), NullType()()]
Ejemplo n.º 4
0
 def grad(self, inputs, ograds):
     grads = [
         NullType("Tried to take gradient thru hashtable.")()
         for i in range(len(inputs))
     ]
     return grads
Ejemplo n.º 5
0
    def test_grad_override(self, cls_ofg):
        x, y = T.vectors('xy')

        def go(inps, gs):
            x, y = inps
            g, = gs
            return [g * y * 2, g * x * 1.5]

        dedz = T.vector('dedz')
        op_mul_grad = cls_ofg([x, y, dedz], go([x, y], [dedz]))

        op_mul = cls_ofg([x, y], [x * y], grad_overrides=go)
        op_mul2 = cls_ofg([x, y], [x * y], grad_overrides=op_mul_grad)

        # single override case (function or OfG instance)
        xx, yy = T.vector('xx'), T.vector('yy')
        for op in [op_mul, op_mul2]:
            zz = T.sum(op(xx, yy))
            dx, dy = T.grad(zz, [xx, yy])
            fn = function([xx, yy], [dx, dy])
            xv = np.random.rand(16).astype(config.floatX)
            yv = np.random.rand(16).astype(config.floatX)
            dxv, dyv = fn(xv, yv)
            assert np.allclose(yv * 2, dxv)
            assert np.allclose(xv * 1.5, dyv)

        # list override case
        def go1(inps, gs):
            x, w, b = inps
            g = gs[0]
            return g * w * 2

        def go2(inps, gs):
            x, w, b = inps
            g = gs[0]
            return g * x * 1.5

        w, b = T.vectors('wb')
        # we make the 3rd gradient default (no override)
        op_linear = cls_ofg([x, w, b], [x * w + b],
                            grad_overrides=[go1, go2, 'default'])
        xx, ww, bb = T.vector('xx'), T.vector('yy'), T.vector('bb')
        zz = T.sum(op_linear(xx, ww, bb))
        dx, dw, db = T.grad(zz, [xx, ww, bb])
        fn = function([xx, ww, bb], [dx, dw, db])
        xv = np.random.rand(16).astype(config.floatX)
        wv = np.random.rand(16).astype(config.floatX)
        bv = np.random.rand(16).astype(config.floatX)
        dxv, dwv, dbv = fn(xv, wv, bv)
        assert np.allclose(wv * 2, dxv)
        assert np.allclose(xv * 1.5, dwv)
        assert np.allclose(np.ones(16, dtype=config.floatX), dbv)

        # NullType and DisconnectedType
        op_linear2 = cls_ofg(
            [x, w, b], [x * w + b],
            grad_overrides=[go1, NullType()(),
                            DisconnectedType()()])
        zz2 = T.sum(op_linear2(xx, ww, bb))
        dx2, dw2, db2 = T.grad(zz2, [xx, ww, bb],
                               return_disconnected='Disconnected',
                               disconnected_inputs='ignore',
                               null_gradients='return')
        assert isinstance(dx2.type, T.TensorType)
        assert dx2.ndim == 1
        assert isinstance(dw2.type, NullType)
        assert isinstance(db2.type, DisconnectedType)
Ejemplo n.º 6
0
    def test_grad_override(self, cls_ofg):
        x, y = tt.vectors("xy")

        def go(inps, gs):
            x, y = inps
            (g, ) = gs
            return [g * y * 2, g * x * 1.5]

        dedz = tt.vector("dedz")
        op_mul_grad = cls_ofg([x, y, dedz], go([x, y], [dedz]))

        op_mul = cls_ofg([x, y], [x * y], grad_overrides=go)
        op_mul2 = cls_ofg([x, y], [x * y], grad_overrides=op_mul_grad)

        # single override case (function or OfG instance)
        xx, yy = tt.vector("xx"), tt.vector("yy")
        for op in [op_mul, op_mul2]:
            zz = tt.sum(op(xx, yy))
            dx, dy = tt.grad(zz, [xx, yy])
            fn = function([xx, yy], [dx, dy])
            xv = np.random.rand(16).astype(config.floatX)
            yv = np.random.rand(16).astype(config.floatX)
            dxv, dyv = fn(xv, yv)
            assert np.allclose(yv * 2, dxv)
            assert np.allclose(xv * 1.5, dyv)

        # list override case
        def go1(inps, gs):
            x, w, b = inps
            g = gs[0]
            return g * w * 2

        def go2(inps, gs):
            x, w, b = inps
            g = gs[0]
            return g * x * 1.5

        w, b = tt.vectors("wb")
        # we make the 3rd gradient default (no override)
        op_linear = cls_ofg([x, w, b], [x * w + b],
                            grad_overrides=[go1, go2, "default"])
        xx, ww, bb = tt.vector("xx"), tt.vector("yy"), tt.vector("bb")
        zz = tt.sum(op_linear(xx, ww, bb))
        dx, dw, db = tt.grad(zz, [xx, ww, bb])
        fn = function([xx, ww, bb], [dx, dw, db])
        xv = np.random.rand(16).astype(config.floatX)
        wv = np.random.rand(16).astype(config.floatX)
        bv = np.random.rand(16).astype(config.floatX)
        dxv, dwv, dbv = fn(xv, wv, bv)
        assert np.allclose(wv * 2, dxv)
        assert np.allclose(xv * 1.5, dwv)
        assert np.allclose(np.ones(16, dtype=config.floatX), dbv)

        # NullType and DisconnectedType
        op_linear2 = cls_ofg(
            [x, w, b],
            [x * w + b],
            grad_overrides=[go1, NullType()(),
                            DisconnectedType()()],
        )
        zz2 = tt.sum(op_linear2(xx, ww, bb))
        dx2, dw2, db2 = tt.grad(
            zz2,
            [xx, ww, bb],
            return_disconnected="Disconnected",
            disconnected_inputs="ignore",
            null_gradients="return",
        )
        assert isinstance(dx2.type, tt.TensorType)
        assert dx2.ndim == 1
        assert isinstance(dw2.type, NullType)
        assert isinstance(db2.type, DisconnectedType)