def return_x_m(f_ary, df_rho_div_f_ary, npt_compressed, data, s_ary, dnds_ary): """ Dedicated calculation of x_m and x_m_sum """ k_max = torch.max(data) + 1 m_ary = torch.arange(k_max + 1, dtype=torch.float64) gamma_ary = torch.exp(torch.lgamma(m_ary + 1)) x_m_ary = df_rho_div_f_ary[:, None] * f_ary[:, None] * torch.trapz( ((dnds_ary * (-torch.ger(f_ary, s_ary)).exp())[:, :, None] * (torch.ger(f_ary, s_ary)[:, :, None]).pow(m_ary) / gamma_ary), s_ary, axis=1) x_m_ary = torch.sum(x_m_ary, axis=0) x_m_ary = torch.ger(npt_compressed, x_m_ary) # Get x_m_sum_ary array x_m_sum_ary = torch.sum( (df_rho_div_f_ary * f_ary)[:, None] * torch.trapz(dnds_ary, s_ary), axis=0) x_m_sum_ary = torch.sum(x_m_sum_ary, axis=0) x_m_sum_ary = npt_compressed * x_m_sum_ary - x_m_ary[:, 0] return x_m_ary, x_m_sum_ary
def forward(self, theta): #size: 1 x nb_basis x 1 mu_basis = self.psi[0].mu.unsqueeze(-1) sigma_basis = self.psi[0].sigma.unsqueeze(-1) a = -5 b = 5 dx = 100 bandwidth = 0.01 #size: 1 x 1 x dx T = torch.linspace(a, b, dx, device=theta.device).unsqueeze(0).unsqueeze(0) inducing_locations = torch.linspace(0, 1, theta.shape[1] - 2, device=theta.device) K_inputs = torch.cdist( inducing_locations.unsqueeze(-1), torch.linspace(a, b, dx, device=theta.device).unsqueeze(-1)) #size: inducing x dx K = self.gaussian_rbf(K_inputs, bandwidth) alpha = theta[:, 2:] #size: bx x 1 x dx f = torch.matmul(alpha, K).unsqueeze(1) #mu, sigma: bs x 1 x 1 sigma = torch.sqrt(-0.5 / theta[:, 1]) sigma_sq = (-0.5 / theta[:, 1]).unsqueeze(-1).unsqueeze(-1) mu = (theta[:, 0] * sigma**2).unsqueeze(-1).unsqueeze(-1) phi1_upper = mu_basis - T phi1_lower = sigma_basis phi1 = self._phi(phi1_upper / phi1_lower) / phi1_lower exp_terms = self.beta_exp(f - 0.5 * (mu - T)**2 / (sigma_sq)).clamp(min=1e-8) #size: bs x 1 x dx #unnormalized_density = self.truncated_parabola(T,mu,sigma_sq) #size: bs x 1 x 1 #Z = torch.trapz(unnormalizedi_density,torch.linspace(a,b,dx,device=theta.device),dim=-1).unsqueeze(-1) Z = torch.trapz(exp_terms, torch.linspace(a, b, dx, device=theta.device), dim=-1).unsqueeze(-1) numerical_integral = torch.trapz(phi1 * exp_terms / Z, torch.linspace(a, b, dx, device=theta.device), dim=-1) return numerical_integral
def _process(self, curves): if curves.ndim == 1: curves = curves.view(1, -1) xs = torch.linspace(0, 1, curves.size(1), device=curves.device) xs = xs.expand_as(curves) aucs = torch.trapz(curves, xs) return aucs
def precision_recall_plot(self, iou_thresholds=None, confidence_thresholds=None): fig, ax = plt.subplots(figsize=(10, 5)) if iou_thresholds is None: iou_thresholds = torch.arange(start=0.5, end=0.99, step=0.10) for iou_threshold in iou_thresholds: precision, recall, f1, iou, dist, confidence_thresholds = self.performance_metrics( iou_threshold=iou_threshold) R = torch.cat((torch.ones(1), recall.cpu(), torch.zeros(1))) P = torch.cat((torch.zeros(1), precision.cpu(), torch.ones(1))) AUC = torch.trapz(R, P) ax.fill_between(R, P, alpha=0.2, step='pre') ax.step(R, P, label=f'IoU>{iou_threshold:.2f} | AUC={AUC:.3f}') ax.set_xlabel('Recall') ax.set_ylabel('Precision') ax.set_xlim((0, 1.05)) ax.set_ylim((0, 1.05)) ax.legend() return fig
def auc( x: torch.Tensor, y: torch.Tensor, ) -> torch.Tensor: """ Computes Area Under the Curve (AUC) using the trapezoidal rule Args: x: x-coordinates y: y-coordinates Return: Tensor containing AUC score (float) Example: >>> x = torch.tensor([0, 1, 2, 3]) >>> y = torch.tensor([0, 1, 2, 2]) >>> auc(x, y) tensor(4.) """ dx = x[1:] - x[:-1] if (dx < 0).any(): if (dx <= 0).all(): direction = -1. else: raise ValueError( f"The 'x' array is neither increasing or decreasing: {x}. Reorder is not supported." ) else: direction = 1. return direction * torch.trapz(y, x)
def Eval_auc(self): print('eval[AUC]:{} dataset with {} method.'.format( self.dataset, self.method)) avg_tpr, avg_fpr, avg_auc, img_num = 0.0, 0.0, 0.0, 0.0 with torch.no_grad(): trans = transforms.Compose([transforms.ToTensor()]) for pred, gt in self.loader: if self.cuda: pred = trans(pred).cuda() pred = (pred - torch.min(pred)) / (torch.max(pred) - torch.min(pred) + 1e-20) gt = trans(gt).cuda() else: pred = trans(pred) pred = (pred - torch.min(pred)) / (torch.max(pred) - torch.min(pred) + 1e-20) gt = trans(gt) TPR, FPR = self._eval_roc(pred, gt, 255) avg_tpr += TPR avg_fpr += FPR img_num += 1.0 avg_tpr = avg_tpr / img_num avg_fpr = avg_fpr / img_num sorted_idxes = torch.argsort(avg_fpr) avg_tpr = avg_tpr[sorted_idxes] avg_fpr = avg_fpr[sorted_idxes] avg_auc = torch.trapz(avg_tpr, avg_fpr) return avg_auc.item(), avg_tpr, avg_fpr
def auc(x: torch.Tensor, y: torch.Tensor, reorder: bool = True): """ Computes Area Under the Curve (AUC) using the trapezoidal rule Args: x: x-coordinates y: y-coordinates reorder: reorder coordinates, so they are increasing. Return: AUC score (float) """ direction = 1. if reorder: # can't use lexsort here since it is not implemented for torch order = torch.argsort(x) x, y = x[order], y[order] else: dx = x[1:] - x[:-1] if (dx < 0).any(): if (dx, 0).all(): direction = -1. else: raise ValueError("Reordering is not turned on, and " "the x array is not increasing: %s" % x) return direction * torch.trapz(y, x)
def integrate_psi_kernel_exp(self,mu,sigma_sq,alpha): a = -5 b = 5 bandwidth=.01 dt_num = 100 t_raw = torch.linspace(a,b,dt_num,device=mu.device) t = t_raw.unsqueeze(0).unsqueeze(0) mu = mu.unsqueeze(-1) sigma_sq = sigma_sq.unsqueeze(-1) mu_basis = self.mu.unsqueeze(-1) sigma_basis = self.sigma.unsqueeze(-1) y1 = 1/(torch.sqrt(2*math.pi*sigma_sq))*torch.exp(-(mu-t).pow(2)/(2*sigma_sq)) y2 = 1/(math.sqrt(2*math.pi)*sigma_basis)*torch.exp(-(mu_basis-t).pow(2)/(2*sigma_basis.pow(2))) dist_matrix = torch.cdist(torch.linspace(0,1,alpha.shape[1],device=mu.device).unsqueeze(-1),torch.linspace(a,b,dt_num,device=mu.device).unsqueeze(-1)) K_matrix=torch.exp(-dist_matrix.pow(2)/(2*bandwidth)) y3 = torch.exp(torch.mm(alpha,K_matrix)).clamp(max=100) y3 = y3.unsqueeze(1) #y3 = torch.ones(y3.shape,device=y3.device) Z = torch.trapz(y1*y3,torch.linspace(a,b,dt_num,device=mu.device),dim=-1).unsqueeze(-1) y = y1*y2*y3 if torch.isnan(y).any(): print('y1*y2*y3 is nan') if torch.isnan(y3).any(): print('y3') print(torch.mm(alpha,K_matrix)) if torch.isnan(torch.mm(alpha,K_matrix)).any(): print('nan before exponentiating') if torch.isnan(alpha).any(): print('nan in alpha') if torch.isnan(K_matrix).any(): print('nan in kernel matrix') if torch.isnan(y2).any(): print('y2') if torch.isnan(y1).any(): print('y1') print(5/0) y=y/Z if torch.isnan(y).any(): print('y1*y2*y3/Z is nan') print(torch.max(alpha)) print(torch.max(y3)) print(5/0) #Need normalization constant integral = torch.trapz(y,torch.linspace(a,b,dt_num,device=mu.device),dim=-1) if torch.isnan(integral).any(): print('nan in integral') return integral
def iso_loss(r, theta, lambda1, lambda2): P0 = torch.tensor(2 * np.pi) area = 0.5 * torch.trapz(r * r, theta) x, y = pol2cart(r, theta) perim = perimeter(x, y) loss = -area + lambda1 * (perim - P0)**2 + lambda2 * (x.mean()**2 + y.mean()**2) return loss
def decod_bit_seq(self, signal_decoded, t_dec, pulse_width, pulse_number, decision_level): ''' Parameters ---------- signal_decoded : TYPE: torch.float64 tensor of shape [batch_size,dim_z,dim_t_dec] DESCRIPTION: decoded signal t_dec : TYPE: torch.float32 tensor of shape [dim_t_dec] DESCRIPTION: positive time when there are pulses pulse_width : TYPE: int DESCRIPTION: Pulse width. pulse_number : TYPE: int DESCRIPTION: number of pulses decision_level : TYPE: float DESCRIPTION: threshold for bit = 1 value < threshold ---> 0 value > threshold ---> 1 Returns ------- decoded_numbers : TYPE: torch.long tensor of shape [batch_size,dim_z, pulse_number-1] DESCRIPTION: decoded bit sequence in bits (1 or 0) ''' device = signal_decoded.device #prepare T = pulse_width n = pulse_number - 1 tt = t_dec.expand(n, -1) #Getting indexes for regrouping on bits slots #Indaxes for t_starts t_starts = (torch.arange(0, n) * T + 0.5 * T).reshape(n, 1).to(device) idx_starts = torch.argmin(torch.abs(tt - t_starts), dim=-1, keepdim=True) #Indaxes for pulses and time w_pulse = idx_starts[1] - idx_starts[0] idx_pulses = torch.arange(0, w_pulse.item()).expand( n, -1).to(device) + idx_starts idx_pulses_line = idx_pulses.reshape(-1) #regrouping on bits slots pulses = torch.index_select(signal_decoded, dim=-1, index=idx_pulses_line) pulses = pulses.view(*signal_decoded.shape[:-1], n, w_pulse) t_pulses = torch.index_select(t_dec, dim=-1, index=idx_pulses[0, :]) # integrating by bits slots decoded_bitSeq = torch.trapz(pulses, t_pulses, dim=-1) # return decoded_bitSeq #decoding decoded_bitSeq = (decoded_bitSeq > decision_level).type(torch.long) return decoded_bitSeq
def integral_normal(panel_i, panel_j, n=100): s = torch.linspace(0, panel_j.length.detach().numpy().item(), n) nom = ((panel_i.point_c[0] - (panel_j.point_a[0] - torch.sin(panel_j.beta) * s)) * torch.cos(panel_i.beta) + (panel_i.point_c[1] - (panel_j.point_a[1] + torch.cos(panel_j.beta) * s)) * torch.sin(panel_i.beta)) denom = ((panel_i.point_c[0] - (panel_j.point_a[0] - torch.sin(panel_j.beta) * s)) ** 2 + (panel_i.point_c[1] - (panel_j.point_a[1] + torch.cos(panel_j.beta) * s)) ** 2) return torch.trapz(nom / denom, s)
def get_mAP(tp, fp, fn): prec = tp / (tp + fp) prec = torch.where(prec == 0, prec, torch.ones_like(prec)) rec = tp / (tp + fn) prec = prec.permute(1, 0) rec = rec.permute(1, 0) AP = torch.trapz(prec, rec) mAP = AP.mean() return mAP
def NA_Model(self, adse, beta, delta, dos_d, vad2): h = self.h ergy = self.ergy eps = np.finfo(float).eps fermi = self.fermi wdos = np.pi * (beta[:, None] * vad2[:, None] * dos_d) + delta[:, None] wdos_ = np.pi * (0 * vad2[:, None] * dos_d) + delta[:, None] # Hilbert transform af = torch.rfft(wdos, 1, onesided=False) htwdos = torch.ifft(af * h[None, :, None], 1)[:, :, 1] deno = (ergy[None, :] - adse[:, None] - htwdos) deno = deno * (torch.abs(deno) > eps) \ + eps * (torch.abs(deno) <= eps) * (deno >= 0) \ - eps * (torch.abs(deno) <= eps) * (deno < 0) integrand = wdos / deno arctan = torch.atan(integrand) arctan = (arctan - np.pi) * (arctan > 0) + (arctan) * (arctan <= 0) d_hyb = 2 / np.pi * torch.trapz(arctan[:, 0:fermi], ergy[None, 0:fermi]) lorentzian = (1/np.pi) * (delta[:,None]) \ / ((ergy[None,:] - adse[:,None])**2 + delta[:,None]**2) na = torch.trapz(lorentzian[:, 0:fermi], ergy[None, 0:fermi]) deno_ = (ergy[None, :] - adse[:, None]) deno_ = deno_ * (torch.abs(deno_) > eps) \ + eps * (torch.abs(deno_) <= eps) * (deno_ >= 0) \ - eps * (torch.abs(deno_) <= eps) * (deno_ < 0) integrand_ = wdos_ / deno_ arctan_ = torch.atan(integrand_) arctan_ = (arctan_ - np.pi) * (arctan_ > 0) + (arctan_) * (arctan_ <= 0) d_hyb_ = 2 / np.pi * torch.trapz(arctan_[:, 0:fermi], ergy[None, 0:fermi]) energy_NA = d_hyb - d_hyb_ dos_ads = wdos / (deno**2 + wdos**2) / np.pi dos_ads = dos_ads / torch.trapz(dos_ads, ergy[None, :])[:, None] return na, energy_NA, dos_ads
def integrate_matric_potential(trained_model: int): raise NotImplementedError( "It is probably useless to integrate? Mean should make more sense, so see below." ) load_trained_model(trained_model) t_space = torch.linspace(0, 4 / 60, dtype=approximator.DTYPE) z_space = torch.linspace(0, 0.254, dtype=approximator.DTYPE) tz_pairs_space = torch.stack((t_space, z_space), dim=-1) net_vals = torch.squeeze(approximation.net(tz_pairs_space), dim=1) trapz = torch.trapz(net_vals, z_space) return trapz
def borji(saliency_map, g_truth, num_split=100, step_size=0.1): """ Measures how well the saliencyMap of an image predicts the ground truth human fixations on the image. :param saliency_map: the saliency map, 4D tensor: (batch, 1, h, w) :param g_truth: the human fixation map (binary matrix), 4D tensor: (batch, 1, h, w) :param num_split: number of random splits :param step_size: sweeping through saliency map :return: score """ s_map = saliency_map.clone().detach() # make the saliencyMap the size of the image of fixationMap if s_map.shape[2:] != g_truth.shape[2:]: import torch.nn.functional as nnf s_map[2:] = nnf.interpolate(s_map[2:], size=g_truth.shape[2:], mode='bicubic', align_corners=False) # normalize saliency map s_map = s_map - s_map.mean(dim=(2, 3)).view(s_map.shape[0], 1, 1) s_map = s_map / s_map.std(dim=(2, 3), unbiased=True).view(s_map.shape[0], 1, 1) # vector of s_map s_vec = torch.flatten(s_map) g_vec = torch.flatten(g_truth) # s_map values at fixation locations s_th = s_vec[g_vec > 0] num_fixations = s_th.shape[0] num_pixels = s_vec.shape[0] # for each fixation, sample num_split values from anywhere on the sal map random = torch.randint(low=1, high=num_pixels, size=(num_fixations, num_split)) rand_fix = s_vec[random] # % calculate AUC per random split (set of random locations) auc = [] for i in range(0, num_split): cur_fix = rand_fix[:, i] h_bound = max(torch.max(s_th), torch.max(cur_fix)) allthreshes = torch.flip(torch.FloatTensor([i for i in arange(0, h_bound.item(), step_size)]), dims=[0]) tp = torch.zeros(allthreshes.shape[0] + 2, 1) fp = torch.zeros(allthreshes.shape[0] + 2, 1) tp[0] = fp[0] = 0; tp[-1] = fp[-1] = 1; print(allthreshes.shape[0]) for j in range(0, allthreshes.shape[0]): thresh = allthreshes[j] tp[j + 1] = (s_th >= thresh).sum() / num_fixations fp[j + 1] = (cur_fix >= thresh).sum() / num_fixations # im not sure about this line: auc.append(torch.trapz(fp, tp)) result = torch.stack(auc, dim=0) score = torch.mean(result)
def blas_lapack_ops(self): m = torch.randn(3, 3) a = torch.randn(10, 3, 4) b = torch.randn(10, 4, 3) v = torch.randn(3) return ( torch.addbmm(m, a, b), torch.addmm(torch.randn(2, 3), torch.randn(2, 3), torch.randn(3, 3)), torch.addmv(torch.randn(2), torch.randn(2, 3), torch.randn(3)), torch.addr(torch.zeros(3, 3), v, v), torch.baddbmm(m, a, b), torch.bmm(a, b), torch.chain_matmul(torch.randn(3, 3), torch.randn(3, 3), torch.randn(3, 3)), # torch.cholesky(a), # deprecated torch.cholesky_inverse(torch.randn(3, 3)), torch.cholesky_solve(torch.randn(3, 3), torch.randn(3, 3)), torch.dot(v, v), torch.eig(m), torch.geqrf(a), torch.ger(v, v), torch.inner(m, m), torch.inverse(m), torch.det(m), torch.logdet(m), torch.slogdet(m), torch.lstsq(m, m), torch.lu(m), torch.lu_solve(m, *torch.lu(m)), torch.lu_unpack(*torch.lu(m)), torch.matmul(m, m), torch.matrix_power(m, 2), # torch.matrix_rank(m), torch.matrix_exp(m), torch.mm(m, m), torch.mv(m, v), # torch.orgqr(a, m), # torch.ormqr(a, m, v), torch.outer(v, v), torch.pinverse(m), # torch.qr(a), torch.solve(m, m), torch.svd(a), # torch.svd_lowrank(a), # torch.pca_lowrank(a), # torch.symeig(a), # deprecated # torch.lobpcg(a, b), # not supported torch.trapz(m, m), torch.trapezoid(m, m), torch.cumulative_trapezoid(m, m), # torch.triangular_solve(m, m), torch.vdot(v, v), )
def average_precision(predictions, ground_truth, iou_threshold): # return the average precision of a class # predictions [train_idx, pred_class, confidence, x, y, w, h] predictions.sort(key=lambda x: x[2], reverse=True) TP_ = torch.zeros((len(predictions))) FP_ = torch.zeros((len(predictions))) gt_used = torch.zeros((len(ground_truth))) for pred_id, pred in enumerate(predictions): # get the label in same image # print("prediction: " + str(pred)) gt_ = [] for bid, bbox in enumerate(ground_truth): if int(bbox[0]) == int(pred[0]) and int(gt_used[bid]) == 0: nbb = [bid] + bbox # print(nbb) gt_.append(nbb) if len(gt_) == 0: FP_[pred_id] = 1 continue best_iou = 0 best_id = 0 for gt in gt_: iou_ = intersection_over_union(torch.tensor(pred[3:]), torch.tensor(gt[4:]), box_format="midpoint") # print("iou_: " + str(iou_)) if iou_ > best_iou: best_iou = iou_ best_id = gt[0] if best_iou >= iou_threshold and int( gt_used[best_id]) == 0: # ground truth haven't checked TP_[pred_id] = 1 gt_used[best_id] = 1 else: FP_[pred_id] = 1 TP_cumsum = torch.cumsum(TP_, dim=0) FP_cumsum = torch.cumsum(FP_, dim=0) rec = TP_cumsum / (len(ground_truth) + 1e-6) pre = torch.divide(TP_cumsum, (TP_cumsum + FP_cumsum + 1e-6)) pre = torch.cat((torch.tensor([1]), pre)) rec = torch.cat((torch.tensor([0]), rec)) # print("gt_used: " + str(gt_used)) # print("pre: " + str(pre)) # print("rec: " + str(rec)) auc = torch.trapz(pre, rec, dim=-1).item() # print("AP: " + str(auc)) return auc
def compute(self) -> Tensor: # Compute true positives, false positives, true negatives, false negatives. self.summary_stats = self.summary_stats.squeeze() false_positives = self.summary_stats[:, 0] true_negatives = self.summary_stats[:, 1] false_negatives = self.summary_stats[:, 2] true_positives = self.summary_stats[:, 3] true_positive_rate = true_positives / (true_positives + false_negatives) false_positive_rate = false_positives / (false_positives + true_negatives) # Compute area under ROC curve. Multiply by -1 because tpr and fpr are computed from the opposite direction. return -1 * torch.trapz(true_positive_rate, false_positive_rate)
def forward(self, x1, x2, diag=False, last_dim_is_batch=False, **kwargs): S = torch.exp(self.latent_params) # density if self.diag_spectrum: Sgrid = S.reshape(1, 1, self.num_locs, self.w2_shape) else: Sgrid = S.reshape(1, 1, self.num_locs, self.num_locs) # reshape variables for broadcasting x1 = x1.reshape(-1, 1, 1, 1) x2 = x2.reshape(1, -1, 1, 1) W1 = self.W1.reshape(1, 1, *self.W1.shape) W2 = self.W2.reshape(1, 1, *self.W2.shape) # (N,N,Nw,Nw) integrand = 0.25 * Sgrid * ( torch.cos(W1 * (x1 - x2)) + torch.cos(W1 * x1 - W2 * x2) + torch.cos(W2 * x1 - W1 * x2) + torch.cos(W2 * (x1 - x2))) # normalization constant Z = torch.trapz(torch.trapz(Sgrid.squeeze(), dx=self.dw), dx=self.dw) # kernel (N, N) output = torch.trapz(torch.trapz(integrand, dx=self.dw), dx=self.dw) / Z if diag: return output.diag() return output
def _auc_compute(x: Tensor, y: Tensor, reorder: bool = False) -> Tensor: if reorder: x, x_idx = _stable_1d_sort(x) y = y[x_idx] dx = x[1:] - x[:-1] if (dx < 0).any(): if (dx <= 0).all(): direction = -1. else: raise ValueError( "The `x` tensor is neither increasing or decreasing." " Try setting the reorder argument to `True`.") else: direction = 1. return direction * torch.trapz(y, x)
def auc( x: torch.Tensor, y: torch.Tensor, reorder: bool = True ) -> torch.Tensor: """ Computes Area Under the Curve (AUC) using the trapezoidal rule Args: x: x-coordinates y: y-coordinates reorder: reorder coordinates, so they are increasing. The unstable algorithm of torch.argsort is used internally to sort `x` which may in some cases cause inaccuracies in the result. WARNING: Deprecated and will be removed in v1.1. Return: Tensor containing AUC score (float) Example: >>> x = torch.tensor([0, 1, 2, 3]) >>> y = torch.tensor([0, 1, 2, 2]) >>> auc(x, y) tensor(4.) """ direction = 1. if reorder: rank_zero_warn("The `reorder` parameter to `auc` has been deprecated and will be removed in v1.1" " Note that when `reorder` is True, the unstable algorithm of torch.argsort is" " used internally to sort 'x' which may in some cases cause inaccuracies" " in the result.", DeprecationWarning) # can't use lexsort here since it is not implemented for torch order = torch.argsort(x) x, y = x[order], y[order] else: dx = x[1:] - x[:-1] if (dx < 0).any(): if (dx, 0).all(): direction = -1. else: # TODO: Update message on removing reorder raise ValueError("Reorder is not turned on, and the 'x' array is" f" neither increasing or decreasing: {x}") return direction * torch.trapz(y, x)
def _auc_compute(x: Tensor, y: Tensor, reorder: bool = False) -> Tensor: with torch.no_grad(): if reorder: # TODO: include stable=True arg when pytorch v1.9 is released x, x_idx = torch.sort(x) y = y[x_idx] dx = x[1:] - x[:-1] if (dx < 0).any(): if (dx <= 0).all(): direction = -1. else: raise ValueError( "The `x` tensor is neither increasing or decreasing." " Try setting the reorder argument to `True`.") else: direction = 1. return direction * torch.trapz(y, x)
def _auc_compute_without_check(x: Tensor, y: Tensor, direction: float) -> Tensor: """Computes area under the curve using the trapezoidal rule. Assumes increasing or decreasing order of `x`. Args: x: x-coordinates, must be either increasing or decreasing y: y-coordinates direction: 1 if increaing, -1 if decreasing Example: >>> x = torch.tensor([0, 1, 2, 3]) >>> y = torch.tensor([0, 1, 2, 2]) >>> x, y = _auc_update(x, y) >>> _auc_compute_without_check(x, y, direction=1.0) tensor(4.) """ with torch.no_grad(): auc_: Tensor = torch.trapz(y, x) * direction return auc_
def make_lambda(self, num_points: int = 1000): """ Compute the lambda matrix used for normalization """ # Compute the raw lambda matrix, computing number of points if needed if self.domain.continuous: points = torch.linspace( self.domain.min_val, self.domain.max_val, steps=num_points ) self.num_points = num_points emb_vecs = self.emb_fun(points) assert emb_vecs.ndim == 2 self.emb_dim = emb_vecs.shape[1] assert emb_vecs.shape[0] == num_points # Get rank-1 matrices for each point, then numerically integrate emb_mats = einsum("bi,bj->bij", emb_vecs, emb_vecs.conj()) lamb_mat = torch.trapz(emb_mats, points, dim=0) else: points = torch.arange(self.domain.max_val).long() emb_vecs = self.emb_fun(points) assert emb_vecs.ndim == 2 self.emb_dim = emb_vecs.shape[1] assert emb_vecs.shape[0] == self.domain.max_val # Get rank-1 matrices for each point, then sum together emb_mats = einsum("bi,bj->bij", emb_vecs, emb_vecs.conj()) lamb_mat = torch.sum(emb_mats, dim=0) assert lamb_mat.ndim == 2 assert lamb_mat.shape[0] == lamb_mat.shape[1] self.lamb_mat = lamb_mat # Check if the computed matrix is diagonal or multiple of the identity if torch.allclose(lamb_mat.diag().diag(), lamb_mat): lamb_mat = lamb_mat.diag() if torch.allclose(lamb_mat.mean(), lamb_mat): self.lamb_mat = lamb_mat.mean() else: self.lamb_mat = lamb_mat
def mAP(self): """ Compute mAP from the TP & FP lists of the evaluation class """ TP = torch.tensor(self.TP) FP = torch.tensor(self.FP) TP_cumsum = torch.cumsum(TP, dim=0) FP_cumsum = torch.cumsum(FP, dim=0) # recall & precision epsilon = 1e-6 recalls = TP_cumsum / (self.total_ground_truth + epsilon) precisions = TP_cumsum / (TP_cumsum + FP_cumsum + epsilon) # torch requirements to calculate area under curve (mAP) recalls = torch.cat((torch.tensor([0]), recalls)) precisions = torch.cat((torch.tensor([1]), precisions)) # mAP = area under precision-recall curve average_precision = torch.trapz(precisions, recalls) return average_precision
def compute(self): """Calculates average recall """ # pylint: disable=no-member # pylint: disable=not-callable ious = torch.tensor(self.ious, dtype=torch.float32) recalls = [] thresholds = torch.arange(start=self.iou_threshold_min, end=self.iou_threshold_max, step=self.iou_step) for th in thresholds: mask = ious >= th recalls.append(ious[mask].size(0) / (ious.size(0) + 1e-16)) recalls = torch.tensor(recalls) average_recall = 2 * torch.trapz(recalls, thresholds) return average_recall
def compute(self, matching_results, data=None): """Computes the average precision, may be used by other metrics. Should not be used as interface (@see BaseMetric for details). Args: matching_results (dict): Pred / Gt matches data (dict, optional): Model inputs (not used) Returns: dict of average precisions. """ # update the p_at_r metric with the current info self._precision_at_recall_metric.similarity_threshold = self.similarity_threshold self._precision_at_recall_metric.reversed_score = self.reversed_score precisions_at_recalls = self._precision_at_recall_metric.compute( matching_results) average_precisions = { class_id: None for class_id in matching_results.keys() } for class_id in matching_results.keys(): precisions = precisions_at_recalls[class_id]['precisions'] recalls = precisions_at_recalls[class_id]['recalls'] assert len(precisions) == len(recalls) if len(precisions) == 0: average_precisions[class_id] = None continue # add start element (needed for trapezoid rule to work) precisions = torch.cat((torch.tensor([1]), precisions)) recalls = torch.cat((torch.tensor([0]), recalls)) # get area under curve avg_precision = torch.trapz(precisions, recalls) average_precisions[class_id] = avg_precision.item() return average_precisions
def test_combined(self): matchings, class_id = self.gen_pseudo_matching_results() metric = AveragePrecision(similarity_threshold=0.5) res = metric.evaluate(matchings, data=None)() # the given boxes are tp, fp, fn (all confidence = 1) # conf decision prec recall # 1.0 TP 1/1 1/2 # 1.0 FP 1/2 1/2 # 1.0 FN 1/2 1/2 precisions = torch.tensor([1, 1 / 2, 1 / 2]) recalls = torch.tensor([1 / 2, 1 / 2, 1 / 2]) # for trapz rule add start point at (x=0,y=1) precisions = torch.cat((torch.tensor([1]), precisions)) recalls = torch.cat((torch.tensor([0]), recalls)) # we have only one class avg_precision = torch.trapz(precisions, recalls) assert np.isclose(res[class_id](), avg_precision)
def test_mlp_embedding(input_dim, num_layers): """ Verify that MLP embedding function runs and gives properly normalized probs """ bond_dim = 10 hidden_dim = 10 embed_fun = init_mlp_embed(input_dim, num_layers=num_layers, hidden_dims=hidden_dim) mps = ProbMPS( seq_len=1, input_dim=input_dim, bond_dim=bond_dim, complex_params=False, embed_fun=embed_fun, ) points = torch.linspace(0, 1, 1000)[:, None] # Add phony spatial dim log_prob_densities = mps(points) assert log_prob_densities.shape == (1000, ) prob_densities = torch.exp(log_prob_densities) total_prob = torch.trapz(prob_densities, points[:, 0]) assert torch.allclose(total_prob, torch.ones(()))
def roc_auc_score(y_true, y_score): """Pytorch implementation almost follows sklearn Args: y_true (Tensor): y_score (Tensor): """ device = y_true.device y_true.squeeze_() y_score.squeeze_() if y_true.shape != y_score.shape: raise TypeError( F"Shapre of y_true and y_score must match. Got {y_true.shape()} and {y_score.shape()}." ) desc_score_indices = torch.argsort(y_score, descending=True) y_score = y_score[desc_score_indices] y_true = y_true[desc_score_indices] distinct_value_indices = torch.nonzero(y_score[1:] - y_score[:-1], as_tuple=False).squeeze() threshold_idxs = torch.cat([ distinct_value_indices, torch.tensor([y_true.numel() - 1], device=device) ]) tps = torch.cumsum(y_true, dim=0)[threshold_idxs] fps = 1 + threshold_idxs - tps tps = torch.cat([torch.zeros(1, device=device), tps]) fps = torch.cat([torch.zeros(1, device=device), fps]) fpr = fps / fps[-1] tpr = tps / tps[-1] area = torch.trapz(tpr, fpr) return area