diff --git a/mmdet/apis/inference.py b/mmdet/apis/inference.py index a6ab2c97f7c3cba691f325c50d189f9cba56e9b2..c26ae0f0f7d6c57b15816d32b1d969594ce1ce11 100644 --- a/mmdet/apis/inference.py +++ b/mmdet/apis/inference.py @@ -30,7 +30,7 @@ def init_detector(config, checkpoint=None, device='cuda:0'): config = mmcv.Config.fromfile(config) elif not isinstance(config, mmcv.Config): raise TypeError('config must be a filename or Config object, ' - 'but got {}'.format(type(config))) + f'but got {type(config)}') config.model.pretrained = None model = build_detector(config.model, test_cfg=config.test_cfg) if checkpoint is not None: diff --git a/mmdet/apis/test.py b/mmdet/apis/test.py index 282c3d76a91ace985476db7230c7a63fe595b084..5b0dea2d85933641a677fd4d2c689779bb7b9c96 100644 --- a/mmdet/apis/test.py +++ b/mmdet/apis/test.py @@ -93,7 +93,7 @@ def collect_results_cpu(result_part, size, tmpdir=None): else: mmcv.mkdir_or_exist(tmpdir) # dump the part result to the dir - mmcv.dump(result_part, osp.join(tmpdir, 'part_{}.pkl'.format(rank))) + mmcv.dump(result_part, osp.join(tmpdir, f'part_{rank}.pkl')) dist.barrier() # collect all parts if rank != 0: @@ -102,7 +102,7 @@ def collect_results_cpu(result_part, size, tmpdir=None): # load results of all parts from tmp dir part_list = [] for i in range(world_size): - part_file = osp.join(tmpdir, 'part_{}.pkl'.format(i)) + part_file = osp.join(tmpdir, f'part_{i}.pkl') part_list.append(mmcv.load(part_file)) # sort the results ordered_results = [] diff --git a/mmdet/apis/train.py b/mmdet/apis/train.py index 8224865a7c75f9e87bbe1dab433acadac7b0ef3f..c88b1cc666b61dde05735a0e0510fe6bec00ab2f 100644 --- a/mmdet/apis/train.py +++ b/mmdet/apis/train.py @@ -40,8 +40,7 @@ def parse_losses(losses): elif isinstance(loss_value, list): log_vars[loss_name] = sum(_loss.mean() for _loss in loss_value) else: - raise TypeError( - '{} is not a tensor or list of tensors'.format(loss_name)) + raise TypeError(f'{loss_name} is not a tensor or list of tensors') loss = sum(_value for _key, _value in log_vars.items() if 'loss' in _key) diff --git a/mmdet/core/anchor/anchor_generator.py b/mmdet/core/anchor/anchor_generator.py index f2c716ec47ea62950d5db300279e3ad5fe53e4a8..020e23947f5542d4229ef6a045b628236d82b2f3 100644 --- a/mmdet/core/anchor/anchor_generator.py +++ b/mmdet/core/anchor/anchor_generator.py @@ -64,21 +64,21 @@ class AnchorGenerator(object): # check center and center_offset if center_offset != 0: assert centers is None, 'center cannot be set when center_offset' \ - '!=0, {} is given.'.format(centers) + f'!=0, {centers} is given.' if not (0 <= center_offset <= 1): - raise ValueError('center_offset should be in range [0, 1], {} is' - ' given.'.format(center_offset)) + raise ValueError('center_offset should be in range [0, 1], ' + f'{center_offset} is given.') if centers is not None: assert len(centers) == len(strides), \ 'The number of strides should be the same as centers, got ' \ - '{} and {}'.format(strides, centers) + f'{strides} and {centers}' # calculate base sizes of anchors self.strides = strides self.base_sizes = list(strides) if base_sizes is None else base_sizes assert len(self.base_sizes) == len(self.strides), \ 'The number of strides should be the same as base sizes, got ' \ - '{} and {}'.format(self.strides, self.base_sizes) + f'{self.strides} and {self.base_sizes}' # calculate scales of anchors assert ((octave_base_scale is not None @@ -261,19 +261,18 @@ class AnchorGenerator(object): def __repr__(self): indent_str = ' ' repr_str = self.__class__.__name__ + '(\n' - repr_str += '{}strides={},\n'.format(indent_str, self.strides) - repr_str += '{}ratios={},\n'.format(indent_str, self.ratios) - repr_str += '{}scales={},\n'.format(indent_str, self.scales) - repr_str += '{}base_sizes={},\n'.format(indent_str, self.base_sizes) - repr_str += '{}scale_major={},\n'.format(indent_str, self.scale_major) - repr_str += '{}octave_base_scale={},\n'.format(indent_str, - self.octave_base_scale) - repr_str += '{}scales_per_octave={},\n'.format(indent_str, - self.scales_per_octave) - repr_str += '{}num_levels={}\n'.format(indent_str, self.num_levels) - repr_str += '{}centers={},\n'.format(indent_str, self.centers) - repr_str += '{}center_offset={})'.format(indent_str, - self.center_offset) + repr_str += f'{indent_str}strides={self.strides},\n' + repr_str += f'{indent_str}ratios={self.ratios},\n' + repr_str += f'{indent_str}scales={self.scales},\n' + repr_str += f'{indent_str}base_sizes={self.base_sizes},\n' + repr_str += f'{indent_str}scale_major={self.scale_major},\n' + repr_str += f'{indent_str}octave_base_scale=' + repr_str += f'{self.octave_base_scale},\n' + repr_str += f'{indent_str}scales_per_octave=' + repr_str += f'{self.scales_per_octave},\n' + repr_str += f'{indent_str}num_levels={self.num_levels}\n' + repr_str += f'{indent_str}centers={self.centers},\n' + repr_str += f'{indent_str}center_offset={self.center_offset})' return repr_str @@ -326,8 +325,8 @@ class SSDAnchorGenerator(AnchorGenerator): else: raise ValueError( 'basesize_ratio_range[0] should be either 0.15' - 'or 0.2 when input_size is 300, got {}.'.format( - basesize_ratio_range[0])) + 'or 0.2 when input_size is 300, got ' + f'{basesize_ratio_range[0]}.') elif input_size == 512: if basesize_ratio_range[0] == 0.1: # SSD512 COCO min_sizes.insert(0, int(input_size * 4 / 100)) @@ -336,13 +335,12 @@ class SSDAnchorGenerator(AnchorGenerator): min_sizes.insert(0, int(input_size * 7 / 100)) max_sizes.insert(0, int(input_size * 15 / 100)) else: - raise ValueError( - 'basesize_ratio_range[0] should be either 0.1' - 'or 0.15 when input_size is 512, got {}.'.format( - basesize_ratio_range[0])) + raise ValueError('basesize_ratio_range[0] should be either 0.1' + 'or 0.15 when input_size is 512, got' + ' {basesize_ratio_range[0]}.') else: raise ValueError('Only support 300 or 512 in SSDAnchorGenerator' - ', got {}.'.format(input_size)) + f', got {input_size}.') anchor_ratios = [] anchor_scales = [] @@ -379,16 +377,16 @@ class SSDAnchorGenerator(AnchorGenerator): def __repr__(self): indent_str = ' ' repr_str = self.__class__.__name__ + '(\n' - repr_str += '{}strides={},\n'.format(indent_str, self.strides) - repr_str += '{}scales={},\n'.format(indent_str, self.scales) - repr_str += '{}scale_major={},\n'.format(indent_str, self.scale_major) - repr_str += '{}input_size={},\n'.format(indent_str, self.input_size) - repr_str += '{}scales={},\n'.format(indent_str, self.scales) - repr_str += '{}ratios={},\n'.format(indent_str, self.ratios) - repr_str += '{}num_levels={}\n'.format(indent_str, self.num_levels) - repr_str += '{}base_sizes={},\n'.format(indent_str, self.base_sizes) - repr_str += '{}basesize_ratio_range={})'.format( - indent_str, self.basesize_ratio_range) + repr_str += f'{indent_str}strides={self.strides},\n' + repr_str += f'{indent_str}scales={self.scales},\n' + repr_str += f'{indent_str}scale_major={self.scale_major},\n' + repr_str += f'{indent_str}input_size={self.input_size},\n' + repr_str += f'{indent_str}scales={self.scales},\n' + repr_str += f'{indent_str}ratios={self.ratios},\n' + repr_str += f'{indent_str}num_levels={self.num_levels},\n' + repr_str += f'{indent_str}base_sizes={self.base_sizes},\n' + repr_str += f'{indent_str}basesize_ratio_range=' + repr_str += f'{self.basesize_ratio_range})' return repr_str diff --git a/mmdet/core/bbox/assigners/assign_result.py b/mmdet/core/bbox/assigners/assign_result.py index 4daaa770f8155cd831d3ebee52a116e022b40a50..f6979e6de046c671c5995f16c67eaaf7915ec541 100644 --- a/mmdet/core/bbox/assigners/assign_result.py +++ b/mmdet/core/bbox/assigners/assign_result.py @@ -71,21 +71,20 @@ class AssignResult(util_mixins.NiceRepr): Create a "nice" summary string describing this assign result """ parts = [] - parts.append('num_gts={!r}'.format(self.num_gts)) + parts.append(f'num_gts={self.num_gts!r}') if self.gt_inds is None: - parts.append('gt_inds={!r}'.format(self.gt_inds)) + parts.append(f'gt_inds={self.gt_inds!r}') else: - parts.append('gt_inds.shape={!r}'.format( - tuple(self.gt_inds.shape))) + parts.append(f'gt_inds.shape={tuple(self.gt_inds.shape)!r}') if self.max_overlaps is None: - parts.append('max_overlaps={!r}'.format(self.max_overlaps)) + parts.append(f'max_overlaps={self.max_overlaps!r}') else: - parts.append('max_overlaps.shape={!r}'.format( - tuple(self.max_overlaps.shape))) + parts.append('max_overlaps.shape=' + f'{tuple(self.max_overlaps.shape)!r}') if self.labels is None: - parts.append('labels={!r}'.format(self.labels)) + parts.append(f'labels={self.labels!r}') else: - parts.append('labels.shape={!r}'.format(tuple(self.labels.shape))) + parts.append(f'labels.shape={tuple(self.labels.shape)!r}') return ', '.join(parts) @classmethod diff --git a/mmdet/core/bbox/iou_calculators/iou2d_calculator.py b/mmdet/core/bbox/iou_calculators/iou2d_calculator.py index 8c8dfa07af05ee6a3b4d8b9e01b10559490f7e83..6732af07439e946167f7f4a3e526e1814fa53513 100644 --- a/mmdet/core/bbox/iou_calculators/iou2d_calculator.py +++ b/mmdet/core/bbox/iou_calculators/iou2d_calculator.py @@ -12,8 +12,7 @@ class BboxOverlaps2D(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(mode={}, is_aligned={})'.format(self.mode, - self.is_aligned) + repr_str += f'(mode={self.mode}, is_aligned={self.is_aligned})' return repr_str diff --git a/mmdet/core/bbox/samplers/sampling_result.py b/mmdet/core/bbox/samplers/sampling_result.py index dcf25eecd6727ae00fc4c1d2a0578f472dc90e0c..b24d9654af97336994fb6b7dc6ca05ff7fea8a48 100644 --- a/mmdet/core/bbox/samplers/sampling_result.py +++ b/mmdet/core/bbox/samplers/sampling_result.py @@ -9,7 +9,7 @@ class SamplingResult(util_mixins.NiceRepr): >>> # xdoctest: +IGNORE_WANT >>> from mmdet.core.bbox.samplers.sampling_result import * # NOQA >>> self = SamplingResult.random(rng=10) - >>> print('self = {}'.format(self)) + >>> print(f'self = {self}') self = <SamplingResult({ 'neg_bboxes': torch.Size([12, 4]), 'neg_inds': tensor([ 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12]), @@ -57,9 +57,9 @@ class SamplingResult(util_mixins.NiceRepr): Example: >>> self = SamplingResult.random() - >>> print('self = {}'.format(self.to(None))) + >>> print(f'self = {self.to(None)}') >>> # xdoctest: +REQUIRES(--gpu) - >>> print('self = {}'.format(self.to(0))) + >>> print(f'self = {self.to(0)}') """ _dict = self.__dict__ for key, value in _dict.items(): @@ -71,7 +71,7 @@ class SamplingResult(util_mixins.NiceRepr): data = self.info.copy() data['pos_bboxes'] = data.pop('pos_bboxes').shape data['neg_bboxes'] = data.pop('neg_bboxes').shape - parts = ['\'{}\': {!r}'.format(k, v) for k, v in sorted(data.items())] + parts = [f"'{k}': {v!r}" for k, v in sorted(data.items())] body = ' ' + ',\n '.join(parts) return '{\n' + body + '\n}' diff --git a/mmdet/core/evaluation/class_names.py b/mmdet/core/evaluation/class_names.py index 784277345d4e9763f69674b39411136f94d12dd7..4b8845f3fa1ee6b0c24c764b349d4dc7c6e8fe32 100644 --- a/mmdet/core/evaluation/class_names.py +++ b/mmdet/core/evaluation/class_names.py @@ -110,7 +110,7 @@ def get_classes(dataset): if dataset in alias2name: labels = eval(alias2name[dataset] + '_classes()') else: - raise ValueError('Unrecognized dataset: {}'.format(dataset)) + raise ValueError(f'Unrecognized dataset: {dataset}') else: - raise TypeError('dataset must a str, but got {}'.format(type(dataset))) + raise TypeError(f'dataset must a str, but got {type(dataset)}') return labels diff --git a/mmdet/core/evaluation/eval_hooks.py b/mmdet/core/evaluation/eval_hooks.py index f10cc5455496b56c7895a5cf5def5bfd1db1117f..31ef23fb933d2a847e072dbcdd1a53b202577480 100644 --- a/mmdet/core/evaluation/eval_hooks.py +++ b/mmdet/core/evaluation/eval_hooks.py @@ -14,9 +14,8 @@ class EvalHook(Hook): def __init__(self, dataloader, interval=1, **eval_kwargs): if not isinstance(dataloader, DataLoader): - raise TypeError( - 'dataloader must be a pytorch DataLoader, but got {}'.format( - type(dataloader))) + raise TypeError('dataloader must be a pytorch DataLoader, but got' + f' {type(dataloader)}') self.dataloader = dataloader self.interval = interval self.eval_kwargs = eval_kwargs @@ -54,9 +53,8 @@ class DistEvalHook(EvalHook): gpu_collect=False, **eval_kwargs): if not isinstance(dataloader, DataLoader): - raise TypeError( - 'dataloader must be a pytorch DataLoader, but got {}'.format( - type(dataloader))) + raise TypeError('dataloader must be a pytorch DataLoader, but got ' + f'{type(dataloader)}') self.dataloader = dataloader self.interval = interval self.gpu_collect = gpu_collect diff --git a/mmdet/core/evaluation/mean_ap.py b/mmdet/core/evaluation/mean_ap.py index 6934a43d80cd6f228c7b938d53764110258cd46a..0573d66f975227407525aaab8f3be3308060235b 100644 --- a/mmdet/core/evaluation/mean_ap.py +++ b/mmdet/core/evaluation/mean_ap.py @@ -442,15 +442,15 @@ def print_map_summary(mean_ap, header = ['class', 'gts', 'dets', 'recall', 'ap'] for i in range(num_scales): if scale_ranges is not None: - print_log('Scale range {}'.format(scale_ranges[i]), logger=logger) + print_log(f'Scale range {scale_ranges[i]}', logger=logger) table_data = [header] for j in range(num_classes): row_data = [ label_names[j], num_gts[i, j], results[j]['num_dets'], - '{:.3f}'.format(recalls[i, j]), '{:.3f}'.format(aps[i, j]) + f'{recalls[i, j]:.3f}', f'{aps[i, j]:.3f}' ] table_data.append(row_data) - table_data.append(['mAP', '', '', '', '{:.3f}'.format(mean_ap[i])]) + table_data.append(['mAP', '', '', '', '{mean_ap[i]:.3f}']) table = AsciiTable(table_data) table.inner_footing_row_border = True print_log('\n' + table.table, logger=logger) diff --git a/mmdet/core/evaluation/recall.py b/mmdet/core/evaluation/recall.py index 3a591e88f0fb4b50b80a663a0e0eef4d253729a9..a8bc065751e5fc38066cc768cff0235da8481d11 100644 --- a/mmdet/core/evaluation/recall.py +++ b/mmdet/core/evaluation/recall.py @@ -133,10 +133,7 @@ def print_recall_summary(recalls, row_header = [''] + iou_thrs[col_idxs].tolist() table_data = [row_header] for i, num in enumerate(proposal_nums[row_idxs]): - row = [ - '{:.3f}'.format(val) - for val in recalls[row_idxs[i], col_idxs].tolist() - ] + row = [f'{val:.3f}' for val in recalls[row_idxs[i], col_idxs].tolist()] row.insert(0, num) table_data.append(row) table = AsciiTable(table_data) diff --git a/mmdet/core/mask/structures.py b/mmdet/core/mask/structures.py index a2ddd884f176788050e08f0330163e25082ef225..20f4d2e6dc2e0e15e2362444178636941d8a11bf 100644 --- a/mmdet/core/mask/structures.py +++ b/mmdet/core/mask/structures.py @@ -92,9 +92,9 @@ class BitmapMasks(BaseInstanceMasks): def __repr__(self): s = self.__class__.__name__ + '(' - s += 'num_masks={}, '.format(len(self.masks)) - s += 'height={}, '.format(len(self.height)) - s += 'width={})'.format(len(self.width)) + s += f'num_masks={len(self.masks)}, ' + s += f'height={len(self.height)}, ' + s += f'width={len(self.width)})' return s def __len__(self): @@ -316,8 +316,7 @@ class PolygonMasks(BaseInstanceMasks): masks = self.masks[index] except Exception: raise ValueError( - 'Unsupported input of type {} for indexing!'.format( - type(index))) + f'Unsupported input of type {type(index)} for indexing!') if isinstance(masks[0], np.ndarray): masks = [masks] # ensure a list of three levels return PolygonMasks(masks, self.height, self.width) @@ -327,9 +326,9 @@ class PolygonMasks(BaseInstanceMasks): def __repr__(self): s = self.__class__.__name__ + '(' - s += 'num_masks={}, '.format(len(self.masks)) - s += 'height={}, '.format(len(self.height)) - s += 'width={})'.format(len(self.width)) + s += f'num_masks={len(self.masks)}, ' + s += f'height={len(self.height)}, ' + s += f'width={len(self.width)})' return s def __len__(self): diff --git a/mmdet/core/optimizer/default_constructor.py b/mmdet/core/optimizer/default_constructor.py index 4ff02ab7d86001ba7af923a304f6690aa3888dab..3ae246bd37eed12c3c4af8f7fd84e1e906c404e6 100644 --- a/mmdet/core/optimizer/default_constructor.py +++ b/mmdet/core/optimizer/default_constructor.py @@ -51,7 +51,7 @@ class DefaultOptimizerConstructor(object): def __init__(self, optimizer_cfg, paramwise_cfg=None): if not isinstance(optimizer_cfg, dict): raise TypeError('optimizer_cfg should be a dict', - 'but got {}'.format(type(optimizer_cfg))) + f'but got {type(optimizer_cfg)}') self.optimizer_cfg = optimizer_cfg self.paramwise_cfg = {} if paramwise_cfg is None else paramwise_cfg self.base_lr = optimizer_cfg.get('lr', None) @@ -61,7 +61,7 @@ class DefaultOptimizerConstructor(object): def _validate_cfg(self): if not isinstance(self.paramwise_cfg, dict): raise TypeError('paramwise_cfg should be None or a dict, ' - 'but got {}'.format(type(self.paramwise_cfg))) + f'but got {type(self.paramwise_cfg)}') # get base lr and weight decay # weight_decay must be explicitly specified if mult is specified if ('bias_decay_mult' in self.paramwise_cfg @@ -111,9 +111,8 @@ class DefaultOptimizerConstructor(object): params.append(param_group) continue if bypass_duplicate and self._is_in(param_group, params): - warnings.warn('{} is duplicate. It is skipped since ' - 'bypass_duplicate={}'.format( - prefix, bypass_duplicate)) + warnings.warn(f'{prefix} is duplicate. It is skipped since ' + f'bypass_duplicate={bypass_duplicate}') continue # bias_lr_mult affects all bias parameters except for norm.bias if name == 'bias' and not is_norm: @@ -135,8 +134,7 @@ class DefaultOptimizerConstructor(object): params.append(param_group) for child_name, child_mod in module.named_children(): - child_prefix = '{}.{}'.format(prefix, - child_name) if prefix else child_name + child_prefix = f'{prefix}.{child_name}' if prefix else child_name self.add_params(params, child_mod, prefix=child_prefix) def __call__(self, model): diff --git a/mmdet/datasets/cityscapes.py b/mmdet/datasets/cityscapes.py index 96d6f4d9a4cdfe9e89ea74387897b97c9c00c2a3..3388cb38fdfe3d60493b769890fba532d4822d5f 100644 --- a/mmdet/datasets/cityscapes.py +++ b/mmdet/datasets/cityscapes.py @@ -138,12 +138,11 @@ class CityscapesDataset(CocoDataset): class_id = CSLabels.name2label[classes].id score = bboxes[i, -1] mask = maskUtils.decode(segms[i]).astype(np.uint8) - png_filename = osp.join( - outfile_prefix, - basename + '_{}_{}.png'.format(i, classes)) + png_filename = osp.join(outfile_prefix, + basename + f'_{i}_{classes}.png') mmcv.imwrite(mask, png_filename) - fout.write('{} {} {}\n'.format( - osp.basename(png_filename), class_id, score)) + fout.write(f'{osp.basename(png_filename)} {class_id} ' + f'{score}\n') result_files.append(pred_txt) return result_files @@ -249,9 +248,7 @@ class CityscapesDataset(CocoDataset): result_dir = osp.join(tmp_dir.name, 'results') eval_results = {} - print_log( - 'Evaluating results under {} ...'.format(result_dir), - logger=logger) + print_log(f'Evaluating results under {result_dir} ...', logger=logger) # set global states in cityscapes evaluation API CSEval.args.cityscapesPath = os.path.join(self.img_prefix, '../..') @@ -266,9 +263,8 @@ class CityscapesDataset(CocoDataset): '*/*_gtFine_instanceIds.png') groundTruthImgList = glob.glob(CSEval.args.groundTruthSearch) - assert len(groundTruthImgList), \ - 'Cannot find ground truth images in {}.'.format( - CSEval.args.groundTruthSearch) + assert len(groundTruthImgList), 'Cannot find ground truth images' \ + f' in {CSEval.args.groundTruthSearch}.' predictionImgList = [] for gt in groundTruthImgList: predictionImgList.append(CSEval.getPrediction(gt, CSEval.args)) diff --git a/mmdet/datasets/coco.py b/mmdet/datasets/coco.py index b5a665f74ca2a4eb8e13c3101fa9db857a156beb..14957166b4c537fbd60acd600fb0ee1c7c904e8e 100644 --- a/mmdet/datasets/coco.py +++ b/mmdet/datasets/coco.py @@ -241,22 +241,19 @@ class CocoDataset(CustomDataset): result_files = dict() if isinstance(results[0], list): json_results = self._det2json(results) - result_files['bbox'] = '{}.{}.json'.format(outfile_prefix, 'bbox') - result_files['proposal'] = '{}.{}.json'.format( - outfile_prefix, 'bbox') + result_files['bbox'] = f'{outfile_prefix}.bbox.json' + result_files['proposal'] = f'{outfile_prefix}.bbox.json' mmcv.dump(json_results, result_files['bbox']) elif isinstance(results[0], tuple): json_results = self._segm2json(results) - result_files['bbox'] = '{}.{}.json'.format(outfile_prefix, 'bbox') - result_files['proposal'] = '{}.{}.json'.format( - outfile_prefix, 'bbox') - result_files['segm'] = '{}.{}.json'.format(outfile_prefix, 'segm') + result_files['bbox'] = f'{outfile_prefix}.bbox.json' + result_files['proposal'] = f'{outfile_prefix}.bbox.json' + result_files['segm'] = f'{outfile_prefix}.segm.json' mmcv.dump(json_results[0], result_files['bbox']) mmcv.dump(json_results[1], result_files['segm']) elif isinstance(results[0], np.ndarray): json_results = self._proposal2json(results) - result_files['proposal'] = '{}.{}.json'.format( - outfile_prefix, 'proposal') + result_files['proposal'] = f'{outfile_prefix}.proposal.json' mmcv.dump(json_results, result_files['proposal']) else: raise TypeError('invalid type of results') @@ -347,14 +344,14 @@ class CocoDataset(CustomDataset): allowed_metrics = ['bbox', 'segm', 'proposal', 'proposal_fast'] for metric in metrics: if metric not in allowed_metrics: - raise KeyError('metric {} is not supported'.format(metric)) + raise KeyError(f'metric {metric} is not supported') result_files, tmp_dir = self.format_results(results, jsonfile_prefix) eval_results = {} cocoGt = self.coco for metric in metrics: - msg = 'Evaluating {}...'.format(metric) + msg = f'Evaluating {metric}...' if logger is None: msg = '\n' + msg print_log(msg, logger=logger) @@ -364,14 +361,14 @@ class CocoDataset(CustomDataset): results, proposal_nums, iou_thrs, logger='silent') log_msg = [] for i, num in enumerate(proposal_nums): - eval_results['AR@{}'.format(num)] = ar[i] - log_msg.append('\nAR@{}\t{:.4f}'.format(num, ar[i])) + eval_results[f'AR@{num}'] = ar[i] + log_msg.append(f'\nAR@{num}\t{ar[i]:.4f}') log_msg = ''.join(log_msg) print_log(log_msg, logger=logger) continue if metric not in result_files: - raise KeyError('{} is not in results'.format(metric)) + raise KeyError(f'{metric} is not in results') try: cocoDt = cocoGt.loadRes(result_files[metric]) except IndexError: @@ -396,7 +393,7 @@ class CocoDataset(CustomDataset): 'AR_l@1000' ] for i, item in enumerate(metric_items): - val = float('{:.3f}'.format(cocoEval.stats[i + 6])) + val = float(f'{cocoEval.stats[i + 6]:.3f}') eval_results[item] = val else: cocoEval.evaluate() @@ -421,8 +418,7 @@ class CocoDataset(CustomDataset): else: ap = float('nan') results_per_category.append( - ('{}'.format(nm['name']), - '{:0.3f}'.format(float(ap)))) + (f'{nm["name"]}', f'{float(ap):0.3f}')) num_columns = min(6, len(results_per_category) * 2) results_flatten = list( @@ -441,12 +437,12 @@ class CocoDataset(CustomDataset): 'mAP', 'mAP_50', 'mAP_75', 'mAP_s', 'mAP_m', 'mAP_l' ] for i in range(len(metric_items)): - key = '{}_{}'.format(metric, metric_items[i]) - val = float('{:.3f}'.format(cocoEval.stats[i])) + key = f'{metric}_{metric_items[i]}' + val = float(f'{cocoEval.stats[i]:.3f}') eval_results[key] = val - eval_results['{}_mAP_copypaste'.format(metric)] = ( - '{ap[0]:.3f} {ap[1]:.3f} {ap[2]:.3f} {ap[3]:.3f} ' - '{ap[4]:.3f} {ap[5]:.3f}').format(ap=cocoEval.stats[:6]) + eval_results[f'{metric}_mAP_copypaste'] = ( + f'{ap[0]:.3f} {ap[1]:.3f} {ap[2]:.3f} {ap[3]:.3f} ' + f'{ap[4]:.3f} {ap[5]:.3f}') if tmp_dir is not None: tmp_dir.cleanup() return eval_results diff --git a/mmdet/datasets/custom.py b/mmdet/datasets/custom.py index d6a1bd6251868d5ba5b2c638177643f070a2a4ad..2f44c438f636c08d5b18e294188cb64c5a769722 100644 --- a/mmdet/datasets/custom.py +++ b/mmdet/datasets/custom.py @@ -181,8 +181,7 @@ class CustomDataset(Dataset): elif isinstance(classes, (tuple, list)): class_names = classes else: - raise ValueError('Unsupported type {} of classes.'.format( - type(classes))) + raise ValueError(f'Unsupported type {type(classes)} of classes.') return class_names @@ -220,7 +219,7 @@ class CustomDataset(Dataset): metric = metric[0] allowed_metrics = ['mAP', 'recall'] if metric not in allowed_metrics: - raise KeyError('metric {} is not supported'.format(metric)) + raise KeyError(f'metric {metric} is not supported') annotations = [self.get_ann_info(i) for i in range(len(self))] eval_results = {} if metric == 'mAP': @@ -241,10 +240,9 @@ class CustomDataset(Dataset): gt_bboxes, results, proposal_nums, iou_thr, logger=logger) for i, num in enumerate(proposal_nums): for j, iou in enumerate(iou_thr): - eval_results['recall@{}@{}'.format(num, iou)] = recalls[i, - j] + eval_results[f'recall@{num}@{iou}'] = recalls[i, j] if recalls.shape[1] > 1: ar = recalls.mean(axis=1) for i, num in enumerate(proposal_nums): - eval_results['AR@{}'.format(num)] = ar[i] + eval_results[f'AR@{num}'] = ar[i] return eval_results diff --git a/mmdet/datasets/pipelines/compose.py b/mmdet/datasets/pipelines/compose.py index 92526f0346dd3d44fdf04538284bc7488c139c5d..9c69705e4af9f448a2820d5fcd48de4e285ee48b 100644 --- a/mmdet/datasets/pipelines/compose.py +++ b/mmdet/datasets/pipelines/compose.py @@ -31,6 +31,6 @@ class Compose(object): format_string = self.__class__.__name__ + '(' for t in self.transforms: format_string += '\n' - format_string += ' {0}'.format(t) + format_string += f' {t}' format_string += '\n)' return format_string diff --git a/mmdet/datasets/pipelines/formating.py b/mmdet/datasets/pipelines/formating.py index 718fe5abda15325d0c9894f3b0879b08395afe34..fe8cbcc57628767b6903b2c61576193bf503fe4c 100644 --- a/mmdet/datasets/pipelines/formating.py +++ b/mmdet/datasets/pipelines/formating.py @@ -25,8 +25,7 @@ def to_tensor(data): elif isinstance(data, float): return torch.FloatTensor([data]) else: - raise TypeError('type {} cannot be converted to tensor.'.format( - type(data))) + raise TypeError(f'type {type(data)} cannot be converted to tensor.') @PIPELINES.register_module @@ -41,7 +40,7 @@ class ToTensor(object): return results def __repr__(self): - return self.__class__.__name__ + '(keys={})'.format(self.keys) + return self.__class__.__name__ + f'(keys={self.keys})' @PIPELINES.register_module @@ -59,7 +58,7 @@ class ImageToTensor(object): return results def __repr__(self): - return self.__class__.__name__ + '(keys={})'.format(self.keys) + return self.__class__.__name__ + f'(keys={self.keys})' @PIPELINES.register_module @@ -75,8 +74,8 @@ class Transpose(object): return results def __repr__(self): - return self.__class__.__name__ + '(keys={}, order={})'.format( - self.keys, self.order) + return self.__class__.__name__ + \ + f'(keys={self.keys}, order={self.order})' @PIPELINES.register_module @@ -95,7 +94,7 @@ class ToDataContainer(object): return results def __repr__(self): - return self.__class__.__name__ + '(fields={})'.format(self.fields) + return self.__class__.__name__ + f'(fields={self.fields})' @PIPELINES.register_module @@ -188,8 +187,8 @@ class Collect(object): return data def __repr__(self): - return self.__class__.__name__ + '(keys={}, meta_keys={})'.format( - self.keys, self.meta_keys) + return self.__class__.__name__ + \ + f'(keys={self.keys}, meta_keys={self.meta_keys})' @PIPELINES.register_module @@ -221,4 +220,4 @@ class WrapFieldsToLists(object): return results def __repr__(self): - return '{}()'.format(self.__class__.__name__) + return f'{self.__class__.__name__}()' diff --git a/mmdet/datasets/pipelines/instaboost.py b/mmdet/datasets/pipelines/instaboost.py index e4d2412824995ff21f13c88180bf7d33f3ced4ba..5460eb6ee188b4c0931320cda67cc5eafe56e563 100644 --- a/mmdet/datasets/pipelines/instaboost.py +++ b/mmdet/datasets/pipelines/instaboost.py @@ -93,5 +93,5 @@ class InstaBoost(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += ('(cfg={}, aug_ratio={})').format(self.cfg, self.aug_ratio) + repr_str += f'(cfg={self.cfg}, aug_ratio={self.aug_ratio})' return repr_str diff --git a/mmdet/datasets/pipelines/loading.py b/mmdet/datasets/pipelines/loading.py index ba555f6ab59c681caa98202db48d9f622f97247e..4e75b0d4ba6fb3b0512174d8256a345ac7c3be2f 100644 --- a/mmdet/datasets/pipelines/loading.py +++ b/mmdet/datasets/pipelines/loading.py @@ -39,8 +39,8 @@ class LoadImageFromFile(object): return results def __repr__(self): - return "{} (to_float32={}, color_type='{}')".format( - self.__class__.__name__, self.to_float32, self.color_type) + return f'{self.__class__.__name__}(to_float32={self.to_float32}, ' \ + f"color_type='{self.color_type}')" @PIPELINES.register_module @@ -80,8 +80,8 @@ class LoadMultiChannelImageFromFiles(object): return results def __repr__(self): - return "{} (to_float32={}, color_type='{}')".format( - self.__class__.__name__, self.to_float32, self.color_type) + return f'{self.__class__.__name__}(to_float32={self.to_float32}, ' \ + f"color_type='{self.color_type}')" @PIPELINES.register_module @@ -181,9 +181,10 @@ class LoadAnnotations(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += ('(with_bbox={}, with_label={}, with_mask={},' - ' with_seg={})').format(self.with_bbox, self.with_label, - self.with_mask, self.with_seg) + repr_str += f'(with_bbox={self.with_bbox}, ' + repr_str += f'with_label={self.with_label}, ' + repr_str += f'with_mask={self.with_mask}, ' + repr_str += f'with_seg={self.with_seg})' return repr_str @@ -198,7 +199,7 @@ class LoadProposals(object): if proposals.shape[1] not in (4, 5): raise AssertionError( 'proposals should have shapes (n, 4) or (n, 5), ' - 'but found {}'.format(proposals.shape)) + f'but found {proposals.shape}') proposals = proposals[:, :4] if self.num_max_proposals is not None: @@ -211,5 +212,5 @@ class LoadProposals(object): return results def __repr__(self): - return self.__class__.__name__ + '(num_max_proposals={})'.format( - self.num_max_proposals) + return self.__class__.__name__ + \ + f'(num_max_proposals={self.num_max_proposals})' diff --git a/mmdet/datasets/pipelines/test_aug.py b/mmdet/datasets/pipelines/test_aug.py index a2b7230de07fd1021e85bae4252b44a7748b318a..bcf1b55fadb535cc84ee61b7f87b5ccf6c4a881c 100644 --- a/mmdet/datasets/pipelines/test_aug.py +++ b/mmdet/datasets/pipelines/test_aug.py @@ -33,6 +33,6 @@ class MultiScaleFlipAug(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(transforms={}, img_scale={}, flip={})'.format( - self.transforms, self.img_scale, self.flip) + repr_str += f'(transforms={self.transforms}, ' + repr_str += f'img_scale={self.img_scale}, flip={self.flip})' return repr_str diff --git a/mmdet/datasets/pipelines/transforms.py b/mmdet/datasets/pipelines/transforms.py index a6f12acceafee88a56fbcdcf2f4a3b9f8424e91e..2857d32966f9d627880e15310f7486940af07969 100644 --- a/mmdet/datasets/pipelines/transforms.py +++ b/mmdet/datasets/pipelines/transforms.py @@ -177,11 +177,10 @@ class Resize(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += ('(img_scale={}, multiscale_mode={}, ratio_range={}, ' - 'keep_ratio={})').format(self.img_scale, - self.multiscale_mode, - self.ratio_range, - self.keep_ratio) + repr_str += f'(img_scale={self.img_scale}, ' + repr_str += f'multiscale_mode={self.multiscale_mode}, ' + repr_str += f'ratio_range={self.ratio_range}, ' + repr_str += f'keep_ratio={self.keep_ratio})' return repr_str @@ -222,8 +221,7 @@ class RandomFlip(object): flipped[..., 1::4] = h - bboxes[..., 3::4] flipped[..., 3::4] = h - bboxes[..., 1::4] else: - raise ValueError( - 'Invalid flipping direction "{}"'.format(direction)) + raise ValueError(f"Invalid flipping direction '{direction}'") return flipped def __call__(self, results): @@ -252,8 +250,7 @@ class RandomFlip(object): return results def __repr__(self): - return self.__class__.__name__ + '(flip_ratio={})'.format( - self.flip_ratio) + return self.__class__.__name__ + f'(flip_ratio={self.flip_ratio})' @PIPELINES.register_module @@ -306,8 +303,9 @@ class Pad(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(size={}, size_divisor={}, pad_val={})'.format( - self.size, self.size_divisor, self.pad_val) + repr_str += f'(size={self.size}, ' + repr_str += f'size_divisor={self.size_divisor}, ' + repr_str += f'pad_val={self.pad_val})' return repr_str @@ -336,8 +334,7 @@ class Normalize(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(mean={}, std={}, to_rgb={})'.format( - self.mean, self.std, self.to_rgb) + repr_str += f'(mean={self.mean}, std={self.std}, to_rgb={self.to_rgb})' return repr_str @@ -399,8 +396,7 @@ class RandomCrop(object): return results def __repr__(self): - return self.__class__.__name__ + '(crop_size={})'.format( - self.crop_size) + return self.__class__.__name__ + f'(crop_size={self.crop_size})' @PIPELINES.register_module @@ -422,8 +418,7 @@ class SegRescale(object): return results def __repr__(self): - return self.__class__.__name__ + '(scale_factor={})'.format( - self.scale_factor) + return self.__class__.__name__ + f'(scale_factor={self.scale_factor})' @PIPELINES.register_module @@ -511,12 +506,12 @@ class PhotoMetricDistortion(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += ('(brightness_delta={}, contrast_range={}, ' - 'saturation_range={}, hue_delta={})').format( - self.brightness_delta, - (self.contrast_lower, self.contrast_upper), - (self.saturation_lower, self.saturation_upper), - self.hue_delta) + repr_str += f'(\nbrightness_delta={self.brightness_delta},\n' + repr_str += f'contrast_range=' + repr_str += f'{(self.contrast_lower, self.contrast_upper)},\n' + repr_str += f'saturation_range=' + repr_str += f'{(self.saturation_lower, self.saturation_upper)},\n' + repr_str += f'hue_delta={self.hue_delta})' return repr_str @@ -584,10 +579,9 @@ class Expand(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(mean={}, to_rgb={}, ratio_range={}, ' \ - 'seg_ignore_label={})'.format( - self.mean, self.to_rgb, self.ratio_range, - self.seg_ignore_label) + repr_str += f'(mean={self.mean}, to_rgb={self.to_rgb}, ' + repr_str += f'ratio_range={self.ratio_range}, ' + repr_str += f'seg_ignore_label={self.seg_ignore_label})' return repr_str @@ -677,8 +671,8 @@ class MinIoURandomCrop(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(min_ious={}, min_crop_size={})'.format( - self.min_ious, self.min_crop_size) + repr_str += f'(min_ious={self.min_ious}, ' + repr_str += f'min_crop_size={self.min_crop_size})' return repr_str @@ -700,8 +694,8 @@ class Corrupt(object): def __repr__(self): repr_str = self.__class__.__name__ - repr_str += '(corruption={}, severity={})'.format( - self.corruption, self.severity) + repr_str += f'(corruption={self.corruption}, ' + repr_str += f'severity={self.severity})' return repr_str @@ -777,8 +771,7 @@ class Albu(object): obj_cls = obj_type else: raise TypeError( - 'type must be a str or valid type, but got {}'.format( - type(obj_type))) + f'type must be a str or valid type, but got {type(obj_type)}') if 'transforms' in args: args['transforms'] = [ @@ -866,6 +859,5 @@ class Albu(object): return results def __repr__(self): - repr_str = self.__class__.__name__ - repr_str += '(transforms={})'.format(self.transforms) + repr_str = self.__class__.__name__ + f'(transforms={self.transforms})' return repr_str diff --git a/mmdet/datasets/voc.py b/mmdet/datasets/voc.py index 24065b9fad840c703706371f509c5264af6aa4de..3c24c19b1269f1b7354474b773ba9e87c8768f2f 100644 --- a/mmdet/datasets/voc.py +++ b/mmdet/datasets/voc.py @@ -32,7 +32,7 @@ class VOCDataset(XMLDataset): metric = metric[0] allowed_metrics = ['mAP', 'recall'] if metric not in allowed_metrics: - raise KeyError('metric {} is not supported'.format(metric)) + raise KeyError(f'metric {metric} is not supported') annotations = [self.get_ann_info(i) for i in range(len(self))] eval_results = {} if metric == 'mAP': @@ -57,10 +57,9 @@ class VOCDataset(XMLDataset): gt_bboxes, results, proposal_nums, iou_thr, logger=logger) for i, num in enumerate(proposal_nums): for j, iou in enumerate(iou_thr): - eval_results['recall@{}@{}'.format(num, iou)] = recalls[i, - j] + eval_results[f'recall@{num}@{iou}'] = recalls[i, j] if recalls.shape[1] > 1: ar = recalls.mean(axis=1) for i, num in enumerate(proposal_nums): - eval_results['AR@{}'.format(num)] = ar[i] + eval_results[f'AR@{num}'] = ar[i] return eval_results diff --git a/mmdet/datasets/wider_face.py b/mmdet/datasets/wider_face.py index 9bf9f8f9bdaeccb24e5a7bfdf5da5239df42b49f..5f3e53d733a0f788fec5491fefa02467c49627b5 100644 --- a/mmdet/datasets/wider_face.py +++ b/mmdet/datasets/wider_face.py @@ -23,9 +23,9 @@ class WIDERFaceDataset(XMLDataset): data_infos = [] img_ids = mmcv.list_from_file(ann_file) for img_id in img_ids: - filename = '{}.jpg'.format(img_id) + filename = '{img_id}.jpg' xml_path = osp.join(self.img_prefix, 'Annotations', - '{}.xml'.format(img_id)) + f'{img_id}.xml') tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') diff --git a/mmdet/datasets/xml_style.py b/mmdet/datasets/xml_style.py index 40cef1b0c097556ec10817f3c582bc59fd4a5b94..5b6214eb5101c73087894e847c459f775bd64667 100644 --- a/mmdet/datasets/xml_style.py +++ b/mmdet/datasets/xml_style.py @@ -20,9 +20,9 @@ class XMLDataset(CustomDataset): data_infos = [] img_ids = mmcv.list_from_file(ann_file) for img_id in img_ids: - filename = 'JPEGImages/{}.jpg'.format(img_id) + filename = f'JPEGImages/{img_id}.jpg' xml_path = osp.join(self.img_prefix, 'Annotations', - '{}.xml'.format(img_id)) + f'{img_id}.xml') tree = ET.parse(xml_path) root = tree.getroot() size = root.find('size') @@ -40,7 +40,7 @@ class XMLDataset(CustomDataset): for data_info in self.data_infos: img_id = data_info['id'] xml_path = osp.join(self.img_prefix, 'Annotations', - '{}.xml'.format(img_id)) + f'{img_id}.xml') tree = ET.parse(xml_path) root = tree.getroot() for obj in root.findall('object'): @@ -53,8 +53,7 @@ class XMLDataset(CustomDataset): def get_ann_info(self, idx): img_id = self.data_infos[idx]['id'] - xml_path = osp.join(self.img_prefix, 'Annotations', - '{}.xml'.format(img_id)) + xml_path = osp.join(self.img_prefix, 'Annotations', f'{img_id}.xml') tree = ET.parse(xml_path) root = tree.getroot() bboxes = [] diff --git a/mmdet/models/anchor_heads/anchor_head.py b/mmdet/models/anchor_heads/anchor_head.py index 9158c2180bd5fc35bdf75244a9b33b1e34ce3093..83f33dcf98fadf368fa9a92d10eb8216a0fae232 100644 --- a/mmdet/models/anchor_heads/anchor_head.py +++ b/mmdet/models/anchor_heads/anchor_head.py @@ -67,7 +67,7 @@ class AnchorHead(nn.Module): self.cls_out_channels = num_classes + 1 if self.cls_out_channels <= 0: - raise ValueError('num_classes={} is too small'.format(num_classes)) + raise ValueError(f'num_classes={num_classes} is too small') self.reg_decoded_bbox = reg_decoded_bbox self.background_label = ( diff --git a/mmdet/models/backbones/hrnet.py b/mmdet/models/backbones/hrnet.py index ee0c62501114da15daf5044d2bb0f5fb02bdda60..5ce5eb9a216ddcd3ad9e0c4f1bf14170d91cb107 100644 --- a/mmdet/models/backbones/hrnet.py +++ b/mmdet/models/backbones/hrnet.py @@ -43,18 +43,18 @@ class HRModule(nn.Module): def _check_branches(self, num_branches, num_blocks, in_channels, num_channels): if num_branches != len(num_blocks): - error_msg = 'NUM_BRANCHES({}) <> NUM_BLOCKS({})'.format( - num_branches, len(num_blocks)) + error_msg = f'NUM_BRANCHES({num_branches}) ' \ + f'!= NUM_BLOCKS({len(num_blocks)})' raise ValueError(error_msg) if num_branches != len(num_channels): - error_msg = 'NUM_BRANCHES({}) <> NUM_CHANNELS({})'.format( - num_branches, len(num_channels)) + error_msg = f'NUM_BRANCHES({num_branches}) ' \ + f'!= NUM_CHANNELS({len(num_channels)})' raise ValueError(error_msg) if num_branches != len(in_channels): - error_msg = 'NUM_BRANCHES({}) <> NUM_INCHANNELS({})'.format( - num_branches, len(in_channels)) + error_msg = f'NUM_BRANCHES({num_branches}) ' \ + f'!= NUM_INCHANNELS({len(in_channels)})' raise ValueError(error_msg) def _make_one_branch(self, diff --git a/mmdet/models/backbones/resnet.py b/mmdet/models/backbones/resnet.py index ee219bd1a60cbb7851112c58b3357f9c3e8d9d52..b541b4e064b1a7ec141e7f38fbb1c7ebbfc20f2b 100644 --- a/mmdet/models/backbones/resnet.py +++ b/mmdet/models/backbones/resnet.py @@ -218,7 +218,7 @@ class Bottleneck(nn.Module): plugin, in_channels=in_channels, postfix=plugin.pop('postfix', '')) - assert not hasattr(self, name), 'duplicate plugin {}'.format(name) + assert not hasattr(self, name), f'duplicate plugin {name}' self.add_module(name, layer) plugin_names.append(name) return plugin_names @@ -362,7 +362,7 @@ class ResNet(nn.Module): zero_init_residual=True): super(ResNet, self).__init__() if depth not in self.arch_settings: - raise KeyError('invalid depth {} for resnet'.format(depth)) + raise KeyError(f'invalid depth {depth} for resnet') self.depth = depth self.base_channels = base_channels self.num_stages = num_stages @@ -417,7 +417,7 @@ class ResNet(nn.Module): dcn=dcn, plugins=stage_plugins) self.inplanes = planes * self.block.expansion - layer_name = 'layer{}'.format(i + 1) + layer_name = f'layer{i + 1}' self.add_module(layer_name, res_layer) self.res_layers.append(layer_name) @@ -548,7 +548,7 @@ class ResNet(nn.Module): param.requires_grad = False for i in range(1, self.frozen_stages + 1): - m = getattr(self, 'layer{}'.format(i)) + m = getattr(self, f'layer{i}') m.eval() for param in m.parameters(): param.requires_grad = False diff --git a/mmdet/models/detectors/base.py b/mmdet/models/detectors/base.py index ce48002d2afb2464e011593048afd6425a9ed319..936eeba05095194f1cc723a763efc1317832ea1e 100644 --- a/mmdet/models/detectors/base.py +++ b/mmdet/models/detectors/base.py @@ -79,19 +79,17 @@ class BaseDetector(nn.Module, metaclass=ABCMeta): def init_weights(self, pretrained=None): if pretrained is not None: - print_log('load model from: {}'.format(pretrained), logger='root') + print_log(f'load model from: {pretrained}', logger='root') async def aforward_test(self, *, img, img_metas, **kwargs): for var, name in [(img, 'img'), (img_metas, 'img_metas')]: if not isinstance(var, list): - raise TypeError('{} must be a list, but got {}'.format( - name, type(var))) + raise TypeError(f'{name} must be a list, but got {type(var)}') num_augs = len(img) if num_augs != len(img_metas): - raise ValueError( - 'num of augmentations ({}) != num of image metas ({})'.format( - len(img), len(img_metas))) + raise ValueError(f'num of augmentations ({len(img)}) ' + f'!= num of image metas ({len(img_metas)})') # TODO: remove the restriction of samples_per_gpu == 1 when prepared samples_per_gpu = img[0].size(0) assert samples_per_gpu == 1 @@ -113,14 +111,12 @@ class BaseDetector(nn.Module, metaclass=ABCMeta): """ for var, name in [(imgs, 'imgs'), (img_metas, 'img_metas')]: if not isinstance(var, list): - raise TypeError('{} must be a list, but got {}'.format( - name, type(var))) + raise TypeError(f'{name} must be a list, but got {type(var)}') num_augs = len(imgs) if num_augs != len(img_metas): - raise ValueError( - 'num of augmentations ({}) != num of image meta ({})'.format( - len(imgs), len(img_metas))) + raise ValueError(f'num of augmentations ({len(imgs)}) ' + f'!= num of image meta ({len(img_metas)})') # TODO: remove the restriction of samples_per_gpu == 1 when prepared samples_per_gpu = imgs[0].size(0) assert samples_per_gpu == 1 @@ -175,7 +171,7 @@ class BaseDetector(nn.Module, metaclass=ABCMeta): else: raise TypeError( 'dataset must be a valid dataset name or a sequence' - ' of class names, not {}'.format(type(dataset))) + f' of class names, not {type(dataset)}') for img, img_meta in zip(imgs, img_metas): h, w, _ = img_meta['img_shape'] diff --git a/mmdet/models/detectors/fast_rcnn.py b/mmdet/models/detectors/fast_rcnn.py index 3bdc26869fab86d371f98383f36f474804fc4946..062607a2923198791e535e8aa37ed4da7c7be54d 100644 --- a/mmdet/models/detectors/fast_rcnn.py +++ b/mmdet/models/detectors/fast_rcnn.py @@ -36,14 +36,12 @@ class FastRCNN(TwoStageDetector): """ for var, name in [(imgs, 'imgs'), (img_metas, 'img_metas')]: if not isinstance(var, list): - raise TypeError('{} must be a list, but got {}'.format( - name, type(var))) + raise TypeError(f'{name} must be a list, but got {type(var)}') num_augs = len(imgs) if num_augs != len(img_metas): - raise ValueError( - 'num of augmentations ({}) != num of image meta ({})'.format( - len(imgs), len(img_metas))) + raise ValueError(f'num of augmentations ({len(imgs)}) ' + f'!= num of image meta ({len(img_metas)})') # TODO: remove the restriction of samples_per_gpu == 1 when prepared samples_per_gpu = imgs[0].size(0) assert samples_per_gpu == 1 diff --git a/mmdet/models/mask_heads/fcn_mask_head.py b/mmdet/models/mask_heads/fcn_mask_head.py index 62849a5824fa6432623043f305fa270295fcb8a9..abe915e7f2b9f8f7f2d7f5cff0c79355d8db1758 100644 --- a/mmdet/models/mask_heads/fcn_mask_head.py +++ b/mmdet/models/mask_heads/fcn_mask_head.py @@ -38,9 +38,9 @@ class FCNMaskHead(nn.Module): None, 'deconv', 'nearest', 'bilinear', 'carafe' ]: raise ValueError( - 'Invalid upsample method {}, accepted methods ' - 'are "deconv", "nearest", "bilinear", "carafe"'.format( - self.upsample_cfg['type'])) + f'Invalid upsample method {self.upsample_cfg["type"]}, ' + 'accepted methods are "deconv", "nearest", "bilinear", ' + '"carafe"') self.num_convs = num_convs # WARN: roi_feat_size is reserved and not used self.roi_feat_size = _pair(roi_feat_size) diff --git a/mmdet/models/necks/fpn.py b/mmdet/models/necks/fpn.py index 54daa8ca564765b823a2afc9e99987c04bbd763d..7b5596ca133445dda327e7878065f5977b195dcb 100644 --- a/mmdet/models/necks/fpn.py +++ b/mmdet/models/necks/fpn.py @@ -45,7 +45,7 @@ class FPN(nn.Module): >>> self = FPN(in_channels, 11, len(in_channels)).eval() >>> outputs = self.forward(inputs) >>> for i in range(len(outputs)): - ... print('outputs[{}].shape = {!r}'.format(i, outputs[i].shape)) + ... print(f'outputs[{i}].shape = {outputs[i].shape}') outputs[0].shape = torch.Size([1, 11, 340, 340]) outputs[1].shape = torch.Size([1, 11, 170, 170]) outputs[2].shape = torch.Size([1, 11, 84, 84]) diff --git a/mmdet/models/roi_heads/cascade_roi_head.py b/mmdet/models/roi_heads/cascade_roi_head.py index 6e42eb136e603bd13418a5450361ecc03e12b628..af7dca14b9b6e1d394760e60d2b65890c4fe03e4 100644 --- a/mmdet/models/roi_heads/cascade_roi_head.py +++ b/mmdet/models/roi_heads/cascade_roi_head.py @@ -243,7 +243,7 @@ class CascadeRoIHead(BaseRoIHead, BBoxTestMixin, MaskTestMixin): rcnn_train_cfg) for name, value in bbox_results['loss_bbox'].items(): - losses['s{}.{}'.format(i, name)] = ( + losses[f's{i}.{name}'] = ( value * lw if 'loss' in name else value) # mask head forward and loss @@ -254,7 +254,7 @@ class CascadeRoIHead(BaseRoIHead, BBoxTestMixin, MaskTestMixin): # TODO: Support empty tensor input. #2280 if mask_results['loss_mask'] is not None: for name, value in mask_results['loss_mask'].items(): - losses['s{}.{}'.format(i, name)] = ( + losses[f's{i}.{name}'] = ( value * lw if 'loss' in name else value) # refine bboxes diff --git a/mmdet/models/roi_heads/htc_roi_head.py b/mmdet/models/roi_heads/htc_roi_head.py index 73426e380a698148bec19d2335b9f15128a6a862..c3eae5fc43b4fdd9e8decc98313ce849624d11fb 100644 --- a/mmdet/models/roi_heads/htc_roi_head.py +++ b/mmdet/models/roi_heads/htc_roi_head.py @@ -250,7 +250,7 @@ class HybridTaskCascadeRoIHead(CascadeRoIHead): roi_labels = bbox_results['bbox_targets'][0] for name, value in bbox_results['loss_bbox'].items(): - losses['s{}.{}'.format(i, name)] = ( + losses[f's{i}.{name}'] = ( value * lw if 'loss' in name else value) # mask head forward and loss @@ -280,7 +280,7 @@ class HybridTaskCascadeRoIHead(CascadeRoIHead): i, x, sampling_results, gt_masks, rcnn_train_cfg, semantic_feat) for name, value in mask_results['loss_mask'].items(): - losses['s{}.{}'.format(i, name)] = ( + losses[f's{i}.{name}'] = ( value * lw if 'loss' in name else value) # refine bboxes (same as Cascade R-CNN) diff --git a/mmdet/models/shared_heads/res_layer.py b/mmdet/models/shared_heads/res_layer.py index ded192d351ca2aaf68c7b166beac4a678d54777e..cfff143d34185cd1a28d5dbdf208ca58e5c5c4d0 100644 --- a/mmdet/models/shared_heads/res_layer.py +++ b/mmdet/models/shared_heads/res_layer.py @@ -43,7 +43,7 @@ class ResLayer(nn.Module): with_cp=with_cp, norm_cfg=self.norm_cfg, dcn=dcn) - self.add_module('layer{}'.format(stage + 1), res_layer) + self.add_module(f'layer{stage + 1}', res_layer) def init_weights(self, pretrained=None): if isinstance(pretrained, str): @@ -60,7 +60,7 @@ class ResLayer(nn.Module): @auto_fp16() def forward(self, x): - res_layer = getattr(self, 'layer{}'.format(self.stage + 1)) + res_layer = getattr(self, f'layer{self.stage + 1}') out = res_layer(x) return out diff --git a/mmdet/ops/activation.py b/mmdet/ops/activation.py index 013c5bb1d86e2246b2dd1bfb3878c78f499b724f..53b72b2ad79b8abfd9b73b0231440d5ab062e986 100644 --- a/mmdet/ops/activation.py +++ b/mmdet/ops/activation.py @@ -28,7 +28,7 @@ def build_activation_layer(cfg): layer_type = cfg_.pop('type') if layer_type not in activation_cfg: - raise KeyError('Unrecognized activation type {}'.format(layer_type)) + raise KeyError(f'Unrecognized activation type {layer_type}') else: activation = activation_cfg[layer_type] if activation is None: diff --git a/mmdet/ops/carafe/grad_check.py b/mmdet/ops/carafe/grad_check.py index 60b79d37101a5bc0064c1cc6dcc57fc12359120b..9ddb2398342d955cc532545490c8ce57bc60e568 100644 --- a/mmdet/ops/carafe/grad_check.py +++ b/mmdet/ops/carafe/grad_check.py @@ -39,9 +39,10 @@ for i in range(loop_num): torch.cuda.synchronize() time_backward += timer.since_last_check() bar.update() -print('\nCARAFE time forward: {} ms/iter | time backward: {} ms/iter'.format( - (time_forward + 1e-3) * 1e3 / loop_num, - (time_backward + 1e-3) * 1e3 / loop_num)) +forward_speed = (time_forward + 1e-3) * 1e3 / loop_num +backward_speed = (time_backward + 1e-3) * 1e3 / loop_num +print(f'\nCARAFE time forward: {forward_speed} ' + f'ms/iter | time backward: {backward_speed} ms/iter') time_naive_forward = 0 time_naive_backward = 0 @@ -55,6 +56,7 @@ for i in range(loop_num): torch.cuda.synchronize() time_naive_backward += timer.since_last_check() bar.update() -print('\nCARAFE naive time forward: {} ms/iter | time backward: {} ms/iter'. - format((time_naive_forward + 1e-3) * 1e3 / loop_num, - (time_naive_backward + 1e-3) * 1e3 / loop_num)) +forward_speed = (time_naive_forward + 1e-3) * 1e3 / loop_num +backward_speed = (time_naive_backward + 1e-3) * 1e3 / loop_num +print('\nCARAFE naive time forward: ' + f'{forward_speed} ms/iter | time backward: {backward_speed} ms/iter') diff --git a/mmdet/ops/conv.py b/mmdet/ops/conv.py index a5efb8377e7af9c5baf492712d09f12c94239369..8316001dfc26c580b99010d2ff3bdc0fae443e23 100644 --- a/mmdet/ops/conv.py +++ b/mmdet/ops/conv.py @@ -30,7 +30,7 @@ def build_conv_layer(cfg, *args, **kwargs): layer_type = cfg_.pop('type') if layer_type not in conv_cfg: - raise KeyError('Unrecognized norm type {}'.format(layer_type)) + raise KeyError(f'Unrecognized norm type {layer_type}') else: conv_layer = conv_cfg[layer_type] diff --git a/mmdet/ops/dcn/deform_conv.py b/mmdet/ops/dcn/deform_conv.py index 36ab443a4461bfb7792efc153eeb514726cd1345..29ba43d19175ce0b8aec64a206bd7087a9d281f0 100644 --- a/mmdet/ops/dcn/deform_conv.py +++ b/mmdet/ops/dcn/deform_conv.py @@ -25,9 +25,8 @@ class DeformConvFunction(Function): deformable_groups=1, im2col_step=64): if input is not None and input.dim() != 4: - raise ValueError( - 'Expected 4D tensor as input, got {}D tensor instead.'.format( - input.dim())) + raise ValueError(f'Expected 4D tensor as input, got {input.dim()}' + 'D tensor instead.') ctx.stride = _pair(stride) ctx.padding = _pair(padding) ctx.dilation = _pair(dilation) @@ -106,9 +105,8 @@ class DeformConvFunction(Function): stride_ = stride[d] output_size += ((in_size + (2 * pad) - kernel) // stride_ + 1, ) if not all(map(lambda s: s > 0, output_size)): - raise ValueError( - 'convolution input is too small (output would be {})'.format( - 'x'.join(map(str, output_size)))) + raise ValueError('convolution input is too small (output would be ' + f'{"x".join(map(str, output_size))})') return output_size @@ -205,11 +203,10 @@ class DeformConv(nn.Module): assert not bias assert in_channels % groups == 0, \ - 'in_channels {} cannot be divisible by groups {}'.format( - in_channels, groups) + f'in_channels {in_channels} is not divisible by groups {groups}' assert out_channels % groups == 0, \ - 'out_channels {} cannot be divisible by groups {}'.format( - out_channels, groups) + f'out_channels {out_channels} is not divisible ' \ + f'by groups {groups}' self.in_channels = in_channels self.out_channels = out_channels @@ -314,8 +311,8 @@ class DeformConvPack(DeformConv): if version is not None and version > 1: print_log( - 'DeformConvPack {} is upgraded to version 2.'.format( - prefix.rstrip('.')), + f'DeformConvPack {prefix.rstrip(".")} is upgraded to ' + 'version 2.', logger='root') super()._load_from_state_dict(state_dict, prefix, local_metadata, @@ -437,8 +434,8 @@ class ModulatedDeformConvPack(ModulatedDeformConv): if version is not None and version > 1: print_log( - 'ModulatedDeformConvPack {} is upgraded to version 2.'.format( - prefix.rstrip('.')), + f'ModulatedDeformConvPack {prefix.rstrip(".")} is upgraded to ' + 'version 2.', logger='root') super()._load_from_state_dict(state_dict, prefix, local_metadata, diff --git a/mmdet/ops/nms/nms_wrapper.py b/mmdet/ops/nms/nms_wrapper.py index c48ec5cb891fc4c91e3423ea13da739dee38ca3d..ed4ee6124dfc767c120b9608475065ab24c068ea 100644 --- a/mmdet/ops/nms/nms_wrapper.py +++ b/mmdet/ops/nms/nms_wrapper.py @@ -39,12 +39,11 @@ def nms(dets, iou_thr, device_id=None): dets_th = dets elif isinstance(dets, np.ndarray): is_numpy = True - device = 'cpu' if device_id is None else 'cuda:{}'.format(device_id) + device = 'cpu' if device_id is None else f'cuda:{device_id}' dets_th = torch.from_numpy(dets).to(device) else: - raise TypeError( - 'dets must be either a Tensor or numpy array, but got {}'.format( - type(dets))) + raise TypeError('dets must be either a Tensor or numpy array, ' + f'but got {type(dets)}') # execute cpu or cuda nms if dets_th.shape[0] == 0: @@ -96,13 +95,12 @@ def soft_nms(dets, iou_thr, method='linear', sigma=0.5, min_score=1e-3): is_tensor = False dets_t = torch.from_numpy(dets) else: - raise TypeError( - 'dets must be either a Tensor or numpy array, but got {}'.format( - type(dets))) + raise TypeError('dets must be either a Tensor or numpy array, ' + f'but got {type(dets)}') method_codes = {'linear': 1, 'gaussian': 2} if method not in method_codes: - raise ValueError('Invalid method for SoftNMS: {}'.format(method)) + raise ValueError(f'Invalid method for SoftNMS: {method}') results = nms_ext.soft_nms(dets_t, iou_thr, method_codes[method], sigma, min_score) diff --git a/mmdet/ops/norm.py b/mmdet/ops/norm.py index d5687cbd9a31be259ee0b202800af53fbba8ca1a..99fc93116e89b60e30d69d73ff2fdea450ecfa2b 100644 --- a/mmdet/ops/norm.py +++ b/mmdet/ops/norm.py @@ -30,7 +30,7 @@ def build_norm_layer(cfg, num_features, postfix=''): layer_type = cfg_.pop('type') if layer_type not in norm_cfg: - raise KeyError('Unrecognized norm type {}'.format(layer_type)) + raise KeyError(f'Unrecognized norm type {layer_type}') else: abbr, norm_layer = norm_cfg[layer_type] if norm_layer is None: diff --git a/mmdet/ops/plugin.py b/mmdet/ops/plugin.py index a39a31234c410aa43443ab532ff73939f819304b..a104c1f56b10de23d95a0239f752cb9552dcfb19 100644 --- a/mmdet/ops/plugin.py +++ b/mmdet/ops/plugin.py @@ -29,7 +29,7 @@ def build_plugin_layer(cfg, postfix='', **kwargs): layer_type = cfg_.pop('type') if layer_type not in plugin_cfg: - raise KeyError('Unrecognized plugin type {}'.format(layer_type)) + raise KeyError(f'Unrecognized plugin type {layer_type}') else: abbr, plugin_layer = plugin_cfg[layer_type] diff --git a/mmdet/ops/roi_align/roi_align.py b/mmdet/ops/roi_align/roi_align.py index 441be14e3d7ef90f21c9a8976682a123f1f54d42..27be883b4241c851c65db559d503aadeeb636eae 100644 --- a/mmdet/ops/roi_align/roi_align.py +++ b/mmdet/ops/roi_align/roi_align.py @@ -144,9 +144,11 @@ class RoIAlign(nn.Module): self.sample_num, self.aligned) def __repr__(self): + indent_str = '\n ' format_str = self.__class__.__name__ - format_str += '(out_size={}, spatial_scale={}, sample_num={}'.format( - self.out_size, self.spatial_scale, self.sample_num) - format_str += ', use_torchvision={}, aligned={})'.format( - self.use_torchvision, self.aligned) + format_str += f'({indent_str}out_size={self.out_size},' + format_str += f'{indent_str}spatial_scale={self.spatial_scale},' + format_str += f'{indent_str}sample_num={self.sample_num},' + format_str += f'{indent_str}use_torchvision={self.use_torchvision},' + format_str += f'{indent_str}aligned={self.aligned})' return format_str diff --git a/mmdet/ops/roi_pool/roi_pool.py b/mmdet/ops/roi_pool/roi_pool.py index 5f52805a9cc94fa7ce2df8e3a9bc94586b2edbe5..13c2708b33308264fda1dce7d9c369910fa33adb 100644 --- a/mmdet/ops/roi_pool/roi_pool.py +++ b/mmdet/ops/roi_pool/roi_pool.py @@ -69,7 +69,7 @@ class RoIPool(nn.Module): def __repr__(self): format_str = self.__class__.__name__ - format_str += '(out_size={}, spatial_scale={}'.format( - self.out_size, self.spatial_scale) - format_str += ', use_torchvision={})'.format(self.use_torchvision) + format_str += f'(out_size={self.out_size}, ' + format_str += f'spatial_scale={self.spatial_scale}, ' + format_str += f'use_torchvision={self.use_torchvision})' return format_str diff --git a/mmdet/ops/sigmoid_focal_loss/sigmoid_focal_loss.py b/mmdet/ops/sigmoid_focal_loss/sigmoid_focal_loss.py index 62e584e604031afda2219349a0ac1bd1e2b22275..0715af38e1e6a918ff10484fb8ecb5464e83ea9b 100644 --- a/mmdet/ops/sigmoid_focal_loss/sigmoid_focal_loss.py +++ b/mmdet/ops/sigmoid_focal_loss/sigmoid_focal_loss.py @@ -49,6 +49,6 @@ class SigmoidFocalLoss(nn.Module): return loss.sum() def __repr__(self): - tmpstr = self.__class__.__name__ + '(gamma={}, alpha={})'.format( - self.gamma, self.alpha) + tmpstr = self.__class__.__name__ + tmpstr += f'(gamma={self.gamma}, alpha={self.alpha})' return tmpstr diff --git a/mmdet/ops/upsample.py b/mmdet/ops/upsample.py index 5501dc9a4543ceb3b5471c718b2b4a66effdff6f..2e405a037ebaa8eb6f4ea4dbcaa07ae639ad73c4 100644 --- a/mmdet/ops/upsample.py +++ b/mmdet/ops/upsample.py @@ -69,7 +69,7 @@ def build_upsample_layer(cfg): layer_type = cfg_.pop('type') if layer_type not in upsample_cfg: - raise KeyError('Unrecognized upsample type {}'.format(layer_type)) + raise KeyError(f'Unrecognized upsample type {layer_type}') else: upsample = upsample_cfg[layer_type] if upsample is None: diff --git a/mmdet/utils/collect_env.py b/mmdet/utils/collect_env.py index f84cd5b5a1de10710f13050ea6fc8de1446972e4..455383f031dc6f2f5fd50958029bfb0e9f1e899e 100644 --- a/mmdet/utils/collect_env.py +++ b/mmdet/utils/collect_env.py @@ -27,7 +27,7 @@ def collect_env(): try: nvcc = osp.join(CUDA_HOME, 'bin/nvcc') nvcc = subprocess.check_output( - '"{}" -V | tail -n1'.format(nvcc), shell=True) + f'"{nvcc}" -V | tail -n1', shell=True) nvcc = nvcc.decode('utf-8').strip() except subprocess.SubprocessError: nvcc = 'Not Available' @@ -60,4 +60,4 @@ def collect_env(): if __name__ == '__main__': for name, val in collect_env().items(): - print('{}: {}'.format(name, val)) + print(f'{name}: {val}') diff --git a/mmdet/utils/contextmanagers.py b/mmdet/utils/contextmanagers.py index 3e81268ae677fdb562abd20ac21bbcfebb6889d5..11eb2e5d5761165cf00228eaefdff363ad4fbac2 100644 --- a/mmdet/utils/contextmanagers.py +++ b/mmdet/utils/contextmanagers.py @@ -85,7 +85,7 @@ async def completed(trace_name='', stream_times_ms = '' for i, stream in enumerate(streams): elapsed_time = start.elapsed_time(end_events[i]) - stream_times_ms += ' {} {:.2f} ms'.format(stream, elapsed_time) + stream_times_ms += f' {stream} {elapsed_time:.2f} ms' logger.info('%s %s %.2f ms %s', trace_name, name, cpu_time, stream_times_ms) diff --git a/mmdet/utils/flops_counter.py b/mmdet/utils/flops_counter.py index df2163fd7107e17489eea56204a713780ef59376..fb484e3016c9f6cf6bd021264d0ad6f4b45998e0 100644 --- a/mmdet/utils/flops_counter.py +++ b/mmdet/utils/flops_counter.py @@ -125,7 +125,7 @@ def print_model_with_flops(model, units='GMac', precision=3, ost=sys.stdout): return ', '.join([ flops_to_string( accumulated_flops_cost, units=units, precision=precision), - '{:.3%} MACs'.format(accumulated_flops_cost / total_flops), + f'{accumulated_flops_cost / total_flops:.3%} MACs', self.original_extra_repr() ]) diff --git a/mmdet/utils/logger.py b/mmdet/utils/logger.py index 3e6a1396b95fe3e66530cfd4144a241b0c692b6f..825ee02ea8b1c05a8262dc823b59ca3489af4ba3 100644 --- a/mmdet/utils/logger.py +++ b/mmdet/utils/logger.py @@ -63,4 +63,4 @@ def print_log(msg, logger=None, level=logging.INFO): elif logger != 'silent': raise TypeError( 'logger should be either a logging.Logger object, "root", ' - '"silent" or None, but got {}'.format(logger)) + f'"silent" or None, but got {logger}') diff --git a/mmdet/utils/profiling.py b/mmdet/utils/profiling.py index 2448ba05e158cf400ea2c60ed6e44fc4a9b0dbba..76428968260f7c6b5d22e780176add417e1c40ab 100644 --- a/mmdet/utils/profiling.py +++ b/mmdet/utils/profiling.py @@ -35,7 +35,6 @@ if sys.version_info >= (3, 7): end.synchronize() cpu_time = (cpu_end - cpu_start) * 1000 gpu_time = start.elapsed_time(end) - msg = '{} {} cpu_time {:.2f} ms '.format(trace_name, name, - cpu_time) - msg += 'gpu_time {:.2f} ms stream {}'.format(gpu_time, stream) + msg = f'{trace_name} {name} cpu_time {cpu_time:.2f} ms ' + msg += f'gpu_time {gpu_time:.2f} ms stream {stream}' print(msg, end_stream) diff --git a/mmdet/utils/util_mixins.py b/mmdet/utils/util_mixins.py index e938ec759775ed1a1d64ddf4531c03f995b67baa..f00d4f945f3d7b23b6c4e2f3952949bb841d1e6a 100644 --- a/mmdet/utils/util_mixins.py +++ b/mmdet/utils/util_mixins.py @@ -20,8 +20,8 @@ Example: ... return self.name >>> s1 = Student('Alice') >>> s2 = Student('Bob') - >>> print('s1 = {}'.format(s1)) - >>> print('s2 = {}'.format(s2)) + >>> print(f's1 = {s1}') + >>> print(f's2 = {s2}') s1 = <Student(Alice)> s2 = <Student(Bob)> @@ -33,7 +33,7 @@ Example: ... def __len__(self): ... return len(self.data) >>> g = Group([1, 2, 3]) - >>> print('g = {}'.format(g)) + >>> print(f'g = {g}') g = <Group(3)> """ @@ -83,13 +83,13 @@ class NiceRepr(object): else: # In all other cases force the subclass to overload __nice__ raise NotImplementedError( - 'Define the __nice__ method for {!r}'.format(self.__class__)) + f'Define the __nice__ method for {self.__class__!r}') def __repr__(self): try: nice = self.__nice__() classname = self.__class__.__name__ - return '<{0}({1}) at {2}>'.format(classname, nice, hex(id(self))) + return f'<{classname}({nice}) at {hex(id(self))}>' except NotImplementedError as ex: warnings.warn(str(ex), category=RuntimeWarning) return object.__repr__(self) @@ -98,7 +98,7 @@ class NiceRepr(object): try: classname = self.__class__.__name__ nice = self.__nice__() - return '<{0}({1})>'.format(classname, nice) + return f'<{classname}({nice})>' except NotImplementedError as ex: warnings.warn(str(ex), category=RuntimeWarning) return object.__repr__(self) diff --git a/setup.py b/setup.py index e70a53110a674ea06a915f2dd5f435c06cd5dde3..390d08a1afe1633a569b5e48a29061df582a61b4 100755 --- a/setup.py +++ b/setup.py @@ -20,9 +20,9 @@ MINOR = 1 PATCH = 0 SUFFIX = '' if PATCH != '': - SHORT_VERSION = '{}.{}.{}{}'.format(MAJOR, MINOR, PATCH, SUFFIX) + SHORT_VERSION = f'{MAJOR}.{MINOR}.{PATCH}{SUFFIX}' else: - SHORT_VERSION = '{}.{}{}'.format(MAJOR, MINOR, SUFFIX) + SHORT_VERSION = f'{MAJOR}.{MINOR}{SUFFIX}' version_file = 'mmdet/version.py' @@ -103,12 +103,12 @@ def make_cuda_ext(name, module, sources, sources_cuda=[]): ] sources += sources_cuda else: - print('Compiling {} without CUDA'.format(name)) + print(f'Compiling {name} without CUDA') extension = CppExtension # raise EnvironmentError('CUDA is required to compile MMDetection!') return extension( - name='{}.{}'.format(module, name), + name=f'{module}.{name}', sources=[os.path.join(*module.split('.'), p) for p in sources], define_macros=define_macros, extra_compile_args=extra_compile_args) diff --git a/tests/async_benchmark.py b/tests/async_benchmark.py index d63c56bf18f17a6f7fc4fc310ec961385b7efbde..eb76c36bc8e9a93cf2d170324e9da1fed19c7db3 100644 --- a/tests/async_benchmark.py +++ b/tests/async_benchmark.py @@ -39,13 +39,13 @@ async def main(): if not os.path.exists(checkpoint_file): url = ('https://s3.ap-northeast-2.amazonaws.com/open-mmlab/mmdetection' '/models/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth') - print('Downloading {} ...'.format(url)) + print(f'Downloading {url} ...') local_filename, _ = urllib.request.urlretrieve(url) os.makedirs(os.path.dirname(checkpoint_file), exist_ok=True) shutil.move(local_filename, checkpoint_file) - print('Saved as {}'.format(checkpoint_file)) + print(f'Saved as {checkpoint_file}') else: - print('Using existing checkpoint {}'.format(checkpoint_file)) + print(f'Using existing checkpoint {checkpoint_file}') device = 'cuda:0' model = init_detector( diff --git a/tests/test_backbone.py b/tests/test_backbone.py index 2cc0ac3588c94c8d16abfeef3b834a8c604e9bdb..6f3d1f9d2bc7e989ae81cab5241b9596a54e3d5b 100644 --- a/tests/test_backbone.py +++ b/tests/test_backbone.py @@ -342,7 +342,7 @@ def test_resnet_backbone(): for param in layer.parameters(): assert param.requires_grad is False for i in range(1, frozen_stages + 1): - layer = getattr(model, 'layer{}'.format(i)) + layer = getattr(model, f'layer{i}') for mod in layer.modules(): if isinstance(mod, _BatchNorm): assert mod.training is False @@ -358,7 +358,7 @@ def test_resnet_backbone(): for param in model.stem.parameters(): assert param.requires_grad is False for i in range(1, frozen_stages + 1): - layer = getattr(model, 'layer{}'.format(i)) + layer = getattr(model, f'layer{i}') for mod in layer.modules(): if isinstance(mod, _BatchNorm): assert mod.training is False diff --git a/tests/test_config.py b/tests/test_config.py index 68cb2fade3d79dbf588d0abca4b5f4de47a4f941..7ee543d2a738b3f661babc2f74a9863903155f50 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -29,14 +29,14 @@ def test_config_build_detector(): from mmdet.models import build_detector config_dpath = _get_config_directory() - print('Found config_dpath = {!r}'.format(config_dpath)) + print(f'Found config_dpath = {config_dpath}') import glob config_fpaths = list(glob.glob(join(config_dpath, '**', '*.py'))) config_fpaths = [p for p in config_fpaths if p.find('_base_') == -1] config_names = [relpath(p, config_dpath) for p in config_fpaths] - print('Using {} config files'.format(len(config_names))) + print(f'Using {len(config_names)} config files') for config_fname in config_names: config_fpath = join(config_dpath, config_fname) @@ -45,7 +45,7 @@ def test_config_build_detector(): config_mod.model config_mod.train_cfg config_mod.test_cfg - print('Building detector, config_fpath = {!r}'.format(config_fpath)) + print(f'Building detector, config_fpath = {config_fpath}') # Remove pretrained keys to allow for testing in an offline environment if 'pretrained' in config_mod.model: @@ -87,7 +87,7 @@ def test_config_data_pipeline(): import numpy as np config_dpath = _get_config_directory() - print('Found config_dpath = {!r}'.format(config_dpath)) + print(f'Found config_dpath = {config_dpath}') # Only tests a representative subset of configurations # TODO: test pipelines using Albu, current Albu throw None given empty GT @@ -117,7 +117,7 @@ def test_config_data_pipeline(): masks = PolygonMasks(masks, h, w) return masks - print('Using {} config files'.format(len(config_names))) + print(f'Using {len(config_names)} config files') for config_fname in config_names: config_fpath = join(config_dpath, config_fname) @@ -131,10 +131,9 @@ def test_config_data_pipeline(): train_pipeline = Compose(config_mod.train_pipeline) test_pipeline = Compose(config_mod.test_pipeline) - print( - 'Building data pipeline, config_fpath = {!r}'.format(config_fpath)) + print(f'Building data pipeline, config_fpath = {config_fpath}') - print('Test training data pipeline: \n{!r}'.format(train_pipeline)) + print(f'Test training data pipeline: \n{train_pipeline!r}') img = np.random.randint(0, 255, size=(888, 666, 3), dtype=np.uint8) if loading_pipeline.get('to_float32', False): img = img.astype(np.float32) @@ -154,7 +153,7 @@ def test_config_data_pipeline(): output_results = train_pipeline(results) assert output_results is not None - print('Test testing data pipeline: \n{!r}'.format(test_pipeline)) + print(f'Test testing data pipeline: \n{test_pipeline!r}') results = dict( filename='test_img.png', img=img, @@ -170,8 +169,8 @@ def test_config_data_pipeline(): assert output_results is not None # test empty GT - print('Test empty GT with training data pipeline: \n{!r}'.format( - train_pipeline)) + print('Test empty GT with training data pipeline: ' + f'\n{train_pipeline!r}') results = dict( filename='test_img.png', img=img, @@ -187,8 +186,7 @@ def test_config_data_pipeline(): output_results = train_pipeline(results) assert output_results is not None - print('Test empty GT with testing data pipeline: \n{!r}'.format( - test_pipeline)) + print(f'Test empty GT with testing data pipeline: \n{test_pipeline!r}') results = dict( filename='test_img.png', img=img, diff --git a/tests/test_heads.py b/tests/test_heads.py index 923b9bc13e725344150dc02c7af24ac69975df38..64a74194b84f7732bcd111a3255965de33d741f2 100644 --- a/tests/test_heads.py +++ b/tests/test_heads.py @@ -334,7 +334,7 @@ def test_refine_boxes(): n_img = demokw['n_img'] rng = demokw['rng'] - print('Test refine_boxes case: {!r}'.format(demokw)) + print(f'Test refine_boxes case: {demokw!r}') tup = _demodata_refine_boxes(n_roi, n_img, rng=rng) rois, labels, bbox_preds, pos_is_gts, img_metas = tup bboxes_list = self.refine_bboxes(rois, labels, bbox_preds, @@ -343,7 +343,7 @@ def test_refine_boxes(): assert sum(map(len, bboxes_list)) <= n_roi assert all(b.shape[1] == 4 for b in bboxes_list) except Exception: - print('Test failed with demokw={!r}'.format(demokw)) + print(f'Test failed with demokw={demokw!r}') raise diff --git a/tests/test_nms.py b/tests/test_nms.py index e99af88e793f3b3c1621eb8ee1740949d54984c1..a2285dec5645171faeda8c18c03ef2887f987f43 100644 --- a/tests/test_nms.py +++ b/tests/test_nms.py @@ -57,7 +57,7 @@ def test_nms_device_and_dtypes_gpu(): [35.2, 11.7, 39.7, 15.7, 0.3]]) for device_id in range(torch.cuda.device_count()): - print('Run NMS on device_id = {!r}'.format(device_id)) + print(f'Run NMS on device_id = {device_id!r}') # GPU can handle float32 but not float64 dets = base_dets.astype(np.float32) supressed, inds = nms(dets, iou_thr, device_id) diff --git a/tests/test_wrappers.py b/tests/test_wrappers.py index e60f93abb7f8c1eb8de802704570c34485c2dd7f..1ae38f70478d4cbe139df2309a37a664f730e97d 100644 --- a/tests/test_wrappers.py +++ b/tests/test_wrappers.py @@ -171,7 +171,7 @@ def test_nn_op_forward_called(): torch.__version__ = '1.4.1' for m in ['Conv2d', 'ConvTranspose2d', 'MaxPool2d']: - with patch('torch.nn.{}.forward'.format(m)) as nn_module_forward: + with patch(f'torch.nn.{m}.forward') as nn_module_forward: # randn input x_empty = torch.randn(0, 3, 10, 10) wrapper = eval(m)(3, 2, 1) diff --git a/tools/analyze_logs.py b/tools/analyze_logs.py index 0608a75cb54733d7f4830ed9195050098821c1be..89edc101a8f937764eb98b7c9528882761f29552 100644 --- a/tools/analyze_logs.py +++ b/tools/analyze_logs.py @@ -9,8 +9,7 @@ import seaborn as sns def cal_train_time(log_dicts, args): for i, log_dict in enumerate(log_dicts): - print('{}Analyze train time of {}{}'.format('-' * 5, args.json_logs[i], - '-' * 5)) + print(f'{"-" * 5}Analyze train time of {args.json_logs[i]}{"-" * 5}') all_times = [] for epoch in log_dict.keys(): if args.include_outliers: @@ -22,12 +21,12 @@ def cal_train_time(log_dicts, args): slowest_epoch = epoch_ave_time.argmax() fastest_epoch = epoch_ave_time.argmin() std_over_epoch = epoch_ave_time.std() - print('slowest epoch {}, average time is {:.4f}'.format( - slowest_epoch + 1, epoch_ave_time[slowest_epoch])) - print('fastest epoch {}, average time is {:.4f}'.format( - fastest_epoch + 1, epoch_ave_time[fastest_epoch])) - print('time std over epochs is {:.4f}'.format(std_over_epoch)) - print('average iter time: {:.4f} s/iter'.format(np.mean(all_times))) + print(f'slowest epoch {slowest_epoch + 1}, ' + f'average time is {epoch_ave_time[slowest_epoch]:.4f}') + print(f'fastest epoch {fastest_epoch + 1}, ' + f'average time is {epoch_ave_time[fastest_epoch]:.4f}') + print(f'time std over epochs is {std_over_epoch:.4f}') + print(f'average iter time: {np.mean(all_times):.4f} s/iter') print() @@ -41,7 +40,7 @@ def plot_curve(log_dicts, args): legend = [] for json_log in args.json_logs: for metric in args.keys: - legend.append('{}_{}'.format(json_log, metric)) + legend.append(f'{json_log}_{metric}') assert len(legend) == (len(args.json_logs) * len(args.keys)) metrics = args.keys @@ -49,11 +48,10 @@ def plot_curve(log_dicts, args): for i, log_dict in enumerate(log_dicts): epochs = list(log_dict.keys()) for j, metric in enumerate(metrics): - print('plot curve of {}, metric is {}'.format( - args.json_logs[i], metric)) + print(f'plot curve of {args.json_logs[i]}, metric is {metric}') if metric not in log_dict[epochs[0]]: - raise KeyError('{} does not contain metric {}'.format( - args.json_logs[i], metric)) + raise KeyError( + f'{args.json_logs[i]} does not contain metric {metric}') if 'mAP' in metric: xs = np.arange(1, max(epochs) + 1) @@ -86,7 +84,7 @@ def plot_curve(log_dicts, args): if args.out is None: plt.show() else: - print('save curve to: {}'.format(args.out)) + print(f'save curve to: {args.out}') plt.savefig(args.out) plt.cla() diff --git a/tools/coco_error_analysis.py b/tools/coco_error_analysis.py index 6aeadadb9cf55ab9e2a8d1a050343c8657bf561e..fba96cafd2e818afacc43b120793dbb1dd228705 100644 --- a/tools/coco_error_analysis.py +++ b/tools/coco_error_analysis.py @@ -37,7 +37,7 @@ def makeplot(rs, ps, outDir, class_name, iou_type): ps_curve[k], ps_curve[k + 1], color=cs[k], - label=str('[{:.3f}'.format(aps[k]) + ']' + types[k])) + label=str(f'[{aps[k]:.3f}]' + types[k])) plt.xlabel('recall') plt.ylabel('precision') plt.xlim(0, 1.) @@ -45,14 +45,13 @@ def makeplot(rs, ps, outDir, class_name, iou_type): plt.title(figure_tile) plt.legend() # plt.show() - fig.savefig(outDir + '/{}.png'.format(figure_tile)) + fig.savefig(outDir + f'/{figure_tile}.png') plt.close(fig) def analyze_individual_category(k, cocoDt, cocoGt, catId, iou_type): nm = cocoGt.loadCats(catId)[0] - print('--------------analyzing {}-{}---------------'.format( - k + 1, nm['name'])) + print(f'--------------analyzing {k + 1}-{nm["name"]}---------------') ps_ = {} dt = copy.deepcopy(cocoDt) nm = cocoGt.loadCats(catId)[0] @@ -107,7 +106,7 @@ def analyze_results(res_file, ann_file, res_types, out_dir): directory = os.path.dirname(out_dir + '/') if not os.path.exists(directory): - print('-------------create {}-----------------'.format(out_dir)) + print(f'-------------create {out_dir}-----------------') os.makedirs(directory) cocoGt = COCO(ann_file) @@ -117,8 +116,7 @@ def analyze_results(res_file, ann_file, res_types, out_dir): res_out_dir = out_dir + '/' + res_type + '/' res_directory = os.path.dirname(res_out_dir) if not os.path.exists(res_directory): - print( - '-------------create {}-----------------'.format(res_out_dir)) + print(f'-------------create {res_out_dir}-----------------') os.makedirs(res_directory) iou_type = res_type cocoEval = COCOeval( @@ -138,8 +136,7 @@ def analyze_results(res_file, ann_file, res_types, out_dir): analyze_results = pool.starmap(analyze_individual_category, args) for k, catId in enumerate(catIds): nm = cocoGt.loadCats(catId)[0] - print('--------------saving {}-{}---------------'.format( - k + 1, nm['name'])) + print(f'--------------saving {k + 1}-{nm["name"]}---------------') analyze_result = analyze_results[k] assert k == analyze_result[0] ps_supercategory = analyze_result[1]['ps_supercategory'] diff --git a/tools/convert_datasets/cityscapes.py b/tools/convert_datasets/cityscapes.py index ae4fe3a31138f516619f00726dab4f67a3c2b080..86ef84fa2ce760dea76ed66b1d48a6b909b6ae02 100644 --- a/tools/convert_datasets/cityscapes.py +++ b/tools/convert_datasets/cityscapes.py @@ -19,8 +19,8 @@ def collect_files(img_dir, gt_dir): segm_file = gt_dir + img_file[ len(img_dir):-len(suffix)] + 'gtFine_labelIds.png' files.append((img_file, inst_file, segm_file)) - assert len(files), 'No images found in {}'.format(img_dir) - print('Loaded {} images from {}'.format(len(files), img_dir)) + assert len(files), f'No images found in {img_dir}' + print(f'Loaded {len(files)} images from {img_dir}') return files @@ -138,7 +138,7 @@ def main(): test='instancesonly_filtered_gtFine_test.json') for split, json_name in set_name.items(): - print('Converting {} into {}'.format(split, json_name)) + print(f'Converting {split} into {json_name}') with mmcv.Timer( print_tmpl='It tooks {}s to convert Cityscapes annotation'): files = collect_files( diff --git a/tools/convert_datasets/pascal_voc.py b/tools/convert_datasets/pascal_voc.py index 4c30c0fb9a204b9b5b430b97a03481233ed4d2ce..307c93cbae9d652bc6e66867730d982402a77053 100644 --- a/tools/convert_datasets/pascal_voc.py +++ b/tools/convert_datasets/pascal_voc.py @@ -70,20 +70,18 @@ def cvt_annotations(devkit_path, years, split, out_file): annotations = [] for year in years: filelist = osp.join(devkit_path, - 'VOC{}/ImageSets/Main/{}.txt'.format(year, split)) + f'VOC{year}/ImageSets/Main/{split}.txt') if not osp.isfile(filelist): - print('filelist does not exist: {}, skip voc{} {}'.format( - filelist, year, split)) + print(f'filelist does not exist: {filelist}, ' + f'skip voc{year} {split}') return img_names = mmcv.list_from_file(filelist) xml_paths = [ - osp.join(devkit_path, - 'VOC{}/Annotations/{}.xml'.format(year, img_name)) + osp.join(devkit_path, f'VOC{year}/Annotations/{img_name}.xml') for img_name in img_names ] img_paths = [ - 'VOC{}/JPEGImages/{}.jpg'.format(year, img_name) - for img_name in img_names + f'VOC{year}/JPEGImages/{img_name}.jpg' for img_name in img_names ] part_annotations = mmcv.track_progress(parse_xml, list(zip(xml_paths, img_paths))) @@ -115,8 +113,8 @@ def main(): if '2007' in years and '2012' in years: years.append(['2007', '2012']) if not years: - raise IOError('The devkit path {} contains neither "VOC2007" nor ' - '"VOC2012" subfolder'.format(devkit_path)) + raise IOError(f'The devkit path {devkit_path} contains neither ' + '"VOC2007" nor "VOC2012" subfolder') for year in years: if year == '2007': prefix = 'voc07' @@ -126,12 +124,12 @@ def main(): prefix = 'voc0712' for split in ['train', 'val', 'trainval']: dataset_name = prefix + '_' + split - print('processing {} ...'.format(dataset_name)) + print(f'processing {dataset_name} ...') cvt_annotations(devkit_path, year, split, osp.join(out_dir, dataset_name + '.pkl')) if not isinstance(year, list): dataset_name = prefix + '_test' - print('processing {} ...'.format(dataset_name)) + print(f'processing {dataset_name} ...') cvt_annotations(devkit_path, year, 'test', osp.join(out_dir, dataset_name + '.pkl')) print('Done!') diff --git a/tools/detectron2pytorch.py b/tools/detectron2pytorch.py index 0a90ad1729b75f0a2324da787521cf316fd50af7..961e6f571b785f01236a660651323cc6372e8189 100644 --- a/tools/detectron2pytorch.py +++ b/tools/detectron2pytorch.py @@ -48,27 +48,21 @@ def convert(src, dst, depth): for i in range(1, len(block_nums) + 1): for j in range(block_nums[i - 1]): if j == 0: - convert_conv_fc(blobs, state_dict, - 'res{}_{}_branch1'.format(i + 1, j), - 'layer{}.{}.downsample.0'.format(i, j), - converted_names) - convert_bn(blobs, state_dict, - 'res{}_{}_branch1_bn'.format(i + 1, j), - 'layer{}.{}.downsample.1'.format(i, j), - converted_names) + convert_conv_fc(blobs, state_dict, f'res{i + 1}_{j}_branch1', + f'layer{i}.{j}.downsample.0', converted_names) + convert_bn(blobs, state_dict, f'res{i + 1}_{j}_branch1_bn', + f'layer{i}.{j}.downsample.1', converted_names) for k, letter in enumerate(['a', 'b', 'c']): convert_conv_fc(blobs, state_dict, - 'res{}_{}_branch2{}'.format(i + 1, j, letter), - 'layer{}.{}.conv{}'.format(i, j, k + 1), - converted_names) + f'res{i + 1}_{j}_branch2{letter}', + f'layer{i}.{j}.conv{k+1}', converted_names) convert_bn(blobs, state_dict, - 'res{}_{}_branch2{}_bn'.format(i + 1, j, letter), - 'layer{}.{}.bn{}'.format(i, j, - k + 1), converted_names) + f'res{i + 1}_{j}_branch2{letter}_bn', + f'layer{i}.{j}.bn{k + 1}', converted_names) # check if all layers are converted for key in blobs: if key not in converted_names: - print('Not Convert: {}'.format(key)) + print(f'Not Convert: {key}') # save checkpoint checkpoint = dict() checkpoint['state_dict'] = state_dict diff --git a/tools/get_flops.py b/tools/get_flops.py index 6c9cb23400c0705289d5ca3bb3430bce6c884a2e..1ecd8757a63e94d1d5ead7d0fe47d1a362936cdd 100644 --- a/tools/get_flops.py +++ b/tools/get_flops.py @@ -44,8 +44,8 @@ def main(): flops, params = get_model_complexity_info(model, input_shape) split_line = '=' * 30 - print('{0}\nInput shape: {1}\nFlops: {2}\nParams: {3}\n{0}'.format( - split_line, input_shape, flops, params)) + print(f'{split_line}\nInput shape: {input_shape}\n' + f'Flops: {flops}\nParams: {params}\n{split_line}') print('!!!Please be cautious if you use the results in papers. ' 'You may need to check if all ops are supported and verify that the ' 'flops computation is correct.') diff --git a/tools/publish_model.py b/tools/publish_model.py index a049f17674b7a1aa730057e5cc294d2368fe707c..b638d25cc27ca6ddc9e946d0bac70fe0fbe98ce6 100644 --- a/tools/publish_model.py +++ b/tools/publish_model.py @@ -22,7 +22,7 @@ def process_checkpoint(in_file, out_file): # add the code here. torch.save(checkpoint, out_file) sha = subprocess.check_output(['sha256sum', out_file]).decode() - final_file = out_file.rstrip('.pth') + '-{}.pth'.format(sha[:8]) + final_file = out_file.rstrip('.pth') + f'-{sha[:8]}.pth' subprocess.Popen(['mv', out_file, final_file]) diff --git a/tools/pytorch2onnx.py b/tools/pytorch2onnx.py index 4f3cf2d8fa07961762f3f7cd93f4f5879984101a..e26213bb098cc0b76adc4c917558a9139c77561d 100644 --- a/tools/pytorch2onnx.py +++ b/tools/pytorch2onnx.py @@ -51,7 +51,7 @@ def export_onnx_model(model, inputs, passes): if passes is not None: all_passes = optimizer.get_available_passes() assert all(p in all_passes for p in passes), \ - 'Only {} are supported'.format(all_passes) + f'Only {all_passes} are supported' onnx_model = optimizer.optimize(onnx_model, passes) return onnx_model @@ -108,7 +108,7 @@ def main(): else: raise NotImplementedError( 'ONNX conversion is currently not currently supported with ' - '{}'.format(model.__class__.__name__)) + f'{model.__class__.__name__}') input_data = torch.empty((1, *input_shape), dtype=next(model.parameters()).dtype, @@ -117,7 +117,7 @@ def main(): onnx_model = export_onnx_model(model, (input_data, ), args.passes) # Print a human readable representation of the graph onnx.helper.printable_graph(onnx_model.graph) - print('saving model in {}'.format(args.out)) + print(f'saving model in {args.out}') onnx.save(onnx_model, args.out) diff --git a/tools/robustness_eval.py b/tools/robustness_eval.py index 1ff3ac074e5091599ddff057eec1157a3e7f6f42..a1b4ce88e174196d6580b272ae77328a4260610a 100644 --- a/tools/robustness_eval.py +++ b/tools/robustness_eval.py @@ -8,14 +8,13 @@ import numpy as np def print_coco_results(results): def _print(result, ap=1, iouThr=None, areaRng='all', maxDets=100): - iStr = ' {:<18} {} @[ IoU={:<9} | \ - area={:>6s} | maxDets={:>3d} ] = {:0.3f}' - titleStr = 'Average Precision' if ap == 1 else 'Average Recall' typeStr = '(AP)' if ap == 1 else '(AR)' - iouStr = '{:0.2f}:{:0.2f}'.format(.5, .95) \ - if iouThr is None else '{:0.2f}'.format(iouThr) - print(iStr.format(titleStr, typeStr, iouStr, areaRng, maxDets, result)) + iouStr = '0.50:0.95' \ + if iouThr is None else f'{iouThr:0.2f}' + iStr = f' {titleStr:<18} {typeStr} @[ IoU={iouStr:<9} | ' + iStr += f'area={areaRng:>6s} | maxDets={maxDets:>3d} ] = {result:0.3f}' + print(iStr) stats = np.zeros((12, )) stats[0] = _print(results[0], 1) @@ -81,33 +80,30 @@ def get_coco_style_results(filename, mPC = np.mean(results[:, 1:, :], axis=(0, 1)) rPC = mPC / P - print('\nmodel: {}'.format(osp.basename(filename))) + print(f'\nmodel: {osp.basename(filename)}') if metric is None: if 'P' in prints: - print('Performance on Clean Data [P] ({})'.format(task)) + print(f'Performance on Clean Data [P] ({task})') print_coco_results(P) if 'mPC' in prints: - print('Mean Performance under Corruption [mPC] ({})'.format(task)) + print(f'Mean Performance under Corruption [mPC] ({task})') print_coco_results(mPC) if 'rPC' in prints: - print('Realtive Performance under Corruption [rPC] ({})'.format( - task)) + print(f'Realtive Performance under Corruption [rPC] ({task})') print_coco_results(rPC) else: if 'P' in prints: - print('Performance on Clean Data [P] ({})'.format(task)) + print(f'Performance on Clean Data [P] ({task})') for metric_i, metric_name in enumerate(metrics): - print('{:5} = {:0.3f}'.format(metric_name, P[metric_i])) + print(f'{metric_name:5} = {P[metric_i]:0.3f}') if 'mPC' in prints: - print('Mean Performance under Corruption [mPC] ({})'.format(task)) + print(f'Mean Performance under Corruption [mPC] ({task})') for metric_i, metric_name in enumerate(metrics): - print('{:5} = {:0.3f}'.format(metric_name, mPC[metric_i])) + print(f'{metric_name:5} = {mPC[metric_i]:0.3f}') if 'rPC' in prints: - print('Relative Performance under Corruption [rPC] ({})'.format( - task)) + print(f'Relative Performance under Corruption [rPC] ({task})') for metric_i, metric_name in enumerate(metrics): - print('{:5} => {:0.1f} %'.format(metric_name, - rPC[metric_i] * 100)) + print(f'{metric_name:5} => {rPC[metric_i] * 100:0.1f} %') return results @@ -143,17 +139,15 @@ def get_voc_style_results(filename, prints='mPC', aggregate='benchmark'): mPC = np.mean(results[:, 1:, :], axis=(0, 1)) rPC = mPC / P - print('\nmodel: {}'.format(osp.basename(filename))) + print(f'\nmodel: {osp.basename(filename)}') if 'P' in prints: - print('{:48} = {:0.3f}'.format('Performance on Clean Data [P] in AP50', - np.mean(P))) + print(f'Performance on Clean Data [P] in AP50 = {np.mean(P):0.3f}') if 'mPC' in prints: - print('{:48} = {:0.3f}'.format( - 'Mean Performance under Corruption [mPC] in AP50', np.mean(mPC))) + print('Mean Performance under Corruption [mPC] in AP50 = ' + f'{np.mean(mPC):0.3f}') if 'rPC' in prints: - print('{:48} = {:0.1f}'.format( - 'Realtive Performance under Corruption [rPC] in %', - np.mean(rPC) * 100)) + print('Realtive Performance under Corruption [rPC] in % = ' + f'{np.mean(rPC) * 100:0.1f}') return np.mean(results, axis=2, keepdims=True) diff --git a/tools/test.py b/tools/test.py index c56029770fb8789fc60e2653adef6a9471844b65..55a4f283f26930712fa36e636a5363ef08693918 100644 --- a/tools/test.py +++ b/tools/test.py @@ -157,7 +157,7 @@ def main(): rank, _ = get_dist_info() if rank == 0: if args.out: - print('\nwriting results to {}'.format(args.out)) + print(f'\nwriting results to {args.out}') mmcv.dump(outputs, args.out) kwargs = {} if args.options is None else args.options if args.format_only: diff --git a/tools/test_robustness.py b/tools/test_robustness.py index e6b19db4caec3487a8adf3d1bf3f778a20452ac0..ecc366f54282161f30248321650b906b1e3464e7 100644 --- a/tools/test_robustness.py +++ b/tools/test_robustness.py @@ -152,7 +152,7 @@ def collect_results(result_part, size, tmpdir=None): else: mmcv.mkdir_or_exist(tmpdir) # dump the part result to the dir - mmcv.dump(result_part, osp.join(tmpdir, 'part_{}.pkl'.format(rank))) + mmcv.dump(result_part, osp.join(tmpdir, f'part_{rank}.pkl')) dist.barrier() # collect all parts if rank != 0: @@ -161,7 +161,7 @@ def collect_results(result_part, size, tmpdir=None): # load results of all parts from tmp dir part_list = [] for i in range(world_size): - part_file = osp.join(tmpdir, 'part_{}.pkl'.format(i)) + part_file = osp.join(tmpdir, f'part_{i}.pkl') part_list.append(mmcv.load(part_file)) # sort the results ordered_results = [] @@ -333,8 +333,7 @@ def main(): test_data_cfg['pipeline'].insert(1, corruption_trans) # print info - print('\nTesting {} at severity {}'.format(corruption, - corruption_severity)) + print(f'\nTesting {corruption} at severity {corruption_severity}') # build the dataloader # TODO: support multiple images per gpu @@ -396,8 +395,7 @@ def main(): is supported for pascal voc') else: if eval_types: - print('Starting evaluate {}'.format( - ' and '.join(eval_types))) + print(f'Starting evaluate {" and ".join(eval_types)}') if eval_types == ['proposal_fast']: result_file = args.out else: @@ -406,10 +404,10 @@ def main(): outputs, args.out) else: for name in outputs[0]: - print('\nEvaluating {}'.format(name)) + print(f'\nEvaluating {name}') outputs_ = [out[name] for out in outputs] result_file = args.out - + '.{}'.format(name) + + f'.{name}' result_files = dataset.results2json( outputs_, result_file) eval_results = coco_eval_with_return( diff --git a/tools/train.py b/tools/train.py index 5cae2f69074f6bed5da395b6c2582fae22ca562e..ad187299b03f772fa2c8018615f2460c766bb6f3 100644 --- a/tools/train.py +++ b/tools/train.py @@ -98,7 +98,7 @@ def main(): mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir)) # init the logger before other steps timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime()) - log_file = osp.join(cfg.work_dir, '{}.log'.format(timestamp)) + log_file = osp.join(cfg.work_dir, f'{timestamp}.log') logger = get_root_logger(log_file=log_file, log_level=cfg.log_level) # init the meta dict to record some important information such as @@ -106,21 +106,20 @@ def main(): meta = dict() # log env info env_info_dict = collect_env() - env_info = '\n'.join([('{}: {}'.format(k, v)) - for k, v in env_info_dict.items()]) + env_info = '\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()]) dash_line = '-' * 60 + '\n' logger.info('Environment info:\n' + dash_line + env_info + '\n' + dash_line) meta['env_info'] = env_info # log some basic info - logger.info('Distributed training: {}'.format(distributed)) - logger.info('Config:\n{}'.format(cfg.text)) + logger.info(f'Distributed training: {distributed}') + logger.info(f'Config:\n{cfg.text}') # set random seeds if args.seed is not None: - logger.info('Set random seed to {}, deterministic: {}'.format( - args.seed, args.deterministic)) + logger.info(f'Set random seed to {args.seed}, ' + f'deterministic: {args.deterministic}') set_random_seed(args.seed, deterministic=args.deterministic) cfg.seed = args.seed meta['seed'] = args.seed diff --git a/tools/upgrade_model_version.py b/tools/upgrade_model_version.py index 00bcdf44ab185a1908124eb759bd6cdad0c45066..3239dbebe09154440e56c924b72f789357c34e06 100644 --- a/tools/upgrade_model_version.py +++ b/tools/upgrade_model_version.py @@ -21,7 +21,7 @@ def convert(in_file, out_file): m = re.search(r'(cls_convs|reg_convs).\d.(weight|bias)', key) if m is not None: param = m.groups()[1] - new_key = key.replace(param, 'conv.{}'.format(param)) + new_key = key.replace(param, f'conv.{param}') out_state_dict[new_key] = val continue