def proposal_target_layer(rpn_rois, gt_boxes, gt_ishard, dontcare_areas,
                              num_classes):
        """
        ----------
        rpn_rois:  (1 x H x W x A, 5) [0, x1, y1, x2, y2]
        gt_boxes: (G, 5) [x1 ,y1 ,x2, y2, class] int
        # gt_ishard: (G, 1) {0 | 1} 1 indicates hard
        dontcare_areas: (D, 4) [ x1, y1, x2, y2]
        num_classes
        ----------
        Returns
        ----------
        rois: (1 x H x W x A, 5) [0, x1, y1, x2, y2]
        labels: (1 x H x W x A, 1) {0,1,...,_num_classes-1}
        bbox_targets: (1 x H x W x A, K x4) [dx1, dy1, dx2, dy2]
        bbox_inside_weights: (1 x H x W x A, Kx4) 0, 1 masks for the computing loss
        bbox_outside_weights: (1 x H x W x A, Kx4) 0, 1 masks for the computing loss
        """
        rpn_rois = rpn_rois.data.cpu().numpy()
        rois, labels, bbox_targets, bbox_inside_weights, bbox_outside_weights = \
            proposal_target_layer_py(rpn_rois, gt_boxes, gt_ishard, dontcare_areas, num_classes)
        # print labels.shape, bbox_targets.shape, bbox_inside_weights.shape
        rois = network.np_to_variable(rois, is_cuda=True)
        labels = network.np_to_variable(labels,
                                        is_cuda=True,
                                        dtype=torch.LongTensor)
        bbox_targets = network.np_to_variable(bbox_targets, is_cuda=True)
        bbox_inside_weights = network.np_to_variable(bbox_inside_weights,
                                                     is_cuda=True)
        bbox_outside_weights = network.np_to_variable(bbox_outside_weights,
                                                      is_cuda=True)

        return rois, labels, bbox_targets, bbox_inside_weights, bbox_outside_weights
    def __init__(self, classes=None, debug=False):
        super(FasterRCNN, self).__init__()

        self.classes = np.asarray(classes)
        self.n_classes = len(classes)

        self.rpn = RPN(debug=debug)
        self.proposal_target_layer = proposal_target_layer_py(self.n_classes)
        if cfg.POOLING_MODE == 'align':
            self.roi_pool = RoIAlign(7, 7, 1.0 / 16)
        elif cfg.POOLING_MODE == 'pool':
            self.roi_pool = RoIPool(7, 7, 1.0 / 16)
        self.score_fc = FC(4096, self.n_classes, relu=False)
        self.bbox_fc = FC(4096, self.n_classes * 4, relu=False)

        # loss
        self.cross_entropy = 0
        self.loss_box = 0
        self.triplet_loss = 0
        # for log
        self.debug = debug
        if cfg.TRIPLET.IS_TRUE:
            self.fc_sim = FC(512 * 7 * 7, 4096, relu=False)
            pos_weight = torch.ones(3)
            pos_weight[0] = 2.0
            if self.debug:
                self.set = 0
                self.match = 0
            if cfg.TRIPLET.LOSS == 'euc':
                self.loss_triplet = tpl.euclidean_distance_loss
            elif cfg.TRIPLET.LOSS == 'log':
                self.loss_triplet = tpl.cross_entropy_l2_dist
                self.relu = nn.ReLU(inplace=True)
                self.BCELoss = nn.BCELoss(weight=pos_weight,
                                          size_average=False)
            elif cfg.TRIPLET.LOSS == 'cls':
                self.loss_triplet = tpl.cross_entropy_cosine_sim
                self.relu = nn.ReLU(inplace=True)
                self.BCELoss = nn.BCELoss(weight=pos_weight,
                                          size_average=False)
        self.init_module = self._init_faster_rcnn_vgg16