Пример #1
0
def test_cp_decomposition(max_d_size, num_dims, d_interval, max_rank,
                          rank_interval, num_samples):
    """
    Purpose:
        benchmark the cp decomposition of a randomly generated CP decomposable tensor
        run tests using hypercube tensors for consistency
    :param max_d_size: maximum dimension size that each mode will reach
    :param num_dims: number of dimensions to test along
    :param d_interval: size of interval to jump by for each data point
    :param max_rank: maximum rank to test against
    :param rank_interval: size of interval for rank to jump by for each data point
    :param num_samples: number of items to sample over for each data point
    """
    rand_state = 5
    for r in range(1, max_rank, rank_interval):
        dims = []
        times = []
        for d in range(2, max_d_size, d_interval):
            time_sum = 0
            print(d)
            for n in range(0, num_samples):
                shp = tuple([d] * num_dims)
                t = rnd.cp_tensor(shp, r, full=True, random_state=rand_state)
                start = time.time()
                parafac(t, rank=r, tol=10e-6, random_state=rand_state)
                end = time.time()
                time_sum += end - start
            dims.append(d)
            times.append(time_sum / num_samples)
        plt.plot(dims, times, label='r = ' + str(r))
    plt.xlabel("Matrix dimension (square matrix)")
    plt.ylabel("Time elapsed (sec)")
    plt.legend(loc='best')
    plt.savefig('test_cp_decomposition.eps', format='eps', dpi=1000)
Пример #2
0
    def get_cp_factors(self):

        if self.pretrained is not None:
            mat_dict = scipy.io.loadmat(self.pretrained)
            
            if mat_dict['R'][0][0] != self.rank:
                print('WRONG FACTORS, do not correspond to desired rank')
                
            PU_z, PU_cout, PU_cin = [Ui[0] for Ui in mat_dict['P_bals_epc_U']]
            Plmbda = mat_dict['P_bals_epc_lambda'].ravel()
            
            f_cin = np.array(PU_cin) 
            f_cout = np.array(PU_cout)
            f_z = (np.array(PU_z)*(Plmbda))
            
        else:
            bias = self.bias
            if isinstance(self.layer, nn.Sequential):
                # Tensorly case
                _, (f_cout, f_cin, f_z) = parafac(kruskal_to_tensor((None, self.weight)),
                                                  self.rank,
                                                  n_iter_max=5000,
                                                  init='random',
                                                  tol=1e-8,
                                                  svd = None,
                                                  cvg_criterion = 'rec_error') 
                
            else:                  
                  # Tensorly case
                _, (f_cout, f_cin, f_z) = parafac(self.weight,
                                                  self.rank,
                                                  n_iter_max=5000,
                                                  init='random',
                                                  tol=1e-8,
                                                  svd = None,
                                                  cvg_criterion = 'rec_error')
                
#         # Reshape factor matrices to 4D weight tensors
#         f_cin: (cin, rank) -> (rank, cin, 1, 1)
#         f_z: (z, rank) -> (rank, 1, h, w)
#         f_cout: (count, rank) -> (count, rank, 1, 1)
        
        # Pytorh case
        f_cin = f_cin.t().unsqueeze_(2).unsqueeze_(3).contiguous()
        f_z = torch.einsum('hwr->rhw', f_z.resize_((*self.kernel_size, self.rank))\
                          ).unsqueeze_(1).contiguous()
        f_cout = f_cout.unsqueeze_(2).unsqueeze_(3).contiguous()

        return [f_cin, f_z,  f_cout], [None, None,  bias]
Пример #3
0
 def loss(self, *views):
     m = views[0].size(0)
     views = _demean(*views)
     covs = [
         (1 - self.r) * view.T @ view
         + self.r * torch.eye(view.size(1), device=view.device)
         for view in views
     ]
     whitened_z = [
         view @ mat_pow(cov, -0.5, self.eps) for view, cov in zip(views, covs)
     ]
     # The idea here is to form a matrix with M dimensions one for each view where at index
     # M[p_i,p_j,p_k...] we have the sum over n samples of the product of the pth feature of the
     # ith, jth, kth view etc.
     for i, el in enumerate(whitened_z):
         # To achieve this we start with the first view so M is nxp.
         if i == 0:
             M = el
         # For the remaining views we expand their dimensions to match M i.e. nx1x...x1xp
         else:
             for _ in range(len(M.size()) - 1):
                 el = torch.unsqueeze(el, 1)
             # Then we perform an outer product by expanding the dimensionality of M and
             # outer product with the expanded el
             M = torch.unsqueeze(M, -1) @ el
     M = torch.mean(M, 0)
     tl.set_backend("pytorch")
     M_parafac = parafac(
         M.detach(), self.latent_dims, verbose=False, normalize_factors=True
     )
     M_parafac.weights = 1
     M_hat = cp_to_tensor(M_parafac)
     return torch.linalg.norm(M - M_hat)
Пример #4
0
 def decompose_moment3(self):
     """
     Performs CP decomposition on third moment.
     :return:
     """
     return np.sort(np.array(parafac(self.whitened_moment3,
                                     self.n_topics)))[::-1]
Пример #5
0
def test(G, verbose=False, compare_parafac=False):
    print "rank of G:", G.rank
    print "G:"
    print G.get_full_tensor()
    print ""

    c = Compressor(accuracy=0.0001,
                   n_iter_max=1000,
                   min_error_dec=1e-2,
                   display_progress=verbose)
    F, info = c.compress(G)
    print "rank of F:", F.rank
    print "number of iter:", info.n_iter
    print "where the rank is increased:", info.iter_with_rank_inc

    print "F:"
    print F.get_full_tensor()
    print ""

    if verbose:
        print "lambdas in F:"
        print F.lambdas
        print "factors in F:"
        for f in F.factors:
            print f
        print ""

    if compare_parafac:
        G_tl = tl.tensor(G.get_full_tensor())
        factors_tl = parafac(G_tl, rank=2)
        for f in factors_tl:
            print f
        print ""
        print tl.kruskal_to_tensor(factors_tl)
        print ""
Пример #6
0
def cp_filter(imgarray, cp_rank):
    """
    imgarray is 3-d numpy array of png image
    """
    imgtensor = tl.tensor(imgarray)
    factors = parafac(imgtensor, rank=cp_rank, init='random', tol=10e-6)
    pass
Пример #7
0
def torch_cp_decomp(W, rank):
    last, first, vertical, horizontal = parafac(W, rank=rank, init='random')
    sr = first.t_()
    rt = last
    rr = torch.stack([vertical.narrow(1, i, 1) @ torch.t(horizontal).narrow(0, i, 1) for i in range(rank)]).unsqueeze_(
        1)
    return [sr, rr, rt]
Пример #8
0
 def fit(self, *views: Tuple[np.ndarray, ...], ):
     if self.c is None:
         self.c = [0] * len(views)
     assert (len(self.c) == len(views)), 'c requires as many values as #views'
     z = self.demean_data(*views)
     n = z[0].shape[0]
     covs = [(1 - self.c[i]) * view.T @ view / (1 - n) + self.c[i] * np.eye(view.shape[1]) for i, view in
             enumerate(z)]
     covs_invsqrt = [np.linalg.inv(sqrtm(cov)) for cov in covs]
     z = [z_ @ cov_invsqrt for z_, cov_invsqrt in zip(z, covs_invsqrt)]
     for i, el in enumerate(z):
         if i == 0:
             M = el
         else:
             for _ in range(len(M.shape) - 1):
                 el = np.expand_dims(el, 1)
             M = np.expand_dims(M, -1) @ el
     M = np.mean(M, 0)
     # for i, cov_invsqrt in enumerate(covs_invsqrt):
     #    M = np.tensordot(M, cov_invsqrt, axes=[[0], [0]])
     tl.set_backend('numpy')
     M_parafac = parafac(M, self.latent_dims, verbose=True)
     self.weights_list = [cov_invsqrt @ fac for i, (view, cov_invsqrt, fac) in
                          enumerate(zip(z, covs_invsqrt, M_parafac.factors))]
     self.score_list = [view @ self.weights_list[i] for i, view in enumerate(z)]
     self.weights_list = [weights / np.linalg.norm(score) for weights, score in
                          zip(self.weights_list, self.score_list)]
     self.score_list = [view @ self.weights_list[i] for i, view in enumerate(z)]
     self.train_correlations = self.predict_corr(*views)
     return self
Пример #9
0
 def fit(
     self,
     *views: np.ndarray,
 ):
     self.n_views = len(views)
     self.check_params()
     assert (len(
         self.c) == len(views)), 'c requires as many values as #views'
     train_views, covs_invsqrt = self.setup_tensor(*views)
     for i, el in enumerate(train_views):
         if i == 0:
             M = el
         else:
             for _ in range(len(M.shape) - 1):
                 el = np.expand_dims(el, 1)
             M = np.expand_dims(M, -1) @ el
     M = np.mean(M, 0)
     tl.set_backend('numpy')
     M_parafac = parafac(M, self.latent_dims, verbose=True)
     self.alphas = [
         cov_invsqrt @ fac for i, (view, cov_invsqrt, fac) in enumerate(
             zip(train_views, covs_invsqrt, M_parafac.factors))
     ]
     self.score_list = [
         view @ self.alphas[i] for i, view in enumerate(train_views)
     ]
     self.weights_list = [
         weights / np.linalg.norm(score)
         for weights, score in zip(self.alphas, self.score_list)
     ]
     self.score_list = [
         view @ self.weights_list[i] for i, view in enumerate(train_views)
     ]
     self.train_correlations = self.predict_corr(*views)
     return self
Пример #10
0
def factorize_dense_cp(tensor, params):
    input_shape, output_shape, rank = params["input_shape"], params[
        "output_shape"], params["rank"]

    shape = tensor.shape
    assert len(shape) == 2, "The tensor should be 2-order."

    order = len(input_shape)
    assert len(output_shape) == order, \
      "The lengths of input and output shape should match."

    assert shape[0] == np.prod(input_shape), \
      "The product of input_shape should match 1st-dimension of the tensor."
    assert shape[1] == np.prod(output_shape), \
      "The product of output_shape should match 2nd-dimension of the tensor."

    tensor = np.reshape(tensor, input_shape + output_shape)
    tensor = np.transpose(
        tensor,
        axes=[
            val for pair in zip(range(order), range(order, 2 * order))
            for val in pair
        ])
    tensor = np.reshape(tensor, np.multiply(input_shape, output_shape))

    factors = parafac(tensor, rank)
    for l in range(order):
        factors[l] = np.reshape(np.transpose(factors[l]),
                                [rank, input_shape[l], output_shape[l]])

    return factors
Пример #11
0
 def decomposition_interact_re_button(self, foo):
     dataset = self.EEMstack_cw[self.datlist_cw.index(
         self.range1.value):self.datlist_cw.index(self.range2.value) + 1]
     if self.decomposition_method_list.value == 'parafac':
         factors = parafac(dataset, rank=self.rank_display.value)
     elif self.decomposition_method_list.value == 'non_negative_parafac':
         factors = non_negative_parafac(dataset,
                                        rank=self.rank_display.value)
     elif self.decomposition_method_list.value == 'test_function':
         factors = non_negative_parafac(dataset,
                                        rank=self.rank_display.value,
                                        fixed_modes=[0, 1],
                                        init="random")
     I_0 = factors[1][0]
     J_0 = factors[1][1]
     K_0 = factors[1][2]
     decomposition_reconstruction_interact(
         I_0,
         J_0,
         K_0,
         self.EEMstack_cw[self.datlist_cw.index(self.data_to_view.value)],
         self.Em_range_cw,
         self.Ex_range_cw,
         self.datlist_cw[self.datlist_cw.index(self.range1.value):self.
                         datlist_cw.index(self.range2.value) + 1],
         self.data_to_view.value,
         crange=self.crange_cw.value)
Пример #12
0
def do_tensor(input_movie_ids):
    # read the pickle file that contains tensor
    actor_movie_year_3d_matrix = cPickle.load(
        open("actor_movie_genre_tensor.pkl", "rb"))
    actor_movie_year_array = np.array(actor_movie_year_3d_matrix)
    # perform cp decomposition
    decomposed = parafac(actor_movie_year_array,
                         no_of_components,
                         init='random')

    mlmovies = util.read_mlmovies()
    mlmovies = mlmovies.loc[mlmovies['year'] >= util.movie_year_for_tensor]
    movies_list = mlmovies.movieid.unique()

    # data frame for movie factor matrix from cp decomposition
    decomposed_movies_df = pd.DataFrame(decomposed[1], index=movies_list)
    # dataframe containing only input movies
    input_movie_df = decomposed_movies_df.loc[input_movie_ids]

    output_movies = {}
    # finding cosine similarity of each movie vector with the input movie vector and fetching the top 5 values
    for index, movie in decomposed_movies_df.iterrows():
        cosine_sum = 0
        order = 1
        for j, input_movie in input_movie_df.iterrows():
            cosine_sum += (1 - cosine(movie, input_movie)) * order
            order -= order_factor
        output_movies[index] = cosine_sum
    return output_movies, decomposed_movies_df, movies_list
Пример #13
0
    def __init__(self, num_filters, filter_h, filter_w, image_channels, rank):

        self.image_channels = image_channels
        self.num_filters = num_filters
        self.filter_h = filter_h
        self.filter_w = filter_w
        self.rank = rank

        self.filters = np.random.randn(num_filters, filter_h, filter_w,
                                       image_channels) / (filter_h * filter_w)

        tensor = tl.tensor(self.filters)
        ##initialize the cp-decomposed convolutional factors
        self.factors = parafac(tensor, rank)
        self.filters_recon = tl.kruskal_to_tensor((self.factors))

        ##initialize moments and parameters for adam
        self.v0 = np.zeros(self.factors[0].shape)
        self.v1 = np.zeros(self.factors[1].shape)
        self.v2 = np.zeros(self.factors[2].shape)
        self.v3 = np.zeros(self.factors[3].shape)
        self.v = [self.v0, self.v1, self.v2, self.v3]

        self.s0 = np.zeros(self.factors[0].shape)
        self.s1 = np.zeros(self.factors[1].shape)
        self.s2 = np.zeros(self.factors[2].shape)
        self.s3 = np.zeros(self.factors[3].shape)
        self.s = [self.s0, self.s1, self.s2, self.s3]

        self.beta1 = 0.99
        self.beta2 = 0.999
    def linear_decomp(self, layer):
        W = layer.weight.data
        ranks = self.estimate_rank(W)
        print('Ranks:', ranks)
        if ranks == 0:
            return layer
        last, first = [None for _ in range(2)]
        if self.decomp_type == 'tucker':
            first, [last] = partial_tucker(W,
                                           modes=[0],
                                           ranks=ranks,
                                           init='svd')
            first_layer = nn.Linear(first.shape[1], first.shape[0], bias=False)
            first_layer.weight.data = first
            last_layer = nn.Linear(last.shape[1], last.shape[0], bias=True)
            last_layer.weight.data = last
        elif self.decomp_type == 'cp':
            weights, [last, first] = parafac(W, rank=ranks, init='random')
            first_layer = nn.Linear(first.shape[0], first.shape[1], bias=False)
            first_layer.weight.data = first.t()
            last_layer = nn.Linear(last.shape[1], last.shape[0], bias=True)
            last_layer.weight.data = last

        if layer.bias is not None:
            last_layer.bias.data = layer.bias.data

        new_layer = nn.Sequential(first_layer, last_layer)

        return new_layer
Пример #15
0
def grouping_use_cp_on_actor_tensor(actor_movie_year_tensor, amy_info):
    # print(actor_movie_year_tensor)
    U = actor_movie_year_tensor
    T = tensor(U.reshape((U.shape[0], U.shape[1], U.shape[2])))
    # Compute rank-5 CP decomposition of Tensor with ALS

    P = decomposition.parafac(T, 5, init="random")

    # Result is a decomposed tensor stored as a Kruskal operator in P

    #fit: float
    #   Fit of the factorization compared to Tensor

    #itr : int
    #   Number of iterations that were needed until convergence

    #exectimes : ndarray of floats
    #   Time needed for each single iteration

    X = P[0].asnumpy()
    Y = P[1].asnumpy()
    Z = P[2].asnumpy()
    print("Top 5 latent sementics for Actor :")
    print(X)
    print("Top 5 latent sementics for Movie :")
    print(Y)
    print("Top 5 latent sementics for Year :")
    print(Z)
    print("Actor Groupings:")
    create_n_groupings(X, amy_info[0], 5)
    print("Movie Groupings:")
    create_n_groupings(Y, list(amy_info[2].keys()), 5)
    print("Year Groupings:")
    create_n_groupings(Z, amy_info[4], 5)
Пример #16
0
def grouping_use_cp_on_tag_tensor(tag_movie_rating, tmr_info):

    U = tag_movie_rating
    # T = vec_to_tensor(U, (U.shape[0], U.shape[1], U.shape[2]))
    T = tensor(U.reshape((U.shape[0], U.shape[1], U.shape[2])))
    # Compute rank-5 CP decomposition of Tensor with ALS and for Hosvd method replace init as nvecs
    P = decomposition.parafac(T, 5, init="random")

    # Result is a decomposed tensor stored as a Kruskal operator in P

    # fit: float
    #   Fit of the factorization compared to Tensor

    # itr : int
    #   Number of iterations that were needed until convergence

    # exectimes : ndarray of floats
    #   Time needed for each single iteration

    X = P[0].asnumpy()
    Y = P[1].asnumpy()
    Z = P[2].asnumpy()

    print("Top 5 latent sementics for Tag :")
    print(X)
    print("Top 5 latent sementics for Movie :")
    print(Y)
    print("Top 5 latent sementics for Rating :")
    print(Z)
    print("Tag Groups")
    create_n_groupings(X, tmr_info[0], 5)
    print("Movie Groups")
    create_n_groupings(Y, tmr_info[2], 5)
    print(" Rating Groups:")
    create_n_groupings(Z, tmr_info[4], 5)
Пример #17
0
def factorize_conv2d_rcp(tensor, params):
  input_shape, output_shape, rank = params["input_shape"], params["output_shape"], params["rank"]

  shape = tensor.shape
  assert len(shape) == 4, "The tensor should be 4-order."

  order = len(input_shape) 
  assert len(output_shape) == order, \
    "The lengths of input shape and output shape should match."

  assert shape[2] == np.prod(input_shape), \
    "The product of input shape should match the 3rd-dimension of the tensor."
  assert shape[3] == np.prod(output_shape), \
    "The product of output shape should match the 4th-dimension of the tensor."

  if shape[0] == 1:
    tensor = np.reshape(tensor, input_shape + output_shape)
    tensor = np.transpose(tensor, axes = [val for pair in zip(range(order), range(order, 2*order)) for val in pair])
    tensor = np.reshape(tensor, np.multiply(input_shape, output_shape))
  else:
    tensor = np.reshape(tensor, [shape[0] * shape[1]] + input_shape + output_shape)
    tensor = np.transpose(tensor, axes = [0] + [val for pair in zip(range(1, 1+order), range(1+order, 1+2*order)) for val in pair])
    tensor = np.reshape(tensor, [shape[0] * shape[1]] + list(np.multiply(input_shape, output_shape)))

  dense_factors = parafac(tensor, rank)

  if shape[0] == 1:
    conv_factor = []
  else:
    dense_factors, conv_factor = dense_factors[1:], np.reshape(dense_factors[0], [shape[0], shape[1], rank])

  for l in range(order):
    dense_factors[l] = np.reshape(np.transpose(dense_factors[l]), [rank, input_shape[l], output_shape[l]])

  return dense_factors, conv_factor
Пример #18
0
def tensorDecom(lst):
    lst2 = []
    for i in lst:
        factors, weights, errors = decomposition.parafac(i, 1)
        factors = factors.reshape(factors.shape[0])
        lst2.append(factors)

    return np.asarray(lst2)
Пример #19
0
def test_randomized_svd():
    """ Imports the tensor of union of all genes among 6 cell lines and performs parafac. """
    tensor, _, _ = form_tensor()
    tInit = initialize_cp(tensor, 7)
    tfac = parafac(tensor, rank=7, init=tInit, linesearch=True, n_iter_max=2)
    r2x = 1 - tl.norm(
        (tl.cp_to_tensor(tfac) - tensor))**2 / (tl.norm(tensor))**2
    assert r2x > 0
Пример #20
0
def cp_decomposition_conv_layer(layer, rank):
    """ Gets a conv layer and a target rank, 
        returns a nn.Sequential object with the decomposition """

    # Perform CP decomposition on the layer weight tensorly.
    _, (last, first, vertical, horizontal) = parafac(layer.weight.data,
                                                     rank=rank,
                                                     init='svd')

    pointwise_s_to_r_layer = torch.nn.Conv2d(in_channels=first.shape[0],
                                             out_channels=first.shape[1],
                                             kernel_size=1,
                                             stride=1,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=False)

    depthwise_vertical_layer = torch.nn.Conv2d(in_channels=vertical.shape[1],
                                               out_channels=vertical.shape[1],
                                               kernel_size=(vertical.shape[0],
                                                            1),
                                               stride=1,
                                               padding=(layer.padding[0], 0),
                                               dilation=layer.dilation,
                                               groups=vertical.shape[1],
                                               bias=False)

    depthwise_horizontal_layer = \
        torch.nn.Conv2d(in_channels=horizontal.shape[1],
                        out_channels=horizontal.shape[1],
                        kernel_size=(1, horizontal.shape[0]), stride=layer.stride,
                        padding=(0, layer.padding[0]),
                        dilation=layer.dilation, groups=horizontal.shape[1], bias=False)

    pointwise_r_to_t_layer = torch.nn.Conv2d(in_channels=last.shape[1],
                                             out_channels=last.shape[0],
                                             kernel_size=1,
                                             stride=1,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=True)

    pointwise_r_to_t_layer.bias.data = layer.bias.data

    depthwise_horizontal_layer.weight.data = \
        torch.transpose(horizontal, 1, 0).unsqueeze(1).unsqueeze(1)
    depthwise_vertical_layer.weight.data = \
        torch.transpose(vertical, 1, 0).unsqueeze(1).unsqueeze(-1)
    pointwise_s_to_r_layer.weight.data = \
        torch.transpose(first, 1, 0).unsqueeze(-1).unsqueeze(-1)
    pointwise_r_to_t_layer.weight.data = last.unsqueeze(-1).unsqueeze(-1)

    new_layers = [
        pointwise_s_to_r_layer, depthwise_vertical_layer,
        depthwise_horizontal_layer, pointwise_r_to_t_layer
    ]

    return nn.Sequential(*new_layers)
Пример #21
0
def cp_decompose_conv(layer, rank=None, criterion=cp_rank):
    """ Gets a conv layer and a target rank, 
        returns a nn.Sequential object with the decomposition """

    if rank is None or rank == -1:
        rank = criterion(layer)
    '''
    # Sanity Check
    if (rank**2 >= conv_layer.in_channels * conv_layer.out_channels):
        print("(rank**2 >= conv_layer.in_channels * conv_layer.out_channels")
        continue
    '''

    # Perform CP decomposition on the layer weight tensorly.
    last, first, vertical, horizontal = \
        parafac(layer.weight.data, rank=rank, init='svd')[1]

    pointwise_s_to_r_layer = torch.nn.Conv2d(in_channels=first.shape[0], \
            out_channels=first.shape[1], kernel_size=1, stride=1, padding=0,
            dilation=layer.dilation, bias=False)

    depthwise_vertical_layer = torch.nn.Conv2d(in_channels=vertical.shape[1],
                                               out_channels=vertical.shape[1],
                                               kernel_size=(vertical.shape[0],
                                                            1),
                                               stride=1,
                                               padding=(layer.padding[0], 0),
                                               dilation=layer.dilation,
                                               groups=vertical.shape[1],
                                               bias=False)

    depthwise_horizontal_layer = \
        torch.nn.Conv2d(in_channels=horizontal.shape[1], \
            out_channels=horizontal.shape[1],
            kernel_size=(1, horizontal.shape[0]), stride=layer.stride,
            padding=(0, layer.padding[0]),
            dilation=layer.dilation, groups=horizontal.shape[1], bias=False)

    pointwise_r_to_t_layer = torch.nn.Conv2d(in_channels=last.shape[1], \
            out_channels=last.shape[0], kernel_size=1, stride=1,
            padding=0, dilation=layer.dilation, bias=True)

    if layer.bias is not None:
        pointwise_r_to_t_layer.bias.data = layer.bias.data

    depthwise_horizontal_layer.weight.data = \
        torch.transpose(horizontal, 1, 0).unsqueeze(1).unsqueeze(1)
    depthwise_vertical_layer.weight.data = \
        torch.transpose(vertical, 1, 0).unsqueeze(1).unsqueeze(-1)
    pointwise_s_to_r_layer.weight.data = \
        torch.transpose(first, 1, 0).unsqueeze(-1).unsqueeze(-1)
    pointwise_r_to_t_layer.weight.data = last.unsqueeze(-1).unsqueeze(-1)

    new_layers = [pointwise_s_to_r_layer, depthwise_vertical_layer, \
                    depthwise_horizontal_layer, pointwise_r_to_t_layer]

    return nn.Sequential(*new_layers)
Пример #22
0
def cp_decomposition(layer, rank, device):

    if isinstance(rank, int):
        ranks = rank
    elif rank == 'VBMF':
        ranks = estimate_ranks(layer)

    last, first, vertical, horizontal = parafac(
        layer.weight.data.cpu().numpy(), rank=ranks, init='random')

    s_to_r_layer = nn.Conv2d(in_channels=first.shape[0],
                             out_channels=first.shape[1],
                             kernel_size=1,
                             padding=0,
                             bias=False)

    r_to_r_layer = nn.Conv2d(in_channels=ranks,
                             out_channels=ranks,
                             kernel_size=vertical.shape[0],
                             stride=layer.stride,
                             padding=layer.padding,
                             dilation=layer.dilation,
                             groups=ranks,
                             bias=False)

    if layer.bias is not None:
        r_to_t_layer = torch.nn.Conv2d(in_channels=last.shape[1],
                                       out_channels=last.shape[0],
                                       kernel_size=1,
                                       stride=1,
                                       padding=0,
                                       dilation=layer.dilation,
                                       bias=True)
        r_to_t_layer.bias.data = layer.bias.data
    else:
        r_to_t_layer = torch.nn.Conv2d(in_channels=last.shape[1],
                                       out_channels=last.shape[0],
                                       kernel_size=1,
                                       stride=1,
                                       padding=0,
                                       dilation=layer.dilation,
                                       bias=False)

    sr = first.t_().unsqueeze_(-1).unsqueeze_(-1)
    rt = last.unsqueeze_(-1).unsqueeze_(-1)
    rr = torch.stack([
        vertical.narrow(1, i, 1) @ torch.t(horizontal).narrow(0, i, 1)
        for i in range(rank)
    ]).unsqueeze_(1)

    s_to_r_layer.weight.data = sr
    r_to_t_layer.weight.data = rt
    r_to_r_layer.weight.data = rr

    new_layers = [s_to_r_layer, r_to_r_layer, r_to_t_layer]
    return new_layers
def cp_decomposition_conv_layer(layer, rank):
    l, f, v, h = parafac(layer.weight.data, rank=rank)[1]
    factors = [l, f, v, h]
    #print([f.shape for f in factors])

    pointwise_s_to_r_layer = torch.nn.Conv2d(in_channels=f.shape[0],
                                             out_channels=f.shape[1],
                                             kernel_size=1,
                                             stride=1,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=False)

    depthwise_vertical_layer = torch.nn.Conv2d(in_channels=v.shape[1],
                                               out_channels=v.shape[1],
                                               kernel_size=(v.shape[0], 1),
                                               stride=1,
                                               padding=(layer.padding[0], 0),
                                               dilation=layer.dilation,
                                               groups=v.shape[1],
                                               bias=False)

    depthwise_horizontal_layer = torch.nn.Conv2d(in_channels=h.shape[1],
                                                 out_channels=h.shape[1],
                                                 kernel_size=(1, h.shape[0]),
                                                 stride=layer.stride,
                                                 padding=(0, layer.padding[0]),
                                                 dilation=layer.dilation,
                                                 groups=h.shape[1],
                                                 bias=False)

    pointwise_r_to_t_layer = torch.nn.Conv2d(in_channels=l.shape[1],
                                             out_channels=l.shape[0],
                                             kernel_size=1,
                                             stride=1,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=True)

    pointwise_r_to_t_layer.bias.data = layer.bias.data
    depthwise_horizontal_layer.weight.data = torch.transpose(
        h, 1, 0).unsqueeze(1).unsqueeze(1)
    depthwise_vertical_layer.weight.data = torch.transpose(
        v, 1, 0).unsqueeze(1).unsqueeze(-1)
    pointwise_s_to_r_layer.weight.data = torch.transpose(
        f, 1, 0).unsqueeze(-1).unsqueeze(-1)
    pointwise_r_to_t_layer.weight.data = l.unsqueeze(-1).unsqueeze(-1)

    new_layers = [
        pointwise_s_to_r_layer, depthwise_vertical_layer,
        depthwise_horizontal_layer, pointwise_r_to_t_layer
    ]
    #for l in new_layers:
    #    print(l.weight.data.shape)

    return nn.Sequential(*new_layers)
Пример #24
0
    def learn_embedding(self,
                        graph=None,
                        edge_f=None,
                        is_weighted=False,
                        no_python=False):
        if not graph and not edge_f:
            raise Exception('graph/edge_f needed')
        if not graph:
            graph = graph_util.loadGraphFromEdgeListTxt(edge_f)

        t1 = time()
        nNodes = graph.number_of_nodes()
        nEdges = graph.number_of_edges()
        print('num nodes: ', nNodes)
        print('num edges: ', nEdges)
        S = nx.to_numpy_matrix(graph, nodelist=sorted(graph.nodes()))
        A = Normalizer(norm='l1').fit_transform(S)

        if self._d == None:
            self._d = 2 * self._K
        else:
            assert self._d == 2 * self._K

        # Tensorization
        md_array = np.zeros((nNodes, nNodes, self._K))
        int_res = A
        for i in range(self._K):
            md_array[:, :, i] = int_res
            int_res = int_res.dot(A)

        emb = np.zeros((nNodes, self._d))
        for i in range(self._K):
            print('Slab id: ', i)
            slab = np.reshape(md_array[:, :, i], (nNodes, nNodes, 1))
            XX = tl.tensor(slab)
            print('Tensor shape: ', XX.shape)
            factors = parafac(XX,
                              rank=self._R,
                              n_iter_max=self._n_iter,
                              init='random')  # random_state=123,
            source_emb = factors[0]
            target_emb = factors[1]
            proximity_emb = factors[2]
            print('Source emb shape: ', source_emb.shape)
            print('Target emb shape: ', target_emb.shape)
            print('Proximity emb shape: ', proximity_emb.shape)
            source_proximity_emb = np.dot(source_emb, proximity_emb.T)
            target_proximity_emb = np.dot(target_emb, proximity_emb.T)
            emb[:, [i, i + self._K]] = np.concatenate(
                (source_proximity_emb, target_proximity_emb), axis=1)

        self._X = emb
        print("Embedding shape: ", self._X.shape)

        t2 = time()
        return self._X, (t2 - t1)
def rank_search_parafac(tensor, rank_range):
    AIC = []
    for rank in range(1, rank_range + 1):
        factors = parafac(tensor, rank=rank)
        recon = tl.kruskal_to_tensor(factors)
        err = tensor - recon
        rank_AIC = 2 * tl.tenalg.inner(err, err) + 2 * rank
        AIC.append(rank_AIC)

    return AIC
Пример #26
0
    def from_tensor(cls, tensor, tensorized_row_shape, tensorized_column_shape, rank, n_matrices=(), init='random', **kwargs):
        n_matrices = _ensure_tuple(n_matrices)
        rank = tl.cp_tensor.validate_cp_rank(n_matrices + tensorized_row_shape + tensorized_column_shape, rank)

        with torch.no_grad():
            weights, factors = parafac(tensor, rank, **kwargs)
        weights = nn.Parameter(weights)
        factors = [nn.Parameter(f) for f in factors]

        return cls(weights, factors, tensorized_row_shape, tensorized_column_shape, rank, n_matrices)
Пример #27
0
    def init_from_tensor(self, tensor, l2_reg=1e-5, **kwargs):
        with torch.no_grad():
            weights, factors = parafac(tensor,
                                       self.rank,
                                       l2_reg=l2_reg,
                                       **kwargs)

        self.weights = nn.Parameter(weights)
        self.factors = FactorList([nn.Parameter(f) for f in factors])
        return self
Пример #28
0
    def _get_gaussians_from_kernel(self):

        try:
            x, y, z = parafac(self.psf, 1)
        except ValueError:
            __, (x, y, z) = parafac(self.psf, 1)

        gauss_params = np.abs(self._fit_gaussian(np.array(np.squeeze(x))))
        gauss_params[1] = gauss_params[2] * 12
        x = self._get_gaussian(gauss_params, self.scaling[0])

        gauss_params = np.abs(self._fit_gaussian(np.array(np.squeeze(y))))
        gauss_params[1] = gauss_params[2] * 12
        y = self._get_gaussian(gauss_params, self.scaling[1])

        gauss_params = np.abs(self._fit_gaussian(np.array(np.squeeze(z))))
        gauss_params[1] = gauss_params[2] * 12
        z = self._get_gaussian(gauss_params, self.scaling[2])

        return x, y, z
    def forward(self, x):
        y=None
        b, c, _, _ = x.size()
        for i in range(0, x.size()[0]):
            x_item = x[i, :, :, :]
            factors = parafac(x_item, rank=self.rank)
            y = torch.cat((y,factors[0].unsqueeze(0)),dim=0) if not y is None else factors[0].unsqueeze(0)

        y = self.rank_fc(y).view(b, c)
        y = self.fc(y).view(b, c, 1, 1)
        return x * y
Пример #30
0
    def from_tensor(cls, tensor, rank='same', **kwargs):
        shape = tensor.shape
        rank = tl.cp_tensor.validate_cp_rank(shape, rank)
        dtype = tensor.dtype

        with torch.no_grad():
            weights, factors = parafac(tensor.to(torch.float64), rank,
                                       **kwargs)

        return cls(nn.Parameter(weights.to(dtype)),
                   [nn.Parameter(f.to(dtype)) for f in factors])
Пример #31
0
    def _cp_decomposition(self, layer, rank, offline=False, filename=''):
        """ Gets a conv layer and a target rank, di
            returns a nn.Sequential object with the decomposition
            Args:
                layer: the conv layer to decompose
                rank: the rank of the CP-decomposition
                offline: bool, if true the weights will be loaded from the file
                         specified in file name
                filename: string, file from which we have to load the weights.

            Returns:
                The compressed 4 layers that substitutes the original one.
        """

        # Perform CP decomposition on the layer weight tensor.
        print('[Decomposer]: computing CP-decomposition of the layer {} with rank {}'.format(layer, rank))
        X = layer.weight.data.numpy()
        size = max(X.shape)

        # THIS SHOULD BE ENHANCED BY USING A SUBPROCESS CALL
        # WHICH CALLS THE MATLAB SCRIPT AND RETRIEVE THE RESULT
        if offline:
            last, first, vertical, horizontal = load_cpd_weights(filename)

        else:
            # SVD init leads to generally better overall compression.
            # However, it can stall for large matrices.
            if size >= 256:
                print("Init random")
                last, first, vertical, horizontal = parafac(
                    X, rank=rank, init='random')
            else:
                last, first, vertical, horizontal = parafac(X, rank=rank, init='svd')

        first_pointwise = torch.nn.Conv2d(in_channels=first.shape[0],
                                                 out_channels=first.shape[1],
                                                 kernel_size=1,
                                                 stride=layer.stride,
                                                 padding=0,
                                                 dilation=layer.dilation,
                                                 bias=False)

        separable_vertical = torch.nn.Conv2d(in_channels=vertical.shape[1],
                                                   out_channels=vertical.shape[1],
                                                   kernel_size=(
                                                       vertical.shape[0], 1),
                                                   stride=layer.stride,
                                                   padding=(layer.padding[0], 0),
                                                   dilation=layer.dilation,
                                                   groups=vertical.shape[1],
                                                   bias=False)

        separable_horizontal = torch.nn.Conv2d(in_channels=horizontal.shape[1],
                                                     out_channels=horizontal.shape[1],
                                                     kernel_size=(
                                                         1, horizontal.shape[0]),
                                                     stride=layer.stride,
                                                     padding=(0, layer.padding[0]),
                                                     dilation=layer.dilation,
                                                     groups=horizontal.shape[1],
                                                     bias=False)

        last_pointwise = torch.nn.Conv2d(in_channels=last.shape[1],
                                                 out_channels=last.shape[0],
                                                 kernel_size=1,
                                                 stride=layer.stride,
                                                 padding=0,
                                                 dilation=layer.dilation,
                                                 bias=True)
        last_pointwise.bias.data = layer.bias.data

        # Transpose dimensions back to what PyTorch expects
        separable_vertical_weights = np.expand_dims(np.expand_dims(
            vertical.transpose(1, 0), axis=1), axis=-1)
        separable_horizontal_weights = np.expand_dims(np.expand_dims(
            horizontal.transpose(1, 0), axis=1), axis=1)
        first_pointwise_weights = np.expand_dims(
            np.expand_dims(first.transpose(1, 0), axis=-1), axis=-1)
        last_pointwise_weights = np.expand_dims(np.expand_dims(
            last, axis=-1), axis=-1)

        set_layer_weights(separable_horizontal,
                          separable_horizontal_weights)
        set_layer_weights(separable_vertical,
                          separable_vertical_weights)
        set_layer_weights(first_pointwise,
                          first_pointwise_weights)
        set_layer_weights(last_pointwise,
                          last_pointwise_weights)

        return [first_pointwise, separable_vertical, separable_horizontal, last_pointwise]
Пример #32
0
def cp_decomposition_conv_layer_BN(layer, rank, matlab=False):
    """ Gets a conv layer and a target rank, 
        returns a nn.Sequential object with the decomposition """

    # Perform CP decomposition on the layer weight tensor.
    print(layer, rank)
    X = layer.weight.data.numpy()
    size = max(X.shape)

    if matlab:
        last, first, vertical, horizontal = load_cpd_weights(
            'dumps/TODO.mat')

    else:
        # using a random initializaer is better for very large matrices 
        # SVD is a bit quicker on smaller ones 
        if size >= 256:
            print("Init random")
            last, first, vertical, horizontal = parafac(
                X, rank=rank, init='random')
        else:
            last, first, vertical, horizontal = parafac(
                X, rank=rank, init='svd')

    pointwise_s_to_r_layer = torch.nn.Conv2d(in_channels=first.shape[0],
                                             out_channels=first.shape[1],
                                             kernel_size=1,
                                             stride=layer.stride,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=False)

    depthwise_vertical_layer = torch.nn.Conv2d(in_channels=vertical.shape[1],
                                               out_channels=vertical.shape[1],
                                               kernel_size=(
                                                   vertical.shape[0], 1),
                                               stride=layer.stride,
                                               padding=(layer.padding[0], 0),
                                               dilation=layer.dilation,
                                               groups=vertical.shape[1],
                                               bias=False)

    depthwise_horizontal_layer = torch.nn.Conv2d(in_channels=horizontal.shape[1],
                                                 out_channels=horizontal.shape[1],
                                                 kernel_size=(
                                                     1, horizontal.shape[0]),
                                                 stride=layer.stride,
                                                 padding=(0, layer.padding[0]),
                                                 dilation=layer.dilation,
                                                 groups=horizontal.shape[1],
                                                 bias=False)

    add_bias = True and layer.bias is not None or False and not layer.bias

    pointwise_r_to_t_layer = torch.nn.Conv2d(in_channels=last.shape[1],
                                             out_channels=last.shape[0],
                                             kernel_size=1,
                                             stride=layer.stride,
                                             padding=0,
                                             dilation=layer.dilation,
                                             bias=add_bias)
    if add_bias:
        pointwise_r_to_t_layer.bias.data = layer.bias.data

    # Transpose dimensions back to what PyTorch expects
    depthwise_vertical_layer_weights = np.expand_dims(np.expand_dims(
        vertical.transpose(1, 0), axis=1), axis=-1)
    depthwise_horizontal_layer_weights = np.expand_dims(np.expand_dims(
        horizontal.transpose(1, 0), axis=1), axis=1)
    pointwise_s_to_r_layer_weights = np.expand_dims(
        np.expand_dims(first.transpose(1, 0), axis=-1), axis=-1)
    pointwise_r_to_t_layer_weights = np.expand_dims(np.expand_dims(
        last, axis=-1), axis=-1)

    # Fill in the weights of the new layers
    depthwise_horizontal_layer.weight.data = \
        torch.from_numpy(np.float32(depthwise_horizontal_layer_weights))
    depthwise_vertical_layer.weight.data = \
        torch.from_numpy(np.float32(depthwise_vertical_layer_weights))
    pointwise_s_to_r_layer.weight.data = \
        torch.from_numpy(np.float32(pointwise_s_to_r_layer_weights))
    pointwise_r_to_t_layer.weight.data = \
        torch.from_numpy(np.float32(pointwise_r_to_t_layer_weights))

    # create BatchNorm layers wrt to decomposed layers weights
    bn_first = nn.BatchNorm2d(first.shape[1])
    bn_vertical = nn.BatchNorm2d(vertical.shape[1])
    bn_horizontal = nn.BatchNorm2d(horizontal.shape[1])
    bn_last = nn.BatchNorm2d(last.shape[0])

    new_layers = [pointwise_s_to_r_layer, bn_first, depthwise_vertical_layer, bn_vertical,
                  depthwise_horizontal_layer, bn_horizontal,  pointwise_r_to_t_layer,
                  bn_last]
    return nn.Sequential(*new_layers)
Пример #33
0
def cp_decomposition_conv_layer(layer, rank):
    """ Gets a conv layer and a target rank, 
        returns a nn.Sequential object with the decomposition """

    # Perform CP decomposition on the layer weight tensor. 
    print(layer, rank)
    X = layer.weight.data.numpy()
    size = max(X.shape)
    # Using the SVD init gives better results, but stalls for large matrices.
    if size >= 256:
        print("Init random")
        last, first, vertical, horizontal = parafac(X, rank=rank, init = 'random')
    else:
        last, first, vertical, horizontal = parafac(X, rank=rank, init = 'svd')

    pointwise_s_to_r_layer = torch.nn.Conv2d(in_channels = first.shape[0], \
            out_channels = first.shape[1],
            kernel_size = 1, \
            stride = layer.stride,
            padding = 0,
            dilation = layer.dilation,
            bias = False)

    depthwise_vertical_layer = torch.nn.Conv2d(in_channels = vertical.shape[1], \
            out_channels = vertical.shape[1],
            kernel_size = (vertical.shape[0], 1),
            stride = layer.stride,
            padding = (layer.padding[0], 0),
            dilation = layer.dilation,
            groups = vertical.shape[1],
            bias = False)

    depthwise_horizontal_layer = torch.nn.Conv2d(in_channels = horizontal.shape[1], \
            out_channels = horizontal.shape[1],
            kernel_size = (1, horizontal.shape[0]),
            stride = layer.stride,
            padding = (0, layer.padding[0]),
            dilation = layer.dilation,
            groups = horizontal.shape[1],
            bias = False)

    pointwise_r_to_t_layer = torch.nn.Conv2d(in_channels = last.shape[1], \
            out_channels = last.shape[0],
            kernel_size = 1, \
            stride = layer.stride,
            padding = 0,
            dilation = layer.dilation,
            bias = True)
    pointwise_r_to_t_layer.bias.data = layer.bias.data

    # Transpose dimensions back to what PyTorch expects
    depthwise_vertical_layer_weights = np.expand_dims(np.expand_dims(\
        vertical.transpose(1, 0), axis = 1), axis = -1)
    depthwise_horizontal_layer_weights = np.expand_dims(np.expand_dims(\
        horizontal.transpose(1, 0), axis = 1), axis = 1)
    pointwise_s_to_r_layer_weights = np.expand_dims(\
        np.expand_dims(first.transpose(1, 0), axis = -1), axis = -1)
    pointwise_r_to_t_layer_weights = np.expand_dims(np.expand_dims(\
        last, axis = -1), axis = -1)

    # Fill in the weights of the new layers
    depthwise_horizontal_layer.weight.data = \
        torch.from_numpy(np.float32(depthwise_horizontal_layer_weights))
    depthwise_vertical_layer.weight.data = \
        torch.from_numpy(np.float32(depthwise_vertical_layer_weights))
    pointwise_s_to_r_layer.weight.data = \
        torch.from_numpy(np.float32(pointwise_s_to_r_layer_weights))
    pointwise_r_to_t_layer.weight.data = \
        torch.from_numpy(np.float32(pointwise_r_to_t_layer_weights))

    new_layers = [pointwise_s_to_r_layer, depthwise_vertical_layer, \
                    depthwise_horizontal_layer, pointwise_r_to_t_layer]
    return nn.Sequential(*new_layers)