Example #1
0
 def __call__(self, x):
     """Implements the chain rule.
     INPUTS
     =======
     x: autodiff.Variable holding a val and grad
 
     RETURNS
     ========
     autodiff.Variable: updated Variable after chain rule was applied 
     """
     # if autodiff.config.mode == 'forward':
     if isinstance(x, Variable):
         out_val = self.get_val(x.val)
         out_grad = np.dot(self.get_grad(x.val), x.grad)
         # out_grad = np.dot(self.get_grad(x.val), x.grad)
         return Variable(val=out_val, grad=out_grad)
     elif isinstance(x, ReverseVariable):
         out_val = self.get_val(x.val)
         res = ReverseVariable(out_val)
         x.children.append(res)
         res.left = x
         res.leftgrad = self.get_grad(x.val)
         return res
     else:
         raise ValueError("Not a variable!")
def test_rpow_exception():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(2)
    a = x + y
    with pytest.raises(TypeError):
        b = "g"**y
    with pytest.raises(ValueError):
        b = 2**a
def test_mul_exception():
    x = ReverseVariable([1, 2])
    y = ReverseVariable([2, 1])
    z = ReverseVariable(4)
    a = x + y
    with pytest.raises(TypeError):
        b = a * "g"
    with pytest.raises(TypeError):
        b = False * y
def test_sub_exception():
    x = ReverseVariable([1, 2])
    y = ReverseVariable([2, 1])
    z = y + x
    a = z + [4.4, 3.3]
    b = a + z
    with pytest.raises(TypeError):
        c = b - "g"
    with pytest.raises(TypeError):
        c = True - b
def test_neg():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(4)
    a = x + y
    b = a / z
    c = -b
    c.reverse()
    assert close(c.val, -np.asarray([[1], [1]]))
    assert close(x.grad, np.eye(2) * -0.25)
    assert close(y.grad, np.eye(2) * -0.25)
    assert close(z.grad, np.asarray([[0.25], [0.25]]))
def test_pow_exception():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(2)
    a = x + y
    with pytest.raises(TypeError):
        b = a**"g"
    with pytest.raises(ValueError):
        b = a**[3, 3]
    with pytest.raises(ValueError):
        b = a**z
    with pytest.raises(ValueError):
        b = z**a
def test_create_function_exception():
    with pytest.raises(NotImplementedError):
        f = F.Function()
        x = ReverseVariable([1, 2, 3])
        y = f(x)
    with pytest.raises(NotImplementedError):
        f = F.Function()
        x = ReverseVariable([1, 2, 3])
        y = f.get_grad(x)
    with pytest.raises(NotImplementedError):
        f = F.Function()
        x = ReverseVariable([1, 2, 3])
        y = f.get_val(x)
def test_arccos():
    x = ReverseVariable(0.5)
    arccos = F.Arccos()
    y = arccos(x)
    y.reverse()
    assert close(y.val, np.pi / 3) and close(x.grad,
                                             -1.0 / np.sqrt(1.0 - 0.5**2))
def test_arcsin():
    x = ReverseVariable(0.5)
    arcsin = F.Arcsin()
    y = arcsin(x)
    y.reverse()
    assert close(y.val, np.pi / 6) and close(x.grad,
                                             1.0 / np.sqrt(1.0 - 0.5**2))
def test_dot():
    x = ReverseVariable([1, 1])
    M = np.asarray(([2, 2], [1, 1]))
    dotm = F.Dot(M)
    y = dotm(x)
    y.reverse()
    assert close(y.val, np.asarray([[4], [2]])) and close(x.grad, M)
def test_exp():
    x = ReverseVariable(2)
    exp = F.Exponent()
    y = exp(x)
    y.reverse()
    assert close(y.val, np.exp(2))
    assert close(x.grad, np.exp(2))
def test_tanh():
    x = ReverseVariable(1)
    tanh = F.Tanh()
    y = tanh(x)
    y.reverse()
    assert close(y.val, np.tanh(1)) and close(x.grad,
                                              (np.cosh(1)**2 - np.sinh(1)**2) /
                                              (np.cosh(1)**2))
def test_logistic():
    x = ReverseVariable(2)
    logi = F.Logistic()
    y = logi(x)
    y.reverse()
    assert close(y.val, 1.0 / (1.0 + np.exp(-(2)))) and close(
        x.grad,
        (1.0 / (1.0 + np.exp(-(2)))) * (1.0 - (1.0 / (1.0 + np.exp(-(2))))))
def test_add():
    x = ReverseVariable([1, 2])
    y = ReverseVariable([2, 1])
    z = x + y
    z.reverse()
    assert close(z.val, np.asarray([[3], [3]]))
    assert close(x.grad, np.eye(2))
    assert close(y.grad, np.eye(2))
    a = z + [4.4, 3.3]
    b = a + z
    b.reverse()
    assert close(b.val, np.asarray([[10.4], [9.3]]))
    assert close(x.grad, np.eye(2) * 2)
    assert close(y.grad, np.eye(2) * 2)
    c = [4.4, 3.3] + b
    c.reverse()
    assert close(c.val, np.asarray([[14.8], [12.6]]))
    assert close(x.grad, np.eye(2) * 2)
    assert close(y.grad, np.eye(2) * 2)
def test_log():
    x = ReverseVariable(2)
    log = F.Log()
    y = log(x)
    y.reverse()
    assert close(y.val, np.log(2)) and close(x.grad, 0.5)
    log2 = F.Log(2)
    y = log2(x)
    y.reverse()
    assert close(y.val, 1)
    assert close(x.grad, 0.5 / np.log(2))
def test_pow():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(2)
    a = x + y
    b = z**2
    b.reverse()
    assert close(b.val, 4)
    assert close(z.grad, 4)
    b = a**2
    b.reverse()
    assert close(b.val, np.asarray([[16], [16]]))
    assert close(x.grad, np.eye(2) * 8)
    assert close(y.grad, np.eye(2) * 8)
    c = z
    d = z**c
    d.reverse()
    assert close(d.val, 4)
    print(z.grad)
    assert close(z.grad, 4 * (np.log(2) + 1))
def test_sub():
    x = ReverseVariable([1, 2])
    y = ReverseVariable([2, 1])
    z = y + x
    a = z + [4.4, 3.3]
    b = a + z
    c = b - x
    c.reverse()
    assert close(c.val, np.asarray([[9.4], [7.3]]))
    assert close(x.grad, np.eye(2))
    assert close(y.grad, np.eye(2) * 2)
    d = 3 - c
    d.reverse()
    assert close(d.val, np.asarray([[-6.4], [-4.3]]))
    assert close(x.grad, np.eye(2) * -1)
    assert close(y.grad, np.eye(2) * -2)
    e = c - 2.1
    e.reverse()
    assert close(e.val, np.asarray([[7.3], [5.2]]))
    assert close(x.grad, np.eye(2))
    assert close(y.grad, np.eye(2) * 2)
def test_div_exception():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(0)
    a = x + y
    with pytest.raises(ValueError):
        b = a / x
    with pytest.raises(ValueError):
        b = a / z
    with pytest.raises(ValueError):
        b = 4.0 / z
    with pytest.raises(ValueError):
        b = a / 0.0
    with pytest.raises(ValueError):
        b = a / np.asarray([1, 1])
    with pytest.raises(ValueError):
        b = 4.0 / x
    with pytest.raises(TypeError):
        b = a / "g"
    with pytest.raises(TypeError):
        a = True / y
def test_div():
    x = ReverseVariable([1, 3])
    y = ReverseVariable([3, 1])
    z = ReverseVariable(4)
    a = x + y
    b = a / z
    b.reverse()
    assert close(b.val, np.asarray([[1], [1]]))
    assert close(x.grad, np.eye(2) * 0.25)
    assert close(y.grad, np.eye(2) * 0.25)
    assert close(z.grad, np.asarray([[-0.25], [-0.25]]))
    c = b / 0.25
    c.reverse()
    assert close(c.val, np.asarray([[4], [4]]))
    assert close(x.grad, np.eye(2))
    assert close(y.grad, np.eye(2))
    assert close(z.grad, np.asarray([[-1], [-1]]))
    d = 4 / z
    d.reverse()
    assert close(d.val, 1)
    assert close(z.grad, -0.25)
def test_mul():
    x = ReverseVariable([1, 2])
    y = ReverseVariable([2, 1])
    z = ReverseVariable(4)
    a = x + y
    b = a * z
    b.reverse()
    assert close(b.val, np.asarray([[12], [12]]))
    assert close(x.grad, np.eye(2) * 4)
    assert close(y.grad, np.eye(2) * 4)
    assert close(z.grad, np.asarray([[3], [3]]))
    c = b * 4
    c.reverse()
    assert close(c.val, np.asarray([[48], [48]]))
    assert close(x.grad, np.eye(2) * 16)
    assert close(y.grad, np.eye(2) * 16)
    assert close(z.grad, np.asarray([[12], [12]]))
    d = 2 * b
    d.reverse()
    assert close(d.val, np.asarray([[24], [24]]))
    assert close(x.grad, np.eye(2) * 8)
    assert close(y.grad, np.eye(2) * 8)
    assert close(z.grad, np.asarray([[6], [6]]))
def test_arctan():
    x = ReverseVariable(1)
    arctan = F.Arctan()
    y = arctan(x)
    y.reverse()
    assert close(y.val, np.pi / 4) and close(x.grad, 0.5)
def test_add_exception():
    x = ReverseVariable([1, 2, 3])
    with pytest.raises(TypeError):
        y = x + "g"
    with pytest.raises(TypeError):
        y = True + x
def test_exp_exception():
    x = ReverseVariable([1, 2, 3])
    exp = F.Exponent()
    with pytest.raises(ValueError):
        y = exp(x)
def test_sin():
    x = ReverseVariable(np.pi / 6)
    sin = F.Sinus()
    y = sin(x)
    y.reverse()
    assert abs(y.val - 0.5) < 1e-4 and abs(x.grad - np.sqrt(3) / 2) < 1e-4
def test_rpow():
    z = ReverseVariable(2)
    b = 2**z
    b.reverse()
    assert close(b.val, 4)
    assert close(z.grad, np.log(2) * 4)
def test_cos():
    x = ReverseVariable(np.pi / 3)
    cos = F.Cosinus()
    y = cos(x)
    y.reverse()
    assert abs(y.val - 0.5) < 1e-4 and abs(x.grad + np.sqrt(3) / 2) < 1e-4
def test_tan():
    x = ReverseVariable(np.pi / 4)
    tan = F.Tangent()
    y = tan(x)
    y.reverse()
    assert abs(y.val - 1) < 1e-4 and abs(x.grad - 2) < 1e-4
def test_tan_exception():
    x = ReverseVariable(np.pi / 2)
    tan = F.Tangent()
    with pytest.raises(ValueError):
        y = tan(x)
def test_create_variable():
    X = ReverseVariable([1, 2, 3])
    assert close(X.val, np.asarray([[1], [2], [3]]))
    y = ReverseVariable(1)
    assert close(y.val, 1)
def test_sinh():
    x = ReverseVariable(1)
    sinh = F.Sinh()
    y = sinh(x)
    y.reverse()
    assert close(y.val, np.sinh(1)) and close(x.grad, np.cosh(1))