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()
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()
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
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
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
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)
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
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]
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)
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
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()
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)
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
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)
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
# 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:")
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)
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
# 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)) #%%
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) #%%
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))
# 那么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