def top_k_top_p_filtering(logits, top_k=0, top_p=1.0, filter_value=-float('Inf')): """ Filter a distribution of logits using top-k and/or nucleus (top-p) filtering Args: logits: logits distribution shape (vocabulary size) top_k > 0: keep only top k tokens with highest probability (top-k filtering). top_p > 0.0: keep the top tokens with cumulative probability >= top_p (nucleus filtering). Nucleus filtering is described in Holtzman et al. (http://arxiv.org/abs/1904.09751) From: https://gist.github.com/thomwolf/1a5a29f6962089e871b94cbd09daf317 """ top_k = min(top_k, logits.shape[-1]) # Safety check logits_np = logits.numpy() if top_k > 0: # Remove all tokens with a probability less than the last token of the top-k indices_to_remove = logits_np < np.sort(logits_np)[-top_k] logits_np[indices_to_remove] = filter_value if top_p < 1.0: sorted_logits = paddle.sort(logits, descending=True) sorted_indices = paddle.argsort(logits, descending=True).numpy() cumulative_probs = paddle.cumsum(paddle.nn.functional.softmax(sorted_logits, axis=-1), axis=-1).numpy() # Remove tokens with cumulative probability above the threshold sorted_indices_to_remove = cumulative_probs > top_p # Shift the indices to the right to keep also the first token above the threshold sorted_indices_to_remove[..., 1:] = sorted_indices_to_remove[..., :-1] sorted_indices_to_remove[..., 0] = 0 indices_to_remove = sorted_indices[sorted_indices_to_remove] logits_np[indices_to_remove] = filter_value return paddle.to_tensor(logits_np)
def hard_nms(box_scores, iou_threshold, top_k=-1, candidate_size=200): """ Args: box_scores (N, 5): boxes in corner-form and probabilities. iou_threshold: intersection over union threshold. top_k: keep top_k results. If k <= 0, keep all the results. candidate_size: only consider the candidates with the highest scores. Returns: picked: a list of indexes of the kept boxes """ scores = box_scores[:, -1] boxes = box_scores[:, :-1] picked = [] _, indexes = paddle.sort(scores, descending=True) indexes = indexes[:candidate_size] while len(indexes) > 0: current = indexes[0] picked.append(current.item()) if 0 < top_k == len(picked) or len(indexes) == 1: break current_box = boxes[current, :] indexes = indexes[1:] rest_boxes = boxes[indexes, :] iou = iou_of( rest_boxes, current_box.unsqueeze(0), ) indexes = indexes[iou <= iou_threshold] return box_scores[picked, :]
def ohem_single(self, score, gt_text, training_mask, ohem_ratio=3): pos_num = int(paddle.sum((gt_text > 0.5).astype('float32'))) - int( paddle.sum( paddle.logical_and((gt_text > 0.5), (training_mask <= 0.5)) .astype('float32'))) if pos_num == 0: selected_mask = training_mask selected_mask = selected_mask.reshape( [1, selected_mask.shape[0], selected_mask.shape[1]]).astype( 'float32') return selected_mask neg_num = int(paddle.sum((gt_text <= 0.5).astype('float32'))) neg_num = int(min(pos_num * ohem_ratio, neg_num)) if neg_num == 0: selected_mask = training_mask selected_mask = selected_mask.view( 1, selected_mask.shape[0], selected_mask.shape[1]).astype('float32') return selected_mask neg_score = paddle.masked_select(score, gt_text <= 0.5) neg_score_sorted = paddle.sort(-neg_score) threshold = -neg_score_sorted[neg_num - 1] selected_mask = paddle.logical_and( paddle.logical_or((score >= threshold), (gt_text > 0.5)), (training_mask > 0.5)) selected_mask = selected_mask.reshape( [1, selected_mask.shape[0], selected_mask.shape[1]]).astype( 'float32') return selected_mask
def forward(self, logit, label): n, c, h, w = logit.shape total_loss = 0.0 if len(label.shape) != len(logit.shape): label = paddle.unsqueeze(label, 1) for i in range(n): x = paddle.unsqueeze(logit[i], 0) y = paddle.unsqueeze(label[i], 0) x = paddle.transpose(x, (0, 2, 3, 1)) y = paddle.transpose(y, (0, 2, 3, 1)) x = paddle.reshape(x, shape=(-1, c)) y = paddle.reshape(y, shape=(-1, )) loss = F.cross_entropy(x, y, weight=self.weight, ignore_index=self.ignore_index, reduction="none") sorted_loss = paddle.sort(loss, descending=True) if sorted_loss[self.K] > self.threshold: new_indices = paddle.nonzero(sorted_loss > self.threshold) loss = paddle.gather(sorted_loss, new_indices) else: loss = sorted_loss[:self.K] total_loss += paddle.mean(loss) return total_loss / float(n)
def test_api_1(self): paddle.disable_static(self.place) var_x = paddle.to_variable(self.input_data) out = paddle.sort(var_x, axis=-1) self.assertEqual((np.sort(self.input_data, axis=-1) == out.numpy()).all(), True) paddle.enable_static()
def TopPProcess(probs, top_p, min_tokens_to_keep): sorted_probs = paddle.sort(probs, descending=True) sorted_indices = paddle.argsort(probs, descending=True) cumulative_probs = paddle.cumsum(sorted_probs, axis=-1) # Remove tokens with cumulative probs above the top_p, But keep at # least min_tokens_to_keep tokens sorted_indices_to_remove = cumulative_probs > top_p if min_tokens_to_keep > 1: # Set 'min_tokens_to_keep - 1' because the first token is kept sorted_indices_to_remove[:, :min_tokens_to_keep - 1] = 0 # Keep the first token sorted_indices_to_remove = paddle.cast(sorted_indices_to_remove, dtype='int64') sorted_indices_to_remove[:, 1:] = ( sorted_indices_to_remove[:, :-1].clone()) sorted_indices_to_remove[:, 0] = 0 # Scatter sorted tensors to original indexing sorted_indices = sorted_indices + paddle.arange( probs.shape[0]).unsqueeze(-1) * probs.shape[-1] condition = paddle.scatter(sorted_indices_to_remove.flatten(), sorted_indices.flatten(), sorted_indices_to_remove.flatten()) condition = paddle.cast(condition, 'bool').reshape(probs.shape) probs = paddle.where(condition, paddle.full_like(probs, 0.0), probs) return probs
def test_api_1(self): with fluid.program_guard(fluid.Program()): input = fluid.data(name="input", shape=[2, 3, 4], dtype="float32") output = paddle.sort(x=input, axis=1) exe = fluid.Executor(self.place) data = np.array([[[5, 8, 9, 5], [0, 0, 1, 7], [6, 9, 2, 4]], [[5, 2, 4, 2], [4, 7, 7, 9], [1, 7, 0, 6]]], dtype='float32') result, = exe.run(feed={'input': data}, fetch_list=[output]) np_result = np.sort(result, axis=1) self.assertEqual((result == np_result).all(), True)
def ohem_single(score, gt_text, training_mask): gt_part = paddle.cast(gt_text > 0.5, dtype='float32') gt_tr_part = paddle.cast(paddle.logical_and(gt_text > 0.5, training_mask <= 0.5), dtype='float32') pos_num = int(paddle.sum(gt_part)) - int(paddle.sum(gt_tr_part)) #pos_num = int(np.sum(gt_text.numpy() > 0.5)) - int(np.sum((gt_text.numpy() > 0.5) & (training_mask.numpy() <= 0.5))) #pos_num = int(paddle.sum(gt_text > 0.5)) - int(paddle.sum((gt_text > 0.5) & (training_mask <= 0.5))) if pos_num == 0: # selected_mask = gt_text.copy() * 0 # may be not good selected_mask = training_mask selected_mask = paddle.reshape( selected_mask, (1, selected_mask.shape[0], selected_mask.shape[1])) selected_mask = paddle.cast(selected_mask, dtype='float32') return selected_mask neg_num = int(np.sum(gt_text.numpy() <= 0.5)) neg_num = int(min(pos_num * 3, neg_num)) if neg_num == 0: selected_mask = training_mask # selected_mask = selected_mask.view(1, selected_mask.shape[0], selected_mask.shape[1]).float() selected_mask = paddle.reshape( selected_mask, (1, selected_mask.shape[0], selected_mask.shape[1])) selected_mask = paddle.cast(selected_mask, dtype='float32') return selected_mask gt_text_flatten = paddle.reshape(gt_text, (-1, )) index = where(gt_text_flatten <= 0.5) index = paddle.reshape(index, (1, -1)) score_flatten = paddle.reshape(score, (1, -1)) neg_score = paddle.index_sample(score_flatten, index) neg_score = paddle.reshape(neg_score, (-1, )) neg_score_sorted = paddle.sort(-neg_score) threshold = -neg_score_sorted[neg_num - 1] item1 = paddle.logical_or(score >= threshold, gt_text > 0.5) selected_mask = paddle.logical_and(item1, training_mask > 0.5) # selected_mask = selected_mask.reshape(1, selected_mask.shape[0], selected_mask.shape[1]).float() selected_mask = paddle.reshape( selected_mask, (1, selected_mask.shape[0], selected_mask.shape[1])) #selected_mask = selected_mask.reshape(1, selected_mask.shape[0], selected_mask.shape[1]) selected_mask = paddle.cast(selected_mask, dtype='float32') return selected_mask
def forward(self, xyz1, xyz2, points1, points2): """ Input: xyz1: input points position data, [B, C, N] xyz2: sampled input points position data, [B, C, S] points1: input points data, [B, D, N] points2: input points data, [B, D, S] Return: new_points: upsampled points data, [B, D', N] """ xyz1 = xyz1.transpose([0, 2, 1]) xyz2 = xyz2.transpose([0, 2, 1]) points2 = points2.transpose([0, 2, 1]) B, N, C = xyz1.shape _, S, _ = xyz2.shape if S == 1: interpolated_points = paddle.tile(points2, [1, N, 1]) else: dists = square_distance(xyz1, xyz2) dists = paddle.sort(dists, axis=-1) idx = paddle.argsort(dists, axis=-1) dists, idx = dists[:, :, :3], idx[:, :, :3] # [B, N, 3] dist_recip = 1.0 / (dists + 1e-8) norm = paddle.sum(dist_recip, axis=2, keepdim=True) weight = dist_recip / norm interpolated_points = paddle.sum(index_points(points2, idx) * weight.reshape([B, N, 3, 1]), axis=2) if points1 is not None: points1 = points1.transpose([0, 2, 1]) new_points = paddle.concat([points1, interpolated_points], axis=-1) else: new_points = interpolated_points new_points = new_points.transpose([0, 2, 1]) for i, conv in enumerate(self.mlp_convs): bn = self.mlp_bns[i] new_points = F.relu(bn(conv(new_points))) return new_points
def func_api_0(self): paddle.disable_static(self.place) var_x = paddle.to_tensor(self.input_data) out = paddle.sort(var_x) self.assertEqual((np.sort(self.input_data) == out.numpy()).all(), True) paddle.enable_static()
def _compute_quantile(x, q, axis=None, keepdim=False, ignore_nan=False): """ Compute the quantile of the input along the specified axis. Args: Args: x (Tensor): The input Tensor, it's data type can be float32, float64. q (int|float|list): The q for calculate quantile, which should be in range [0, 1]. If q is a list, each q will be calculated and the first dimension of output is same to the number of ``q`` . axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int. ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` . If ``axis`` is less than 0, it works the same way as :math:`axis + D`. If ``axis`` is a list, quantile is calculated over all elements of given axises. If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None. keepdim (bool, optional): Whether to reserve the reduced dimension(s) in the output Tensor. If ``keepdim`` is True, the dimensions of the output Tensor is the same as ``x`` except in the reduced dimensions(it is of size 1 in this case). Otherwise, the shape of the output Tensor is squeezed in ``axis`` . Default is False. ignore_nan: (bool, optional): Whether to ignore NaN of input Tensor. If ``ignore_nan`` is True, it will calculate nanquantile. Otherwise it will calculate quantile. Default is False. Returns: Tensor, results of quantile along ``axis`` of ``x``. In order to obtain higher precision, data type of results will be float64. """ # Validate x if not isinstance(x, Variable): raise TypeError("input x should be a Tensor.") # Validate q if isinstance(q, (int, float)): q = [q] elif isinstance(q, (list, tuple)): if len(q) <= 0: raise ValueError("q should not be empty") else: raise TypeError("Type of q should be int, float, list or tuple.") # Validate axis dims = len(x.shape) out_shape = list(x.shape) if axis is None: x = paddle.flatten(x) axis = 0 out_shape = [1] * dims else: if isinstance(axis, list): if len(axis) <= 0: raise ValueError("axis should not be empty") axis_src, axis_dst = [], [] for axis_single in axis: if not isinstance(axis_single, int) or not ( axis_single < dims and axis_single >= -dims): raise ValueError( "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))." ) if axis_single < 0: axis_single = axis_single + dims axis_src.append(axis_single) out_shape[axis_single] = 1 axis_dst = list(range(-len(axis), 0)) x = paddle.moveaxis(x, axis_src, axis_dst) x = paddle.flatten(x, axis_dst[0], axis_dst[-1]) axis = axis_dst[0] else: if not isinstance(axis, int) or not (axis < dims and axis >= -dims): raise ValueError( "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))." ) if axis < 0: axis += dims out_shape[axis] = 1 mask = x.isnan() valid_counts = mask.logical_not().sum(axis=axis, keepdim=True, dtype='float64') indices = [] for q_num in q: if q_num < 0 or q_num > 1: raise ValueError("q should be in range [0, 1]") if paddle.in_dynamic_mode(): q_num = paddle.to_tensor(q_num, dtype='float64') if ignore_nan: indices.append(q_num * (valid_counts - 1)) else: # TODO(Asthestarsfalll): Use paddle.index_fill instead of where index = q_num * (valid_counts - 1) last_index = x.shape[axis] - 1 nums = paddle.full_like(index, fill_value=last_index) index = paddle.where(mask.any(axis=axis, keepdim=True), nums, index) indices.append(index) sorted_tensor = paddle.sort(x, axis) outputs = [] # TODO(chenjianye): replace the for-loop to directly take elements. for index in indices: indices_below = paddle.floor(index).astype(paddle.int32) indices_upper = paddle.ceil(index).astype(paddle.int32) tensor_upper = paddle.take_along_axis( sorted_tensor, indices_upper, axis=axis) tensor_below = paddle.take_along_axis( sorted_tensor, indices_below, axis=axis) weights = (index - indices_below.astype('float64')) out = paddle.lerp( tensor_below.astype('float64'), tensor_upper.astype('float64'), weights) if not keepdim: out = paddle.squeeze(out, axis=axis) else: out = out.reshape(out_shape) outputs.append(out) if len(q) > 1: outputs = paddle.stack(outputs, 0) else: outputs = outputs[0] return outputs
def quantile(x, q, axis=None, keepdim=False): """ Compute the quantile of the input along the specified axis. Args: x (Tensor): The input Tensor, it's data type can be float32, float64. q (int|float|list): The q for calculate quantile, which should be in range [0, 1]. If q is a list, each q will be calculated and the first dimension of output is same to the number of ``q`` . axis (int|list, optional): The axis along which to calculate quantile. ``axis`` should be int or list of int. ``axis`` should be in range [-D, D), where D is the dimensions of ``x`` . If ``axis`` is less than 0, it works the same way as :math:`axis + D`. If ``axis`` is a list, quantile is calculated over all elements of given axises. If ``axis`` is None, quantile is calculated over all elements of ``x``. Default is None. keepdim (bool, optional): Whether to reserve the reduced dimension(s) in the output Tensor. If ``keepdim`` is True, the dimensions of the output Tensor is the same as ``x`` except in the reduced dimensions(it is of size 1 in this case). Otherwise, the shape of the output Tensor is squeezed in ``axis`` . Default is False. name (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`. Returns: Tensor, results of quantile along ``axis`` of ``x``. If data type of ``x`` is float64, data type of results will be float64, otherwise data type will be float32. Examples: .. code-block:: python import paddle x = paddle.randn((2,3)) #[[-1.28740597, 0.49533170, -1.00698614], # [-1.11656201, -1.01010525, -2.23457789]]) y1 = paddle.quantile(x, q=0.5, axis=[0, 1]) # y1 = -1.06333363 y2 = paddle.quantile(x, q=0.5, axis=1) # y2 = [-1.00698614, -1.11656201] y3 = paddle.quantile(x, q=[0.3, 0.5], axis=1) # y3 =[[-1.11915410, -1.56376839], # [-1.00698614, -1.11656201]] y4 = paddle.quantile(x, q=0.8, axis=1, keepdim=True) # y4 = [[-0.10559537], # [-1.05268800]]) """ if not isinstance(x, Variable): raise TypeError("input x should be a Tensor.") dims = len(x.shape) out_shape = x.shape if axis is None: x = paddle.flatten(x) axis = 0 out_shape = [1] * dims else: if isinstance(axis, list): if (len(axis) <= 0): raise ValueError("axis should not be empty") axis_src, axis_dst = [], [] for axis_single in axis: if not isinstance(axis_single, int) or not ( axis_single < dims and axis_single >= -dims): raise ValueError( "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))." ) if axis_single < 0: axis_single = axis_single + dims axis_src.append(axis_single) out_shape[axis_single] = 1 axis_dst = list(range(-len(axis), 0)) x = paddle.moveaxis(x, axis_src, axis_dst) x = paddle.flatten(x, axis_dst[0], axis_dst[-1]) axis = axis_dst[0] else: if not isinstance(axis, int) or not (axis < dims and axis >= -dims): raise ValueError( "Axis should be None, int, or a list, element should in range [-rank(x), rank(x))." ) if axis < 0: axis += dims out_shape[axis] = 1 indices = [] if isinstance(q, (int, float)): if q < 0 or q > 1: raise ValueError("q should be in range [0, 1]") indices.append(q * (x.shape[axis] - 1)) elif isinstance(q, (list, tuple)): if len(q) <= 0: raise ValueError("q should not be empty") for q_num in q: if q_num < 0 or q_num > 1: raise ValueError("q should be in range [0, 1]") indices.append(q_num * (x.shape[axis] - 1)) else: raise TypeError("Type of q should be int, float, list or tuple.") indices = paddle.to_tensor(indices).astype(paddle.float32) sorted_tensor = paddle.sort(x, axis) indices_below = paddle.floor(indices).astype(paddle.int32) indices_upper = paddle.ceil(indices).astype(paddle.int32) outputs = [] # TODO(chenjianye): replace the for-loop to directly take elements. for i in range(len(indices)): if (indices_upper[i] != indices_below[i]): tensor_below = paddle.take_along_axis(sorted_tensor, indices_below[i], axis) tensor_upper = paddle.take_along_axis(sorted_tensor, indices_upper[i], axis) weights = (indices[i] - indices_below[i]).astype(x.dtype) out = paddle.lerp(tensor_below, tensor_upper, weights) else: out = paddle.take_along_axis(sorted_tensor, indices_below[i], axis) if not keepdim: out = paddle.squeeze(out, axis=axis) else: out = out.reshape(out_shape) outputs.append(out) if isinstance(q, (list, tuple)): return paddle.stack(outputs, 0) else: return outputs[0]
def sort(x, axis=1, descending=False): return convertTensor( paddle.sort(x, axis=axis, descending=descending, name=None))