Example #1
0
def calIntsAcc(gt_i, pred_i, data_batch=1):
    n, c, h, w = gt_i.shape
    pred_i = pred_i.view(n, c, h, w)
    ref_int = gt_i[:, :3].repeat(1, gt_i.shape[1] / 3, 1, 1)
    gt_i = gt_i / ref_int
    scale = torch.gels(gt_i.view(-1, 1), pred_i.view(-1, 1))
    ints_ratio = (gt_i - scale[0][0] * pred_i).abs() / (gt_i + 1e-8)
    ints_error = torch.stack(ints_ratio.split(3, 1), 1).mean(2)
    return {'ints_ratio': ints_ratio.mean()}, ints_error.squeeze()
Example #2
0
def cal_ints_acc(gt_i, pred_i):
    batch, img_num, _ = gt_i.shape
    if batch > 1:  # compute error for a signle batch
        gt_i = gt_i.narrow(0, 0, 1)
        pred_i = pred_i.narrow(0, 0, 1)
    ref_int = gt_i.narrow(1, 0, 1)
    gt_i = gt_i / ref_int
    scale = torch.gels(gt_i.view(-1, 1), pred_i.view(-1, 1))
    ints_ratio = (gt_i - scale[0][0] * pred_i).abs() / (gt_i + 1e-8)
    ints_error = ints_ratio.mean(2)
    return {'ints_ratio': ints_ratio.mean().item()}, ints_error.squeeze()
Example #3
0
 def fit(self, states, returns):
     features = self._features(states)
     reg = self.reg * th.eye(features.size(1))
     reg = reg.to(states.device)
     A = features.t() @ features + reg
     b = features.t() @ returns
     if hasattr(th, 'lstsq'):  # Required for torch < 1.3.0
         coeffs, _ = th.lstsq(b, A)
     else:
         coeffs, _ = th.gels(b, A)
     self.linear.weight.data = coeffs.data.t()
def get_intersection_of_plane(normal_vectors):
    """

    :param normal_vectors: [M = 4, {A, B, D}]
    :return:
    """
    points = torch.empty((4, 2), dtype=torch.float32)
    for i in range(4):
        param = normal_vectors[:, [i, (i + 1) % 4]]
        coefficient = param[:2].t()
        ordinate = -param[2]
        points[i] = torch.gels(ordinate, coefficient)[0].squeeze()
    return points
Example #5
0
def adjusted_projection(vectors, L_max, sum_points=True, radius=True):
    radii = vectors.norm(2, -1)
    vectors = vectors[radii > 0.]
    angles = e3nn.o3.xyz_to_angles(vectors)

    coeff = projection(vectors, L_max, sum_points=False, radius=radius)

    A = torch.einsum(
        "ia,ib->ab",
        (e3nn.o3.spherical_harmonics(list(range(L_max + 1)), *angles), coeff))
    try:
        coeff *= torch.lstsq(radii, A).solution.view(-1)
    except:
        coeff *= torch.gels(radii, A).solution.view(-1)
    return coeff.sum(-1) if sum_points else coeff
Example #6
0
def solve2theta(source, target):
    source, target = source.clone(), target.clone()
    oks = source[2, :] == 1
    assert torch.sum(oks).item() >= 3, "valid points : {:} is short".format(
        oks)
    if target.size(0) == 2:
        target = torch.cat((target, oks.unsqueeze(0).float()), dim=0)
    source, target = source[:, oks], target[:, oks]
    source, target = source.transpose(1, 0), target.transpose(1, 0)
    assert source.size(1) == target.size(1) == 3
    # X, residual, rank, s = np.linalg.lstsq(target.numpy(), source.numpy())
    # theta = torch.Tensor(X.T[:2, :])
    X_, qr = torch.gels(source, target)
    theta = X_[:3, :2].transpose(1, 0)
    return theta
Example #7
0
        def gels(self, X, Y):
            assert X.dim() == 2
            assert Y.dim() == 2
            assert X.size(1) == Y.size(1)  # same dim
            num_x = len(X)

            Xtt = X.t().to(self.device)  # dim * num_x
            Ytt = Y.t().to(self.device)  # dim * num_y
            coef, _ = torch.gels(Ytt, Xtt)
            coef = coef[:num_x]
            # projection
            Ytt_hat = torch.mm(Xtt, coef)
            Y_hat = Ytt_hat.t()  # num_y * dim
            coef = coef.t()  # num_y * num_x

            return coef, Y_hat
def weight_reconstruction(next_module,
                          next_input_feature,
                          next_output_feature,
                          cpu=True):
    """
    reconstruct the weight of the next layer to the one being pruned
    :param next_module: torch.nn.module, module of the next layer to the one being pruned
    :param next_input_feature: torch.(cuda.)Tensor, new input feature map of the next layer
    :param next_output_feature: torch.(cuda.)Tensor, original output feature map of the next layer
    :param cpu: bool, whether done in cpu
    :return:
        void
    """
    if next_module.bias is not None:
        bias_size = [1] * next_output_feature.dim()
        bias_size[1] = -1
        next_output_feature -= next_module.bias.view(bias_size)
    if cpu:
        next_input_feature = next_input_feature.cpu()
    if isinstance(next_module, torch.nn.modules.conv._ConvNd):
        unfold = torch.nn.Unfold(kernel_size=next_module.kernel_size,
                                 dilation=next_module.dilation,
                                 padding=next_module.padding,
                                 stride=next_module.stride)
        if not cpu:
            unfold = unfold.cuda()
        unfold.eval()
        next_input_feature = unfold(next_input_feature)
        next_input_feature = next_input_feature.transpose(1, 2)
        num_fields = next_input_feature.size(0) * next_input_feature.size(1)
        next_input_feature = next_input_feature.reshape(num_fields, -1)
        next_output_feature = next_output_feature.view(
            next_output_feature.size(0), next_output_feature.size(1), -1)
        next_output_feature = next_output_feature.transpose(1, 2).reshape(
            num_fields, -1)
    if cpu:
        next_output_feature = next_output_feature.cpu()
    param, _ = torch.gels(next_output_feature.data, next_input_feature.data)
    param = param[
        0:next_input_feature.size(1), :].clone().t().contiguous().view(
            next_output_feature.size(1), -1)
    if isinstance(next_module, torch.nn.modules.conv._ConvNd):
        param = param.view(next_module.out_channels, next_module.in_channels,
                           *next_module.kernel_size)
    del next_module.weight
    next_module.weight = torch.nn.Parameter(param)
Example #9
0
def get_bases(C, U=None, S=None, iszca=False, islesq=False):
    K, KA = C.shape
    if iszca and U is not None:
        C = U.t().mm(C)
    if islesq and K > KA:
        I = tc.diag(tc.ones(K))
        Cv, _ = tc.gels(I, C)
    else:
        #        ipdb.set_trace()
        u, s, v = tc.svd(C, some=True)
        k0 = tc.sum(s / s[0] >= 1e-2)
        Cv = u[:, :k0] * (1.0 / s[:k0])
        Cv = Cv.mm(v[:, :k0].t())
    if U is None or S is None:
        B = Cv.t()
    else:
        V = U[:, :K] * S[:K]
        B = V.mm(Cv).t()
    return B
Example #10
0
    def directtf(self, pc1, pc2, indexor):
        _, indices = torch.unique(pc2[0, :], return_inverse=True)
        unique_indices = torch.unique(indices)
        #M = pc1.new_zeros(indexor.nonzero().numel() * 2, 12)
        A = pc1.new_zeros(indexor[unique_indices].nonzero().numel() * 3, 12)
        B = pc1.new_zeros(indexor[unique_indices].nonzero().numel() * 3, 1)

        if indexor.nonzero().numel() < 3:
            logger.warn(
                'Not enought correspondances to use dlt ({} match)'.format(
                    indexor.nonzero().numel()))
        cpt = 0
        for i in unique_indices:
            if indexor[i].item():
                A[cpt, :4] = pc1[:, i]
                A[cpt + 1, 4:8] = pc1[:, i]
                A[cpt + 2, 8:] = pc1[:, i]
                B[cpt] = pc2[0, i]
                B[cpt + 1] = pc2[1, i]
                B[cpt + 2] = pc2[2, i]

                cpt += 3

        X, _ = torch.gels(B, A)
        X = X[:12]

        P = X.view(3, 4)
        T = pc2.new_zeros(4, 4)
        T[:3, :] = P
        T[3, 3] = 1
        #R = T[:3, :3]
        #R = utils.quat_to_rot(utils.rot_to_quat(T[:3, :3]))

        R = normalize_rotmat(T[:3, :3])
        if torch.det(R) < 0:
            print('Inverse')
            R *= -1

        T[:3, :3] = R

        return T, utils.rot_to_quat(T[:3, :3]), T[:3, 3]
Example #11
0
def adjusted_projection(vectors, L_max, sum=False):
    radii = vectors.norm(2, -1)
    vectors = vectors[radii > 0.0]
    radii = radii[radii > 0.0]

    angles = SO3.xyz_to_angles(vectors)
    coeff = SO3.spherical_harmonics_dirac(L_max, *angles)
    coeff *= radii.unsqueeze(-2)
    # Handle case where only have a center
    if coeff.shape[1] == 0:
        return torch.zeros(coeff.shape[0])

    A = torch.einsum(
        "ia,ib->ab", SO3.spherical_harmonics(range(L_max + 1), *angles), coeff
    )
    coeff *= torch.gels(radii, A).solution.view(-1)
    if sum:
        return coeff.sum(-1)
    else:
        rank = len(coeff.shape)
        return coeff.permute(*range(1, rank), 0)
Example #12
0
def solve(A, b, out=None, bias=True, reg=0):
    '''
	Solves for x to minimize (Ax-b)^2
	for some matrix A and vector b
	x is returned as a linear layer (either with or without a bias term)
	Will update out if given, otherwise the output will be a new linear layer
	:param A: D x N pytorch tensor
	:param b: N x K pytorch tensor
	:param out: instance of torch.nn.Linear(D,K)
	:param bias: learn a bias term in addition to weights
	:return: torch.nn.Linear(D, K) instance where the weights (and bias) solve Ax=b
	'''
    # A: M x N
    # b: N x K
    # x: M x K

    if reg > 0:
        R = A.t() @ A
        b = A.t() @ b
        A = R + reg * torch.eye(A.size(1)).type_as(A)

    # print(A.size(), b.size())

    if bias:
        A = torch.cat([A, torch.ones(*(A.size()[:-1] + (1, ))).type_as(A)], -1)

    x, _ = torch.gels(b, A)

    if out is None:
        out = nn.Linear(A.size(-1) - 1, b.size(-1), bias=bias).to(A.device)

    out.weight.data.copy_(
        x[:A.size(-1) -
          1].t())  # TODO: make sure this works both with and without bias

    if bias:
        out.bias.data.copy_(x[A.size(-1) - 1:A.size(-1), :].squeeze())

    return out
Example #13
0
def _get_perspective_coeffs(startpoints, endpoints):
    """Helper function to get the coefficients (a, b, c, d, e, f, g, h) for the perspective transforms.

    In Perspective Transform each pixel (x, y) in the orignal image gets transformed as,
     (x, y) -> ( (ax + by + c) / (gx + hy + 1), (dx + ey + f) / (gx + hy + 1) )

    Args:
        List containing [top-left, top-right, bottom-right, bottom-left] of the orignal image,
        List containing [top-left, top-right, bottom-right, bottom-left] of the transformed
                   image
    Returns:
        octuple (a, b, c, d, e, f, g, h) for transforming each pixel.
    """
    matrix = []

    for p1, p2 in zip(endpoints, startpoints):
        matrix.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0] * p1[0], -p2[0] * p1[1]])
        matrix.append([0, 0, 0, p1[0], p1[1], 1, -p2[1] * p1[0], -p2[1] * p1[1]])

    A = torch.tensor(matrix, dtype=torch.float)
    B = torch.tensor(startpoints, dtype=torch.float).view(8)
    res = torch.gels(B, A)[0]
    return res.squeeze_(1).tolist()
Example #14
0
def RGBalbedoSHToLight(colorImg, albedoImg, SH, confidence_map):
    
    #remove non-zeros [now confidence_map is the more clean] 
    confidence_map[colorImg==0] = 0
    confidence_map[albedoImg==0] = 0
    
    id_non_not = confidence_map.nonzero()
    idx_non = torch.unbind(id_non_not, 1) # this only works for two dimesion
    
    colorImg_non = colorImg[idx_non]
    albedoImg_non = albedoImg[idx_non]
    
    #get the shadingImg element-wise divide
    shadingImg_non = torch.div(colorImg_non, albedoImg_non)    
    shadingImg_non2 = shadingImg_non.view(-1,1)

    #:means 9 channels [get the shading image]
    SH0 = SH[0,:,:]; SH0_non = SH0[idx_non]
    SH1 = SH[1,:,:]; SH1_non = SH1[idx_non]
    SH2 = SH[2,:,:]; SH2_non = SH2[idx_non]
    SH3 = SH[3,:,:]; SH3_non = SH3[idx_non]
    SH4 = SH[4,:,:]; SH4_non = SH4[idx_non]
    SH5 = SH[5,:,:]; SH5_non = SH5[idx_non]
    SH6 = SH[6,:,:]; SH6_non = SH6[idx_non]
    SH7 = SH[7,:,:]; SH7_non = SH7[idx_non]
    SH8 = SH[8,:,:]; SH8_non = SH8[idx_non]
           
    SH_NON = torch.stack([SH0_non, SH1_non, SH2_non, SH3_non, SH4_non, SH5_non, SH6_non, SH7_non, SH8_non], dim=-1)
    
    ## only use the first N soultions if M>N  A(M*N) B(N*K) X should (N*K)[use N if M appears] 
    ## torch.gels(B, A, out=None)  Tensor
    ## https://pytorch.org/docs/stable/torch.html#torch.gels  
    light, _ = torch.gels(shadingImg_non2, SH_NON)  
    light_9 = light[0:9] # use first 9

    return (light_9, SH)
Example #15
0
def create_dic(A, M=50, N=10, Lmin=1, Lstep=1, Lmax=49, Epsilon=0.1, mode=0):
    '''
    Main function of create dictionary D (random)
    # Matrix A should be written in a general one line per row matrix format.
    :return: D
    # The output D is written in  "desired D directory" in a general one line per row matrix format.
    '''
    # Set random seed
    torch.manual_seed(0)
    # Set random seed (if using NVIDIA GPU) - ref: https://discuss.pytorch.org/t/are-gpu-and-cpu-random-seeds-independent/142
    # torch.cuda.manual_seed_all(0)

    # Time interval
    # timeval t1, t2;

    # Initialize matrix
    D = torch.randn(M, Lmin).cuda()

    # Normalize columns of matrix A
    for i in range(0, N):
        if (torch.norm(A[:, i], 2) > 1E-5):
            A[:, i] /= torch.norm(A[:, i], 2)

    # Create dictionary D randomly in lstep
    global_error_D = 100.00
    l = Lmin
    lold = 0
    perm_tensor = torch.randperm(N).cuda()
    error_D = 0.00
    print("*************************************")
    # Adjust the length of D to meet the error requirement
    while ((global_error_D > (Epsilon * Epsilon)) and (l < Lmax + 1)):

        # Sort the index of Error columns if chosing Adaptive mode
        if mode == 1:
            idx = Adaptive_idx(A, D)
            idx = idx.cuda()

        # Resize D
        tempD = torch.zeros(M, l).cuda()
        for i in range(D.shape[1]):
            tempD[:, i] = D[:, i]
        D = tempD
        i = lold

        for i in range(lold, l):
            if mode == 0:
                D[:, i] = A[:, perm_tensor[
                    i]]  #/ torch.norm(A[:, perm_tensor[i]], 2)
            elif mode == 1:
                D[:, i] = A[:, idx[0]]
            else:
                raise "Type 0/1 for --mode"

        X_a_tmp = torch.randn(l, N).cuda()
        X_a = torch.randn(l, N).cuda()

        X_a_tmp, _ = torch.gels(A, D)
        X_a = X_a_tmp[0:l, :].cuda()

        # Add a filter
        threshold = 0.0
        for i in range(X_a.shape[0]):
            for j in range(X_a.shape[1]):
                if abs(X_a[i][j]) < threshold:
                    X_a[i][j] = 0.0

        for i in range(0, N):
            tmp = torch.mm(D, X_a)[:, i] - A[:, i]
            error_D = error_D + torch.sum(tmp * tmp)

        error_D = error_D / N
        if error_D < global_error_D:
            global_error_D = error_D

        lold = l
        l = l + Lstep

    print("Oringinal size is: ", N, M)
    print("Dictionary size is: ", l - 1, M)
    print("Coefficient size is: ", X_a.size())
    print("Final abs error is: ", global_error_D)
    print("-------------------------------------")

    return D, X_a
def compute_approximate_multipliers(
    loss,
    constraints,
    parameters,
    state=None,
    return_timing=False,
    allow_unused=False,
    warn=True,
):
    """Assumes that the constraints are well-conditioned and approximates the
    optimal Lagrange multipliers by applying Broyden's trick to approximate the 
    jacobians. This requires that the constraints and loss be effectively only
    functions of the parameters, not the model input (i.e. a reduction must 
    have been applied along the batch axis of the loss and constraints)

    WARNING: This method has been shown to be unstable and should not be used!

    :param loss: tensor corresponding to the evalutated loss
    :param constraints: a single tensor corresponding to the evaluated
        constraints (you may need to torch.stack() first)
    :param parameters: an iterable of the parameters to optimize
    :param state: state of the approximation, as returned by this function. Set
        to None to reinitialize the function
    :param return_timing: whether to also return the timing data
    :param warn: whether to warn if the constraints are ill-conditioned. If set
        to "error", then will throw a RuntimeError if this occurs
    :param allow_used: whether to allow some parameter to not be an input of
        the loss or constraints function. Defaults to False
    :returns: multipliers, state (, timing), if the timing is also requested. 
        Multipliers will have the same shape as the constraints
    :throws: RuntimeError if the jacobian of the constraints are not full rank
    """
    warnings.warn(
        "The approximation method for multiplier computation is unstable. It has therefore been deprecated",
        DeprecationWarning,
    )
    # multipliers = (J(g(s)) J(g(s))^T)^{-1} (g(s) - J(g(s)) J(f(s))^T)
    #   where f is the loss, g is the constraints vector, and s is the
    #   paramters of the neural network

    timing = dict()

    def record_timing(start_time, event):
        end_time = perf_counter()
        timing[event.value] = end_time - start_time
        return end_time

    # Handle the special case of only one constraint
    original_constraints_size = constraints.size()
    if constraints.dim() == loss.dim():
        constraints = constraints.unsqueeze(-1)

    start_time = perf_counter()

    if state is None:
        jac_fT = torch.cat(
            [
                jac.view(*loss.size(), -1) for jac in jacobian(
                    loss,
                    parameters,
                    batched=False,
                    create_graph=True,
                    allow_unused=allow_unused,
                )
            ],
            dim=-1,
        )
        start_time = record_timing(start_time, Timing_Events.COMPUTE_JF)
        jac_g = torch.cat(
            [
                jac.view(*constraints.size(), -1) for jac in jacobian(
                    constraints,
                    parameters,
                    batched=False,
                    create_graph=True,
                    allow_unused=allow_unused,
                )
            ],
            dim=-1,
        )
        start_time = record_timing(start_time, Timing_Events.COMPUTE_JG)
        state = Jacobian_Approximation_State(
            jac_fT,
            jac_g,
            [x.clone().detach() for x in parameters],
            loss.clone().detach(),
            constraints.clone().detach(),
        )
        start_time = record_timing(start_time, Timing_Events.UPDATE_STATE)
        timing[Timing_Events.APPROXIMATE_JF.value] = -999.0
        timing[Timing_Events.APPROXIMATE_JG.value] = -999.0
        timing[Timing_Events.RECOMPUTED_JACOBIANS.value] = True
    else:
        # Broyden's trick: (for iterative approximations to the Jacobian of the function y(s))
        # J(y_{k+1})~= Y_{k+1} = Y_k + (1/((s_{k+1} - s_k)^T(s_{k+1} - s_k)) ...
        #  * ((y_{k+1} - y_k) - Y_k (s_{k+1} - s_k)) (s_{k+1} - s_k)^T
        delta_parameters = torch.cat([
            (new - old).view(-1)
            for (old, new) in zip(state.last_parameters, parameters)
        ])
        delta_parameters_dot_product = delta_parameters @ delta_parameters
        delta_loss = (loss - state.last_loss).view(1)
        jac_fT = (state.loss_jacobian + torch.ger(
            delta_loss - (state.loss_jacobian @ delta_parameters),
            delta_parameters,
        ) / delta_parameters_dot_product).view(-1)
        start_time = record_timing(start_time, Timing_Events.APPROXIMATE_JF)
        delta_constraints = constraints - state.last_constraints
        jac_g = (state.constraint_jacobian + torch.ger(
            delta_constraints - (state.constraint_jacobian @ delta_parameters),
            delta_parameters,
        ) / delta_parameters_dot_product)
        start_time = record_timing(start_time, Timing_Events.APPROXIMATE_JG)
        state = Jacobian_Approximation_State(
            jac_fT,
            jac_g,
            [x.clone().detach() for x in parameters],
            loss.clone().detach(),
            constraints.clone().detach(),
        )
        start_time = record_timing(start_time, Timing_Events.UPDATE_STATE)
        timing[Timing_Events.COMPUTE_JF.value] = -999.0
        timing[Timing_Events.COMPUTE_JG.value] = -999.0
        timing[Timing_Events.RECOMPUTED_JACOBIANS.value] = False

    # Possibly batched version of J(g) * J(g)^T
    gram_matrix = torch.einsum("...ij,...kj->...ik", jac_g, jac_g)
    start_time = record_timing(start_time, Timing_Events.COMPUTE_GRAM)
    untransformed_multipliers = (
        constraints -
        torch.einsum("...ij,...j->...i", jac_g, jac_fT)).unsqueeze(-1)
    start_time = record_timing(start_time,
                               Timing_Events.COMPUTE_PRE_MULTIPLIERS)

    try:
        # We do this this way because there is some chance we can provide this externally later
        cholesky_L = torch.cholesky(gram_matrix)
        start_time = record_timing(start_time, Timing_Events.CHOLESKY)
        multipliers = torch.cholesky_solve(untransformed_multipliers,
                                           cholesky_L)
        start_time = record_timing(start_time, Timing_Events.CHOLESKY_SOLVE)
        timing[Timing_Events.ERRORED.value] = False
        timing[Timing_Events.LEAST_SQUARES.value] = -999.0
    except RuntimeError as rte:
        if warn:
            print("Error occurred while computing constrained loss:")
            print(rte)
            print("Constraints are likely ill-conditioned (i.e. jacobian is"
                  " not full rank at this point). Falling back to computing"
                  " pseudoinverse")
            if warn == "error":
                raise rte

        multipliers = untransformed_multipliers.new_zeros(
            untransformed_multipliers.size())
        if len(original_constraints_size) > 1:
            # torch.gels is NOT yet batch-enabled. As such, we do the batching manually
            for b in range(len(multipliers)):
                # discard the QR decomposition
                multipliers[b], __ = torch.gels(untransformed_multipliers[b],
                                                gram_matrix[b])
        else:
            # not batched
            multipliers, __ = torch.gels(untransformed_multipliers,
                                         gram_matrix)
        start_time = record_timing(start_time, Timing_Events.LEAST_SQUARES)
        timing[Timing_Events.ERRORED.value] = True
        timing[Timing_Events.CHOLESKY_SOLVE.value] = -999.0
        if Timing_Events.CHOLESKY.value not in timing:
            timing[Timing_Events.CHOLESKY.value] = -999.0

    if return_timing:
        return multipliers.view(original_constraints_size), state, timing
    else:
        return multipliers.view(original_constraints_size), state
Example #17
0
    def __init__(self, data, Us=None, idxs=None, device=None, requires_grad=None,
                 ranks_cp=None, ranks_tucker=None, ranks_tt=None, eps=None,
                 max_iter=25, tol=1e-4, verbose=False):

        """
        The constructor can either:

        - Decompose an uncompressed tensor

        - Use an explicit list of tensor cores (and optionally, factors)

        See `this notebook <https://github.com/rballester/tntorch/blob/master/tutorials/decompositions.ipynb>`_ for examples of use.

        :param data: a NumPy ndarray, PyTorch tensor, or a list of cores (which can represent either CP factors or TT cores)
        :param Us: optional list of Tucker factors
        :param idxs: annotate maskable tensors (*advanced users*)
        :param device: PyTorch device
        :param requires_grad: Boolean
        :param ranks_cp: an integer (or list)
        :param ranks_tucker: an integer (or list)
        :param ranks_tt: an integer (or list)
        :param eps: maximal error
        :param max_iter: maximum number of iterations when computing a CP decomposition using ALS
        :param tol: stopping criterion (change in relative error) when computing a CP decomposition using ALS
        :param verbose: Boolean

        :return: a :class:`Tensor`
        """

        if isinstance(data, (list, tuple)):
            if not all([2 <= d.dim() <= 3 for d in data]):
                raise ValueError('All tensor cores must have 2 (for CP) or 3 (for TT) dimensions')
            for n in range(len(data)-1):
                if (data[n+1].dim() == 3 and data[n].shape[-1] != data[n+1].shape[0]) or (data[n+1].dim() == 2 and data[n].shape[-1] != data[n+1].shape[1]):
                    raise ValueError('Core ranks do not match')
            self.cores = data
            N = len(data)
        else:
            if isinstance(data, np.ndarray):
                data = torch.Tensor(data, device=device)
            elif isinstance(data, torch.Tensor):
                data = data.to(device)
            else:
                raise ValueError('A tntorch.Tensor may be built either from a list of cores, one NumPy ndarray, or one PyTorch tensor')
            N = data.dim()
        if Us is None:
            Us = [None]*N
        self.Us = Us
        if isinstance(data, torch.Tensor):
            if data.dim() == 0:
                data = data*torch.ones(1, device=device)
            if ranks_cp is not None:  # Compute CP from full tensor: CP-ALS
                if ranks_tt is not None:
                    raise ValueError('ALS for CP-TT is not yet supported')
                assert not hasattr(ranks_cp, '__len__')
                start = time.time()
                if verbose:
                    print('ALS', end='')
                if ranks_tucker is not None:  # CP on Tucker's core
                    self.cores = _full_rank_tt(data)
                    self.round_tucker(rmax=ranks_tucker)
                    data = self.tucker_core()
                    data_norm = tn.norm(data)
                    self.cores = [torch.randn(sh, ranks_cp, device=device) for sh in data.shape]
                else:  # We initialize CP factor to HOSVD
                    data_norm = torch.norm(data)
                    self.cores = []
                    for n in range(data.dim()):
                        gram = tn.unfolding(data, n)
                        gram = gram.matmul(gram.t())
                        eigvals, eigvecs = torch.symeig(gram, eigenvectors=True)
                        # Sort eigenvectors in decreasing importance
                        reverse = np.arange(len(eigvals)-1, -1, -1)  # Negative steps not yet supported in PyTorch
                        idx = np.argsort(eigvals.to('cpu'))[reverse[:ranks_cp]]
                        self.cores.append(eigvecs[:, idx])
                        if self.cores[-1].shape[1] < ranks_cp:  # Complete with random entries
                            self.cores[-1] = torch.cat((self.cores[-1], torch.randn(self.cores[-1].shape[0], ranks_cp-self.cores[-1].shape[1])), dim=1)
                if verbose:
                    print(' -- initialization time =', time.time() - start)
                grams = [None] + [self.cores[n].t().matmul(self.cores[n]) for n in range(1, self.dim())]
                errors = []
                converged = False
                for iter in range(max_iter):
                    for n in range(self.dim()):
                        khatri = torch.ones(1, ranks_cp, device=device)
                        prod = torch.ones(ranks_cp, ranks_cp, device=device)
                        for m in range(self.dim()-1, -1, -1):
                            if m != n:
                                prod *= grams[m]
                                khatri = torch.reshape(torch.einsum('ir,jr->ijr', (self.cores[m], khatri)), [-1, ranks_cp])
                        unfolding = tn.unfolding(data, n)
                        self.cores[n] = torch.gels(unfolding.matmul(khatri).t(), prod)[0].t()
                        grams[n] = self.cores[n].t().matmul(self.cores[n])
                    errors.append(torch.norm(data - tn.Tensor(self.cores).torch()) / data_norm)
                    if len(errors) >= 2 and errors[-2] - errors[-1] < tol:
                        converged = True
                    if verbose:
                        print('iter: {: <{}} | eps: '.format(iter, len('{}'.format(max_iter))), end='')
                        print('{:.8f}'.format(errors[-1]), end='')
                        print(' | total time: {:9.4f}'.format(time.time() - start), end='')
                        if converged:
                            print(' <- converged (tol={})'.format(tol))
                        elif iter == max_iter-1:
                            print(' <- max_iter was reached: {}'.format(max_iter))
                        else:
                            print()
                    if converged:
                        break
            else:
                self.cores = _full_rank_tt(data)
                self.Us = [None]*data.dim()
                if ranks_tucker is not None:
                    self.round_tucker(rmax=ranks_tucker)
                if ranks_tt is not None:
                    self.round_tt(rmax=ranks_tt)

        # Check factor shapes
        for n in range(self.dim()):
            if self.Us[n] is None:
                continue
            assert self.Us[n].dim() == 2
            assert self.cores[n].shape[-2] == self.Us[n].shape[1]

        # Set cores/Us requires_grad, if needed
        if requires_grad:
            for n in range(self.dim()):
                if self.Us[n] is not None:
                    self.Us[n].requires_grad_()
                self.cores[n].requires_grad_()

        if idxs is None:
            idxs = [torch.arange(sh, device=device) for sh in self.shape]
        self.idxs = idxs
        if eps is not None:  # TT-SVD (or TT-EIG) algorithm
            if ranks_cp is not None or ranks_tucker is not None or ranks_tt is not None:
                raise ValueError('Specify eps or ranks, but not both')
            self.round(eps)
Example #18
0
def create_dic(A, M=50, N=10, Lmin=1, Lstep=1, Lmax=49, Epsilon=0.1, mode=0):
    '''
    Main function of create dictionary D (random)
    # Matrix A should be written in a general one line per row matrix format.
    :return: D
    # The output D is written in  "desired D directory" in a general one line per row matrix format.
    '''
    # Set random seed
    torch.manual_seed(0)
    # Set random seed (if using NVIDIA GPU) - ref: https://discuss.pytorch.org/t/are-gpu-and-cpu-random-seeds-independent/142
    # torch.cuda.manual_seed_all(0)

    # Time interval
    # timeval t1, t2;

    # Initialize matrix
    # A = torch.zeros(M, N)
    # D = torch.zeros(M, Lmin)
    # A = torch.randn(M, N)
    D = (0.2 + torch.randn(M, Lmin)).cuda()
    #print(D)
    #print(A[:, 0])
    # D[:,0] = A[:,0].view(M, Lmin)
    '''
    # Load Cifar10 data
    transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=512, shuffle=True, num_workers=2)
    testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=512, shuffle=False, num_workers=2)
    dataiter = iter(trainloader)
    
    
    img, _ = dataiter.next()
    A = img[0,0,:,:].view(-1).view(1,N)
    print A.shape
    for i in range(M-1):
        A = torch.cat((A,img[i+1,0,:,:].view(-1).view(1, N)),dim=0)
    print A.shape
    '''

    # Normalize columns of matrix A
    for i in range(0, N):
        if (torch.norm(A[:, i], 2) > 1E-5):
            A[:, i] /= torch.norm(A[:, i], 2)

    # Create dictionary D randomly in lstep
    global_error_D = 100.00
    l = Lmin
    lold = 0
    perm_tensor = torch.randperm(N)
    error_D = 0.00

    # Adjust the length of D to meet the error requirement
    while ((global_error_D > (Epsilon * Epsilon)) and (l < Lmax + 1)):

        # Sort the index of Error columns if chosing Adaptive mode
        if mode == 1:
            idx = Adaptive_idx(A, D)

        # Resize D
        tempD = torch.zeros(M, l).cuda()
        for i in range(D.shape[1]):
            tempD[:, i] = D[:, i]
        D = tempD
        i = lold

        for i in range(lold, l):
            if mode == 0:
                #print("Shape of D: ", D.shape)
                #print("Shape of A: ", A.shape)
                D[:, i] = A[:, perm_tensor[
                    i]]  #/ torch.norm(A[:, perm_tensor[i]], 2)
            elif mode == 1:
                D[:, i] = A[:, idx[i]]
            else:
                raise "Type 0/1 for --mode"

        # Solve the D * X_a = A
        # print("A shap: ", A.shape)
        # print("D shap: ", D.shape)
        X_a_tmp = torch.randn(l, N).cuda()
        X_a = torch.randn(l, N).cuda()
        #X_a_tmp = torch.randn(l, N)
        #X_a = torch.randn(l, N)
        # X_a_tmp, _ = torch.gels(A.cpu(), D.cpu())
        #A = A.cuda()
        #D = D.cuda()
        #X_a_tmp = X_a_tmp.cuda()

        X_a_tmp, _ = torch.gels(A, D)
        X_a = X_a_tmp[0:l, :]

        # Add a filter
        threshold = 0.0
        for i in range(X_a.shape[0]):
            for j in range(X_a.shape[1]):
                if abs(X_a[i][j]) < threshold:
                    X_a[i][j] = 0.0

        # print("X_a shap: ", X_a)
        # print("X_a shape: ", X_a.shape)
        # print("Normalized A:", A)
        for i in range(0, N):
            #print("tmp", torch.mm(D, X_a)[:,i])
            #print("A[:,i]", A[:,i])
            #print("D shap: ", D.shape)
            #print("X_a shape: ", X_a.shape)
            tmp = torch.mm(D, X_a)[:, i] - A[:, i]
            error_D = error_D + torch.sum(tmp * tmp)

        #print("Error: ", error_D)

        error_D = error_D / N
        if error_D < global_error_D:
            global_error_D = error_D

        lold = l
        #print("Dictionary size is: ",l)
        #print("Original size is: ", A.shape)
        #print("Shape of D: ", D.shape)
        #print("Shape of X_a: ", X_a.shape)
        #print("Error is: ", global_error_D)
        l = l + Lstep

    print("Oringinal size is: ", N)
    print("Dictionary size is: ", l)
    print("Final error is: ", global_error_D)

    return D, X_a
Example #19
0
    # No Translation
    A = torch.cat([
        adamCuda.drdP_tensor[112 * 2:112 * 2 + 53 * 3, :],
        adamCuda.drdc_tensor[112 * 2:112 * 2 + 53 * 3, :]
    ], 1)
    B = torch.cat([adamCuda.dposepriorlossdP_tensor, dposepriorlossdc_tensor],
                  1)
    C = torch.cat(
        [dshapecoefflossdP_tensor, adamCuda.dshapecoefflossdc_tensor], 1)
    J = torch.cat([A, B, C], 0)
    r = torch.cat([
        adamCuda.r_tensor[112 * 2:112 * 2 + 53 * 3, :],
        adamCuda.posepriorloss_tensor, adamCuda.shapecoeffloss_tensor
    ])

    delta_b, qr = torch.gels(r, J)

    #lr = 0.00000001
    lr = 1
    eulers_tensor = eulers_tensor - lr * delta_b[0:186].view(62, 3)
    bodyshape_tensor = bodyshape_tensor - lr * delta_b[186:186 + 30]

    error = torch.abs(torch.sum(adamCuda.r_tensor))
    print(error)

    ################
    torch.cuda.synchronize()
    end = time.time()
    #print(end - start)

    #stop
import torch

x = torch.Tensor([[1],[2]])
y = torch.Tensor([[1],[1]])
print(x.size())

X = torch.cat((x, torch.ones_like(x)),1)
print(X)
print(X[1,0])
print(torch.matmul(X, y))

# Solution 1
##############################
## Fill in the arguments
##############################
res1 = torch.gels(y, X)
print("Solution 1:")
print(res1[0])

# Solution 2
print(torch.matmul(torch.transpose(X, 0, 1),X))
print(torch.matmul(torch.transpose(X, 0, 1),y))

##############################
## How to compute l and r?
## Dimensions: l (2x2); r (2x1)
##############################
l = torch.matmul(torch.transpose(X, 0, 1),X)
r = torch.matmul(torch.transpose(X, 0, 1),y)
res2 = torch.gesv(r,l)
print("Solution 2:")
Example #21
0
import numpy
import torch
from sklearn import datasets

data = numpy.genfromtxt('./data/data.txt', delimiter=',')
x = numpy.zeros((data.shape))
x[:, 0] = data[:, 0]
x[:, 1] = 1.0
xTensor = torch.from_numpy(x)
y = numpy.zeros((data.shape[0], 1))
y[:, 0] = data[:, 1]
yTensor = torch.from_numpy(y)

alpha, _ = torch.gels(yTensor, xTensor)
Example #22
0
    def fit(self,
            *datasets,
            learn_bias=True,
            batch_size=None,
            max_epochs=1,
            dtype=None,
            underdetermined=False,
            dry_run=False):
        '''Trains a least squares model.

        Users should not call this method directly, but instead call the
        estimator as a function.

        .. todo::
            :class:`LeastSquares` does not yet support CUDA.

        Arguments:
            datasets (Dataset):
                The datasets to fit. If more than one are given, they are
                combined using `toys.zip`. The target is taken from the last
                column.

        Keyword Arguments:
            learn_bias (bool):
                If true (the default), learn an additive bias/intercept term.
                If false, the intercept is always 0.
            batch_size (int):
                The number of samples in each batch. This should be greater
                than the number of input features. The default is to read the
                entire dataset in a single batch.
            max_epochs (int):
                The number of times to iterate over the dataset.
            dtype (str or torch.dtype):
                Cast the module to this data type. This can be a PyTorch dtype
                object, a conventional name like 'float' and 'double', or an
                explicit name like 'float32' and 'float64'. The default is
                determined by `torch.get_default_dtype` and may be set with
                `torch.set_default_dtype`.
            underdetermined (bool):
                The estimator issues a warning if the problem is
                underdetermined, i.e. the batch size is less than the number
                of features. Set this to true to ignore the warning.
            dry_run (bool):
                If true, break from loops early. Useful for debugging.

        Returns:
            model (TorchModel):
                A linear model minimizing the mean squared error. The model
                expects $n$ inputs where $n$ is the number of feature columns
                in the training data.
        '''
        dataset = toys.zip(*datasets)
        dataset = toys.flatten(dataset, supervised=True)

        batch_size = batch_size or len(dataset)
        batch_size = min(batch_size, len(dataset))

        dtype = dtype or torch.get_default_dtype()
        dtype = parse_dtype(dtype)

        x, y = dataset[0]
        in_features = len(x)
        out_features = len(y)

        if not underdetermined and batch_size < in_features:
            logger.warning('least squares problem is underdetermined')
            logger.warning(
                f'  this means that the batch size is less than the number of features'
            )
            logger.warning(
                f'  batch_size={batch_size}, features={in_features}')
            logger.warning(
                f'  set underdetermined=True to disable this warning')

        if learn_bias:
            x_mean = Mean(dim=0)
            y_mean = Mean(dim=0)
            for x, y in toys.batches(dataset, batch_size):
                x_mean.accumulate(x)
                y_mean.accumulate(y)
            x_mean = x_mean.reduce()
            y_mean = y_mean.reduce()

        weight = Mean(dim=0)
        for i in range(max_epochs):
            for x, y in toys.batches(dataset, batch_size):
                if learn_bias:
                    x -= x_mean
                    y -= y_mean

                # gels is the LAPACK routine for least squares.
                # https://pytorch.org/docs/stable/torch.html#torch.gels
                # https://software.intel.com/en-us/mkl-developer-reference-c-gels
                batch_weight, _ = torch.gels(y, x)
                batch_weight = batch_weight[:in_features]
                assert batch_weight.shape == (in_features, out_features)

                # We duplicate the solution for this batch to weight it by the
                # batch size. This has no memory overhead, see `Tensor.expand`.
                batch_weight = batch_weight.unsqueeze(0)
                batch_weight = batch_weight.expand(len(x), in_features,
                                                   out_features)
                weight.accumulate(batch_weight)

                if dry_run:
                    break

        weight = weight.reduce()
        bias = y_mean - x_mean @ weight if learn_bias else 0

        mod = LeastSquaresModule(weight, bias)
        mod = TorchModel(mod, device_ids=[], dtype=dtype)
        mod = mod.eval()
        return mod
Example #23
0
# Read in the data.
with open('temp_co2_data.csv') as csvfile:
    reader = csv.reader(csvfile, delimiter=',')
    next(csvfile)  # skip the first line of csvfile
    xss, yss = [], []
    for row in reader:
        xss.append([float(row[2]), float(row[3])])
        yss.append([float(row[1])])

# The tensors xss and yss now containing the features (i.e., inputs) and targets
# (outputs) of the data.
xss, yss = torch.tensor(xss), torch.tensor(yss)

# For validation, compute the least-squares regression plane using linear alg.
GELS = torch.gels(yss, torch.cat((torch.ones(len(xss), 1), xss), 1))

# Compute the column-wise means and standard deviations.
xss_means, yss_means = xss.mean(0), yss.mean()
xss_stds, yss_stds = xss.std(0), yss.std()

# Mean center and normalize
xss, yss = xss - xss_means, yss - yss_means
xss, yss = xss / xss_stds, yss / yss_stds


# Build the model
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.layer = nn.Linear(2, 1)
PI = torch.mm(torch.inverse(torch.mm(torch.transpose(X, 0, 1), X)),
              torch.transpose(X, 0, 1))
W = torch.mm(PI, Y)
print("W", W)

print("Precision:")
print(torch.mm(X, W))
print(Y)
print(torch.dist(torch.mm(X, W), Y, 1))

# The solution is bad!
# We forget the bias term. Let's add it

Xc = torch.cat((X, torch.ones((X.size(0), 1))), 1)

PIc = torch.mm(torch.inverse(torch.mm(torch.transpose(Xc, 0, 1), Xc)),
               torch.transpose(Xc, 0, 1))
Wc = torch.mm(PIc, Y)

print("Precision:")
print(torch.mm(Xc, Wc))
print(Y)
print(torch.dist(torch.mm(Xc, Wc), Y, 1))

G, _ = torch.gels(Y, X)
# The solution is in the first row
print("By gesls(): X=", G[0])

G, _ = torch.gels(Y, Xc)
# The solution is in the first two rows
print("By gesls(): X=", G[0:2])
#%%
##torch里面的dot,只能用于向量对向量的内积
##torch.dot(X,X.t())


#%%
b=torch.tensor([7,8,9],dtype=torch.float).reshape(3,-1)
b

#%% [markdown]
# # 3. 解析方法:使用torch的线性代数库解
# 
# ## 3.1 torch.gels

#%%
p,_=torch.gels(b,X)


#%%
p

#%% [markdown]
# ## 3.2 使用解析解进行手动计算验证
# 
# 即 $\hat{x} = (A^{T}A)^{-1}A^{T}b$

#%%
a1=torch.inverse(torch.mm(X.t(),X))


#%%
Example #26
0
def cross(function,
          domain=None,
          tensors=None,
          function_arg='vectors',
          ranks_tt=None,
          kickrank=3,
          rmax=100,
          eps=1e-6,
          max_iter=25,
          val_size=1000,
          verbose=True,
          return_info=False,
          _minimize=False):
    """
    Cross-approximation routine that samples a black-box function and returns an N-dimensional tensor train approximating it. It accepts either:

    - A domain (tensor product of :math:`N` given arrays) and a function :math:`\\mathbb{R}^N \\to \\mathbb{R}`
    - A list of :math:`K` tensors of dimension :math:`N` and equal shape and a function :math:`\\mathbb{R}^K \\to \\mathbb{R}`

    :Examples:

    >>> tn.cross(function=lambda x: x**2, tensors=[t])  # Compute the element-wise square of `t` using 5 TT-ranks

    >>> domain = [torch.linspace(-1, 1, 32)]*5
    >>> tn.cross(function=lambda x, y, z, t, w: x**2 + y*z + torch.cos(t + w), domain=domain)  # Approximate a function over the rectangle :math:`[-1, 1]^5`

    >>> tn.cross(function=lambda x: torch.sum(x**2, dim=1), domain=domain, function_arg='matrix')  # An example where the function accepts a matrix

    References:

    - I. Oseledets, E. Tyrtyshnikov: `"TT-cross Approximation for Multidimensional Arrays" (2009) <http://www.mat.uniroma2.it/~tvmsscho/papers/Tyrtyshnikov5.pdf>`_
    - D. Savostyanov, I. Oseledets: `"Fast Adaptive Interpolation of Multi-dimensional Arrays in Tensor Train Format" (2011) <https://ieeexplore.ieee.org/document/6076873>`_
    - S. Dolgov, R. Scheichl: `"A Hybrid Alternating Least Squares - TT Cross Algorithm for Parametric PDEs" (2018) <https://arxiv.org/pdf/1707.04562.pdf>`_
    - A. Mikhalev's `maxvolpy package <https://bitbucket.org/muxas/maxvolpy>`_
    - I. Oseledets (and others)'s `ttpy package <https://github.com/oseledets/ttpy>`_

    :param function: should produce a vector of :math:`P` elements. Accepts either :math:`N` comma-separated vectors, or a matrix (see `function_arg`)
    :param domain: a list of :math:`N` vectors (incompatible with `tensors`)
    :param tensors: a :class:`Tensor` or list thereof (incompatible with `domain`)
    :param function_arg: if 'vectors', `function` accepts :math:`N` vectors of length :math:`P` each. If 'matrix', a matrix of shape :math:`P \\times N`.
    :param ranks_tt: int or list of :math:`N-1` ints. If None, will be determined adaptively
    :param kickrank: when adaptively found, ranks will be increased by this amount after every iteration (full sweep left-to-right and right-to-left)
    :param rmax: this rank will not be surpassed
    :param eps: the procedure will stop after this validation error is met (as measured after each iteration)
    :param max_iter: int
    :param val_size: size of the validation set
    :param verbose: default is True
    :param return_info: if True, will also return a dictionary with informative metrics about the algorithm's outcome

    :return: an N-dimensional TT :class:`Tensor` (if `return_info`=True, also a dictionary)
    """

    try:
        import maxvolpy.maxvol
    except ModuleNotFoundError:
        raise ModuleNotFoundError(
            "Functions that require cross-approximation require the optional maxvolpy package, which can be installed by 'pip install maxvolpy'. More info is available at https://bitbucket.org/muxas/maxvolpy"
        )

    assert domain is not None or tensors is not None
    assert function_arg in ('vectors', 'matrix')
    if function_arg == 'matrix':

        def f(*args):
            return function(torch.cat([arg[:, None] for arg in args], dim=1))
    else:
        f = function
    if tensors is None:
        tensors = tn.meshgrid(domain)
    if not hasattr(tensors, '__len__'):
        tensors = [tensors]
    tensors = [t.decompress_tucker_factors(_clone=False) for t in tensors]
    Is = list(tensors[0].shape)
    N = len(Is)

    # Process ranks and cap them, if needed
    if ranks_tt is None:
        ranks_tt = 1
    else:
        kickrank = None
    if not hasattr(ranks_tt, '__len__'):
        ranks_tt = [ranks_tt] * (N - 1)
    ranks_tt = [1] + list(ranks_tt) + [1]
    Rs = np.array(ranks_tt)
    for n in list(range(1, N)) + list(range(N - 1, -1, -1)):
        Rs[n] = min(Rs[n - 1] * Is[n - 1], Rs[n], Is[n] * Rs[n + 1])

    # Initialize cores at random
    cores = [torch.randn(Rs[n], Is[n], Rs[n + 1]) for n in range(N)]

    # Prepare left and right sets
    lsets = [np.array([[0]])] + [None] * (N - 1)
    randint = np.hstack(
        [np.random.randint(0, Is[n + 1], [max(Rs), 1])
         for n in range(N - 1)] + [np.zeros([max(Rs), 1], dtype=np.int)])
    rsets = [randint[:Rs[n + 1], n:] for n in range(N - 1)] + [np.array([[0]])]

    # Initialize left and right interfaces for `tensors`
    def init_interfaces():
        t_linterfaces = []
        t_rinterfaces = []
        for t in tensors:
            linterfaces = [torch.ones(1, t.ranks_tt[0])] + [None] * (N - 1)
            rinterfaces = [None] * (N - 1) + [
                torch.ones(t.ranks_tt[t.dim()], 1)
            ]
            for j in range(N - 1):
                M = torch.ones(t.cores[-1].shape[-1], len(rsets[j]))
                for n in range(N - 1, j, -1):
                    if t.cores[n].dim() == 3:  # TT core
                        M = torch.einsum(
                            'iaj,ja->ia',
                            (t.cores[n][:, rsets[j][:, n - 1 - j], :], M))
                    else:  # CP factor
                        M = torch.einsum(
                            'ai,ia->ia',
                            (t.cores[n][rsets[j][:, n - 1 - j], :], M))
                rinterfaces[j] = M
            t_linterfaces.append(linterfaces)
            t_rinterfaces.append(rinterfaces)
        return t_linterfaces, t_rinterfaces

    t_linterfaces, t_rinterfaces = init_interfaces()

    # Create a validation set
    Xs_val = [torch.as_tensor(np.random.choice(I, val_size)) for I in Is]
    ys_val = f(*[t[Xs_val].torch() for t in tensors])
    if ys_val.dim() > 1:
        assert ys_val.dim() == 2
        assert ys_val.shape[1] == 1
        ys_val = ys_val[:, 0]
    assert len(ys_val) == val_size
    norm_ys_val = torch.norm(ys_val)

    if verbose:
        print(
            'Cross-approximation over a {}D domain containing {:g} grid points:'
            .format(N, tensors[0].numel()))
    start = time.time()
    converged = False

    info = {
        'nsamples': 0,
        'eval_time': 0,
        'val_epss': [],
        'min': 0,
        'argmin': None
    }

    def evaluate_function(
            j
    ):  # Evaluate function over Rs[j] x Rs[j+1] fibers, each of size I[j]
        Xs = []
        for k, t in enumerate(tensors):
            if tensors[k].cores[j].dim() == 3:  # TT core
                V = torch.einsum('ai,ibj,jc->abc',
                                 (t_linterfaces[k][j], tensors[k].cores[j],
                                  t_rinterfaces[k][j]))
            else:  # CP factor
                V = torch.einsum('ai,bi,ic->abc',
                                 (t_linterfaces[k][j], tensors[k].cores[j],
                                  t_rinterfaces[k][j]))
            Xs.append(V.flatten())

        eval_start = time.time()
        evaluation = f(*Xs)
        info['eval_time'] += time.time() - eval_start
        if _minimize:
            evaluation = np.pi / 2 - torch.atan(
                evaluation - info['min']
            )  # Function used by I. Oseledets for TT minimization in ttpy
            evaluation_argmax = torch.argmax(evaluation)
            eval_min = torch.tan(np.pi / 2 -
                                 evaluation[evaluation_argmax]) + info['min']
            if info['min'] == 0 or eval_min < info['min']:
                coords = np.unravel_index(evaluation_argmax,
                                          [Rs[j], Is[j], Rs[j + 1]])
                info['min'] = eval_min
                info['argmin'] = tuple(lsets[j][coords[0]][1:]) + tuple(
                    [coords[1]]) + tuple(rsets[j][coords[2]][:-1])

        # Check for nan/inf values
        if evaluation.dim() == 2:
            evaluation = evaluation[:, 0]
        invalid = (torch.isnan(evaluation) | torch.isinf(evaluation)).nonzero()
        if len(invalid) > 0:
            invalid = invalid[0].item()
            raise ValueError(
                'Invalid return value for function {}: f({}) = {}'.format(
                    function,
                    ', '.join('{:g}'.format(x[invalid].numpy()) for x in Xs),
                    f(*[x[invalid:invalid + 1][:, None] for x in Xs]).item()))

        V = torch.reshape(evaluation, [Rs[j], Is[j], Rs[j + 1]])
        info['nsamples'] += V.numel()
        return V

    # Sweeps
    for i in range(max_iter):

        if verbose:
            print('iter: {: <{}}'.format(i,
                                         len('{}'.format(max_iter)) + 1),
                  end='')
            sys.stdout.flush()

        left_locals = []

        # Left-to-right
        for j in range(0, N - 1):

            # Update tensors for current indices
            V = evaluate_function(j)

            # QR + maxvol towards the right
            V = torch.reshape(V, [-1, V.shape[2]])  # Left unfolding
            Q, R = torch.qr(V)
            if _minimize:
                local, _ = maxvolpy.maxvol.rect_maxvol(Q.detach().numpy(),
                                                       maxK=Q.shape[1])
            else:
                local, _ = maxvolpy.maxvol.maxvol(Q.detach().numpy())
            V = torch.gels(Q.t(), Q[local, :].t())[0].t()
            cores[j] = torch.reshape(V, [Rs[j], Is[j], Rs[j + 1]])
            left_locals.append(local)

            # Map local indices to global ones
            local_r, local_i = np.unravel_index(local, [Rs[j], Is[j]])
            lsets[j + 1] = np.c_[lsets[j][local_r, :], local_i]
            for k, t in enumerate(tensors):
                if t.cores[j].dim() == 3:  # TT core
                    t_linterfaces[k][j + 1] = torch.einsum(
                        'ai,iaj->aj', (t_linterfaces[k][j][local_r, :],
                                       t.cores[j][:, local_i, :]))
                else:  # CP factor
                    t_linterfaces[k][j + 1] = torch.einsum(
                        'ai,ai->ai', (t_linterfaces[k][j][local_r, :],
                                      t.cores[j][local_i, :]))

        # Right-to-left sweep
        for j in range(N - 1, 0, -1):

            # Update tensors for current indices
            V = evaluate_function(j)

            # QR + maxvol towards the left
            V = torch.reshape(V, [Rs[j], -1])  # Right unfolding
            Q, R = torch.qr(V.t())
            if _minimize:
                local, _ = maxvolpy.maxvol.rect_maxvol(Q.detach().numpy(),
                                                       maxK=Q.shape[1])
            else:
                local, _ = maxvolpy.maxvol.maxvol(Q.detach().numpy())
            V = torch.gels(Q.t(), Q[local, :].t())[0]
            cores[j] = torch.reshape(torch.as_tensor(V),
                                     [Rs[j], Is[j], Rs[j + 1]])

            # Map local indices to global ones
            local_i, local_r = np.unravel_index(local, [Is[j], Rs[j + 1]])
            rsets[j - 1] = np.c_[local_i, rsets[j][local_r, :]]
            for k, t in enumerate(tensors):
                if t.cores[j].dim() == 3:  # TT core
                    t_rinterfaces[k][j - 1] = torch.einsum(
                        'iaj,ja->ia', (t.cores[j][:, local_i, :],
                                       t_rinterfaces[k][j][:, local_r]))
                else:  # CP factor
                    t_rinterfaces[k][j - 1] = torch.einsum(
                        'ai,ia->ia',
                        (t.cores[j][local_i, :], t_rinterfaces[k][j][:,
                                                                     local_r]))

        # Leave the first core ready
        V = evaluate_function(0)
        cores[0] = V

        # Evaluate validation error
        val_eps = torch.norm(ys_val -
                             tn.Tensor(cores)[Xs_val].torch()) / norm_ys_val
        info['val_epss'].append(val_eps)
        if val_eps < eps:
            converged = True

        if verbose:  # Print status
            print('| eps: {:.3e}'.format(val_eps), end='')
            print(' | total time: {:8.4f} | largest rank: {:3d}'.format(
                time.time() - start, max(Rs)),
                  end='')
            if converged:
                print(' <- converged: eps < {}'.format(eps))
            elif i == max_iter - 1:
                print(' <- max_iter was reached: {}'.format(max_iter))
            else:
                print()
        if converged:
            break
        elif i < max_iter - 1 and kickrank is not None:  # Augment ranks
            newRs = Rs.copy()
            newRs[1:-1] = np.minimum(rmax, newRs[1:-1] + kickrank)
            for n in list(range(1, N)) + list(range(N - 1, 0, -1)):
                newRs[n] = min(newRs[n - 1] * Is[n - 1], newRs[n],
                               Is[n] * newRs[n + 1])
            extra = np.hstack([
                np.random.randint(0, Is[n + 1], [max(newRs), 1])
                for n in range(N - 1)
            ] + [np.zeros([max(newRs), 1], dtype=np.int)])
            for n in range(N - 1):
                if newRs[n + 1] > Rs[n + 1]:
                    rsets[n] = np.vstack(
                        [rsets[n], extra[:newRs[n + 1] - Rs[n + 1], n:]])
            Rs = newRs
            t_linterfaces, t_rinterfaces = init_interfaces(
            )  # Recompute interfaces

    if val_eps > eps and not _minimize:
        logging.warning(
            'eps={:g} (larger than {}) when cross-approximating {}'.format(
                val_eps, eps, function))

    if verbose:
        print(
            'Did {} function evaluations, which took {:.4g}s ({:.4g} evals/s)'.
            format(info['nsamples'], info['eval_time'],
                   info['nsamples'] / info['eval_time']))
        print()

    if return_info:
        info['lsets'] = lsets
        info['rsets'] = rsets
        info['left_locals'] = left_locals
        info['total_time'] = time.time() - start
        info['val_eps'] = val_eps
        return tn.Tensor([torch.Tensor(c) for c in cores]), info
    else:
        return tn.Tensor([torch.Tensor(c) for c in cores])
url = r'http://en.wikipedia.org/wiki/World_population_estimates'
df = pd.read_html(url, header=0, attrs={"class" : "wikitable"})[2]
df


#%%
years = torch.tensor(df.iloc[:, 0], dtype=torch.float32)
populations = torch.tensor(df.iloc[:, 1], dtype=torch.float32)

#%% [markdown]
# 线性回归

#%%
x = torch.stack([years, torch.ones_like(years)], 1)
y = populations
wr, _ = torch.gels(y, x)
slope, intercept = wr[:2, 0]
result = 'population = {:.2e} * year + {:.2e}'.format(slope, intercept)
print('回归结果:' + result)


#%%
x = torch.stack([years, torch.ones_like(years)], 1)
y = populations
w = x.t().mm(x).inverse().mm(x.t()).mv(y)
slope, intercept = w
result = 'population = {:.2e} * year + {:.2e}'.format(slope, intercept)
print('回归结果:' + result)


#%%
Example #28
0
 def update_B(self):
     b = torch.gels(self.Y, self.A(self.X) * self.M)[0]
     self.B.weight.copy_(b[:self.k].transpose(1, 0))
Example #29
0
# 那么out和mat的为n元向量。 可选参数_alpha_ 和 beta 分别是 mat∗vec和mat的比例因子,即out=(beta∗tensor)+(alpha∗(mat@vec))
M = torch.randn(2)
mat = torch.randn(2, 3)
vec = torch.randn(3)
torch.addmv(M, mat, vec)

#点乘
torch.dot(torch.Tensor([1, 2]), torch.Tensor([1, 2]))

#特征分解
torch.eig(torch.randn(4, 4), eigenvectors=True)

#最小二乘解
A = torch.Tensor([[1, 1, 1], [2, 3, 4], [3, 5, 2], [4, 2, 5], [5, 4, 3]])
B = torch.Tensor([[-10, -3], [12, 14], [14, 12], [16, 16], [18, 16]])
X, _ = torch.gels(B, A)
X

#计算线性方程组AX=B的解
A = torch.Tensor([[6.80, -2.11, 5.66, 5.97, 8.23],
                  [-6.05, -3.30, 5.36, -4.44, 1.08],
                  [-0.45, 2.58, -2.70, 0.27, 9.04],
                  [8.32, 2.71, 4.35, -7.17, 2.14],
                  [-9.67, -5.14, -7.26, 6.08, -6.87]]).t()
B = torch.Tensor([[4.02, 6.19, -8.22, -7.57, -3.03],
                  [-1.56, 4.00, -8.67, 1.75, 2.86],
                  [9.81, -4.09, -4.57, -8.61, 8.99]]).t()
X, LU = torch.gesv(B, A)

#计算矩阵的逆矩阵
a = torch.randn(4, 4)
    def forward(self, input_img, depth_target, albedo):
        with torch.no_grad():
            depth_target = (depth_target + 1.0) / 2.0
            input_img_scale = (input_img + 1.0) / 2.0
            mask = input_img_scale[:, 0, :, :].clone()
            mask = mask.unsqueeze(1)
            #mask = ((mask+1)/2.0)*255.0
            input_img = (input_img + 1) / 2.0

            npix = torch.zeros(input_img.shape[0], 1)
            for i in range(input_img.shape[0]):
                npix[i, 0] = torch.sum(mask[i, :, :] >= 0)
            mask_index = (mask > 0)
            mask[mask == 0] = 0
            mask[mask != 0] = 1
            input_img = input_img * mask
            mask_im = mask.cpu().data.numpy()
            # print 'mask shape',mask.shape
            # import cv2
            # cv2.imwrite('mask_xx.png',mask_im[0,:,:]*255)
            nrows = input_img.shape[2]
            ncols = input_img.shape[3]
            nchannels = input_img.shape[1]

            gx, gy = np.linspace(0, nrows - 1,
                                 nrows), np.linspace(0, nrows - 1, nrows)
            grid_x_y = np.stack(np.meshgrid(gx, gy))

            grid_x_y = Variable(torch.FloatTensor(grid_x_y)).cuda()
            xx = grid_x_y[0, :, :]
            yy = grid_x_y[1, :, :]

            xx = (xx - 256.0) / 608.3650
            yy = (yy - 256.0) / 608.3650

            xx = xx * depth_target
            yy = yy * depth_target
            zz = depth_target

            p = torch.zeros(depth_target.shape[0], nrows, ncols, 3)

            p[:, :, :, 0] = xx[:, 0, :, :]
            p[:, :, :, 1] = yy[:, 0, :, :]
            p[:, :, :, 2] = zz[:, 0, :, :]

            p_ctr = p[:, 1:-1, 1:-1, :]
            vw = p_ctr - p[:, 1:-1, 2:, :]
            vs = p[:, 2:, 1:-1, :] - p_ctr
            ve = p_ctr - p[:, 1:-1, :-2, :]
            vn = p[:, :-2, 1:-1, :] - p_ctr

            normal_1 = torch.cross(vw, vs)
            normal_2 = torch.cross(ve, vn)

            normal = normal_1 + normal_2
            normal_mag = torch.sqrt(
                pow(normal[:, :, :, 0], 2) + pow(normal[:, :, :, 1], 2) +
                pow(normal[:, :, :, 2], 2))

            normal_x = normal[:, :, :, 0] / normal_mag
            normal_y = normal[:, :, :, 1] / normal_mag
            normal_z = normal[:, :, :, 2] / normal_mag
            normal_x_pad = torch.zeros(input_img.shape[0], nrows, ncols)
            normal_y_pad = torch.zeros(input_img.shape[0], nrows, ncols)
            normal_z_pad = torch.zeros(input_img.shape[0], nrows, ncols)
            normal_x_pad[:, 1:-1, 1:-1] = normal[:, :, :, 0]
            normal_y_pad[:, 1:-1, 1:-1] = normal[:, :, :, 1]
            normal_z_pad[:, 1:-1, 1:-1] = normal[:, :, :, 2]
            n_x = torch.zeros(input_img.shape[0], nrows, ncols)
            n_y = torch.zeros(input_img.shape[0], nrows, ncols)
            n_z = torch.zeros(input_img.shape[0], nrows, ncols)
            n_mag = torch.zeros(input_img.shape[0], nrows, ncols)

            n_x[:, 1:-1, 1:-1] = normal_x
            n_y[:, 1:-1, 1:-1] = normal_y
            n_z[:, 1:-1, 1:-1] = normal_z

            n_mag[:, 1:-1, 1:-1] = normal_mag

            x2 = n_x * n_x
            y2 = n_y * n_y
            z2 = n_z * n_z
            xy = n_x * n_y
            xz = n_x * n_z
            yz = n_y * n_z

            N = torch.zeros(input_img.shape[0], ncols, nrows, 9)
            N = N.cuda()
            pi_pi = 3.14159
            N[:, :, :,
              0] = pi_pi * torch.Tensor([1 / np.sqrt(4 * pi_pi)]) * n_mag
            N[:, :, :, 1] = (2 * pi_pi / 3.0) * torch.Tensor(
                [np.sqrt(3 / (4 * pi_pi))]) * normal_z_pad
            N[:, :, :, 2] = (2 * pi_pi / 3.0) * torch.Tensor(
                [np.sqrt(3 / (4 * pi_pi))]) * normal_x_pad
            N[:, :, :, 3] = (2 * pi_pi / 3.0) * torch.Tensor(
                [np.sqrt(3 / (4 * pi_pi))]) * normal_y_pad
            N[:, :, :, 4] = (pi_pi / 4.0) * (0.5) * torch.Tensor(
                [np.sqrt(5 / (4 * pi_pi))]) * ((2 * z2 - x2 - y2) * n_mag)
            N[:, :, :, 5] = (pi_pi / 4.0) * (
                3 * torch.Tensor([np.sqrt(5 / (12 * pi_pi))])) * (xz * n_mag)
            N[:, :, :, 6] = (pi_pi / 4.0) * (
                3 * torch.Tensor([np.sqrt(5 / (12 * pi_pi))])) * (yz * n_mag)
            N[:, :, :,
              7] = (pi_pi /
                    4.0) * (3 * torch.Tensor([np.sqrt(5 / (48 * pi_pi))])) * (
                        (x2 - y2) * n_mag)
            N[:, :, :, 8] = (pi_pi / 4.0) * (
                3 * torch.Tensor([np.sqrt(5 / (12 * pi_pi))])) * (xy * n_mag)

            S = torch.zeros(input_img.shape[0], 3, 9).cuda()

            rhoc = albedo
            rhoc = rhoc.cuda()
            rhoc_mask = rhoc * mask

            input_img_fla = torch.zeros(input_img.shape[0], nchannels,
                                        nrows * ncols)

            input_img_fla = input_img_fla.cuda()

            for i_bat in range(input_img.shape[0]):
                for i_chan in range(nchannels):
                    input_img_fla[i_bat,
                                  i_chan, :] = input_img[i_bat,
                                                         i_chan, :, :].view(-1)

            N_flatten = torch.zeros(input_img.shape[0], nrows * ncols, 9)
            rhoc_N = torch.zeros_like(N_flatten).cuda()

            rhoc_mask_fla = rhoc_mask.view(input_img.shape[0], 3, -1)
            N_fla = N.view(input_img.shape[0], -1, 9)
            for i_n_bat in range(nchannels):
                rhoc_mask_fla_single = rhoc_mask_fla[:, i_n_bat, :]

                for j_n_bat in range(9):

                    rhoc_N[:, :, j_n_bat] = N_fla[:, :, j_n_bat].view(
                        input_img.shape[0], -1).cuda() * rhoc_mask_fla_single

            for i_batfi in range(input_img.shape[0]):
                for i_c in range(3):

                    b = input_img_fla[i_batfi, i_c, :].unsqueeze(1)
                    A = rhoc_N[i_batfi, :, :].squeeze(0)
                    mask_select = mask[i_batfi, :, :]

                    mask_select_fla = mask_select.view(-1)
                    mask_select_ind = mask_select_fla.nonzero()

                    A_nonzero = A[mask_select_ind[:, 0], :]
                    b_nonzero = b[mask_select_ind[:, 0], :]
                    X, _ = torch.gels(b_nonzero, A_nonzero)
                    X = X.cuda()

                    S[i_batfi, i_c, :] = X[0:9, :].squeeze(1)

            return S