Exemple #1
0
def test_cp_vonneumann_entropy_mixed_state():
    """Test for cp_vonneumann_entropy on CP tensors. 
    This test checks that the VNE of mixed states is calculated correctly.
    """
    state1 = tl.tensor([[
        0.03004805, 0.42426117, 0.5483771, 0.4784077, 0.25792725, 0.34388784,
        0.99927586, 0.96605812
    ]])
    state1 = state1 / tl.norm(state1)
    state2 = tl.tensor([[
        0.84250089, 0.43429687, 0.26551928, 0.18262211, 0.55584835, 0.2565509,
        0.33197401, 0.97741178
    ]])
    state2 = state2 / tl.norm(state2)
    mat_mixed = tl.tensor((tl.dot(tl.transpose(state1), state1) +
                           tl.dot(tl.transpose(state2), state2)) / 2.)
    actual_vne = 0.5546
    mat = parafac(tl.tensor(mat_mixed), rank=2, normalize_factors=True)
    mat_unnorm = parafac(tl.tensor(mat_mixed), rank=2, normalize_factors=False)
    tl_vne = cp_vonneumann_entropy(mat)
    tl_vne_unnorm = cp_vonneumann_entropy(mat_unnorm)
    tl.testing.assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
    tl.testing.assert_array_almost_equal(tl_vne_unnorm, actual_vne, decimal=3)
    assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
    assert_array_almost_equal(tl_vne_unnorm, actual_vne, decimal=3)
def test_tt_factorized_linear():
    x = tlr.random_tt((2, 7), rank=[1, 7, 1])
    weights = tlr.random_tt_matrix((2, 7, 2, 7), rank=[1, 10, 1])
    out = tt_factorized_linear(x, weights).to_tensor()
    out = tl.reshape(out, (-1, 1))
    manual_out = tl.dot(weights.to_matrix(),
                        tl.reshape(x.to_tensor(), (-1, 1)))
    assert_array_almost_equal(out, manual_out, decimal=4)
def test_cp_copy():
    shape = (3, 4, 5)
    rank = 4
    cp_tensor = random_cp(shape, rank)
    weights, factors = cp_tensor
    weights_normalized, factors_normalized = cp_normalize(cp_tensor.cp_copy())
    # Check that modifying copy tensor doesn't change the original tensor
    assert_array_almost_equal(cp_to_tensor((weights, factors)), cp_to_tensor(cp_tensor))
Exemple #4
0
def test_cp_to_tensor():
    """Test for cp_to_tensor."""
    U1 = np.reshape(np.arange(1, 10), (3, 3))
    U2 = np.reshape(np.arange(10, 22), (4, 3))
    U3 = np.reshape(np.arange(22, 28), (2, 3))
    U4 = np.reshape(np.arange(28, 34), (2, 3))
    U = [tl.tensor(t) for t in [U1, U2, U3, U4]]
    true_res = tl.tensor([[[[  46754.,   51524.],
                            [  52748.,   58130.]],

                           [[  59084.,   65114.],
                            [  66662.,   73466.]],

                           [[  71414.,   78704.],
                            [  80576.,   88802.]],

                           [[  83744.,   92294.],
                            [  94490.,  104138.]]],


                          [[[ 113165.,  124784.],
                            [ 127790.,  140912.]],

                           [[ 143522.,  158264.],
                            [ 162080.,  178730.]],

                           [[ 173879.,  191744.],
                            [ 196370.,  216548.]],

                           [[ 204236.,  225224.],
                            [ 230660.,  254366.]]],


                          [[[ 179576.,  198044.],
                            [ 202832.,  223694.]],

                           [[ 227960.,  251414.],
                            [ 257498.,  283994.]],

                           [[ 276344.,  304784.],
                            [ 312164.,  344294.]],

                           [[ 324728.,  358154.],
                            [ 366830.,  404594.]]]])
    res = cp_to_tensor((tl.ones(3), U))
    assert_array_equal(res, true_res, err_msg='Khatri-rao incorrectly transformed into full tensor.')

    columns = 4
    rows = [3, 4, 2]
    matrices = [tl.tensor(np.arange(k * columns).reshape((k, columns))) for k in rows]
    tensor = cp_to_tensor((tl.ones(columns), matrices))
    for i in range(len(rows)):
        unfolded = unfold(tensor, mode=i)
        U_i = matrices.pop(i)
        reconstructed = tl.dot(U_i, tl.transpose(khatri_rao(matrices)))
        assert_array_almost_equal(reconstructed, unfolded)
        matrices.insert(i, U_i)
Exemple #5
0
def test_vonneumann_entropy_pure_state():
    """Test for vonneumann_entropy on 2-dimensional tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state / tl.norm(state)
    mat_pure = tl.dot(state, tl.transpose(state))
    tl_vne = vonneumann_entropy(mat_pure)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
Exemple #6
0
def test_cp_normalize():
    shape = (3, 4, 5)
    rank = 4
    cp_tensor = random_cp(shape, rank)
    weights, factors = cp_normalize(cp_tensor)
    expected_norm = tl.ones(rank)
    for f in factors:
        assert_array_almost_equal(tl.norm(f, axis=0), expected_norm)
    assert_array_almost_equal(cp_to_tensor((weights, factors)), cp_to_tensor(cp_tensor))
Exemple #7
0
def test_tt_vonneumann_entropy_pure_state():
    """Test for tt_vonneumann_entropy TT tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state/tl.norm(state)
    mat_pure = tl.reshape(tl.dot(state, tl.transpose(state)), (2, 2, 2, 2, 2, 2))
    mat_pure = matrix_product_state(mat_pure, rank=(1, 3, 2, 1, 2, 3, 1))
    tl_vne = tt_vonneumann_entropy(mat_pure)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
Exemple #8
0
def test_cp_vonneumann_entropy_pure_state():
    """Test for cp_vonneumann_entropy on 2-dimensional CP tensors.
    This test checks that pure states have a VNE of zero.
    """
    state = tl.randn((8, 1))
    state = state / tl.norm(state)
    mat_pure = tl.dot(state, tl.transpose(state))
    mat = parafac(mat_pure, rank=1, normalize_factors=True)
    tl_vne = cp_vonneumann_entropy(mat)
    assert_array_almost_equal(tl_vne, 0, decimal=3)
def test_tensor_product():
    """Test tensor_dot"""
    rng = random.check_random_state(1234)

    X = tl.tensor(rng.random_sample((4, 5, 6)))
    Y = tl.tensor(rng.random_sample((3, 4, 7)))
    tdot = tl.tensor_to_vec(tensor_dot(X, Y))
    true_dot = tl.tensor_to_vec(
        tenalg.outer([tl.tensor_to_vec(X),
                      tl.tensor_to_vec(Y)]))
    testing.assert_array_almost_equal(tdot, true_dot)
def test_cp_flip_sign():
    shape = (3, 4, 5)
    rank = 4
    cp_tensor = random_cp(shape, rank)
    weights, factors = cp_flip_sign(cp_tensor)

    assert_(tl.all(tl.mean(factors[1], axis=0) > 0))
    assert_(tl.all(tl.mean(factors[2], axis=0) > 0))
    assert_equal(cp_tensor.rank, cp_tensor.rank)
    assert_array_equal(cp_tensor.weights, weights)
    assert_array_almost_equal(cp_to_tensor((weights, factors)), cp_to_tensor(cp_tensor))
Exemple #11
0
def test_outer_product():
    """Test outer_dot"""
    rng = tl.check_random_state(1234)

    X = tl.tensor(rng.random_sample((4, 5, 6)))
    Y = tl.tensor(rng.random_sample((3, 4)))
    Z = tl.tensor(rng.random_sample((2)))
    tdot = outer([X, Y, Z])
    true_dot = tenalg.tensordot(X, Y, ())
    true_dot = tenalg.tensordot(true_dot, Z, ())
    testing.assert_array_almost_equal(tdot, true_dot)
Exemple #12
0
def test_vonneumann_entropy_mixed_state():
    """Test for vonneumann_entropy on 2-dimensional tensors.
    This test checks that the VNE of mixed states is calculated correctly.
    """
    state1 = tl.tensor([[0.03004805, 0.42426117, 0.5483771 , 0.4784077 , 0.25792725, 0.34388784, 0.99927586, 0.96605812]])
    state1 = state1/tl.norm(state1)
    state2 = tl.tensor([[0.84250089, 0.43429687, 0.26551928, 0.18262211, 0.55584835, 0.2565509 , 0.33197401, 0.97741178]])
    state2 = state2/tl.norm(state2)
    mat_mixed = tl.tensor((tl.dot(tl.transpose(state1), state1) + tl.dot(tl.transpose(state2), state2))/2.)
    actual_vne = 0.5546
    tl_vne = vonneumann_entropy(mat_mixed)
    assert_array_almost_equal(tl_vne, actual_vne, decimal=3)
Exemple #13
0
def test_cp_to_tensor_with_weights():
    A = tl.reshape(tl.arange(1,5), (2,2))
    B = tl.reshape(tl.arange(5,9), (2,2))
    weigths = tl.tensor([2,-1], **tl.context(A))

    out = cp_to_tensor((weigths, [A,B]))
    expected = tl.tensor([[-2,-2], [6, 10]])  # computed by hand
    assert_array_equal(out, expected)

    (weigths, factors) = random_cp((5, 5, 5), rank=5, normalise_factors=True, full=False)
    true_res = tl.dot(tl.dot(factors[0], tl.diag(weigths)),
                      tl.transpose(tl.tenalg.khatri_rao(factors[1:])))
    true_res = tl.fold(true_res, 0, (5, 5, 5))  
    res = cp_to_tensor((weigths, factors))
    assert_array_almost_equal(true_res, res,
     err_msg='weights incorrectly incorporated in cp_to_tensor')
def test_linear_tensor_dot_tucker(factorization, factorized_linear):
    in_shape = (4, 5)
    in_dim = prod(in_shape)
    out_shape = (6, 2)
    rank = 3
    batch_size = 2

    tensor = tl.randn((batch_size, in_dim))
    fact_weight = TensorizedTensor.new((out_shape, in_shape),
                                       rank=rank,
                                       factorization=factorization)
    fact_weight.normal_()
    full_weight = fact_weight.to_matrix()
    true_res = torch.matmul(tensor, full_weight.T)
    res = factorized_linear(tensor, fact_weight, transpose=True)
    res = res.reshape(batch_size, -1)
    testing.assert_array_almost_equal(true_res, res, decimal=5)
Exemple #15
0
def test_mps_entanglement_entropy():
    """Test for the tt_mps_entanglement_entropy on TT tensors.
    This test checks that the EE of both product and entangled states is calculated correctly.
    """
    #Product state
    mps = tl.tensor([1, 0, 0, 0, 0, 0, 0, 0], dtype=tl.float32)
    mps = tl.reshape(mps, (2, 2, 2))
    mps = matrix_product_state(mps, rank=[1, 2, 2, 1])
    tl_ee = mps_entanglement_entropy(mps, 1)
    assert_array_almost_equal(tl_ee, 0, decimal=3)

    #Entangled state
    mps = tl.tensor([1, 0, 0, 0, 0, 0, 0, 1], dtype=tl.float32)
    mps = mps / tl.norm(mps)
    mps = tl.reshape(mps, (2, 2, 2))
    mps = matrix_product_state(mps, rank=[1, 2, 2, 1])
    tl_ee = mps_entanglement_entropy(mps, 1)
    assert_array_almost_equal(tl_ee, 1, decimal=3)
Exemple #16
0
def test_batched_outer_product():
    """Test batched_outer_dot

    Notes
    -----
    At the time of writing, MXNet doesn't support transpose 
    for tensors of order higher than 6
    """
    rng = tl.check_random_state(1234)
    batch_size = 3

    X = tl.tensor(rng.random_sample((batch_size, 4, 5, 6)))
    Y = tl.tensor(rng.random_sample((batch_size, 3)))
    Z = tl.tensor(rng.random_sample((batch_size, 2)))
    res = batched_outer([X, Y, Z])
    true_res = tenalg.tensordot(X, Y, (), batched_modes=0)
    true_res = tenalg.tensordot(true_res, Z, (), batched_modes=0)

    testing.assert_array_almost_equal(res, true_res)
def test_batched_tensor_product():
    """Test batched-tensor_dot

    Notes
    -----
    At the time of writing, MXNet doesn't support transpose 
    for tensors of order higher than 6
    """
    rng = random.check_random_state(1234)
    batch_size = 3

    X = tl.tensor(rng.random_sample((batch_size, 4, 5, 6)))
    Y = tl.tensor(rng.random_sample((batch_size, 3, 7)))
    tdot = tl.unfold(batched_tensor_dot(X, Y), 0)
    for i in range(batch_size):
        true_dot = tl.tensor_to_vec(
            tenalg.outer([tl.tensor_to_vec(X[i]),
                          tl.tensor_to_vec(Y[i])]))
        testing.assert_array_almost_equal(tdot[i], true_dot)
Exemple #18
0
def test_unfolding_dot_khatri_rao():
    """Test for unfolding_dot_khatri_rao
    
    Check against other version check sparse safe
    """
    shape = (10, 10, 10, 4)
    rank = 5
    tensor = tl.tensor(np.random.random(shape))
    weights, factors = random_cp(shape=shape, rank=rank, 
                                      full=False, normalise_factors=True)
    
    for mode in range(tl.ndim(tensor)):
        # Version forming explicitely the khatri-rao product
        unfolded = unfold(tensor, mode)
        kr_factors = khatri_rao(factors, weights=weights, skip_matrix=mode)
        true_res = tl.dot(unfolded, kr_factors)

        # Efficient sparse-safe version
        res = unfolding_dot_khatri_rao(tensor, (weights, factors), mode)
        assert_array_almost_equal(true_res, res, decimal=3)
Exemple #19
0
def test_FactorizedLinear(factorization):
    random_state = 12345
    rng = tl.check_random_state(random_state)
    batch_size = 2
    in_features = 9
    in_shape = (3, 3)
    out_features = 16
    out_shape = (4, 4)
    data = tl.tensor(rng.random_sample((batch_size, in_features)))

    # Creat from a tensor factorization
    tensor = TensorizedMatrix.new(out_shape,
                                  in_shape,
                                  rank='same',
                                  factorization=factorization)
    tensor.normal_()
    fc = nn.Linear(in_features, out_features, bias=True)
    fc.weight.data = tensor.to_matrix()
    tfc = FactorizedLinear(in_shape,
                           out_shape,
                           rank='same',
                           factorization=tensor,
                           bias=True)
    tfc.bias.data = fc.bias
    res_fc = fc(data)
    res_tfc = tfc(data)
    testing.assert_array_almost_equal(res_fc, res_tfc, decimal=2)

    # Decompose an existing layer
    fc = nn.Linear(in_features, out_features, bias=True)
    tfc = FactorizedLinear.from_linear(fc, (3, 3), (4, 4), rank=34, bias=True)
    res_fc = fc(data)
    res_tfc = tfc(data)
    testing.assert_array_almost_equal(res_fc, res_tfc, decimal=2)

    # Multi-layer factorization
    fc1 = nn.Linear(in_features, out_features, bias=True)
    fc2 = nn.Linear(in_features, out_features, bias=True)
    tfc = FactorizedLinear.from_linear_list([fc1, fc2],
                                            in_shape,
                                            out_shape,
                                            rank=38,
                                            bias=True)
    ## Test first parametrized conv
    res_fc = fc1(data)
    res_tfc = tfc[0](data)
    testing.assert_array_almost_equal(res_fc, res_tfc, decimal=2)
    ## Test second parametrized conv
    res_fc = fc2(data)
    res_tfc = tfc[1](data)
    testing.assert_array_almost_equal(res_fc, res_tfc, decimal=2)
Exemple #20
0
def test_FactorizedEmbedding(factorization,dims):

    
    
    NUM_EMBEDDINGS,EMBEDDING_DIM=dims
    BATCH_SIZE = 3

    #create factorized embedding
    factorized_embedding = FactorizedEmbedding(NUM_EMBEDDINGS,EMBEDDING_DIM,factorization=factorization)

    #make test embedding of same shape and same weight
    test_embedding = torch.nn.Embedding(factorized_embedding.weight.shape[0],factorized_embedding.weight.shape[1]) 
    test_embedding.weight.data.copy_(factorized_embedding.weight.to_matrix().detach())
    
    #create batch and test using all entries (shuffled since entries may not be sorted)
    batch = torch.randperm(NUM_EMBEDDINGS)#.view(-1,1)
    normal_embed = test_embedding(batch)
    factorized_embed = factorized_embedding(batch)
    testing.assert_array_almost_equal(normal_embed,factorized_embed,decimal=2)
    
    #split batch into tensor with first dimension 3
    batch = torch.randperm(NUM_EMBEDDINGS)
    split_size = NUM_EMBEDDINGS//5
   
    split_batch = [batch[:1*split_size],batch[1*split_size:2*split_size],batch[3*split_size:4*split_size]]

    split_batch = torch.stack(split_batch,0)

    normal_embed = test_embedding(split_batch)
    factorized_embed = factorized_embedding(split_batch)
    testing.assert_array_almost_equal(normal_embed,factorized_embed,decimal=2)

    #BlockTT has no init_from_matrix, so skip that test
    if factorization=='BlockTT':
        return

    del factorized_embedding

    #init from test layer which is low rank
    factorized_embedding = FactorizedEmbedding.from_embedding(test_embedding,factorization=factorization,rank=8)
    
    #test using same batch as before, only test that shapes match
    normal_embed = test_embedding(batch)
    factorized_embed = factorized_embedding(batch)
    testing.assert_array_almost_equal(normal_embed.shape,factorized_embed.shape,decimal=2)
def test_cp_mode_dot():
    """Test for cp_mode_dot
    
        We will compare cp_mode_dot 
        (which operates directly on decomposed tensors)
        with mode_dot (which operates on full tensors)
        and check that the results are the same.
    """
    rng = tl.check_random_state(12345)
    shape = (5, 4, 6)
    rank = 3
    cp_ten = random_cp(shape, rank=rank, orthogonal=True, full=False)
    full_tensor = tl.cp_to_tensor(cp_ten)
    # matrix for mode 1
    matrix = tl.tensor(rng.random_sample((7, shape[1])))
    # vec for mode 2
    vec = tl.tensor(rng.random_sample(shape[2]))

    # Test cp_mode_dot with matrix
    res = cp_mode_dot(cp_ten, matrix, mode=1, copy=True)
    # Note that if copy=True is not respected, factors will be changes
    # And the next test will fail
    res = tl.cp_to_tensor(res)
    true_res = mode_dot(full_tensor, matrix, mode=1)
    assert_array_almost_equal(true_res, res)

    # Check that the data was indeed copied
    rec = tl.cp_to_tensor(cp_ten)
    assert_array_almost_equal(full_tensor, rec)

    # Test cp_mode_dot with vec
    res = cp_mode_dot(cp_ten, vec, mode=2, copy=True)
    res = tl.cp_to_tensor(res)
    true_res = mode_dot(full_tensor, vec, mode=2)
    assert_equal(res.shape, true_res.shape)
    assert_array_almost_equal(true_res, res)
Exemple #22
0
def single_conv_test(factorization,
                     implementation,
                     order=2,
                     rank=0.5,
                     rng=None,
                     input_channels=4,
                     output_channels=5,
                     kernel_size=3,
                     batch_size=1,
                     activation_size=(8, 7),
                     device='cpu'):
    rng = tl.check_random_state(rng)
    input_shape = (batch_size, input_channels) + activation_size
    kernel_shape = (output_channels, input_channels) + (kernel_size, ) * order

    if rank is None:
        rank = max(kernel_shape)

    if order == 1:
        FullConv = nn.Conv1d
    elif order == 2:
        FullConv = nn.Conv2d
    elif order == 3:
        FullConv = nn.Conv3d

    # Factorized input tensor
    factorization_shape = kernel_shape_to_factorization_shape(
        factorization, kernel_shape)
    decomposed_weights = FactorizedTensor.new(
        shape=factorization_shape, rank=rank,
        factorization=factorization).normal_(0, 1)
    full_weights = tensor_to_kernel(factorization,
                                    decomposed_weights.to_tensor().to(device))
    data = torch.tensor(rng.random_sample(input_shape),
                        dtype=torch.float32).to(device)

    # PyTorch regular Conv
    conv = FullConv(input_channels,
                    output_channels,
                    kernel_size,
                    bias=True,
                    padding=1)
    true_bias = conv.bias.data
    conv.weight.data = full_weights

    # Factorized conv
    fact_conv = FactorizedConv.from_factorization(
        decomposed_weights,
        implementation=implementation,
        bias=true_bias,
        padding=1)

    # First check it has the correct implementation
    msg = f'Created implementation={implementation} but {fact_conv.implementation} was created.'
    assert fact_conv.implementation == implementation, msg

    # Check that it gives the same result as the full conv
    true_res = conv(data)
    res = fact_conv(data)
    msg = f'{fact_conv.__class__.__name__} does not give same result as {FullConv.__class__.__name__}.'
    assert_array_almost_equal(true_res, res, decimal=4, err_msg=msg)

    # Check that the parameters of the decomposition are transposed back correctly
    decomposed_weights, bias = fact_conv.weight, fact_conv.bias
    rec = tensor_to_kernel(factorization, decomposed_weights.to_tensor())
    msg = msg = f'{fact_conv.__class__.__name__} does not return the decomposition it was constructed with.'
    assert_array_almost_equal(rec, full_weights, err_msg=msg)
    msg = msg = f'{fact_conv.__class__.__name__} does not return the bias it was constructed with.'
    assert_array_almost_equal(bias, true_bias, err_msg=msg)

    conv = FullConv(input_channels,
                    output_channels,
                    kernel_size,
                    bias=True,
                    padding=1)
    conv.weight.data.uniform_(-1, 1)
    fact_conv = FactorizedConv.from_conv(
        conv, rank=30, factorization=factorization
    )  #, decomposition_kwargs=dict(init='svd', l2_reg=1e-5))
    true_res = conv(data)
    res = fact_conv(data)
    msg = f'{fact_conv.__class__.__name__} does not give same result as {FullConv.__class__.__name__}.'
    assert_array_almost_equal(true_res, res, decimal=2, err_msg=msg)