def execute(self, x): if self.num_parameters != 1: assert self.num_parameters == x.size( 1), f"num_parameters does not match input channels in PReLU" return jt.maximum( 0, x) + self.a.broadcast(x, [0, 2, 3]) * jt.minimum(0, x) else: return jt.maximum(0, x) + self.a * jt.minimum(0, x)
def partCombiner2_bg(center, eyel, eyer, nose, mouth, hair, bg, maskh, maskb, comb_op=1, load_h=512, load_w=512): if comb_op == 0: # use max pooling, pad black for eyes etc padvalue = -1 hair = masked(hair, maskh) bg = masked(bg, maskb) else: # use min pooling, pad white for eyes etc padvalue = 1 hair = addone_with_mask(hair, maskh) bg = addone_with_mask(bg, maskb) ratio = load_h // 256 rhs = np.array([EYE_H, EYE_H, NOSE_H, MOUTH_H]) * ratio rws = np.array([EYE_W, EYE_W, NOSE_W, MOUTH_W]) * ratio bs, nc, _, _ = eyel.shape eyel_p = jt.ones((bs, nc, load_h, load_w)) eyer_p = jt.ones((bs, nc, load_h, load_w)) nose_p = jt.ones((bs, nc, load_h, load_w)) mouth_p = jt.ones((bs, nc, load_h, load_w)) locals = [eyel, eyer, nose, mouth] locals_p = [eyel_p, eyer_p, nose_p, mouth_p] for i in range(bs): c = center[i].data #x,y for j in range(4): locals_p[j][i] = jt.nn.ConstantPad2d( (int(c[j, 0] - rws[j] / 2), int(load_w - (c[j, 0] + rws[j] / 2)), int(c[j, 1] - rhs[j] / 2), int(load_h - (c[j, 1] + rhs[j] / 2))), padvalue)(locals[j][i]) if comb_op == 0: eyes = jt.maximum(locals_p[0], locals_p[1]) eye_nose = jt.maximum(eyes, locals_p[2]) eye_nose_mouth = jt.maximum(eye_nose, locals_p[3]) eye_nose_mouth_hair = jt.maximum(hair, eye_nose_mouth) result = jt.maximum(bg, eye_nose_mouth_hair) else: eyes = jt.minimum(locals_p[0], locals_p[1]) eye_nose = jt.minimum(eyes, locals_p[2]) eye_nose_mouth = jt.minimum(eye_nose, locals_p[3]) eye_nose_mouth_hair = jt.minimum(hair, eye_nose_mouth) result = jt.minimum(bg, eye_nose_mouth_hair) return result
def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): # Returns the IoU of box1 to box2. box1 is 4, box2 is nx4 box2 = box2.transpose(1, 0) # Get the coordinates of bounding boxes if x1y1x2y2: # x1, y1, x2, y2 = box1 b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3] b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3] else: # transform from xywh to xyxy b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2 b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2 b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2 b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2 # Intersection area inter = (jt.minimum(b1_x2, b2_x2) - jt.maximum(b1_x1, b2_x1)).clamp(0) * \ (jt.minimum(b1_y2, b2_y2) - jt.maximum(b1_y1, b2_y1)).clamp(0) # Union Area w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps union = w1 * h1 + w2 * h2 - inter + eps iou = inter / union if GIoU or DIoU or CIoU: cw = jt.maximum(b1_x2, b2_x2) - jt.minimum( b1_x1, b2_x1) # convex (smallest enclosing box) width ch = jt.maximum(b1_y2, b2_y2) - jt.minimum(b1_y1, b2_y1) # convex height if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 c2 = cw**2 + ch**2 + eps # convex diagonal squared rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2)**2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2)** 2) / 4 # center distance squared if DIoU: return iou - rho2 / c2 # DIoU elif CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47 v = (4 / math.pi**2) * jt.pow( jt.atan(w2 / h2) - jt.atan(w1 / h1), 2) with jt.no_grad(): alpha = v / (v - iou + (1 + eps)) return iou - (rho2 / c2 + v * alpha) # CIoU else: # GIoU https://arxiv.org/pdf/1902.09630.pdf c_area = cw * ch + eps # convex area return iou - (c_area - union) / c_area # GIoU else: return iou # IoU
def sample_pdf(bins, weights, N_samples, det=False): # Get pdf weights = weights + 1e-5 # prevent nans pdf = weights / jt.sum(weights, -1, keepdims=True) cdf = jt.cumsum(pdf, -1) cdf = jt.concat([jt.zeros_like(cdf[..., :1]), cdf], -1) # (batch, len(bins)) # Take uniform samples if det: u = jt.linspace(0., 1., steps=N_samples) u = u.expand(list(cdf.shape[:-1]) + [N_samples]) else: u = jt.random(list(cdf.shape[:-1]) + [N_samples]) # Invert CDF inds = jt.searchsorted(cdf, u, right=True) below = jt.maximum(jt.zeros_like(inds - 1), inds - 1) above = jt.minimum((cdf.shape[-1] - 1) * jt.ones_like(inds), inds) inds_g = jt.stack([below, above], -1) # (batch, N_samples, 2) matched_shape = [inds_g.shape[0], inds_g.shape[1], cdf.shape[-1]] cdf_g = jt.gather(cdf.unsqueeze(1).expand(matched_shape), 2, inds_g) bins_g = jt.gather(bins.unsqueeze(1).expand(matched_shape), 2, inds_g) denom = (cdf_g[..., 1] - cdf_g[..., 0]) denom[denom < 1e-5] = 1.0 t = (u - cdf_g[..., 0]) / denom samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0]) return samples
def metric(k): # compute metric r = wh[:, None] / k[None] x = jt.minimum(r, 1. / r).min(2) # ratio metric best = x.max(1) # best_x aat = (x > 1. / thr).float().sum(1).mean() # anchors above threshold bpr = (best > 1. / thr).float().mean() # best possible recall return bpr, aat
def wh_iou(wh1, wh2): # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2 wh1 = wh1[:, None] # [N,1,2] wh2 = wh2[None] # [1,M,2] inter = jt.minimum(wh1, wh2).prod(2) # [N,M] return inter / (wh1.prod(2) + wh2.prod(2) - inter ) # iou = inter / (area1 + area2 - inter)
def training_step(self, batch, batch_idx): noises = jt.array( np.random.randn(*batch['action'].shape).astype(np.float32) ) * self.FLAGS.policy_noise # TODO: use jt randomness noises = noises.clamp(-self.FLAGS.noise_clip, self.FLAGS.noise_clip) next_actions = self.policy_target( batch['next_observation']).add(noises).clamp(-1, 1) next_qfs = [ qfn(batch['next_observation'], next_actions) for qfn in self.qfns_target ] min_next_qf = jt.minimum(next_qfs[0], next_qfs[1]) qf_ = (batch['reward'] + (1 - batch['done'].float32()) * self.FLAGS.gamma * min_next_qf).detach() qfn_losses = [ nn.mse_loss(qfn(batch['observation'], batch['action']), qf_) for qfn in self.qfns ] self.qfns_opt.step(qfn_losses[0] + qfn_losses[1]) if self.n_batches % self.FLAGS.policy_freq == 0: policy_loss = -self.qfns[0](batch['observation'], self.policy( batch['observation'])).mean() self.policy_opt.step(policy_loss) polyak_copy(self.policy, self.policy_target, self.FLAGS.tau) for qfn, qfn_target in zip(self.qfns, self.qfns_target): polyak_copy(qfn, qfn_target, self.FLAGS.tau) return {'loss': [qfn_loss.data for qfn_loss in qfn_losses]}
def execute(self, pred, target, weight=None): pred_left = pred[:, 0] pred_top = pred[:, 1] pred_right = pred[:, 2] pred_bottom = pred[:, 3] target_left = target[:, 0] target_top = target[:, 1] target_right = target[:, 2] target_bottom = target[:, 3] target_area = (target_left + target_right) * \ (target_top + target_bottom) pred_area = (pred_left + pred_right) * \ (pred_top + pred_bottom) w_intersect = jt.minimum(pred_left, target_left) + jt.minimum( pred_right, target_right) g_w_intersect = jt.maximum(pred_left, target_left) + jt.maximum( pred_right, target_right) h_intersect = jt.minimum(pred_bottom, target_bottom) + jt.minimum( pred_top, target_top) g_h_intersect = jt.maximum(pred_bottom, target_bottom) + jt.maximum( pred_top, target_top) ac_uion = g_w_intersect * g_h_intersect + 1e-7 area_intersect = w_intersect * h_intersect area_union = target_area + pred_area - area_intersect ious = (area_intersect + 1.0) / (area_union + 1.0) gious = ious - (ac_uion - area_union) / ac_uion if self.loc_loss_type == 'iou': losses = -jt.log(ious) elif self.loc_loss_type == 'linear_iou': losses = 1 - ious elif self.loc_loss_type == 'giou': losses = 1 - gious else: raise NotImplementedError if weight is not None and weight.sum() > 0: return (losses * weight).sum() / weight.sum() else: assert losses.numel() != 0 return losses.mean()
def test_min(self): np.random.seed(1) a = np.random.rand(5,10).astype("float32") b = np.random.rand(5,10).astype("float32") ja = jt.array(a) jb = jt.array(b) jc = jt.minimum(ja,jb) assert (jc.data==np.minimum(a,b)).all(), f"\n{jc.data}\n{np.minimum(a,b)}\n{a}\n{b}" jda, jdb = jt.grad(jc, [ja, jb]) assert (jda.data==(a<b)*1).all() assert (jdb.data==1-(a<b)).all()
def bbox_iou(bbox_a, bbox_b): assert bbox_a.shape[1]==4 and bbox_b.shape[1]==4 # top left tl = jt.maximum(bbox_a[:, :2].unsqueeze(1), bbox_b[:, :2]) # bottom right br = jt.minimum(bbox_a[:,2:].unsqueeze(1), bbox_b[:, 2:]) area_i = jt.prod(br - tl, dim=2) * (tl < br).all(dim=2) area_a = jt.prod(bbox_a[:, 2:] - bbox_a[:, :2], dim=1) area_b = jt.prod(bbox_b[:, 2:] - bbox_b[:, :2], dim=1) return area_i / (area_a.unsqueeze(1) + area_b - area_i)
def elemwise_box_iou(box_a, box_b): """ Does the same as above but instead of pairwise, elementwise along the inner dimension. """ max_xy = jt.minimum(box_a[:, 2:], box_b[:, 2:]) min_xy = jt.maximum(box_a[:, :2], box_b[:, :2]) inter = jt.clamp((max_xy - min_xy), min_v=0) inter = inter[:, 0] * inter[:, 1] area_a = (box_a[:, 2] - box_a[:, 0]) * (box_a[:, 3] - box_a[:, 1]) area_b = (box_b[:, 2] - box_b[:, 0]) * (box_b[:, 3] - box_b[:, 1]) union = area_a + area_b - inter union = jt.clamp(union, min_v=0.1) # Return value is [n] for inputs [n, 4] return jt.clamp(inter / union, max_v=1)
def intersect(box_a, box_b): """ We resize both tensors to [A,B,2] without new malloc: [A,2] -> [A,1,2] -> [A,B,2] [B,2] -> [1,B,2] -> [A,B,2] Then we compute the area of intersect between box_a and box_b. Args: box_a: (tensor) bounding boxes, Shape: [n,A,4]. box_b: (tensor) bounding boxes, Shape: [n,B,4]. Return: (tensor) intersection area, Shape: [n,A,B]. """ n = box_a.shape[0] A = box_a.shape[1] B = box_b.shape[1] max_xy = jt.minimum(box_a[:, :, 2:].unsqueeze(2).expand((n, A, B, 2)), box_b[:, :, 2:].unsqueeze(1).expand((n, A, B, 2))) min_xy = jt.maximum(box_a[:, :, :2].unsqueeze(2).expand((n, A, B, 2)), box_b[:, :, :2].unsqueeze(1).expand((n, A, B, 2))) return jt.clamp(max_xy - min_xy, min_v=0).prod(3) # inter
def intersect(box_a, box_b): """ We resize both tensors to [A,B,2] without new malloc: [A,2] -> [A,1,2] -> [A,B,2] [B,2] -> [1,B,2] -> [A,B,2] Then we compute the area of intersect between box_a and box_b. Args: box_a: (tensor) bounding boxes, Shape: [A,4]. box_b: (tensor) bounding boxes, Shape: [B,4]. Return: (tensor) intersection area, Shape: [A,B]. """ A = box_a.size(0) B = box_b.size(0) max_xy = jt.minimum(box_a[:, 2:].unsqueeze(1).expand(A, B, 2), box_b[:, 2:].unsqueeze(0).expand(A, B, 2)) min_xy = jt.maximum(box_a[:, :2].unsqueeze(1).expand(A, B, 2), box_b[:, :2].unsqueeze(0).expand(A, B, 2)) inter = jt.clamp((max_xy - min_xy), min_v=0) return inter[:, :, 0] * inter[:, :, 1]
def boxlist_partly_overlap(boxlist1, boxlist2): """Compute the intersection over union of two set of boxes. The box order must be (xmin, ymin, xmax, ymax). Arguments: box1: (BoxList) bounding boxes, sized [N,4]. box2: (BoxList) bounding boxes, sized [M,4]. Returns: (tensor) iou, sized [N,M]. Reference: https://github.com/chainer/chainercv/blob/master/chainercv/utils/bbox/bbox_iou.py """ if boxlist1.size != boxlist2.size: raise RuntimeError( "boxlists should have same image size, got {}, {}".format( boxlist1, boxlist2)) N = len(boxlist1) M = len(boxlist2) area1 = boxlist1.area() area2 = boxlist2.area() box1, box2 = boxlist1.bbox, boxlist2.bbox lt = jt.maximum(box1[:, :2].unsqueeze(1), box2[:, :2]) # [N,M,2] rb = jt.minimum(box1[:, 2:].unsqueeze(1), box2[:, 2:]) # [N,M,2] TO_REMOVE = 1 wh = (rb - lt + TO_REMOVE).clamp(min_v=0, max_v=999999) # [N,M,2] inter = wh[:, :, 0] * wh[:, :, 1] # [N,M] iou = inter / (area1[:].unsqueeze(1) + area2 - inter) overlap = iou > 0 not_complete_overlap = (inter - area1[:].unsqueeze(1)) * ( inter - area2[:].unsqueeze(0)) != 0 partly_overlap = overlap * not_complete_overlap return partly_overlap
def sanitize_coordinates(_x1, _x2, img_size: int, padding: int = 0, cast: bool = True): """ Sanitizes the input coordinates so that x1 < x2, x1 != x2, x1 >= 0, and x2 <= image_size. Also converts from relative to absolute coordinates and casts the results to long tensors. If cast is false, the result won't be cast to longs. Warning: this does things in-place behind the scenes so copy if necessary. """ _x1 = _x1 * img_size _x2 = _x2 * img_size if cast: _x1 = _x1.int32() _x2 = _x2.int32() x1 = jt.minimum(_x1, _x2) x2 = jt.maximum(_x1, _x2) x1 = jt.clamp(x1 - padding, min_v=0) x2 = jt.clamp(x2 + padding, max_v=img_size) return x1, x2
def clip_grad_norm(self, max_norm:float, norm_type:int=2): r"""Clips gradient norm of this optimizer. The norm is computed over all gradients together. Args: max_norm (float or int): max norm of the gradients norm_type (int): 1-norm or 2-norm Example:: a = jt.ones(2) opt = jt.optim.SGD([a], 0.1) loss = a*a opt.zero_grad() opt.backward(loss) print(opt.param_groups[0]['grads'][0].norm()) # output: 2.83 opt.clip_grad_norm(0.01, 2) print(opt.param_groups[0]['grads'][0].norm()) # output: 0.01 opt.step() """ if self.__zero_grad: return grads = [] for pg in self.param_groups: for p, g in zip(pg["params"], pg["grads"]): if p.is_stop_grad(): continue grads.append(g.flatten()) if len(grads) == 0: return total_norm = jt.norm(jt.concat(grads), norm_type) clip_coef = jt.minimum(max_norm / (total_norm + 1e-6), 1.0) for pg in self.param_groups: for p, g in zip(pg["params"], pg["grads"]): if p.is_stop_grad(): continue g *= clip_coef
def box_iou(box1, box2): # https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py """ Return intersection-over-union (Jaccard index) of boxes. Both sets of boxes are expected to be in (x1, y1, x2, y2) format. Arguments: box1 (Tensor[N, 4]) box2 (Tensor[M, 4]) Returns: iou (Tensor[N, M]): the NxM matrix containing the pairwise IoU values for every element in boxes1 and boxes2 """ def box_area(box): # box = 4xn return (box[2] - box[0]) * (box[3] - box[1]) area1 = box_area(box1.transpose(1, 0)) area2 = box_area(box2.transpose(1, 0)) # inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) inter = (jt.minimum(box1[:, None, 2:], box2[:, 2:]) - jt.maximum(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2) return inter / (area1[:, None] + area2 - inter ) # iou = inter / (area1 + area2 - inter)
def relu6(x): return jt.minimum(jt.maximum(x, 0), 6)
def metric(k, wh): # compute metrics r = wh[:, None] / k[None] x = jt.minimum(r, 1. / r).min(2) # ratio metric # x = wh_iou(wh, torch.tensor(k)) # iou metric return x, x.max(1) # x, best_x
def relu6(x): return jt.minimum(jt.maximum(x, 0), 6) class PReLU(Module):