コード例 #1
0
    def collision_detection(self, obj):
        if isinstance(obj, Object.Bullet):
            pot = [
                self.position[0], self.position[1] - self.earth,
                self.position[2]
            ]
            after_bullet = obj.position
            before_bullet = obj.back()

            before_to_after = util.Vec(after_bullet) - util.Vec(before_bullet)
            pot_to_before = util.Vec(before_bullet) - util.Vec(pot)
            pot_to_after = util.Vec(after_bullet) - util.Vec(pot)

            if util.dot(before_to_after, -1 * pot_to_before) < 0:
                if util.norm(pot_to_before) < self.radius:
                    return True
                else:
                    return False
            elif util.dot(before_to_after, pot_to_after) < 0:
                if util.norm(pot_to_after) < self.radius:
                    return True
                else:
                    return False
            else:
                if util.norm(util.cross3d(before_to_after, pot_to_before)
                             ) / util.norm(before_to_after) < self.radius:
                    return True
                else:
                    return False
コード例 #2
0
ファイル: util_test.py プロジェクト: aurotripathy/stuff
 def extra_checks(A, X, B):
     x = u.Vec(X)
     u.check_equal(u.Vec(A @ X @ B), x @ u.Kron(B, A.t()))
     u.check_equal(u.Vec(A @ X @ B), u.Kron(B.t(), A) @ x)
     u.check_equal(u.Vecr(A @ X @ B), u.Kron(A, B.t()) @ u.Vecr(X))
     u.check_equal(u.Vecr(A @ X @ B), u.Vecr(X) @ u.Kron(A.t(), B))
     u.check_equal(u.Vecr(A @ X @ B),
                   u.Vecr(X) @ u.Kron(A.t(), B).normal_form())
     u.check_equal(u.Vecr(A @ X @ B),
                   u.matmul(u.Kron(A, B.t()).normal_form(), u.Vecr(X)))
     u.check_equal(u.Vec(A @ X @ B),
                   u.matmul(u.Kron(B.t(), A).normal_form(), x))
     u.check_equal(u.Vec(A @ X @ B), x @ u.Kron(B, A.t()).normal_form())
     u.check_equal(u.Vec(A @ X @ B),
                   x.normal_form() @ u.Kron(B, A.t()).normal_form())
     u.check_equal(u.Vec(A @ X @ B),
                   u.Kron(B.t(), A).normal_form() @ x.normal_form())
     u.check_equal(u.Vecr(A @ X @ B),
                   u.Kron(A, B.t()).normal_form() @ u.Vecr(X).normal_form())
     u.check_equal(u.Vecr(A @ X @ B),
                   u.Vecr(X).normal_form() @ u.Kron(A.t(), B).normal_form())
コード例 #3
0
ファイル: hessian_test.py プロジェクト: aurotripathy/stuff
def test_explicit_hessian():
    """Check computation of hessian of loss(B'WA) from https://github.com/yaroslavvb/kfac_pytorch/blob/master/derivation.pdf


    """

    torch.set_default_dtype(torch.float64)
    A = torch.tensor([[-1., 4], [3, 0]])
    B = torch.tensor([[-4., 3], [2, 6]])
    X = torch.tensor([[-5., 0], [-2, -6]], requires_grad=True)

    Y = B.t() @ X @ A
    u.check_equal(Y, [[-52, 64], [-81, -108]])
    loss = torch.sum(Y * Y) / 2
    hess0 = u.hessian(loss, X).reshape([4, 4])
    hess1 = u.Kron(A @ A.t(), B @ B.t())

    u.check_equal(loss, 12512.5)

    # PyTorch autograd computes Hessian with respect to row-vectorized parameters, whereas
    # autograd_lib uses math convention and does column-vectorized.
    # Commuting order of Kronecker product switches between two representations
    u.check_equal(hess1.commute(), hess0)

    # Do a test using Linear layers instead of matrix multiplies
    model: u.SimpleFullyConnected2 = u.SimpleFullyConnected2([2, 2, 2], bias=False)
    model.layers[0].weight.data.copy_(X)

    # Transpose to match previous results, layers treat dim0 as batch dimension
    u.check_equal(model.layers[0](A.t()).t(), [[5, -20], [-16, -8]])  # XA = (A'X0)'

    model.layers[1].weight.data.copy_(B.t())
    u.check_equal(model(A.t()).t(), Y)

    Y = model(A.t()).t()    # transpose to data-dimension=columns
    loss = torch.sum(Y * Y) / 2
    loss.backward()

    u.check_equal(model.layers[0].weight.grad, [[-2285, -105], [-1490, -1770]])
    G = B @ Y @ A.t()
    u.check_equal(model.layers[0].weight.grad, G)

    u.check_equal(hess0, u.Kron(B @ B.t(), A @ A.t()))

    # compute newton step
    u.check_equal(u.Kron([email protected](), [email protected]()).pinv() @ u.vec(G), u.v2c([-5, -2, 0, -6]))

    # compute Newton step using factored representation
    autograd_lib.add_hooks(model)

    Y = model(A.t())
    n = 2
    loss = torch.sum(Y * Y) / 2
    autograd_lib.backprop_hess(Y, hess_type='LeastSquares')
    autograd_lib.compute_hess(model, method='kron', attr_name='hess_kron', vecr_order=False, loss_aggregation='sum')
    param = model.layers[0].weight

    hess2 = param.hess_kron
    print(hess2)

    u.check_equal(hess2, [[425, 170, -75, -30], [170, 680, -30, -120], [-75, -30, 225, 90], [-30, -120, 90, 360]])

    # Gradient test
    model.zero_grad()
    loss.backward()
    u.check_close(u.vec(G).flatten(), u.Vec(param.grad))

    # Newton step test
    # Method 0: PyTorch native autograd
    newton_step0 = param.grad.flatten() @ torch.pinverse(hess0)
    newton_step0 = newton_step0.reshape(param.shape)
    u.check_equal(newton_step0, [[-5, 0], [-2, -6]])

    # Method 1: colummn major order
    ihess2 = hess2.pinv()
    u.check_equal(ihess2.LL, [[1/16, 1/48], [1/48, 17/144]])
    u.check_equal(ihess2.RR, [[2/45, -(1/90)], [-(1/90), 1/36]])
    u.check_equal(torch.flatten(hess2.pinv() @ u.vec(G)), [-5, -2, 0, -6])
    newton_step1 = (ihess2 @ u.Vec(param.grad)).matrix_form()

    # Method2: row major order
    ihess2_rowmajor = ihess2.commute()
    newton_step2 = ihess2_rowmajor @ u.Vecr(param.grad)
    newton_step2 = newton_step2.matrix_form()

    u.check_equal(newton_step0, newton_step1)
    u.check_equal(newton_step0, newton_step2)
コード例 #4
0
ファイル: hessian_test.py プロジェクト: aurotripathy/stuff
def _test_explicit_hessian_refactored():

    """Check computation of hessian of loss(B'WA) from https://github.com/yaroslavvb/kfac_pytorch/blob/master/derivation.pdf


    """

    torch.set_default_dtype(torch.float64)
    A = torch.tensor([[-1., 4], [3, 0]])
    B = torch.tensor([[-4., 3], [2, 6]])
    X = torch.tensor([[-5., 0], [-2, -6]], requires_grad=True)

    Y = B.t() @ X @ A
    u.check_equal(Y, [[-52, 64], [-81, -108]])
    loss = torch.sum(Y * Y) / 2
    hess0 = u.hessian(loss, X).reshape([4, 4])
    hess1 = u.Kron(A @ A.t(), B @ B.t())

    u.check_equal(loss, 12512.5)

    # Do a test using Linear layers instead of matrix multiplies
    model: u.SimpleFullyConnected2 = u.SimpleFullyConnected2([2, 2, 2], bias=False)
    model.layers[0].weight.data.copy_(X)

    # Transpose to match previous results, layers treat dim0 as batch dimension
    u.check_equal(model.layers[0](A.t()).t(), [[5, -20], [-16, -8]])  # XA = (A'X0)'

    model.layers[1].weight.data.copy_(B.t())
    u.check_equal(model(A.t()).t(), Y)

    Y = model(A.t()).t()    # transpose to data-dimension=columns
    loss = torch.sum(Y * Y) / 2
    loss.backward()

    u.check_equal(model.layers[0].weight.grad, [[-2285, -105], [-1490, -1770]])
    G = B @ Y @ A.t()
    u.check_equal(model.layers[0].weight.grad, G)

    autograd_lib.register(model)
    activations_dict = autograd_lib.ModuleDict()  # todo(y): make save_activations ctx manager automatically create A
    with autograd_lib.save_activations(activations_dict):
        Y = model(A.t())

    Acov = autograd_lib.ModuleDict(autograd_lib.SecondOrderCov)
    for layer, activations in activations_dict.items():
        print(layer, activations)
        Acov[layer].accumulate(activations, activations)
    autograd_lib.set_default_activations(activations_dict)
    autograd_lib.set_default_Acov(Acov)

    B = autograd_lib.ModuleDict(autograd_lib.SymmetricFourthOrderCov)
    autograd_lib.backward_accum(Y, "identity", B, retain_graph=False)

    print(B[model.layers[0]])

    autograd_lib.backprop_hess(Y, hess_type='LeastSquares')
    autograd_lib.compute_hess(model, method='kron', attr_name='hess_kron', vecr_order=False, loss_aggregation='sum')
    param = model.layers[0].weight

    hess2 = param.hess_kron
    print(hess2)

    u.check_equal(hess2, [[425, 170, -75, -30], [170, 680, -30, -120], [-75, -30, 225, 90], [-30, -120, 90, 360]])

    # Gradient test
    model.zero_grad()
    loss.backward()
    u.check_close(u.vec(G).flatten(), u.Vec(param.grad))

    # Newton step test
    # Method 0: PyTorch native autograd
    newton_step0 = param.grad.flatten() @ torch.pinverse(hess0)
    newton_step0 = newton_step0.reshape(param.shape)
    u.check_equal(newton_step0, [[-5, 0], [-2, -6]])

    # Method 1: colummn major order
    ihess2 = hess2.pinv()
    u.check_equal(ihess2.LL, [[1/16, 1/48], [1/48, 17/144]])
    u.check_equal(ihess2.RR, [[2/45, -(1/90)], [-(1/90), 1/36]])
    u.check_equal(torch.flatten(hess2.pinv() @ u.vec(G)), [-5, -2, 0, -6])
    newton_step1 = (ihess2 @ u.Vec(param.grad)).matrix_form()

    # Method2: row major order
    ihess2_rowmajor = ihess2.commute()
    newton_step2 = ihess2_rowmajor @ u.Vecr(param.grad)
    newton_step2 = newton_step2.matrix_form()

    u.check_equal(newton_step0, newton_step1)
    u.check_equal(newton_step0, newton_step2)
コード例 #5
0
ファイル: util_test.py プロジェクト: aurotripathy/stuff
def test_kron():
    """Test kron, vec and vecr identities"""
    torch.set_default_dtype(torch.float64)
    a = torch.tensor([1, 2, 3, 4]).reshape(2, 2)
    b = torch.tensor([5, 6, 7, 8]).reshape(2, 2)
    u.check_close(u.Kron(a, b).trace(), 65)

    a = torch.tensor([[2., 7, 9], [1, 9, 8], [2, 7, 5]])
    b = torch.tensor([[6., 6, 1], [10, 7, 7], [7, 10, 10]])
    Ck = u.Kron(a, b)
    u.check_close(a.flatten().norm() * b.flatten().norm(), Ck.frobenius_norm())

    u.check_close(Ck.frobenius_norm(), 4 * math.sqrt(11635.))

    Ci = [[
        0, 5 / 102, -(7 / 204), 0, -(70 / 561), 49 / 561, 0, 125 / 1122,
        -(175 / 2244)
    ],
          [
              1 / 20, -(53 / 1020), 8 / 255, -(7 / 55), 371 / 2805,
              -(224 / 2805), 5 / 44, -(265 / 2244), 40 / 561
          ],
          [
              -(1 / 20), 3 / 170, 3 / 170, 7 / 55, -(42 / 935), -(42 / 935),
              -(5 / 44), 15 / 374, 15 / 374
          ],
          [
              0, -(5 / 102), 7 / 204, 0, 20 / 561, -(14 / 561), 0, 35 / 1122,
              -(49 / 2244)
          ],
          [
              -(1 / 20), 53 / 1020, -(8 / 255), 2 / 55, -(106 / 2805),
              64 / 2805, 7 / 220, -(371 / 11220), 56 / 2805
          ],
          [
              1 / 20, -(3 / 170), -(3 / 170), -(2 / 55), 12 / 935, 12 / 935,
              -(7 / 220), 21 / 1870, 21 / 1870
          ], [0, 5 / 102, -(7 / 204), 0, 0, 0, 0, -(5 / 102), 7 / 204],
          [
              1 / 20, -(53 / 1020), 8 / 255, 0, 0, 0, -(1 / 20), 53 / 1020,
              -(8 / 255)
          ],
          [
              -(1 / 20), 3 / 170, 3 / 170, 0, 0, 0, 1 / 20, -(3 / 170),
              -(3 / 170)
          ]]
    C = Ck.expand()
    C0 = u.to_numpy(C)
    Ci = torch.tensor(Ci)
    u.check_close(C @ Ci @ C, C)

    u.check_close(Ck.inv().expand(), torch.inverse(Ck.expand()))
    u.check_close(Ck.inv().expand_vec(), torch.inverse(Ck.expand_vec()))
    u.check_close(Ck.pinv().expand(), torch.pinverse(Ck.expand()))

    u.check_close(linalg.pinv(C0), Ci, rtol=1e-5, atol=1e-6)
    u.check_close(torch.pinverse(C), Ci, rtol=1e-5, atol=1e-6)
    u.check_close(Ck.inv().expand(), Ci, rtol=1e-5, atol=1e-6)
    u.check_close(Ck.pinv().expand(), Ci, rtol=1e-5, atol=1e-6)

    Ck2 = u.Kron(b, 2 * a)
    u.check_close((Ck @ Ck2).expand(), Ck.expand() @ Ck2.expand())
    u.check_close((Ck @ Ck2).expand_vec(), Ck.expand_vec() @ Ck2.expand_vec())

    d2 = 3
    d1 = 2
    G = torch.randn(d2, d1)
    g = u.vec(G)
    H = u.Kron(u.random_cov(d1), u.random_cov(d2))

    Gt = G.t()
    gt = g.reshape(1, -1)

    vecX = u.Vec([1, 2, 3, 4], shape=(2, 2))
    K = u.Kron([[5, 6], [7, 8]], [[9, 10], [11, 12]])

    u.check_equal(vecX @ K, [644, 706, 748, 820])
    u.check_equal(K @ vecX, [543, 655, 737, 889])

    u.check_equal(u.matmul(vecX @ K, vecX), 7538)
    u.check_equal(vecX @ (vecX @ K), 7538)
    u.check_equal(vecX @ vecX, 30)

    vecX = u.Vec([1, 2], shape=(1, 2))
    K = u.Kron([[5]], [[9, 10], [11, 12]])

    u.check_equal(vecX.norm()**2, 5)

    # check kronecker rules
    X = torch.tensor([[1., 2], [3, 4]])
    A = torch.tensor([[5., 6], [7, 8]])
    B = torch.tensor([[9., 10], [11, 12]])
    x = u.Vec(X)

    # kron/vec/vecr identities
    u.check_equal(u.Vec(A @ X @ B), x @ u.Kron(B, A.t()))
    u.check_equal(u.Vec(A @ X @ B), u.Kron(B.t(), A) @ x)
    u.check_equal(u.Vecr(A @ X @ B), u.Kron(A, B.t()) @ u.Vecr(X))
    u.check_equal(u.Vecr(A @ X @ B), u.Vecr(X) @ u.Kron(A.t(), B))

    def extra_checks(A, X, B):
        x = u.Vec(X)
        u.check_equal(u.Vec(A @ X @ B), x @ u.Kron(B, A.t()))
        u.check_equal(u.Vec(A @ X @ B), u.Kron(B.t(), A) @ x)
        u.check_equal(u.Vecr(A @ X @ B), u.Kron(A, B.t()) @ u.Vecr(X))
        u.check_equal(u.Vecr(A @ X @ B), u.Vecr(X) @ u.Kron(A.t(), B))
        u.check_equal(u.Vecr(A @ X @ B),
                      u.Vecr(X) @ u.Kron(A.t(), B).normal_form())
        u.check_equal(u.Vecr(A @ X @ B),
                      u.matmul(u.Kron(A, B.t()).normal_form(), u.Vecr(X)))
        u.check_equal(u.Vec(A @ X @ B),
                      u.matmul(u.Kron(B.t(), A).normal_form(), x))
        u.check_equal(u.Vec(A @ X @ B), x @ u.Kron(B, A.t()).normal_form())
        u.check_equal(u.Vec(A @ X @ B),
                      x.normal_form() @ u.Kron(B, A.t()).normal_form())
        u.check_equal(u.Vec(A @ X @ B),
                      u.Kron(B.t(), A).normal_form() @ x.normal_form())
        u.check_equal(u.Vecr(A @ X @ B),
                      u.Kron(A, B.t()).normal_form() @ u.Vecr(X).normal_form())
        u.check_equal(u.Vecr(A @ X @ B),
                      u.Vecr(X).normal_form() @ u.Kron(A.t(), B).normal_form())

    # shape checks
    d1, d2 = 3, 4
    extra_checks(torch.ones((d1, d1)), torch.ones((d1, d2)),
                 torch.ones((d2, d2)))

    A = torch.rand(d1, d1)
    B = torch.rand(d2, d2)
    #x = torch.rand((d1*d2))
    #X = x.t().reshape(d1, d2)
    # X = torch.rand((d1, d2))
    # x = u.vec(X)
    x = torch.rand((d1 * d2))