def test_gzsd(self, rcnn_test_cfg, cls_score, bbox_pred): unseen_class_inds = get_unseen_class_ids(dataset=rcnn_test_cfg.dataset_name, split=rcnn_test_cfg.split) seen_class_inds = get_seen_class_ids(dataset=rcnn_test_cfg.dataset_name, split=rcnn_test_cfg.split) seen_class_inds_bg = np.concatenate(([81], seen_class_inds)) unseen_class_inds_bg = np.concatenate(([0], unseen_class_inds)) cls_score[:, seen_class_inds_bg] = F.softmax(cls_score[:, seen_class_inds_bg], dim=1) cls_score[:, unseen_class_inds_bg] = F.softmax(cls_score[:, unseen_class_inds_bg], dim=1) seen_score = cls_score[:, seen_class_inds] unseen_score = cls_score[:, unseen_class_inds] seen=seen_score.argmax(1) unseen=unseen_score.argmax(1) seen = seen_class_inds[seen.data.cpu().numpy()] unseen = unseen_class_inds[unseen.data.cpu().numpy()] ar = torch.from_numpy(np.array([0,1,2,3])) for ii in range(bbox_pred.shape[0]): bbox_pred[ii, ar+(unseen[ii]*4) ] = bbox_pred[ii, ar+(seen[ii]*4) ] seen_score[seen_score < 0.3] = 0.0 cls_score[:, seen_class_inds] = seen_score cls_score[:, unseen_class_inds] = unseen_score new_scores = cls_score[:, :-1] new_scores[:, 0] = (cls_score[:, 0] + cls_score[:, -1]) / 2 cls_score = new_scores return cls_score, bbox_pred
def load_annotations(self, ann_file, classes_to_load=None, split=None): self.set_classes_split() unseen_class_ids, seen_class_ids = get_unseen_class_ids( 'voc') - 1, get_seen_class_ids('voc') - 1 img_infos = [] if self.classes_to_load == 'seen': self.cat_to_load = seen_class_ids elif self.classes_to_load == 'unseen': self.cat_to_load = unseen_class_ids self.class_names_to_load = np.array(self.CLASSES)[self.cat_to_load] # classes_loaded = [] img_ids = mmcv.list_from_file(ann_file) for img_id in img_ids: filename = 'JPEGImages/{}.jpg'.format(img_id) xml_path = osp.join(self.img_prefix, 'Annotations', '{}.xml'.format(img_id)) tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') width = int(size.find('width').text) height = int(size.find('height').text) # include_image = include_image = self.should_include_image(root) include_image = self.should_include_image(root) # if classes_to_exclude is not None: # for obj in root.findall('object'): # name = obj.find('name').text # if name in classes_to_exclude: # include_image = False # break # classes_loaded.append(name) if include_image == True: img_infos.append( dict(id=img_id, filename=filename, width=width, height=height)) # import pdb; pdb.set_trace() # files = ["VOC2007/"+filename['filename'] for filename in img_infos] # print(f"classes loaded {np.unique(np.array(classes_loaded))}") return img_infos
def copy_synthesised_weights(model, filename, dataset_name='voc', split='65_15'): logger = get_root_logger('INFO') checkpoint = torch.load(filename, map_location='cpu') if isinstance(checkpoint, OrderedDict): state_dict = checkpoint elif isinstance(checkpoint, dict) and 'state_dict' in checkpoint: state_dict = checkpoint['state_dict'] else: raise RuntimeError( 'No state_dict found in checkpoint file {}'.format(filename)) if hasattr(model, 'module'): own_state = model.module.state_dict() else: own_state = model.state_dict() unseen_class_inds = get_unseen_class_ids(dataset=dataset_name, split=split) seen_bg_weights = own_state['bbox_head.fc_cls.weight'][0].data.cpu().numpy( ).copy() seen_bg_bias = own_state['bbox_head.fc_cls.bias'][0].data.cpu().numpy( ).copy() own_state['bbox_head.fc_cls.bias'][unseen_class_inds] = state_dict[ 'fc1.bias'][1:] own_state['bbox_head.fc_cls.weight'][unseen_class_inds] = state_dict[ 'fc1.weight'][1:] alpha1 = 0.35 alpha2 = 0.65 own_state['bbox_head.fc_cls.bias'][0] = alpha1 * own_state[ 'bbox_head.fc_cls.bias'][0] + alpha2 * state_dict['fc1.bias'][0] own_state['bbox_head.fc_cls.weight'][0] = alpha1 * own_state[ 'bbox_head.fc_cls.weight'][0] + alpha2 * state_dict['fc1.weight'][0] logger.info( f'{dataset_name} {unseen_class_inds.shape} seenbg: {alpha1} synbg: {alpha2} copied classifier weights from {filename} \n' ) return seen_bg_weights, seen_bg_bias
def _filter_classes(self, classes_to_load=None, exclude_all=False, split='65_15'): """ exclude_all: exludes all images where any object of exluded categories is present """ img_ids = self.coco.getImgIds() cat_ids = np.array(self.coco.getCatIds()) unseen_class_labels, seen_class_labels = get_unseen_class_ids('coco', split=split)-1, get_seen_class_ids('coco', split=split) -1 seen_classes_cat_ids = cat_ids[seen_class_labels] unseen_classes_cat_ids = cat_ids[unseen_class_labels] self.cat_to_load = cat_ids if classes_to_load == 'seen': self.cat_to_load = seen_classes_cat_ids elif classes_to_load == 'unseen': self.cat_to_load = unseen_classes_cat_ids images_ids_to_exclude = [] images_ids_to_load = [] for index in range(len(img_ids)): ann_ids = self.coco.getAnnIds(imgIds=img_ids[index]) target = self.coco.loadAnns(ann_ids) for i in range(len(target)): if exclude_all: if target[i]['category_id'] not in self.cat_to_load: # unknown object found in the image, therefore, ignore the image images_ids_to_exclude.append(img_ids[index]) break else: if target[i]['category_id'] in self.cat_to_load: images_ids_to_load.append(img_ids[index]) break if exclude_all: images_ids_to_load = np.setdiff1d(np.array(img_ids), np.array(images_ids_to_exclude)).astype(int).tolist() # import pdb; pdb.set_trace() return images_ids_to_load
def test_zsd(self, rcnn_test_cfg, cls_score, bbox_pred): unseen_class_inds = get_unseen_class_ids(dataset=rcnn_test_cfg.dataset_name, split=rcnn_test_cfg.split) seen_class_inds = get_seen_class_ids(dataset=rcnn_test_cfg.dataset_name, split=rcnn_test_cfg.split) seen_score = cls_score[:, seen_class_inds] unseen_score = cls_score[:, unseen_class_inds] seen=seen_score.argmax(1) unseen=unseen_score.argmax(1) seen = seen_class_inds[seen.data.cpu().numpy()] unseen = unseen_class_inds[unseen.data.cpu().numpy()] ar = torch.from_numpy(np.array([0,1,2,3])) for ii in range(seen.shape[0]): bbox_pred[ii, ar+(unseen[ii]*4) ] = bbox_pred[ii, ar+(seen[ii]*4) ] cls_score[:,seen_class_inds]=-1.0e3 cls_score = F.softmax(cls_score, dim=1) return cls_score, bbox_pred
def load_annotations(self, ann_file, classes_to_load=None, split=None): img_infos = [] unseen_class_ids, seen_class_ids = get_unseen_class_ids('imagenet')-1, get_seen_class_ids('imagenet')-1 if self.classes_to_load == 'seen': self.cat_to_load = seen_class_ids elif self.classes_to_load == 'unseen': self.cat_to_load = unseen_class_ids self.class_names_to_load = np.array(self.CLASSES)[self.cat_to_load] print(self.class_names_to_load) img_ids = mmcv.list_from_file(ann_file) img_ids = [img_id.split(' ')[0] for img_id in img_ids] img_ids = [img_id for img_id in img_ids if 'extra' not in img_id] map_det_file = open('map_det.txt', 'r') map_det = map_det_file.readlines() map_det = [det.strip().split(' ') for det in map_det] self.map_det = {det[0]: det[2] for det in map_det} for img_id in img_ids: data_split = 'train' if 'train' in img_id else 'val' filename = f'Data/DET/{data_split}/{img_id}.JPEG' xml_path = f'{self.img_prefix}Annotations/DET/{data_split}/{img_id}.xml' tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') width = int(size.find('width').text) height = int(size.find('height').text) include_image = self.should_include_image(root) if include_image == True: img_infos.append( dict(id=img_id, filename=filename, width=width, height=height)) print(f'total {self.classes_to_load} images loaded {len(img_infos)}') return img_infos
def get_unseen_class_inds(self, dataset='voc'): return get_unseen_class_ids(dataset)
def print_map_summary(aps, results, dataset=None, dataset_name=None, ranges=None, recalls=None, split='65_15'): """Print mAP and results of each class. Args: mean_ap(float): calculated from `eval_map` results(list): calculated from `eval_map` dataset(None or str or list): dataset name or dataset classes. ranges(list or Tuple): ranges of areas """ num_scales = len(results[0]['ap']) if isinstance(results[0]['ap'], np.ndarray) else 1 if ranges is not None: assert len(ranges) == num_scales num_classes = len(results) print(f"num_classes ----------- {num_classes}") recalls = np.zeros((num_scales, num_classes), dtype=np.float32) precisions = np.zeros((num_scales, num_classes), dtype=np.float32) aps = np.zeros((num_scales, num_classes), dtype=np.float32) num_gts = np.zeros((num_scales, num_classes), dtype=int) for i, cls_result in enumerate(results): if cls_result['recall'].size > 0: recalls[:, i] = np.array(cls_result['recall'], ndmin=2)[:, -1] precisions[:, i] = np.array(cls_result['precision'], ndmin=2)[:, -1] aps[:, i] = cls_result['ap'] num_gts[:, i] = cls_result['num_gts'] if dataset is None: label_names = [str(i) for i in range(1, num_classes + 1)] elif mmcv.is_str(dataset): label_names = get_classes(dataset) else: label_names = dataset # if not isinstance(mean_ap, list): # mean_ap = [mean_ap] # if not isinstance(mean_recall, list): # mean_recall = [mean_recall] header = ['class', 'gts', 'dets', 'recall', 'precision', 'ap'] indexes = [np.arange(0, len(label_names))] if dataset_name is not None: # print(dataset_name) unseen_class_inds = get_unseen_class_ids(dataset=dataset_name, split=split) - 1 seen_class_inds = get_seen_class_ids(dataset=dataset_name, split=split) - 1 indexes = [seen_class_inds, unseen_class_inds] means_table = [] for i in range(num_scales): if ranges is not None: print("Area range ", ranges[i]) for ind in range(len(indexes)): table_data = [header] # for j in range(num_classes): classes_inds = indexes[ind] curr_aps = [] curr_recalls = [] for j in classes_inds: if num_gts[i, j] > 0: row_data = [ label_names[j], num_gts[i, j], results[j]['num_dets'], '{:.3f}'.format(recalls[i, j]), '{:.3f}'.format(precisions[i, j]), '{:.3f}'.format(aps[i, j]) ] table_data.append(row_data) curr_aps.append(aps[i, j]) curr_recalls.append(recalls[i, j]) # import pdb; pdb.set_trace() mean_ap = np.array( curr_aps).mean().item() if len(curr_aps) > 0 else 0.0 mean_recall = np.array( curr_recalls).mean().item() if len(curr_recalls) > 0 else 0.0 table_data.append([ 'mean', '', '', '{:.3f}'.format(mean_recall), '', '{:.3f}'.format(mean_ap) ]) means_table.append([ 'mean', '', '', '{:.3f}'.format(mean_recall), '', '{:.3f}'.format(mean_ap) ]) table = AsciiTable(table_data) table.inner_footing_row_border = True print(table.table) table = AsciiTable(means_table) table.inner_footing_row_border = True print(table.table)