Beispiel #1
0
    def product(self, tensor_in, axis=None):
        """
        Product of array elements over given axes.

        Args:
            tensor_in (Tensor): Tensor object
            axis (Number): The axes over which to take the product

        Returns:
            MXNet NDArray: ndarray of the product over the axes.
        """
        tensor_in = self.astensor(tensor_in)
        if axis is None:
            return nd.prod(tensor_in)
        return nd.prod(tensor_in, axis)
Beispiel #2
0
def calIOU(anchor, gt):
    assert len(anchor.shape) in (1,2,3)
    assert len(gt.shape) in (1,2,3)
    
    anchor = anchor.reshape((-1,4))
    if len(gt.shape) < 3:
        gt = gt.reshape((1,1,4)) if len(gt.shape) == 1 else nd.expand_dims(gt, axis=0)
    anchor = nd.expand_dims(anchor, axis=1)
    gt = nd.expand_dims(gt, axis=1)
    
    max_tl = nd.maximum(nd.take(anchor, nd.array([0,1]), axis=-1), nd.take(gt, nd.array([0,1]), axis=-1))
    min_br = nd.minimum(nd.take(anchor, nd.array([2,3]), axis=-1), nd.take(gt, nd.array([2,3]), axis=-1))
    
    area = nd.prod(min_br-max_tl, axis=-1)
    i = nd.where((max_tl >= min_br).sum(axis=-1), nd.zeros_like(area), area)
    
    anchor_area = nd.prod(anchor[:,:,2:]-anchor[:,:,:2], axis=-1)
    gt_area = nd.prod(gt[:,:,:,2:]-gt[:,:,:,:2], axis=-1)
    total_area = anchor_area + gt_area - i
    iou = i / total_area
    
    return iou
Beispiel #3
0
def test_prod():
    a = nd.ones(LARGE_X)
    b = nd.prod(a, axis=0)
    assert b[0] == 1
def test_prod():
    a = nd.array(np.ones((SMALL_Y, LARGE_X)))
    b = nd.prod(a, axis=1)
    assert b.shape[0] == SMALL_Y
    def generate_targets(self, img, boxes):
        """
        img : [H, W, 3]
        boxes : [N, 5]
        """
        rh, rw, _ = img.shape
        rx = nd.arange(0, rw).reshape((1, -1))
        ry = nd.arange(0, rh).reshape((-1, 1))
        sx = nd.tile(rx, reps=(rh, 1))
        sy = nd.tile(ry, reps=(1, rw))

        areas = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
        boxes = boxes[nd.argsort(areas)]
        boxes = nd.concat(nd.zeros((1, 5)), boxes, dim=0) # for gt assign confusion
        x0, y0, x1, y1, cls = nd.split(boxes, num_outputs=5, axis=-1, squeeze_axis=True)
        n = boxes.shape[0]

        # [H, W, N]
        of_l = sx.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(x0, axis=0), axis=0)
        of_t = sy.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(y0, axis=0), axis=0)
        of_r = -(sx.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(x1, axis=0), axis=0))
        of_b = -(sy.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(y1, axis=0), axis=0))

        # [H, W, N]
        eps = 1e-5
        ctr =(nd.minimum(of_l, of_r) / nd.maximum(of_l, of_r)) * \
                (nd.minimum(of_t, of_b) / nd.maximum(of_t, of_b) + eps)
        ctr = nd.sqrt(nd.abs(ctr))
        ctr[:, :, 0] = 0

        # [H, W, N, 4]
        offsets = nd.concat(of_l.reshape(-2, 1), of_t.reshape(-2, 1),
                            of_r.reshape(-2, 1), of_b.reshape(-2, 1), dim=-1)

        # fh = int(np.ceil(((rh + 1) / 2) // 2 / 2))
        # fw = int(np.ceil(((rw + 1) / 2) // 2 / 2))
        fh = int(np.ceil(np.ceil(np.ceil(rh / 2) / 2) / 2))
        fw = int(np.ceil(np.ceil(np.ceil(rw / 2) / 2) / 2))

        fm_list = []
        for i in range(self._stages):
            fm_list.append((fh, fw))
            fh = int(np.ceil(fh / 2))
            fw = int(np.ceil(fw / 2))
        fm_list = fm_list[::-1]
        cls_targets = []
        ctr_targets = []
        box_targets = []
        cor_targets = []
        stride = self._stride
        for i in range(self._stages):
            fh, fw = fm_list[i]
            cls_target = nd.zeros((fh, fw))
            box_target = nd.zeros((fh, fw, 4))
            ctr_target = nd.zeros((fh, fw))

            cx = nd.arange(0, fw).reshape((1, -1))
            cy = nd.arange(0, fh).reshape((-1, 1))
            sx = nd.tile(cx, reps=(fh, 1))
            sy = nd.tile(cy, reps=(1, fw))
            syx = nd.stack(sy.reshape(-1), sx.reshape(-1)).transpose().astype('int32')
            # bugs in this type
            # bx = sxy[:, 0] * stride + nd.floor(sxy[:, 0] / 2).astype(np.int32)
            # by = sxy[:, 1] * stride + nd.floor(sxy[:, 1] / 2).astype(np.int32)
            by = syx[:, 0] * stride
            bx = syx[:, 1] * stride
            cor_targets.append(nd.stack(bx, by, axis=1))

            # [FH*FW, N, 4]
            of_byx = offsets[by, bx]
            # of_byx = nd.gather_nd(offsets, indices=byx.transpose())
            min_vr, max_vr = self._valid_range[i]
            # [FH*FW, N]
            is_in_box = nd.prod(of_byx > 0, axis=-1)
            is_valid_area = (of_byx.max(axis=-1) >= min_vr) * (of_byx.max(axis=-1) <= max_vr)
            # [FH*FW, N]
            valid_pos = nd.elemwise_mul(is_in_box, is_valid_area)
            of_valid = nd.zeros((fh, fw, n))
            of_valid[syx[:, 0], syx[:, 1], :] = valid_pos # 1, 0
            of_valid[:, :, 0] = 0
            # [FH, FW]
            gt_inds = nd.argmax(of_valid, axis=-1)
            # box targets
            box_target[syx[:, 0], syx[:, 1]] = boxes[gt_inds[syx[:, 0], syx[:, 1]], :4]
            box_target = box_target.reshape(-1, 4)
            # cls targets
            cls_target[syx[:, 0], syx[:, 1]] = cls[gt_inds[syx[:, 0], syx[:, 1]]]
            cls_target = cls_target.reshape(-1)
            # ctr targets
            ctr_target[syx[:, 0], syx[:, 1]] = ctr[by, bx, gt_inds[syx[:, 0], syx[:, 1]]]
            ctr_target = ctr_target.reshape(-1)
            box_targets.append(box_target)
            cls_targets.append(cls_target)
            ctr_targets.append(ctr_target)
            stride = int(stride / 2)
        box_targets = nd.concat(*box_targets, dim=0)
        cls_targets = nd.concat(*cls_targets, dim=0)
        ctr_targets = nd.concat(*ctr_targets, dim=0)
        cor_targets = nd.concat(*cor_targets, dim=0)
        cor_targets = cor_targets.astype('float32')

        return cls_targets, ctr_targets, box_targets, cor_targets
Beispiel #6
0
    def generate_targets(self, img, boxes):
        """
        img : [H, W, 3]
        boxes : [N, 5]
        """
        rh, rw, _ = img.shape
        rh, rw = int(rh/4), int(rw/4)
        rx = nd.arange(0, rw).reshape((1, -1))
        ry = nd.arange(0, rh).reshape((-1, 1))
        sx = nd.tile(rx, reps=(rh, 1))
        sy = nd.tile(ry, reps=(1, rw))

        x0, y0, x1, y1, _ = nd.split(boxes, 5, axis=-1, squeeze_axis=True)
        areas = (x1 - x0) * (y1 - y0)
        # areas = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])

        boxes_id = nd.argsort(areas)
        boxes_id = nd.concat(nd.array([-1]), boxes_id, dim=0)

        boxes = nd.take(boxes, nd.argsort(areas)) # min -> max
        boxes = nd.concat(nd.zeros((1, 5)), boxes, dim=0) # for gt assign confusion
        x0, y0, x1, y1, cls = nd.split(boxes, num_outputs=5, axis=-1, squeeze_axis=True)
        n = boxes.shape[0]

        # [H, W, N]
        of_l = sx.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(x0/4, axis=0), axis=0)
        of_t = sy.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(y0/4, axis=0), axis=0)
        of_r = -(sx.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(x1/4, axis=0), axis=0))
        of_b = -(sy.reshape(-2, 1) - nd.expand_dims(nd.expand_dims(y1/4, axis=0), axis=0))

        # [H, W, N]
        eps = 1e-5
        # ctr = nd.minimum(of_l, of_r) / (nd.maximum(of_l, of_r) + eps) * \
        #         nd.minimum(of_t, of_b) / (nd.maximum(of_t, of_b) + eps)
        # ctr = nd.sqrt(nd.abs(ctr))
        # ctr[:, :, 0] = 0

        # # flat ctr
        of_l = of_l * (of_l > 0)
        of_r = of_r * (of_r > 0)
        of_t = of_t * (of_t > 0)
        of_b = of_b * (of_b > 0)
        # ctr2 = nd.minimum(of_l, of_r) / (nd.maximum(of_l, of_r) + of_l + of_r) * \
        #         nd.minimum(of_t, of_b) / (nd.maximum(of_t, of_b) + of_t + of_b)
        # ctr2 = 3 * nd.sqrt(nd.abs(ctr2))
        # ctr2[:, :, 0] = 0

        # slim ctr
        # ctr = nd.minimum(of_l, of_r) / (nd.maximum(of_l, of_r) + nd.abs(of_l - of_r) + eps) * \
        #        nd.minimum(of_t, of_b) / (nd.maximum(of_t, of_b) + nd.abs(of_t - of_b) + eps)
        ctr = nd.minimum(of_l, of_r) / (nd.maximum(of_l, of_r) + eps) * \
                nd.minimum(of_t, of_b) / (nd.maximum(of_t, of_b) + eps)
        # ctr = nd.power(0.8, 0.1 * nd.sqrt(nd.square(of_l - of_r) + nd.square(of_t - of_b) + eps))
        # ctr = nd.power(0.8, nd.sqrt(nd.abs(of_l - of_r) + nd.abs(of_t - of_b) + eps))
        ctr = nd.sqrt(nd.abs(ctr))
        ctr[:, :, 0] = 0
        # [H, W, N, 4]
        offsets = nd.concat(of_l.reshape(-2, 1), of_t.reshape(-2, 1),
                            of_r.reshape(-2, 1), of_b.reshape(-2, 1), dim=-1) * 4.

        fh = int(np.ceil(rh / 2))
        fw = int(np.ceil(rw / 2))
        # fh = int(np.ceil(np.ceil(np.ceil(rh / 2) / 2) / 2))
        # fw = int(np.ceil(np.ceil(np.ceil(rw / 2) / 2) / 2))

        fm_list = []
        for i in range(self._stages):
            fm_list.append((fh, fw))
            fh = int(np.ceil(fh / 2))
            fw = int(np.ceil(fw / 2))
        fm_list = fm_list[::-1]
        cls_targets = []
        ctr_targets = []
        box_targets = []
        match_targets = []
        stride = int(self._stride/4)
        for i in range(self._stages):
            fh, fw = fm_list[i]
            # cls_target = nd.zeros((fh, fw))
            # box_target = nd.zeros((fh, fw, 4))
            # ctr_target = nd.zeros((fh, fw))
            # match_target = nd.zeros((fh, fw))

            cx = nd.arange(0, fw).reshape((1, -1))
            cy = nd.arange(0, fh).reshape((-1, 1))
            sx = nd.tile(cx, reps=(fh, 1))
            sy = nd.tile(cy, reps=(1, fw))
            syx = nd.stack(sy.reshape(-1), sx.reshape(-1)).transpose().astype('int32')
            # bugs in this type
            # bx = sxy[:, 0] * stride + nd.floor(sxy[:, 0] / 2).astype(np.int32)
            # by = sxy[:, 1] * stride + nd.floor(sxy[:, 1] / 2).astype(np.int32)
            by, bx = nd.split(syx*stride, 2, axis=-1, squeeze_axis=True)
            # by = syx[:, 0] * stride
            # bx = syx[:, 1] * stride

            # [FH*FW, N, 4]
            of_byx = nd.take(offsets.reshape((-1, n, 4)), by*740/4+bx)
            of_ctr = nd.take(ctr.reshape((-1, n)), by*740/4 + bx)
            # of_byx = offsets[by, bx]
            # ctr_aware = ctr[by, bx]
            # of_byx = nd.gather_nd(offsets, indices=byx.transpose())
            min_vr, max_vr = self._valid_range[i]
            # [FH*FW, N]
            is_in_box = nd.prod(of_byx > 0, axis=-1)
            is_valid_area = (of_byx.max(axis=-1) >= min_vr) * (of_byx.max(axis=-1) <= max_vr)
            # [FH*FW, N]
            valid_pos = nd.elemwise_mul(is_in_box, is_valid_area) * of_ctr
            # valid_pos = nd.elemwise_mul(is_in_box, is_valid_area)
            # of_valid = nd.zeros((fh, fw, n))
            # of_valid[syx[:, 0], syx[:, 1], :] = valid_pos * ctr_aware # 1, 0
            of_valid = valid_pos.reshape((fh, fw, n))
            of_valid[:, :, 0] = 0
            # [FH, FW]
            # gt_inds = nd.argmax(of_valid, axis=-1)
            gt_inds = nd.argmax(of_valid, axis=-1).reshape(-1)
            # box targets
            box_target = nd.take(boxes, gt_inds).slice_axis(begin=0, end=4, axis=-1)
            # box_target[syx[:, 0], syx[:, 1]] = boxes[gt_inds[syx[:, 0], syx[:, 1]], :4]
            # box_target = box_target.reshape(-1, 4)

            # cls targets
            cls_target = nd.take(cls, gt_inds)
            # cls_target[syx[:, 0], syx[:, 1]] = cls[gt_inds[syx[:, 0], syx[:, 1]]]
            # cls_target = cls_target.reshape(-1)

            # match targets the number of matches less than ctr targets
            # match_gt_inds = nd.argmax(of_valid * (of_valid > 0.01), axis=-1).reshape(-1)
            match_target = nd.take(boxes_id, gt_inds)
            # match_target[syx[:, 0], syx[:, 1]] = boxes_id[match_gt_inds[syx[:,0], syx[:,1]]]
            # match_target = match_target.reshape(-1)

            # ctr targets
            ctr_target = nd.pick(of_ctr, gt_inds)
            # ctr_target[syx[:, 0], syx[:, 1]] = ctr[by, bx, gt_inds[syx[:, 0], syx[:, 1]]]
            # ctr_target = ctr_target.reshape(-1)
            box_targets.append(box_target)
            cls_targets.append(cls_target)
            ctr_targets.append(ctr_target)
            stride = int(stride / 2)
            match_targets.append(match_target)
        box_targets = nd.concat(*box_targets, dim=0)
        cls_targets = nd.concat(*cls_targets, dim=0)
        ctr_targets = nd.concat(*ctr_targets, dim=0)
        match_targets = nd.concat(*match_targets, dim=0)
        return cls_targets, ctr_targets, box_targets, match_targets
Beispiel #7
0
    def __init__(
        self,
        num_inputs,
        action_space,
        gamma=0.99,
        tau=5e-3,
        lr=3e-4,
        alpha=0.2,
        automatic_entropy_tuning=False,
        batch_size=256,
        hidden_size=64,
        target_update_interval=1,
        gpu=False,
        **kwargs
    ):

        # discount factor
        self.gamma = gamma

        # entropy configuration
        self.alpha = alpha
        self.automatic_entropy_tuning = automatic_entropy_tuning

        # factor for updating the target network
        self.tau = tau
        # interval to update the critic target network wrt the critic
        self.target_update_interval = target_update_interval

        # parameter for casting variables
        self.device = mx.gpu() if gpu else mx.cpu()
        mx.Context.default_ctx = mx.Context(self.device, 0)

        # ==========================================================================================
        # We use a particular variation of SAC that uses Q-networks instead of a value network
        # ==========================================================================================

        self.critic = [
            QNetwork(num_inputs, action_space.shape[0], hidden_size, self.device),
            QNetwork(num_inputs, action_space.shape[0], hidden_size, self.device),
        ]

        self.critic_optim = [
            gluon.Trainer(
                self.critic[0].collect_params(), "adam", {"learning_rate": lr}
            ),
            gluon.Trainer(
                self.critic[1].collect_params(), "adam", {"learning_rate": lr}
            ),
        ]

        self.critic_target = [
            QNetwork(num_inputs, action_space.shape[0], hidden_size, self.device),
            QNetwork(num_inputs, action_space.shape[0], hidden_size, self.device),
        ]

        # the critic target doesn't need a optimizer, since it uses the update mechanism
        hard_update(self.critic_target[0], self.critic[0])
        hard_update(self.critic_target[1], self.critic[1])

        # Target Entropy = −dim(A) (e.g. , -6 for HalfCheetah-v2) as given in the paper
        if self.automatic_entropy_tuning == True:
            self.target_entropy = -nd.prod(nd.array(action_space.shape)).asscalar()
            self.log_alpha = mx.gluon.Parameter(
                "log_alpha", shape=(1,), init=mx.init.Zero(), dtype="float64"
            )
            self.log_alpha.initialize(ctx=self.device)
            self.alpha_optim = gluon.Trainer(
                [self.log_alpha],
                optimizer="adam",
                optimizer_params={"learning_rate": lr},
            )

        self.policy = GaussianPolicy(
            num_inputs, action_space.shape[0], hidden_size, action_space, self.device
        )

        self.policy_optim = gluon.Trainer(
            self.policy.collect_params(),
            optimizer="adam",
            optimizer_params={"learning_rate": lr},
        )