def predict(self, imgs, sizes=None, visualize=False):
        """
        在计算mAP的时候使用
        :param imgs: 一个batch的图片
        :param sizes: batch中每张图片的输入尺寸
        :return: 返回所有一个batch中所有图片的坐标,类,类概率值 三个值都是list型数据,里面包含的是numpy数据
        """

        self.eval()
        if visualize:
            self.use_preset('visualize')
        prepared_imgs = imgs

        bboxes = list()
        labels = list()
        scores = list()

        for img, size in zip(prepared_imgs, sizes):
            img = at.totensor(img[None]).float()
            scale = img.shape[3] / size[1]
            roi_cls_loc, roi_scores, rois = self(img, scale=scale)
            roi_score = roi_scores.data
            roi_cls_loc = roi_cls_loc.data
            roi = at.totensor(rois) / scale

            mean = torch.Tensor(self.loc_normalize_mean).repeat(self.n_class)[None]
            std = torch.Tensor(self.loc_normalize_std).repeat(self.n_class)[None]

            roi_cls_loc = (roi_cls_loc * std + mean)
            roi_cls_loc = roi_cls_loc.view(-1, self.n_class, 4)
            roi = roi.view(-1, 1, 4).expand_as(roi_cls_loc)
            # 从这里其实可以看出,roi_cls_loc是位置偏差,是用来计算更接近的位置,而不是位置,
            cls_bbox = loc2bbox(at.tonumpy(roi).reshape((-1, 4)),
                                at.tonumpy(roi_cls_loc).reshape((-1, 4)))
            cls_bbox = at.totensor(cls_bbox)
            cls_bbox = cls_bbox.view(-1, self.n_class * 4)
            # 这里应该是控制cls_bbox的边界,在min和max之间
            cls_bbox[:, 0::2] = (cls_bbox[:, 0::2]).clamp(min=0, max=size[0])
            cls_bbox[:, 1::2] = (cls_bbox[:, 1::2]).clamp(min=0, max=size[1])

            prob = at.tonumpy(F.softmax(at.totensor(roi_score), dim=1))

            raw_cls_bbox = at.tonumpy(cls_bbox)
            raw_prob = at.tonumpy(prob)
            bbox, label, score = self._suppress(raw_cls_bbox, raw_prob)
            bboxes.append(bbox)
            labels.append(label)
            scores.append(score)

        self.use_preset('evaluate')
        self.train()
        # 这里返回的是预测图片的bbox,labels,scores
        return bboxes, labels, scores
Beispiel #2
0
    def clustering(self, mymodel, outdim):
        mymodel.eval()
        features = np.zeros([self.lendata, outdim])
        with torch.no_grad():
            for i, outputt in enumerate(self.dataloader):
                image, label, path, id = outputt

                out, feature = mymodel(image)
                #features[i, :] = tonumpy(feature['lastlinear'])
                features[i, :] = tonumpy(feature)
                '''feature=mymodel(image)
                features[i,:]=tonumpy(feature)'''
                self.ids.append(id)
                self.filenames.append(path)
        if self.use_pca:
            model2 = PCA(n_components=500, random_state=728)
            model2.fit(np.transpose(features))
            temp = np.transpose(model2.components_)
            self.images_new = temp
        else:
            self.images_new = features
        model = KMeans(n_clusters=self.n_clusters)
        s = model.fit(self.images_new)
        print('Kmeans-Clustering..........')
        iddict = {}
        dict = {}
        center_mean = {}
        globalmean = 0.
        centers = model.cluster_centers_
        labels = model.labels_
        l, f = centers.shape

        for i in range(l):
            dict[str(i)] = {'center': centers[i, :].tolist(), 'features': []}

        for i in range(self.lendata):
            dict[str(labels[i])]['features'].append(
                self.images_new[i].tolist())
            iddict[str(scalar(self.ids[i]))] = {}
            iddict[str(scalar(self.ids[i]))]['label'] = labels[i]
            iddict[str(scalar(self.ids[i]))]['feature'] = self.images_new[i]

        for d in dict:
            ft = np.asarray(dict[d]['features'])
            temp = pow(ft, 2).sum(1).reshape([ft.shape[0], -1])
            dis = temp - 2 * np.dot(ft, np.transpose(ft)) + np.transpose(temp)
            dis = np.around(dis, decimals=5).sum()
            n = ft.shape[0]
            if n != 1:
                dis /= n * (n - 1)
            center_mean[d] = dis
            globalmean += float(dis) / l

        return iddict, center_mean, globalmean
Beispiel #3
0
 def forward(self, x):
     y = x.view(-1, x.size(1), x.size(2) * x.size(3))  # b x c x hw
     vladres = np.zeros([y.size(0), self.k, y.size(-1)])
     for i in range(y.size(0)):
         feature = tonumpy(y[i])
         c, hw = feature.shape
         self.model.fit(feature)
         clusters = self.model.cluster_centers_
         labels = self.model.labels_
         for j in range(c):
             label = labels[j]
             vladres[i, label, :] += feature[j] - clusters[label]
     vladres = totensor(vladres)
     return vladres
Beispiel #4
0
def train(**kwargs):
    opt._parse(kwargs)

    dataset = Dataset(opt)
    print('load data')
    dataloader = data_.DataLoader(dataset, \
                                  batch_size=1, \
                                  shuffle=True, \
                                  # pin_memory=True,
                                  num_workers=opt.num_workers)
    testset = TestDataset(opt)
    test_dataloader = data_.DataLoader(testset,
                                       batch_size=1,
                                       num_workers=opt.test_num_workers,
                                       shuffle=False, \
                                       pin_memory=True
                                       )
    faster_rcnn = FasterRCNNVGG16()
    print('model construct completed')
    trainer = FasterRCNNTrainer(faster_rcnn).cuda()
    if opt.load_path:
        trainer.load(opt.load_path)
        print('load pretrained model from %s' % opt.load_path)
    trainer.vis.text(dataset.db.label_names, win='labels')
    best_map = 0
    lr_ = opt.lr
    for epoch in range(opt.epoch):
        trainer.reset_meters()
        for ii, (img, bbox_, label_, scale) in tqdm(enumerate(dataloader)):
            scale = at.scalar(scale)
            img, bbox, label = img.cuda().float(), bbox_.cuda(), label_.cuda()
            trainer.train_step(img, bbox, label, scale)

            if (ii + 1) % opt.plot_every == 0:
                if os.path.exists(opt.debug_file):
                    ipdb.set_trace()

                # plot loss
                trainer.vis.plot_many(trainer.get_meter_data())

                # plot groud truth bboxes
                ori_img_ = inverse_normalize(at.tonumpy(img[0]))


                # plot predicti bboxes
                _bboxes, _labels, _scores = trainer.faster_rcnn.predict([ori_img_], visualize=True)


                # rpn confusion matrix(meter)
                trainer.vis.text(str(trainer.rpn_cm.value().tolist()), win='rpn_cm')
                # roi confusion matrix
                trainer.vis.img('roi_cm', at.totensor(trainer.roi_cm.conf, False).float())
        eval_result = eval(test_dataloader, faster_rcnn, test_num=opt.test_num)
        trainer.vis.plot('test_map', eval_result['map'])
        lr_ = trainer.faster_rcnn.optimizer.param_groups[0]['lr']
        log_info = 'lr:{}, map:{},loss:{}'.format(str(lr_),
                                                  str(eval_result['map']),
                                                  str(trainer.get_meter_data()))
        trainer.vis.log(log_info)

        if eval_result['map'] > best_map:
            best_map = eval_result['map']
            best_path = trainer.save(best_map=best_map)
        if epoch == 9:
            trainer.load(best_path)
            trainer.faster_rcnn.scale_lr(opt.lr_decay)
            lr_ = lr_ * opt.lr_decay

        if epoch == 13:
            break
Beispiel #5
0
    def forward(self, imgs, bboxes, labels, scale):
        # 每次进来一张图,对应的bbox,对应的label
        n = bboxes.shape[0]
        if n != 1:
            raise ValueError('Currently only batch size 1 is supported.')

        _, _, H, W = imgs.shape
        img_size = (H, W)
        # 求出特征图
        features = self.faster_rcnn.extractor(imgs)
        # 求出rpn网络输出的损失,roi,所有anchor
        # rpn_locs(N, H W A, 4)
        rpn_locs, rpn_scores, rois, anchor = self.faster_rcnn.rpn(
            features, img_size, scale)
        # bbox(R, 4) label(R, 1)
        bbox = bboxes[0]
        label = labels[0]
        rpn_score = rpn_scores[0]
        rpn_loc = rpn_locs[0]
        roi = rois
        # bbox和label是真实的bbox和label
        # roi是预测的bbox
        # 返回的是选择后的roi以及roi对应真实bbox的位置偏差,以及roi所给的label
        sample_roi, gt_roi_loc, gt_roi_label = self.proposal_target_creator(
            roi, at.tonumpy(bbox), at.tonumpy(label), self.loc_normalize_mean,
            self.loc_normalize_std)

        # 应该是返回在特征图上的roi全连接之后的位置和概率
        roi_cls_loc, roi_score = self.faster_rcnn.head(features, sample_roi)

        # rpn loss
        # 给anchor标记标签,loc上默认值是0,正样本为位移偏移量
        # label上默认值为-1,正样本为1
        gt_rpn_loc, gt_rpn_label = self.anchor_target_creator(
            at.tonumpy(bbox), anchor, img_size)
        gt_rpn_label = at.totensor(gt_rpn_label).long()
        gt_rpn_loc = at.totensor(gt_rpn_loc)

        # rpn_loc(H * W * A, 4)
        rpn_loc_loss = _fast_rcnn_loc_loss(rpn_loc, gt_rpn_loc,
                                           gt_rpn_label.data, self.rpn_sigma)
        # 计算rpn网络的分类损失,忽略label = -1的
        rpn_cls_loss = F.cross_entropy(rpn_score,
                                       gt_rpn_label,
                                       ignore_index=-1)

        # ROI loss
        n_sample = roi_cls_loc.shape[0]
        roi_cls_loc = roi_cls_loc.view(n_sample, -1, 4)
        roi_loc = roi_cls_loc[torch.arange(0, n_sample).long(),
                              at.totensor(gt_roi_label).long()]
        gt_roi_label = at.totensor(gt_roi_label).long()
        gt_roi_loc = at.totensor(gt_roi_loc)

        roi_loc_loss = _fast_rcnn_loc_loss(roi_loc, gt_roi_loc,
                                           gt_roi_label.data, self.roi_sigma)

        roi_cls_loss = nn.CrossEntropyLoss()(roi_score, gt_roi_label)

        losses = {
            'rpn_loc_loss': rpn_loc_loss,
            'rpn_cls_loss': rpn_cls_loss,
            'roi_loc_loss': roi_loc_loss,
            'roi_cls_loss': roi_cls_loss
        }
        losses['total_loss'] = sum(losses.values())
        return losses
Beispiel #6
0
    def forward(self, imgs, bboxes, labels, scale):
        """Forward Faster R-CNN and calculate losses.
        Here are notations used.
        * :math:`N` is the batch size.
        * :math:`R` is the number of bounding boxes per image.
        Currently, only :math:`N=1` is supported.
        Args:
            imgs (~torch.autograd.Variable): A variable with a batch of images.
            bboxes (~torch.autograd.Variable): A batch of bounding boxes.
                Its shape is :math:`(N, R, 4)`.
            labels (~torch.autograd..Variable): A batch of labels.
                Its shape is :math:`(N, R)`. The background is excluded from
                the definition, which means that the range of the value
                is :math:`[0, L - 1]`. :math:`L` is the number of foreground
                classes.
            scale (float): Amount of scaling applied to
                the raw image during preprocessing.
        Returns:
            namedtuple of 5 losses
        """
        n = bboxes.shape[0]
        if n != 1:
            raise ValueError('Currently only batch size 1 is supported.')

        _, _, H, W = imgs.shape
        img_size = (H, W)

        features = self.faster_rcnn.extractor(imgs)

        rpn_locs, rpn_scores, rois, roi_indices, anchor = \
            self.faster_rcnn.rpn(features, img_size, scale)

        # Since batch size is one, convert variables to singular form
        bbox = bboxes[0]
        label = labels[0]
        rpn_score = rpn_scores[0]
        rpn_loc = rpn_locs[0]
        roi = rois

        # Sample RoIs and forward
        # it's fine to break the computation graph of rois,
        # consider them as constant input
        sample_roi, gt_roi_loc, gt_roi_label = self.proposal_target_creator(
            roi, at.tonumpy(bbox), at.tonumpy(label), self.loc_normalize_mean,
            self.loc_normalize_std)
        # NOTE it's all zero because now it only support for batch=1 now
        sample_roi_index = t.zeros(len(sample_roi))
        roi_cls_loc, roi_score = self.faster_rcnn.head(features, sample_roi,
                                                       sample_roi_index)

        # ------------------ RPN losses -------------------#
        gt_rpn_loc, gt_rpn_label = self.anchor_target_creator(
            at.tonumpy(bbox), anchor, img_size)
        gt_rpn_label = at.totensor(gt_rpn_label).long()
        gt_rpn_loc = at.totensor(gt_rpn_loc)
        rpn_loc_loss = _fast_rcnn_loc_loss(rpn_loc, gt_rpn_loc,
                                           gt_rpn_label.data, self.rpn_sigma)

        # NOTE: default value of ignore_index is -100 ...
        rpn_cls_loss = F.cross_entropy(rpn_score,
                                       gt_rpn_label.cuda(),
                                       ignore_index=-1)
        _gt_rpn_label = gt_rpn_label[gt_rpn_label > -1]
        _rpn_score = at.tonumpy(rpn_score)[at.tonumpy(gt_rpn_label) > -1]
        self.rpn_cm.add(at.totensor(_rpn_score, False),
                        _gt_rpn_label.data.long())

        # ------------------ ROI losses (fast rcnn loss) -------------------#
        n_sample = roi_cls_loc.shape[0]
        roi_cls_loc = roi_cls_loc.view(n_sample, -1, 4)
        roi_loc = roi_cls_loc[t.arange(0, n_sample).long().cuda(), \
                              at.totensor(gt_roi_label).long()]
        gt_roi_label = at.totensor(gt_roi_label).long()
        gt_roi_loc = at.totensor(gt_roi_loc)

        roi_loc_loss = _fast_rcnn_loc_loss(roi_loc.contiguous(), gt_roi_loc,
                                           gt_roi_label.data, self.roi_sigma)

        roi_cls_loss = nn.CrossEntropyLoss()(roi_score, gt_roi_label.cuda())

        self.roi_cm.add(at.totensor(roi_score, False),
                        gt_roi_label.data.long())

        losses = [rpn_loc_loss, rpn_cls_loss, roi_loc_loss, roi_cls_loss]
        losses = losses + [sum(losses)]

        return LossTuple(*losses)