[Enhancement] Add codespell pre-commit hook and fix typos (#920)
* add codespell pre-commit hook and fix typos * Update mmseg/models/decode_heads/dpt_head.py * Update mmseg/models/backbones/vit.py * Update mmseg/models/backbones/vit.py * fix typos * skip formating typo * deprecate formating * skip ipynb * unstage ipynb changes * unstage ipynb changes * fix typos in ipynb * unstage ipynb changespull/1801/head
parent
279b7e5d25
commit
67f1420472
|
@ -3,4 +3,4 @@ blank_issues_enabled: false
|
|||
contact_links:
|
||||
- name: MMSegmentation Documentation
|
||||
url: https://mmsegmentation.readthedocs.io
|
||||
about: Check the docs and FAQ to see if you question is already anwsered.
|
||||
about: Check the docs and FAQ to see if you question is already answered.
|
||||
|
|
|
@ -30,7 +30,7 @@ A clear and concise description of what the bug is.
|
|||
|
||||
**Environment**
|
||||
|
||||
1. Please run `python mmseg/utils/collect_env.py` to collect necessary environment infomation and paste it here.
|
||||
1. Please run `python mmseg/utils/collect_env.py` to collect necessary environment information and paste it here.
|
||||
2. You may add addition that may be helpful for locating the problem, such as
|
||||
- How you installed PyTorch [e.g., pip, conda, source]
|
||||
- Other environment variables that may be related (such as `$PATH`, `$LD_LIBRARY_PATH`, `$PYTHONPATH`, etc.)
|
||||
|
|
|
@ -34,6 +34,10 @@ repos:
|
|||
hooks:
|
||||
- id: markdownlint
|
||||
args: ["-r", "~MD002,~MD013,~MD029,~MD033,~MD034,~MD036"]
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.1.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
- repo: https://github.com/myint/docformatter
|
||||
rev: v1.3.1
|
||||
hooks:
|
||||
|
|
|
@ -124,7 +124,7 @@ Please refer to [get_started.md](docs/get_started.md#installation) for installat
|
|||
|
||||
Please see [train.md](docs/train.md) and [inference.md](docs/inference.md) for the basic usage of MMSegmentation.
|
||||
There are also tutorials for [customizing dataset](docs/tutorials/customize_datasets.md), [designing data pipeline](docs/tutorials/data_pipeline.md), [customizing modules](docs/tutorials/customize_models.md), and [customizing runtime](docs/tutorials/customize_runtime.md).
|
||||
We also provide many [training tricks](docs/tutorials/training_tricks.md) for better training and [usefule tools](docs/useful_tools.md) for deployment.
|
||||
We also provide many [training tricks](docs/tutorials/training_tricks.md) for better training and [useful tools](docs/useful_tools.md) for deployment.
|
||||
|
||||
A Colab tutorial is also provided. You may preview the notebook [here](demo/MMSegmentation_Tutorial.ipynb) or directly [run](https://colab.research.google.com/github/open-mmlab/mmsegmentation/blob/master/demo/MMSegmentation_Tutorial.ipynb) on Colab.
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ model = dict(
|
|||
channels=512, # The intermediate channels of decode head.
|
||||
pool_scales=(1, 2, 3, 6), # The avg pooling scales of PSPHead. Please refer to paper for details.
|
||||
dropout_ratio=0.1, # The dropout ratio before final classification layer.
|
||||
num_classes=19, # Number of segmentation classs. Usually 19 for cityscapes, 21 for VOC, 150 for ADE20k.
|
||||
num_classes=19, # Number of segmentation class. Usually 19 for cityscapes, 21 for VOC, 150 for ADE20k.
|
||||
norm_cfg=dict(type='SyncBN', requires_grad=True), # The configuration of norm layer.
|
||||
align_corners=False, # The align_corners argument for resize in decoding.
|
||||
loss_decode=dict( # Config of loss function for the decode_head.
|
||||
|
@ -82,7 +82,7 @@ model = dict(
|
|||
num_convs=1, # Number of convs in FCNHead. It is usually 1 in auxiliary head.
|
||||
concat_input=False, # Whether concat output of convs with input before classification layer.
|
||||
dropout_ratio=0.1, # The dropout ratio before final classification layer.
|
||||
num_classes=19, # Number of segmentation classs. Usually 19 for cityscapes, 21 for VOC, 150 for ADE20k.
|
||||
num_classes=19, # Number of segmentation class. Usually 19 for cityscapes, 21 for VOC, 150 for ADE20k.
|
||||
norm_cfg=dict(type='SyncBN', requires_grad=True), # The configuration of norm layer.
|
||||
align_corners=False, # The align_corners argument for resize in decoding.
|
||||
loss_decode=dict( # Config of loss function for the decode_head.
|
||||
|
@ -132,7 +132,7 @@ test_pipeline = [
|
|||
flip=False, # Whether to flip images during testing
|
||||
transforms=[
|
||||
dict(type='Resize', # Use resize augmentation
|
||||
keep_ratio=True), # Whether to keep the ratio between height and width, the img_scale set here will be supressed by the img_scale set above.
|
||||
keep_ratio=True), # Whether to keep the ratio between height and width, the img_scale set here will be suppressed by the img_scale set above.
|
||||
dict(type='RandomFlip'), # Thought RandomFlip is added in pipeline, it is not used when flip=False
|
||||
dict(
|
||||
type='Normalize', # Normalization config, the values are from img_norm_cfg
|
||||
|
@ -245,7 +245,7 @@ runner = dict(
|
|||
checkpoint_config = dict( # Config to set the checkpoint hook, Refer to https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py for implementation.
|
||||
by_epoch=False, # Whether count by epoch or not.
|
||||
interval=4000) # The save interval.
|
||||
evaluation = dict( # The config to build the evaluation hook. Please refer to mmseg/core/evaulation/eval_hook.py for details.
|
||||
evaluation = dict( # The config to build the evaluation hook. Please refer to mmseg/core/evaluation/eval_hook.py for details.
|
||||
interval=4000, # The interval of evaluation.
|
||||
metric='mIoU') # The evaluation metric.
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ Tricks not implemented by the optimizer should be implemented through optimizer
|
|||
_delete_=True, grad_clip=dict(max_norm=35, norm_type=2))
|
||||
```
|
||||
|
||||
If your config inherits the base config which already sets the `optimizer_config`, you might need `_delete_=True` to overide the unnecessary settings. See the [config documenetation](https://mmsegmentation.readthedocs.io/en/latest/config.html) for more details.
|
||||
If your config inherits the base config which already sets the `optimizer_config`, you might need `_delete_=True` to override the unnecessary settings. See the [config documentation](https://mmsegmentation.readthedocs.io/en/latest/config.html) for more details.
|
||||
|
||||
- __Use momentum schedule to accelerate model convergence__:
|
||||
We support momentum scheduler to modify model's momentum according to learning rate, which could make the model converge in a faster way.
|
||||
|
@ -198,7 +198,7 @@ custom_hooks = [
|
|||
|
||||
### Modify default runtime hooks
|
||||
|
||||
There are some common hooks that are not registerd through `custom_hooks`, they are
|
||||
There are some common hooks that are not registered through `custom_hooks`, they are
|
||||
|
||||
- log_config
|
||||
- checkpoint_config
|
||||
|
|
|
@ -241,7 +241,7 @@ runner = dict(
|
|||
checkpoint_config = dict( # 设置检查点钩子 (checkpoint hook) 的配置文件。执行时请参考 https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/checkpoint.py。
|
||||
by_epoch=False, # 是否按照每个 epoch 去算 runner。
|
||||
interval=4000) # 保存的间隔
|
||||
evaluation = dict( # 构建评估钩 (evaluation hook) 的配置文件。细节请参考 mmseg/core/evaulation/eval_hook.py。
|
||||
evaluation = dict( # 构建评估钩 (evaluation hook) 的配置文件。细节请参考 mmseg/core/evaluation/eval_hook.py。
|
||||
interval=4000, # 评估的间歇点
|
||||
metric='mIoU') # 评估的指标
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import torch
|
|||
|
||||
|
||||
def f_score(precision, recall, beta=1):
|
||||
"""calcuate the f-score value.
|
||||
"""calculate the f-score value.
|
||||
|
||||
Args:
|
||||
precision (float | torch.Tensor): The precision value.
|
||||
|
@ -40,7 +40,7 @@ def intersect_and_union(pred_label,
|
|||
ignore_index (int): Index that will be ignored in evaluation.
|
||||
label_map (dict): Mapping old labels to new labels. The parameter will
|
||||
work only when label is str. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. The parameter will
|
||||
reduce_zero_label (bool): Whether ignore zero label. The parameter will
|
||||
work only when label is str. Default: False.
|
||||
|
||||
Returns:
|
||||
|
@ -102,7 +102,7 @@ def total_intersect_and_union(results,
|
|||
num_classes (int): Number of categories.
|
||||
ignore_index (int): Index that will be ignored in evaluation.
|
||||
label_map (dict): Mapping old labels to new labels. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. Default: False.
|
||||
reduce_zero_label (bool): Whether ignore zero label. Default: False.
|
||||
|
||||
Returns:
|
||||
ndarray: The intersection of prediction and ground truth histogram
|
||||
|
@ -148,7 +148,7 @@ def mean_iou(results,
|
|||
nan_to_num (int, optional): If specified, NaN values will be replaced
|
||||
by the numbers defined by the user. Default: None.
|
||||
label_map (dict): Mapping old labels to new labels. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. Default: False.
|
||||
reduce_zero_label (bool): Whether ignore zero label. Default: False.
|
||||
|
||||
Returns:
|
||||
dict[str, float | ndarray]:
|
||||
|
@ -187,7 +187,7 @@ def mean_dice(results,
|
|||
nan_to_num (int, optional): If specified, NaN values will be replaced
|
||||
by the numbers defined by the user. Default: None.
|
||||
label_map (dict): Mapping old labels to new labels. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. Default: False.
|
||||
reduce_zero_label (bool): Whether ignore zero label. Default: False.
|
||||
|
||||
Returns:
|
||||
dict[str, float | ndarray]: Default metrics.
|
||||
|
@ -228,7 +228,7 @@ def mean_fscore(results,
|
|||
nan_to_num (int, optional): If specified, NaN values will be replaced
|
||||
by the numbers defined by the user. Default: None.
|
||||
label_map (dict): Mapping old labels to new labels. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. Default: False.
|
||||
reduce_zero_label (bool): Whether ignore zero label. Default: False.
|
||||
beta (int): Determines the weight of recall in the combined score.
|
||||
Default: False.
|
||||
|
||||
|
@ -274,7 +274,7 @@ def eval_metrics(results,
|
|||
nan_to_num (int, optional): If specified, NaN values will be replaced
|
||||
by the numbers defined by the user. Default: None.
|
||||
label_map (dict): Mapping old labels to new labels. Default: dict().
|
||||
reduce_zero_label (bool): Wether ignore zero label. Default: False.
|
||||
reduce_zero_label (bool): Whether ignore zero label. Default: False.
|
||||
Returns:
|
||||
float: Overall accuracy on all images.
|
||||
ndarray: Per category accuracy, shape (num_classes, ).
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
from .compose import Compose
|
||||
from .formating import (Collect, ImageToTensor, ToDataContainer, ToTensor,
|
||||
Transpose, to_tensor)
|
||||
from .formatting import (Collect, ImageToTensor, ToDataContainer, ToTensor,
|
||||
Transpose, to_tensor)
|
||||
from .loading import LoadAnnotations, LoadImageFromFile
|
||||
from .test_time_aug import MultiScaleFlipAug
|
||||
from .transforms import (CLAHE, AdjustGamma, Normalize, Pad,
|
||||
|
|
|
@ -1,289 +1,9 @@
|
|||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
from collections.abc import Sequence
|
||||
# flake8: noqa
|
||||
import warnings
|
||||
|
||||
import mmcv
|
||||
import numpy as np
|
||||
import torch
|
||||
from mmcv.parallel import DataContainer as DC
|
||||
from .formatting import *
|
||||
|
||||
from ..builder import PIPELINES
|
||||
|
||||
|
||||
def to_tensor(data):
|
||||
"""Convert objects of various python types to :obj:`torch.Tensor`.
|
||||
|
||||
Supported types are: :class:`numpy.ndarray`, :class:`torch.Tensor`,
|
||||
:class:`Sequence`, :class:`int` and :class:`float`.
|
||||
|
||||
Args:
|
||||
data (torch.Tensor | numpy.ndarray | Sequence | int | float): Data to
|
||||
be converted.
|
||||
"""
|
||||
|
||||
if isinstance(data, torch.Tensor):
|
||||
return data
|
||||
elif isinstance(data, np.ndarray):
|
||||
return torch.from_numpy(data)
|
||||
elif isinstance(data, Sequence) and not mmcv.is_str(data):
|
||||
return torch.tensor(data)
|
||||
elif isinstance(data, int):
|
||||
return torch.LongTensor([data])
|
||||
elif isinstance(data, float):
|
||||
return torch.FloatTensor([data])
|
||||
else:
|
||||
raise TypeError(f'type {type(data)} cannot be converted to tensor.')
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ToTensor(object):
|
||||
"""Convert some results to :obj:`torch.Tensor` by given keys.
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys that need to be converted to Tensor.
|
||||
"""
|
||||
|
||||
def __init__(self, keys):
|
||||
self.keys = keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert data in results to :obj:`torch.Tensor`.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data converted
|
||||
to :obj:`torch.Tensor`.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
results[key] = to_tensor(results[key])
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(keys={self.keys})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ImageToTensor(object):
|
||||
"""Convert image to :obj:`torch.Tensor` by given keys.
|
||||
|
||||
The dimension order of input image is (H, W, C). The pipeline will convert
|
||||
it to (C, H, W). If only 2 dimension (H, W) is given, the output would be
|
||||
(1, H, W).
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Key of images to be converted to Tensor.
|
||||
"""
|
||||
|
||||
def __init__(self, keys):
|
||||
self.keys = keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert image in results to :obj:`torch.Tensor` and
|
||||
transpose the channel order.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the image data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the image converted
|
||||
to :obj:`torch.Tensor` and transposed to (C, H, W) order.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
img = results[key]
|
||||
if len(img.shape) < 3:
|
||||
img = np.expand_dims(img, -1)
|
||||
results[key] = to_tensor(img.transpose(2, 0, 1))
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(keys={self.keys})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class Transpose(object):
|
||||
"""Transpose some results by given keys.
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys of results to be transposed.
|
||||
order (Sequence[int]): Order of transpose.
|
||||
"""
|
||||
|
||||
def __init__(self, keys, order):
|
||||
self.keys = keys
|
||||
self.order = order
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert image in results to :obj:`torch.Tensor` and
|
||||
transpose the channel order.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the image data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the image converted
|
||||
to :obj:`torch.Tensor` and transposed to (C, H, W) order.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
results[key] = results[key].transpose(self.order)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + \
|
||||
f'(keys={self.keys}, order={self.order})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ToDataContainer(object):
|
||||
"""Convert results to :obj:`mmcv.DataContainer` by given fields.
|
||||
|
||||
Args:
|
||||
fields (Sequence[dict]): Each field is a dict like
|
||||
``dict(key='xxx', **kwargs)``. The ``key`` in result will
|
||||
be converted to :obj:`mmcv.DataContainer` with ``**kwargs``.
|
||||
Default: ``(dict(key='img', stack=True),
|
||||
dict(key='gt_semantic_seg'))``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
fields=(dict(key='img',
|
||||
stack=True), dict(key='gt_semantic_seg'))):
|
||||
self.fields = fields
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert data in results to
|
||||
:obj:`mmcv.DataContainer`.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data converted to
|
||||
:obj:`mmcv.DataContainer`.
|
||||
"""
|
||||
|
||||
for field in self.fields:
|
||||
field = field.copy()
|
||||
key = field.pop('key')
|
||||
results[key] = DC(results[key], **field)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(fields={self.fields})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class DefaultFormatBundle(object):
|
||||
"""Default formatting bundle.
|
||||
|
||||
It simplifies the pipeline of formatting common fields, including "img"
|
||||
and "gt_semantic_seg". These fields are formatted as follows.
|
||||
|
||||
- img: (1)transpose, (2)to tensor, (3)to DataContainer (stack=True)
|
||||
- gt_semantic_seg: (1)unsqueeze dim-0 (2)to tensor,
|
||||
(3)to DataContainer (stack=True)
|
||||
"""
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to transform and format common fields in results.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data that is formatted with
|
||||
default bundle.
|
||||
"""
|
||||
|
||||
if 'img' in results:
|
||||
img = results['img']
|
||||
if len(img.shape) < 3:
|
||||
img = np.expand_dims(img, -1)
|
||||
img = np.ascontiguousarray(img.transpose(2, 0, 1))
|
||||
results['img'] = DC(to_tensor(img), stack=True)
|
||||
if 'gt_semantic_seg' in results:
|
||||
# convert to long
|
||||
results['gt_semantic_seg'] = DC(
|
||||
to_tensor(results['gt_semantic_seg'][None,
|
||||
...].astype(np.int64)),
|
||||
stack=True)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class Collect(object):
|
||||
"""Collect data from the loader relevant to the specific task.
|
||||
|
||||
This is usually the last stage of the data loader pipeline. Typically keys
|
||||
is set to some subset of "img", "gt_semantic_seg".
|
||||
|
||||
The "img_meta" item is always populated. The contents of the "img_meta"
|
||||
dictionary depends on "meta_keys". By default this includes:
|
||||
|
||||
- "img_shape": shape of the image input to the network as a tuple
|
||||
(h, w, c). Note that images may be zero padded on the bottom/right
|
||||
if the batch tensor is larger than this shape.
|
||||
|
||||
- "scale_factor": a float indicating the preprocessing scale
|
||||
|
||||
- "flip": a boolean indicating if image flip transform was used
|
||||
|
||||
- "filename": path to the image file
|
||||
|
||||
- "ori_shape": original shape of the image as a tuple (h, w, c)
|
||||
|
||||
- "pad_shape": image shape after padding
|
||||
|
||||
- "img_norm_cfg": a dict of normalization information:
|
||||
- mean - per channel mean subtraction
|
||||
- std - per channel std divisor
|
||||
- to_rgb - bool indicating if bgr was converted to rgb
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys of results to be collected in ``data``.
|
||||
meta_keys (Sequence[str], optional): Meta keys to be converted to
|
||||
``mmcv.DataContainer`` and collected in ``data[img_metas]``.
|
||||
Default: (``filename``, ``ori_filename``, ``ori_shape``,
|
||||
``img_shape``, ``pad_shape``, ``scale_factor``, ``flip``,
|
||||
``flip_direction``, ``img_norm_cfg``)
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
keys,
|
||||
meta_keys=('filename', 'ori_filename', 'ori_shape',
|
||||
'img_shape', 'pad_shape', 'scale_factor', 'flip',
|
||||
'flip_direction', 'img_norm_cfg')):
|
||||
self.keys = keys
|
||||
self.meta_keys = meta_keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to collect keys in results. The keys in ``meta_keys``
|
||||
will be converted to :obj:mmcv.DataContainer.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to collect.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the following keys
|
||||
- keys in``self.keys``
|
||||
- ``img_metas``
|
||||
"""
|
||||
|
||||
data = {}
|
||||
img_meta = {}
|
||||
for key in self.meta_keys:
|
||||
img_meta[key] = results[key]
|
||||
data['img_metas'] = DC(img_meta, cpu_only=True)
|
||||
for key in self.keys:
|
||||
data[key] = results[key]
|
||||
return data
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + \
|
||||
f'(keys={self.keys}, meta_keys={self.meta_keys})'
|
||||
warnings.warn('DeprecationWarning: mmseg.datasets.pipelines.formating will be '
|
||||
'deprecated in 2021, please replace it with '
|
||||
'mmseg.datasets.pipelines.formatting.')
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
# Copyright (c) OpenMMLab. All rights reserved.
|
||||
from collections.abc import Sequence
|
||||
|
||||
import mmcv
|
||||
import numpy as np
|
||||
import torch
|
||||
from mmcv.parallel import DataContainer as DC
|
||||
|
||||
from ..builder import PIPELINES
|
||||
|
||||
|
||||
def to_tensor(data):
|
||||
"""Convert objects of various python types to :obj:`torch.Tensor`.
|
||||
|
||||
Supported types are: :class:`numpy.ndarray`, :class:`torch.Tensor`,
|
||||
:class:`Sequence`, :class:`int` and :class:`float`.
|
||||
|
||||
Args:
|
||||
data (torch.Tensor | numpy.ndarray | Sequence | int | float): Data to
|
||||
be converted.
|
||||
"""
|
||||
|
||||
if isinstance(data, torch.Tensor):
|
||||
return data
|
||||
elif isinstance(data, np.ndarray):
|
||||
return torch.from_numpy(data)
|
||||
elif isinstance(data, Sequence) and not mmcv.is_str(data):
|
||||
return torch.tensor(data)
|
||||
elif isinstance(data, int):
|
||||
return torch.LongTensor([data])
|
||||
elif isinstance(data, float):
|
||||
return torch.FloatTensor([data])
|
||||
else:
|
||||
raise TypeError(f'type {type(data)} cannot be converted to tensor.')
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ToTensor(object):
|
||||
"""Convert some results to :obj:`torch.Tensor` by given keys.
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys that need to be converted to Tensor.
|
||||
"""
|
||||
|
||||
def __init__(self, keys):
|
||||
self.keys = keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert data in results to :obj:`torch.Tensor`.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data converted
|
||||
to :obj:`torch.Tensor`.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
results[key] = to_tensor(results[key])
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(keys={self.keys})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ImageToTensor(object):
|
||||
"""Convert image to :obj:`torch.Tensor` by given keys.
|
||||
|
||||
The dimension order of input image is (H, W, C). The pipeline will convert
|
||||
it to (C, H, W). If only 2 dimension (H, W) is given, the output would be
|
||||
(1, H, W).
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Key of images to be converted to Tensor.
|
||||
"""
|
||||
|
||||
def __init__(self, keys):
|
||||
self.keys = keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert image in results to :obj:`torch.Tensor` and
|
||||
transpose the channel order.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the image data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the image converted
|
||||
to :obj:`torch.Tensor` and transposed to (C, H, W) order.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
img = results[key]
|
||||
if len(img.shape) < 3:
|
||||
img = np.expand_dims(img, -1)
|
||||
results[key] = to_tensor(img.transpose(2, 0, 1))
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(keys={self.keys})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class Transpose(object):
|
||||
"""Transpose some results by given keys.
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys of results to be transposed.
|
||||
order (Sequence[int]): Order of transpose.
|
||||
"""
|
||||
|
||||
def __init__(self, keys, order):
|
||||
self.keys = keys
|
||||
self.order = order
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert image in results to :obj:`torch.Tensor` and
|
||||
transpose the channel order.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the image data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the image converted
|
||||
to :obj:`torch.Tensor` and transposed to (C, H, W) order.
|
||||
"""
|
||||
|
||||
for key in self.keys:
|
||||
results[key] = results[key].transpose(self.order)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + \
|
||||
f'(keys={self.keys}, order={self.order})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class ToDataContainer(object):
|
||||
"""Convert results to :obj:`mmcv.DataContainer` by given fields.
|
||||
|
||||
Args:
|
||||
fields (Sequence[dict]): Each field is a dict like
|
||||
``dict(key='xxx', **kwargs)``. The ``key`` in result will
|
||||
be converted to :obj:`mmcv.DataContainer` with ``**kwargs``.
|
||||
Default: ``(dict(key='img', stack=True),
|
||||
dict(key='gt_semantic_seg'))``.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
fields=(dict(key='img',
|
||||
stack=True), dict(key='gt_semantic_seg'))):
|
||||
self.fields = fields
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to convert data in results to
|
||||
:obj:`mmcv.DataContainer`.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data converted to
|
||||
:obj:`mmcv.DataContainer`.
|
||||
"""
|
||||
|
||||
for field in self.fields:
|
||||
field = field.copy()
|
||||
key = field.pop('key')
|
||||
results[key] = DC(results[key], **field)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + f'(fields={self.fields})'
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class DefaultFormatBundle(object):
|
||||
"""Default formatting bundle.
|
||||
|
||||
It simplifies the pipeline of formatting common fields, including "img"
|
||||
and "gt_semantic_seg". These fields are formatted as follows.
|
||||
|
||||
- img: (1)transpose, (2)to tensor, (3)to DataContainer (stack=True)
|
||||
- gt_semantic_seg: (1)unsqueeze dim-0 (2)to tensor,
|
||||
(3)to DataContainer (stack=True)
|
||||
"""
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to transform and format common fields in results.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to convert.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the data that is formatted with
|
||||
default bundle.
|
||||
"""
|
||||
|
||||
if 'img' in results:
|
||||
img = results['img']
|
||||
if len(img.shape) < 3:
|
||||
img = np.expand_dims(img, -1)
|
||||
img = np.ascontiguousarray(img.transpose(2, 0, 1))
|
||||
results['img'] = DC(to_tensor(img), stack=True)
|
||||
if 'gt_semantic_seg' in results:
|
||||
# convert to long
|
||||
results['gt_semantic_seg'] = DC(
|
||||
to_tensor(results['gt_semantic_seg'][None,
|
||||
...].astype(np.int64)),
|
||||
stack=True)
|
||||
return results
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
|
||||
@PIPELINES.register_module()
|
||||
class Collect(object):
|
||||
"""Collect data from the loader relevant to the specific task.
|
||||
|
||||
This is usually the last stage of the data loader pipeline. Typically keys
|
||||
is set to some subset of "img", "gt_semantic_seg".
|
||||
|
||||
The "img_meta" item is always populated. The contents of the "img_meta"
|
||||
dictionary depends on "meta_keys". By default this includes:
|
||||
|
||||
- "img_shape": shape of the image input to the network as a tuple
|
||||
(h, w, c). Note that images may be zero padded on the bottom/right
|
||||
if the batch tensor is larger than this shape.
|
||||
|
||||
- "scale_factor": a float indicating the preprocessing scale
|
||||
|
||||
- "flip": a boolean indicating if image flip transform was used
|
||||
|
||||
- "filename": path to the image file
|
||||
|
||||
- "ori_shape": original shape of the image as a tuple (h, w, c)
|
||||
|
||||
- "pad_shape": image shape after padding
|
||||
|
||||
- "img_norm_cfg": a dict of normalization information:
|
||||
- mean - per channel mean subtraction
|
||||
- std - per channel std divisor
|
||||
- to_rgb - bool indicating if bgr was converted to rgb
|
||||
|
||||
Args:
|
||||
keys (Sequence[str]): Keys of results to be collected in ``data``.
|
||||
meta_keys (Sequence[str], optional): Meta keys to be converted to
|
||||
``mmcv.DataContainer`` and collected in ``data[img_metas]``.
|
||||
Default: (``filename``, ``ori_filename``, ``ori_shape``,
|
||||
``img_shape``, ``pad_shape``, ``scale_factor``, ``flip``,
|
||||
``flip_direction``, ``img_norm_cfg``)
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
keys,
|
||||
meta_keys=('filename', 'ori_filename', 'ori_shape',
|
||||
'img_shape', 'pad_shape', 'scale_factor', 'flip',
|
||||
'flip_direction', 'img_norm_cfg')):
|
||||
self.keys = keys
|
||||
self.meta_keys = meta_keys
|
||||
|
||||
def __call__(self, results):
|
||||
"""Call function to collect keys in results. The keys in ``meta_keys``
|
||||
will be converted to :obj:mmcv.DataContainer.
|
||||
|
||||
Args:
|
||||
results (dict): Result dict contains the data to collect.
|
||||
|
||||
Returns:
|
||||
dict: The result dict contains the following keys
|
||||
- keys in``self.keys``
|
||||
- ``img_metas``
|
||||
"""
|
||||
|
||||
data = {}
|
||||
img_meta = {}
|
||||
for key in self.meta_keys:
|
||||
img_meta[key] = results[key]
|
||||
data['img_metas'] = DC(img_meta, cpu_only=True)
|
||||
for key in self.keys:
|
||||
data[key] = results[key]
|
||||
return data
|
||||
|
||||
def __repr__(self):
|
||||
return self.__class__.__name__ + \
|
||||
f'(keys={self.keys}, meta_keys={self.meta_keys})'
|
|
@ -194,7 +194,7 @@ class GELayer(BaseModule):
|
|||
init_cfg (dict or list[dict], optional): Initialization config dict.
|
||||
Default: None.
|
||||
Returns:
|
||||
x (torch.Tensor): Intermidiate feature map in
|
||||
x (torch.Tensor): Intermediate feature map in
|
||||
Semantic Branch.
|
||||
"""
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ class TransformerEncoderLayer(BaseModule):
|
|||
qkv_bias (bool): enable bias for qkv if True.
|
||||
Default: True.
|
||||
act_cfg (dict): The activation config for FFNs.
|
||||
Defalut: dict(type='GELU').
|
||||
Default: dict(type='GELU').
|
||||
norm_cfg (dict): Config dict for normalization layer.
|
||||
Default: dict(type='LN').
|
||||
batch_first (bool): Key, Query and Value are shape of
|
||||
|
@ -277,7 +277,7 @@ class MixVisionTransformer(BaseModule):
|
|||
norm_cfg (dict): Config dict for normalization layer.
|
||||
Default: dict(type='LN')
|
||||
act_cfg (dict): The activation config for FFNs.
|
||||
Defalut: dict(type='GELU').
|
||||
Default: dict(type='GELU').
|
||||
pretrained (str, optional): model pretrained path. Default: None.
|
||||
init_cfg (dict or list[dict], optional): Initialization config dict.
|
||||
Default: None.
|
||||
|
|
|
@ -33,7 +33,7 @@ class TransformerEncoderLayer(BaseModule):
|
|||
Default: 2.
|
||||
qkv_bias (bool): enable bias for qkv if True. Default: True
|
||||
act_cfg (dict): The activation config for FFNs.
|
||||
Defalut: dict(type='GELU').
|
||||
Default: dict(type='GELU').
|
||||
norm_cfg (dict): Config dict for normalization layer.
|
||||
Default: dict(type='LN').
|
||||
batch_first (bool): Key, Query and Value are shape of
|
||||
|
@ -126,7 +126,7 @@ class VisionTransformer(BaseModule):
|
|||
norm_cfg (dict): Config dict for normalization layer.
|
||||
Default: dict(type='LN')
|
||||
act_cfg (dict): The activation config for FFNs.
|
||||
Defalut: dict(type='GELU').
|
||||
Default: dict(type='GELU').
|
||||
patch_norm (bool): Whether to add a norm in PatchEmbed Block.
|
||||
Default: False.
|
||||
final_norm (bool): Whether to add a additional layer to normalize
|
||||
|
|
|
@ -227,7 +227,7 @@ class DPTHead(BaseDecodeHead):
|
|||
expand_channels (bool): Whether expand the channels in post process
|
||||
block. Default: False.
|
||||
act_cfg (dict): The activation config for residual conv unit.
|
||||
Defalut dict(type='ReLU').
|
||||
Default dict(type='ReLU').
|
||||
norm_cfg (dict): Config dict for normalization layer.
|
||||
Default: dict(type='BN').
|
||||
"""
|
||||
|
|
|
@ -51,7 +51,7 @@ def weight_reduce_loss(loss, weight=None, reduction='mean', avg_factor=None):
|
|||
loss (Tensor): Element-wise loss.
|
||||
weight (Tensor): Element-wise weights.
|
||||
reduction (str): Same as built-in losses of PyTorch.
|
||||
avg_factor (float): Avarage factor when computing the mean of losses.
|
||||
avg_factor (float): Average factor when computing the mean of losses.
|
||||
|
||||
Returns:
|
||||
Tensor: Processed loss values.
|
||||
|
|
|
@ -3,11 +3,11 @@ def nlc_to_nchw(x, hw_shape):
|
|||
"""Convert [N, L, C] shape tensor to [N, C, H, W] shape tensor.
|
||||
|
||||
Args:
|
||||
x (Tensor): The input tensor of shape [N, L, C] before convertion.
|
||||
x (Tensor): The input tensor of shape [N, L, C] before conversion.
|
||||
hw_shape (Sequence[int]): The height and width of output feature map.
|
||||
|
||||
Returns:
|
||||
Tensor: The output tensor of shape [N, C, H, W] after convertion.
|
||||
Tensor: The output tensor of shape [N, C, H, W] after conversion.
|
||||
"""
|
||||
H, W = hw_shape
|
||||
assert len(x.shape) == 3
|
||||
|
@ -20,10 +20,10 @@ def nchw_to_nlc(x):
|
|||
"""Flatten [N, C, H, W] shape tensor to [N, L, C] shape tensor.
|
||||
|
||||
Args:
|
||||
x (Tensor): The input tensor of shape [N, C, H, W] before convertion.
|
||||
x (Tensor): The input tensor of shape [N, C, H, W] before conversion.
|
||||
|
||||
Returns:
|
||||
Tensor: The output tensor of shape [N, L, C] after convertion.
|
||||
Tensor: The output tensor of shape [N, L, C] after conversion.
|
||||
"""
|
||||
assert len(x.shape) == 4
|
||||
return x.flatten(2).transpose(1, 2).contiguous()
|
||||
|
|
|
@ -11,3 +11,9 @@ known_first_party = mmseg
|
|||
known_third_party = PIL,cityscapesscripts,cv2,detail,matplotlib,mmcv,numpy,onnxruntime,packaging,prettytable,pytest,pytorch_sphinx_theme,requests,scipy,seaborn,torch,ts
|
||||
no_lines_before = STDLIB,LOCALFOLDER
|
||||
default_section = THIRDPARTY
|
||||
|
||||
[codespell]
|
||||
skip = *.po,*.ts,*.ipynb
|
||||
count =
|
||||
quiet-level = 3
|
||||
ignore-words-list = formating,sur,hist
|
||||
|
|
|
@ -425,7 +425,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(strides)=num_stages
|
||||
# Check if num_stages matches strides, len(strides)=num_stages
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
@ -440,7 +440,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(enc_num_convs)=num_stages
|
||||
# Check if num_stages matches strides, len(enc_num_convs)=num_stages
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
@ -455,7 +455,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(dec_num_convs)=num_stages-1
|
||||
# Check if num_stages matches strides, len(dec_num_convs)=num_stages-1
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
@ -470,7 +470,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(downsamples)=num_stages-1
|
||||
# Check if num_stages matches strides, len(downsamples)=num_stages-1
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
@ -485,7 +485,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(enc_dilations)=num_stages
|
||||
# Check if num_stages matches strides, len(enc_dilations)=num_stages
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
@ -500,7 +500,7 @@ def test_unet():
|
|||
unet(x)
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
# Check if num_stages matchs strides, len(dec_dilations)=num_stages-1
|
||||
# Check if num_stages matches strides, len(dec_dilations)=num_stages-1
|
||||
unet = UNet(
|
||||
in_channels=3,
|
||||
base_channels=4,
|
||||
|
|
|
@ -173,7 +173,7 @@ def test_patch_embed():
|
|||
# test L = out_h * out_w
|
||||
assert shape[0] * shape[1] == x3.shape[1]
|
||||
|
||||
# test thte init_out_size with nn.Unfold
|
||||
# test the init_out_size with nn.Unfold
|
||||
assert patch_merge_3.init_out_size[1] == (input_size[0] - 2 * 4 -
|
||||
1) // 2 + 1
|
||||
assert patch_merge_3.init_out_size[0] == (input_size[0] - 2 * 4 -
|
||||
|
@ -195,7 +195,7 @@ def test_patch_embed():
|
|||
|
||||
_, shape = patch_merge_3(dummy_input)
|
||||
# when input_size equal to real input
|
||||
# the out_size shoule be equal to `init_out_size`
|
||||
# the out_size should be equal to `init_out_size`
|
||||
assert shape == patch_merge_3.init_out_size
|
||||
|
||||
input_size = (H, W)
|
||||
|
@ -213,7 +213,7 @@ def test_patch_embed():
|
|||
|
||||
_, shape = patch_merge_3(dummy_input)
|
||||
# when input_size equal to real input
|
||||
# the out_size shoule be equal to `init_out_size`
|
||||
# the out_size should be equal to `init_out_size`
|
||||
assert shape == patch_merge_3.init_out_size
|
||||
|
||||
# test adap padding
|
||||
|
@ -288,7 +288,7 @@ def test_patch_embed():
|
|||
assert out_size == (2, 1)
|
||||
assert x_out.size(1) == out_size[0] * out_size[1]
|
||||
|
||||
# test different kernel_size with diffrent stride
|
||||
# test different kernel_size with different stride
|
||||
input_size = (6, 5)
|
||||
kernel_size = (6, 2)
|
||||
stride = (6, 2)
|
||||
|
@ -437,7 +437,7 @@ def test_patch_merging():
|
|||
assert out_size == (2, 1)
|
||||
assert x_out.size(1) == out_size[0] * out_size[1]
|
||||
|
||||
# test different kernel_size with diffrent stride
|
||||
# test different kernel_size with different stride
|
||||
input_size = (6, 5)
|
||||
kernel_size = (6, 2)
|
||||
stride = (6, 2)
|
||||
|
|
|
@ -14,14 +14,14 @@ def convert_mit(ckpt):
|
|||
for k, v in ckpt.items():
|
||||
if k.startswith('head'):
|
||||
continue
|
||||
# patch embedding convertion
|
||||
# patch embedding conversion
|
||||
elif k.startswith('patch_embed'):
|
||||
stage_i = int(k.split('.')[0].replace('patch_embed', ''))
|
||||
new_k = k.replace(f'patch_embed{stage_i}', f'layers.{stage_i-1}.0')
|
||||
new_v = v
|
||||
if 'proj.' in new_k:
|
||||
new_k = new_k.replace('proj.', 'projection.')
|
||||
# transformer encoder layer convertion
|
||||
# transformer encoder layer conversion
|
||||
elif k.startswith('block'):
|
||||
stage_i = int(k.split('.')[0].replace('block', ''))
|
||||
new_k = k.replace(f'block{stage_i}', f'layers.{stage_i-1}.1')
|
||||
|
@ -45,7 +45,7 @@ def convert_mit(ckpt):
|
|||
new_k = new_k.replace('dwconv.dwconv.', '1.')
|
||||
new_k = new_k.replace('fc2.', '4.')
|
||||
string += f'{new_k} {v.shape}-{new_v.shape}'
|
||||
# norm layer convertion
|
||||
# norm layer conversion
|
||||
elif k.startswith('norm'):
|
||||
stage_i = int(k.split('.')[0].replace('norm', ''))
|
||||
new_k = k.replace(f'norm{stage_i}', f'layers.{stage_i-1}.2')
|
||||
|
|
|
@ -117,7 +117,7 @@ def onnx2tensorrt(onnx_file: str,
|
|||
import tensorrt as trt
|
||||
min_shape = input_config['min_shape']
|
||||
max_shape = input_config['max_shape']
|
||||
# create trt engine and wraper
|
||||
# create trt engine and wrapper
|
||||
opt_shape_dict = {'input': [min_shape, min_shape, max_shape]}
|
||||
max_workspace_size = get_GiB(workspace_size)
|
||||
trt_engine = onnx2trt(
|
||||
|
@ -254,7 +254,7 @@ if __name__ == '__main__':
|
|||
'Dataset {} does not found.'.format(args.dataset)
|
||||
for max_value, min_value in zip(args.max_shape, args.min_shape):
|
||||
assert max_value >= min_value, \
|
||||
'max_shape sould be larger than min shape'
|
||||
'max_shape should be larger than min shape'
|
||||
|
||||
input_config = {
|
||||
'min_shape': args.min_shape,
|
||||
|
|
|
@ -113,7 +113,7 @@ def pytorch2libtorch(model,
|
|||
|
||||
imgs = mm_inputs.pop('imgs')
|
||||
|
||||
# replace the orginal forword with forward_dummy
|
||||
# replace the original forword with forward_dummy
|
||||
model.forward = model.forward_dummy
|
||||
model.eval()
|
||||
traced_model = torch.jit.trace(
|
||||
|
|
Loading…
Reference in New Issue