diff --git a/.circleci/config.yml b/.circleci/config.yml index 0390ed26d23..635a984a1ca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,7 +26,7 @@ workflows: tools/.* lint_only false configs/.* lint_only false .circleci/.* lint_only false - base-revision: dev-1.x + base-revision: main # this is the path of the configuration we should trigger once # path filtering and pipeline parameter value updates are # complete. In this case, we are using the parent dynamic diff --git a/.circleci/test.yml b/.circleci/test.yml index a968b3df9a5..57f89e18f5e 100644 --- a/.circleci/test.yml +++ b/.circleci/test.yml @@ -61,10 +61,11 @@ jobs: command: | pip install git+https://github.com/open-mmlab/mmengine.git@main pip install -U openmim - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x + mim install mmcv>=2.0.0 + pip install mmpretrain>=1.0.0rc7 + pip install mmdet>=3.0.0 pip install -r requirements/tests.txt -r requirements/optional.txt + python -m pip install albumentations>=0.3.2 --no-binary qudida,albumentations - run: name: Build and install command: | @@ -72,7 +73,7 @@ jobs: - run: name: Skip timm unittests and generate coverage report command: | - python -m coverage run --branch --source mmseg -m pytest tests/ --ignore tests/test_models/test_backbones/test_timm_backbone.py + python -m coverage run --branch --source mmseg -m pytest tests/ --ignore tests/test_models/test_backbones/test_timm_backbone.py --ignore tests/test_apis/test_rs_inferencer.py python -m coverage xml python -m coverage report -m build_cuda: @@ -96,22 +97,23 @@ jobs: name: Clone Repos command: | git clone -b main --depth 1 https://github.com/open-mmlab/mmengine.git /home/circleci/mmengine - git clone -b dev-1.x --depth 1 https://github.com/open-mmlab/mmclassification.git /home/circleci/mmclassification - git clone -b dev-3.x --depth 1 https://github.com/open-mmlab/mmdetection.git /home/circleci/mmdetection - run: name: Build Docker image command: | docker build .circleci/docker -t mmseg:gpu --build-arg PYTORCH=<< parameters.torch >> --build-arg CUDA=<< parameters.cuda >> --build-arg CUDNN=<< parameters.cudnn >> - docker run --gpus all -t -d -v /home/circleci/project:/mmseg -v /home/circleci/mmengine:/mmengine -v /home/circleci/mmclassification:/mmclassification -v /home/circleci/mmdetection:/mmdetection -w /mmseg --name mmseg mmseg:gpu + docker run --gpus all -t -d -v /home/circleci/project:/mmseg -v /home/circleci/mmengine:/mmengine -v /home/circleci/mmpretrain:/mmpretrain -v /home/circleci/mmdetection:/mmdetection -w /mmseg --name mmseg mmseg:gpu - run: name: Install mmseg dependencies command: | docker exec mmseg pip install -e /mmengine docker exec mmseg pip install -U openmim - docker exec mmseg mim install 'mmcv>=2.0.0rc4' - docker exec mmseg pip install -e /mmclassification - docker exec mmseg pip install -e /mmdetection + docker exec mmseg mim install mmcv>=2.0.0 + docker exec mmseg pip install mmpretrain>=1.0.0rc7 + docker exec mmseg mim install mmdet>=3.0.0 + docker exec mmseg apt-get update + docker exec mmseg apt-get install -y git docker exec mmseg pip install -r requirements/tests.txt -r requirements/optional.txt + docker exec mmseg python -m pip install albumentations>=0.3.2 --no-binary qudida,albumentations - run: name: Build and install command: | @@ -119,7 +121,7 @@ jobs: - run: name: Run unittests but skip timm unittests command: | - docker exec mmseg pytest tests/ --ignore tests/test_models/test_backbones/test_timm_backbone.py + docker exec mmseg pytest tests/ --ignore tests/test_models/test_backbones/test_timm_backbone.py --ignore tests/test_models/test_backbones/test_timm_backbone.py --ignore tests/test_apis/test_rs_inferencer.py workflows: pr_stage_lint: when: << pipeline.parameters.lint_only >> @@ -130,8 +132,7 @@ workflows: branches: ignore: - dev-1.x - - 1.x - - master + - main pr_stage_test: when: not: @@ -143,12 +144,11 @@ workflows: branches: ignore: - dev-1.x - - 1.x - - master + - main - build_cpu: name: minimum_version_cpu - torch: 1.6.0 - torchvision: 0.7.0 + torch: 1.8.1 + torchvision: 0.9.1 python: "3.7" requires: - lint @@ -179,12 +179,12 @@ workflows: jobs: - build_cuda: name: minimum_version_gpu - torch: 1.6.0 + torch: 1.8.1 # Use double quotation mark to explicitly specify its type # as string instead of number - cuda: "10.1" + cuda: "10.2" filters: branches: only: - dev-1.x - - 1.x + - main diff --git a/.dev/batch_test_list.py b/.dev_scripts/batch_test_list.py similarity index 100% rename from .dev/batch_test_list.py rename to .dev_scripts/batch_test_list.py diff --git a/.dev/batch_train_list.txt b/.dev_scripts/batch_train_list.txt similarity index 100% rename from .dev/batch_train_list.txt rename to .dev_scripts/batch_train_list.txt diff --git a/.dev/benchmark_evaluation.sh b/.dev_scripts/benchmark_evaluation.sh similarity index 100% rename from .dev/benchmark_evaluation.sh rename to .dev_scripts/benchmark_evaluation.sh diff --git a/.dev_scripts/benchmark_full_models.txt b/.dev_scripts/benchmark_full_models.txt new file mode 100644 index 00000000000..64b968d0f3d --- /dev/null +++ b/.dev_scripts/benchmark_full_models.txt @@ -0,0 +1,57 @@ +ann/ann_r50-d8_4xb2-40k_cityscapes-512x1024.py +apcnet/apcnet_r50-d8_4xb4-80k_ade20k-512x512.py +beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py +bisenetv1/bisenetv1_r18-d32_4xb4-160k_coco-stuff164k-512x512.py +bisenetv2/bisenetv2_fcn_4xb4-ohem-160k_cityscapes-1024x1024.py +ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py +cgnet/cgnet_fcn_4xb4-60k_cityscapes-680x680.py +convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py +danet/danet_r50-d8_4xb2-40k_cityscapes-512x1024.py +deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-512x1024.py +deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-769x769.py +dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py +dnlnet/dnl_r50-d8_4xb2-40k_cityscapes-512x1024.py +dpt/dpt_vit-b16_8xb2-160k_ade20k-512x512.py +emanet/eemanet_r50-d8_4xb2-80k_cityscapes-512x1024.py +encnet/encnet_r50-d8_4xb4-80k_ade20k-512x512.py +erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py +fastfcn/fastfcn_r50-d32_jpu_aspp_4xb2-80k_cityscapes-512x1024.py +fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py +fcn/fcn_r50-d8_4xb2-40k_cityscapes-512x1024.py +gcnet/gcnet_r50-d8_4xb2-40k_cityscapes-769x769.py +hrnet/fcn_hr18s_4xb4-80k_ade20k-512x512.py +icnet/icnet_r50-d8_4xb2-80k_cityscapes-832x832.py +isanet/isanet_r50-d8_4xb2-80k_cityscapes-512x1024.py +knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-640x640.py +mae/mae-base_upernet_8xb2-amp-160k_ade20k-512x512.py +mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024.py +mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024.py +mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512.py +mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py +maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512.py +maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512.py +maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512.py +maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512.py +mobilenet_v2/mobilenet-v2-d8_pspnet_4xb2-80k_cityscapes-512x1024.py +mobilenet_v3/mobilenet-v3-d8-scratch_lraspp_4xb4-320k_cityscapes-512x1024.py +nonlocal_net/nonlocal_r50-d8_4xb2-40k_cityscapes-512x1024.py +ocrnet/ocrnet_hr18_4xb4-80k_ade20k-512x512.py +pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes.py +point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py +poolformer/fpn_poolformer_m48_8xb4-40k_ade20k-512x512.py +psanet/psanet_r101-d8_4xb4-80k_ade20k-512x512.py +pspnet/pspnet_r50-d8-rsb_4xb2-adamw-80k_cityscapes-512x1024.py +resnest/resnest_s101-d8_deeplabv3_4xb4-160k_ade20k-512x512.py +segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py +segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py +segmenter/segmenter_vit-t_mask_8xb1-160k_ade20k-512x512.py +segnext/segnext_mscan-t_1xb16-adamw-160k_ade20k-512x512.py +sem_fpn/fpn_r101_4xb2-80k_cityscapes-512x1024.py +setr/setr_vit-l-mla_8xb1-160k_ade20k-512x512.py +stdc/stdc1_in1k-pre_4xb12-80k_cityscapes-512x1024.py +swin/swin-small-patch4-window7-in1k-pre_upernet_8xb2-160k_ade20k-512x512.py +twins/twins_pcpvt-s_uperhead_8xb4-160k_ade20k-512x512.py +unet/unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py +upernet/upernet_r50_4xb2-40k_cityscapes-769x769.py +vit/vit_deit-s16_upernet_8xb2-80k_ade20k-512x512.py +san/san-vit-b16_coco-stuff164k-640x640.py diff --git a/.dev/benchmark_inference.py b/.dev_scripts/benchmark_inference.py similarity index 100% rename from .dev/benchmark_inference.py rename to .dev_scripts/benchmark_inference.py diff --git a/.dev_scripts/benchmark_options.py b/.dev_scripts/benchmark_options.py new file mode 100644 index 00000000000..51909a091ce --- /dev/null +++ b/.dev_scripts/benchmark_options.py @@ -0,0 +1,10 @@ +third_part_libs = [ + 'pip install mmengine', + 'pip install mmcv>=2.0.0', + 'pip install mmcls==1.0.0rc6', + 'pip install mmdet==3.0.0', + 'pip install -r requirements.txt', + 'pip install timm', +] + +default_floating_range = 0.5 diff --git a/.dev/benchmark_train.sh b/.dev_scripts/benchmark_train.sh similarity index 100% rename from .dev/benchmark_train.sh rename to .dev_scripts/benchmark_train.sh diff --git a/.dev_scripts/benchmark_train_models.txt b/.dev_scripts/benchmark_train_models.txt new file mode 100644 index 00000000000..01f279d8d64 --- /dev/null +++ b/.dev_scripts/benchmark_train_models.txt @@ -0,0 +1,26 @@ +bisenetv1/bisenetv1_r18-d32_4xb4-160k_coco-stuff164k-512x512.py +bisenetv2/bisenetv2_fcn_4xb4-ohem-160k_cityscapes-1024x1024.py +deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-512x1024.py +deeplabv3/deeplabv3_r101-d8_4xb4-160k_ade20k-512x512.py +deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-769x769.py +deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_ade20k-512x512.py +hrnet/fcn_hr18s_4xb4-80k_ade20k-512x512.py +hrnet/fcn_hr18_4xb2-160k_cityscapes-512x1024.py +knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-512x512.py +knet/knet-s3_r50-d8_pspnet_8xb2-adamw-80k_ade20k-512x512.py +mae/mae-base_upernet_8xb2-amp-160k_ade20k-512x512.py +mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py +maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512.py +mobilenet_v2/mobilenet-v2-d8_deeplabv3_4xb2-80k_cityscapes-512x1024.py +ocrnet/ocrnet_hr48_4xb4-80k_ade20k-512x512.py +pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes.py +pspnet/pspnet_r50-d8-rsb_4xb2-adamw-80k_cityscapes-512x1024.py +pspnet/pspnet_r101-d8_4xb4-80k_ade20k-512x512.py +segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py +segmenter/segmenter_vit-t_mask_8xb1-160k_ade20k-512x512.py +segnext/segnext_mscan-t_1xb16-adamw-160k_ade20k-512x512.py +swin/swin-base-patch4-window12-in22k-384x384-pre_upernet_8xb2-160k_ade20k-512x512.py +twins/twins_pcpvt-l_uperhead_8xb2-160k_ade20k-512x512.py +unet/unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py +upernet/upernet_r101_4xb2-40k_cityscapes-512x1024.py +san/san-vit-b16_coco-stuff164k-640x640.py diff --git a/.dev/check_urls.py b/.dev_scripts/check_urls.py similarity index 100% rename from .dev/check_urls.py rename to .dev_scripts/check_urls.py diff --git a/.dev/gather_benchmark_evaluation_results.py b/.dev_scripts/gather_benchmark_evaluation_results.py similarity index 100% rename from .dev/gather_benchmark_evaluation_results.py rename to .dev_scripts/gather_benchmark_evaluation_results.py diff --git a/.dev/gather_benchmark_train_results.py b/.dev_scripts/gather_benchmark_train_results.py similarity index 100% rename from .dev/gather_benchmark_train_results.py rename to .dev_scripts/gather_benchmark_train_results.py diff --git a/.dev/gather_models.py b/.dev_scripts/gather_models.py similarity index 100% rename from .dev/gather_models.py rename to .dev_scripts/gather_models.py diff --git a/.dev/generate_benchmark_evaluation_script.py b/.dev_scripts/generate_benchmark_evaluation_script.py similarity index 98% rename from .dev/generate_benchmark_evaluation_script.py rename to .dev_scripts/generate_benchmark_evaluation_script.py index bdc5a8fca0c..4c48f854204 100644 --- a/.dev/generate_benchmark_evaluation_script.py +++ b/.dev_scripts/generate_benchmark_evaluation_script.py @@ -17,7 +17,7 @@ def parse_args(): parser.add_argument( '--out', type=str, - default='.dev/benchmark_evaluation.sh', + default='.dev_scripts/benchmark_evaluation.sh', help='path to save model benchmark script') args = parser.parse_args() diff --git a/.dev/generate_benchmark_train_script.py b/.dev_scripts/generate_benchmark_train_script.py similarity index 98% rename from .dev/generate_benchmark_train_script.py rename to .dev_scripts/generate_benchmark_train_script.py index 4e6fa181ff5..4bfdfbf09fd 100644 --- a/.dev/generate_benchmark_train_script.py +++ b/.dev_scripts/generate_benchmark_train_script.py @@ -19,7 +19,7 @@ def parse_args(): parser.add_argument( '--out', type=str, - default='.dev/benchmark_train.sh', + default='.dev_scripts/benchmark_train.sh', help='path to save model benchmark script') args = parser.parse_args() diff --git a/.dev/log_collector/example_config.py b/.dev_scripts/log_collector/example_config.py similarity index 100% rename from .dev/log_collector/example_config.py rename to .dev_scripts/log_collector/example_config.py diff --git a/.dev/log_collector/log_collector.py b/.dev_scripts/log_collector/log_collector.py similarity index 100% rename from .dev/log_collector/log_collector.py rename to .dev_scripts/log_collector/log_collector.py diff --git a/.dev/log_collector/readme.md b/.dev_scripts/log_collector/readme.md similarity index 100% rename from .dev/log_collector/readme.md rename to .dev_scripts/log_collector/readme.md diff --git a/.dev/log_collector/utils.py b/.dev_scripts/log_collector/utils.py similarity index 100% rename from .dev/log_collector/utils.py rename to .dev_scripts/log_collector/utils.py diff --git a/.dev/update_model_index.py b/.dev_scripts/update_model_index.py similarity index 97% rename from .dev/update_model_index.py rename to .dev_scripts/update_model_index.py index ae30fc3bff0..eb87c02f17e 100755 --- a/.dev/update_model_index.py +++ b/.dev_scripts/update_model_index.py @@ -78,6 +78,9 @@ def get_model_info(md_file: str, config_dir: str, if line.startswith('' in line: + return None, None + # get dataset names if line.startswith('###'): current_dataset = line.split('###')[1].strip() @@ -279,14 +282,20 @@ def update_model_index(config_dir_list: List[str]) -> bool: collection_name_list: List[str] = get_collection_name_list(md_file_list) # hard code to add 'FPN' collection_name_list.append('FPN') + remove_config_dir_list = [] # parse md file for md_file, config_dir in zip(md_file_list, config_dir_list): results, collection_name = get_model_info(md_file, config_dir, collection_name_list) + if results is None: + remove_config_dir_list.append(config_dir) + continue filename = osp.join(config_dir, 'metafile.yaml') file_modified |= dump_yaml_and_check_difference(results, filename) if collection_name != '': collection_name_list.append(collection_name) - + # remove config dir + for config_dir in remove_config_dir_list: + config_dir_list.remove(config_dir) file_modified |= update_model_index(config_dir_list) sys.exit(1 if file_modified else 0) diff --git a/.dev/upload_modelzoo.py b/.dev_scripts/upload_modelzoo.py similarity index 100% rename from .dev/upload_modelzoo.py rename to .dev_scripts/upload_modelzoo.py diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ab64085cbae..0e0c6c992eb 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -8,12 +8,12 @@ concurrency: jobs: build-n-publish: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 if: startsWith(github.event.ref, 'refs/tags') steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python 3.7 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.7 - name: Build MMSegmentation diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 97cfda589ab..00000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: lint - -on: [push, pull_request] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - name: Set up Python 3.7 - uses: actions/setup-python@v2 - with: - python-version: 3.7 - - name: Install pre-commit hook - run: | - python -m pip install pre-commit - pre-commit install - - name: Linting - run: pre-commit run --all-files - - name: Check docstring coverage - run: | - python -m pip install interrogate - interrogate -v --ignore-init-method --ignore-module --ignore-nested-functions --ignore-regex "__repr__" --fail-under 75 mmseg diff --git a/.github/workflows/merge_stage_test.yml b/.github/workflows/merge_stage_test.yml deleted file mode 100644 index dbe526d9411..00000000000 --- a/.github/workflows/merge_stage_test.yml +++ /dev/null @@ -1,261 +0,0 @@ -name: merge_stage_test - -on: - push: - paths-ignore: - - 'README.md' - - 'README_zh-CN.md' - - 'docs/**' - - 'demo/**' - - '.dev_scripts/**' - - '.circleci/**' - - 'projects/**' - branches: - - dev-1.x - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build_cpu_py: - runs-on: ubuntu-18.04 - strategy: - matrix: - python-version: [3.8, 3.9] - torch: [1.8.1] - include: - - torch: 1.8.1 - torchvision: 0.9.1 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - pip install wheel - - name: Install PyTorch - run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: rm -rf .eggs && pip install -e . - - name: Run unittests and generate coverage report - run: | - pip install timm - coverage run --branch --source mmseg -m pytest tests/ - coverage xml - coverage report -m - build_cpu_pt: - runs-on: ubuntu-18.04 - strategy: - matrix: - python-version: [3.7] - torch: [1.6.0, 1.7.1, 1.8.1, 1.9.1, 1.10.1, 1.11.0, 1.12.0] - # torch: [1.6.0, 1.7.1, 1.8.1, 1.9.1, 1.10.1, 1.11.0, 1.12.0, 1.13.0] - include: - - torch: 1.6.0 - torchvision: 0.7.0 - - torch: 1.7.1 - torchvision: 0.8.2 - - torch: 1.8.1 - torchvision: 0.9.1 - - torch: 1.9.1 - torchvision: 0.10.1 - - torch: 1.10.1 - torchvision: 0.11.2 - - torch: 1.11.0 - torchvision: 0.12.0 - - torch: 1.12.0 - torchvision: 0.13.0 - # - torch: 1.13.0 - # torchvision: 0.14.0 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - pip install wheel - - name: Install Pillow - run: pip install Pillow==6.2.2 - - name: Install PyTorch - run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: rm -rf .eggs && pip install -e . - - name: Run unittests and generate coverage report - # timm from v0.6.11 requires torch>=1.7 - if: ${{matrix.torch != '1.6.0'}} - run: | - pip install timm - coverage run --branch --source mmseg -m pytest tests/ - coverage xml - coverage report -m - - name: Skip timm unittests and generate coverage report - if: ${{matrix.torch == '1.6.0'}} - run: | - coverage run --branch --source mmseg -m pytest tests/ --ignore tests/test_models/test_backbones/test_timm_backbone.py - coverage xml - coverage report -m - # Only upload coverage report for python3.7 && pytorch1.8.1 with timm - - name: Upload coverage to Codecov - if: ${{matrix.torch == '1.8.1' && matrix.python-version == '3.7'}} - uses: codecov/codecov-action@v2 - with: - files: ./coverage.xml - flags: unittests - env_vars: OS,PYTHON - name: codecov-umbrella - fail_ci_if_error: false - - build_cu102: - runs-on: ubuntu-18.04 - container: - image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel - strategy: - matrix: - python-version: [3.7] - include: - - torch: 1.8.1 - cuda: 10.2 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - pip install wheel - - name: Fetch GPG keys - run: | - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub - - name: Install Python-dev - run: apt-get update && apt-get install -y python${{matrix.python-version}}-dev - - name: Install system dependencies - run: | - apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: | - python setup.py check -m -s - TORCH_CUDA_ARCH_LIST=7.0 pip install -e . - build_cu116: - runs-on: ubuntu-18.04 - container: - image: pytorch/pytorch:1.13.0-cuda11.6-cudnn8-devel - strategy: - matrix: - python-version: [3.7] - include: - - torch: 1.13.0 - cuda: 11.6 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - pip install wheel - - name: Fetch GPG keys - run: | - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub - - name: Install Python-dev - run: apt-get update && apt-get install -y python${{matrix.python-version}}-dev - - name: Install system dependencies - run: | - apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: | - python setup.py check -m -s - TORCH_CUDA_ARCH_LIST=7.0 pip install -e . - build_windows: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-2022] - python: [3.7] - platform: [cpu, cu111] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - python -m pip install pip --upgrade - pip install wheel - - name: Install OpenCV - run: pip install opencv-python>=3 - - name: Install PyTorch - run: pip install torch==1.8.1+${{matrix.platform}} torchvision==0.9.1+${{matrix.platform}} -f https://download.pytorch.org/whl/lts/1.8/torch_lts.html - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: pip install -e . - - name: Run unittests - run: | - pip install timm - coverage run --branch --source mmseg -m pytest tests/ --ignore tests\test_models\test_forward.py tests\test_models\test_backbones\test_beit.py - - name: Generate coverage report - run: | - coverage xml - coverage report -m diff --git a/.github/workflows/pr_stage_test.yml b/.github/workflows/pr_stage_test.yml deleted file mode 100644 index a6f8ec0d223..00000000000 --- a/.github/workflows/pr_stage_test.yml +++ /dev/null @@ -1,152 +0,0 @@ -name: pr_stage_test - -on: - pull_request: - paths-ignore: - - 'README.md' - - 'README_zh-CN.md' - - 'docs/**' - - 'demo/**' - - '.dev_scripts/**' - - '.circleci/**' - - 'projects/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build_cpu: - runs-on: ubuntu-18.04 - strategy: - matrix: - python-version: [3.7] - include: - - torch: 1.8.1 - torchvision: 0.9.1 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - # Install wheel for source distribution build. https://github.com/pypa/pip/blob/main/src/pip/_internal/wheel_builder.py#L94 - pip install wheel - - name: Install Pillow - run: pip install Pillow==6.2.2 - if: ${{matrix.torchvision == '0.4.2'}} - - name: Install PyTorch - run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html - - name: Install other dependencies - run: | - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: rm -rf .eggs && pip install -e . - - name: Run unittests and generate coverage report - run: | - pip install timm - coverage run --branch --source mmseg -m pytest tests/ - coverage xml - coverage report -m - # Upload coverage report for python3.7 && pytorch1.8.1 cpu with timm - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1.0.14 - with: - file: ./coverage.xml - flags: unittests - env_vars: OS,PYTHON - name: codecov-umbrella - fail_ci_if_error: false - - build_cu102: - runs-on: ubuntu-18.04 - container: - image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel - strategy: - matrix: - python-version: [3.7] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - pip install pip --upgrade - pip install wheel - - name: Fetch GPG keys - run: | - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub - apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub - - name: Install Python-dev - run: apt-get update && apt-get install -y python${{matrix.python-version}}-dev - if: ${{matrix.python-version != 3.9}} - - name: Install system dependencies - run: | - apt-get update - apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libxrender-dev - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: | - python setup.py check -m -s - TORCH_CUDA_ARCH_LIST=7.0 pip install -e . - build_windows: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [windows-2022] - python: [3.7] - platform: [cpu, cu111] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: | - python -m pip install pip --upgrade - pip install wheel - - name: Install OpenCV - run: pip install opencv-python>=3 - - name: Install PyTorch - run: pip install torch==1.8.1+${{matrix.platform}} torchvision==0.9.1+${{matrix.platform}} -f https://download.pytorch.org/whl/lts/1.8/torch_lts.html - - name: Install mmseg dependencies - run: | - python -V - pip install -U openmim - pip install git+https://github.com/open-mmlab/mmengine.git - mim install 'mmcv>=2.0.0rc4' - pip install git+https://github.com/open-mmlab/mmclassification.git@dev-1.x - pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x - - name: Install unittest dependencies - run: pip install -r requirements/tests.txt -r requirements/optional.txt - - name: Build and install - run: pip install -e . - - name: Run unittests - run: | - pip install timm - coverage run --branch --source mmseg -m pytest tests/ --ignore tests\test_models\test_forward.py tests\test_models\test_backbones\test_beit.py - - name: Generate coverage report - run: | - coverage xml - coverage report -m diff --git a/.github/workflows/test_mim.yml b/.github/workflows/test_mim.yml deleted file mode 100644 index 390fcf87d74..00000000000 --- a/.github/workflows/test_mim.yml +++ /dev/null @@ -1,45 +0,0 @@ - -name: test-mim - -on: - push: - paths: - - 'model-index.yml' - - 'configs/**' - - pull_request: - paths: - - 'model-index.yml' - - 'configs/**' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build_cpu: - runs-on: ubuntu-18.04 - strategy: - matrix: - python-version: [3.7] - torch: [1.8.0] - include: - - torch: 1.8.0 - torch_version: torch1.8 - torchvision: 0.9.0 - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Upgrade pip - run: pip install pip --upgrade - - name: Install PyTorch - run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html - - name: Install openmim - run: pip install openmim - - name: Build and install - run: rm -rf .eggs && mim install -e . - - name: test commands of mim - run: mim search mmsegmentation>=1.0.0rc0 diff --git a/.owners.yml b/.owners.yml index b850b095075..20f2070d409 100644 --- a/.owners.yml +++ b/.owners.yml @@ -1,10 +1,7 @@ assign: strategy: # random - # daily-shift-based - round-robin + # round-robin + daily-shift-based assignees: - - MeowZheng - - MengzhangLI - - linfangjian01 - - xiaoachen98 + - xiexinch diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3bc3fd09a8a..aa5942748ab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,15 +42,17 @@ repos: hooks: - id: docformatter args: ["--in-place", "--wrap-descriptions", "79"] - - repo: local - hooks: - - id: update-model-index - name: update-model-index - description: Collect model information and update model-index.yml - entry: .dev/update_model_index.py - additional_dependencies: [pyyaml] - language: python - require_serial: true + # temporarily remove update-model-index to avoid conflict raised + # by depth estimator models + # - repo: local + # hooks: + # - id: update-model-index + # name: update-model-index + # description: Collect model information and update model-index.yml + # entry: .dev_scripts/update_model_index.py + # additional_dependencies: [pyyaml] + # language: python + # require_serial: true - repo: https://github.com/asottile/pyupgrade rev: v3.0.0 hooks: diff --git a/.readthedocs.yml b/.readthedocs.yml index 6cfbf5d310f..65a65ba1ba7 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,9 +1,14 @@ version: 2 -formats: all +build: + os: ubuntu-22.04 + tools: + python: "3.7" + +formats: + - epub python: - version: 3.7 install: - requirements: requirements/docs.txt - requirements: requirements/readthedocs.txt diff --git a/MANIFEST.in b/MANIFEST.in index e307d818176..bd8c7c06d2c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ include requirements/*.txt include mmseg/.mim/model-index.yml -recursive-include mmseg/.mim/configs *.py *.yml +include mmaction/.mim/dataset-index.yml +recursive-include mmseg/.mim/configs *.py *.yaml recursive-include mmseg/.mim/tools *.py *.sh diff --git a/README.md b/README.md index a17557cb814..85cfd5aab8c 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,15 @@ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mmsegmentation)](https://pypi.org/project/mmsegmentation/) [![PyPI](https://img.shields.io/pypi/v/mmsegmentation)](https://pypi.org/project/mmsegmentation) -[![docs](https://img.shields.io/badge/docs-latest-blue)](https://mmsegmentation.readthedocs.io/en/1.x/) +[![docs](https://img.shields.io/badge/docs-latest-blue)](https://mmsegmentation.readthedocs.io/en/latest/) [![badge](https://github.com/open-mmlab/mmsegmentation/workflows/build/badge.svg)](https://github.com/open-mmlab/mmsegmentation/actions) [![codecov](https://codecov.io/gh/open-mmlab/mmsegmentation/branch/master/graph/badge.svg)](https://codecov.io/gh/open-mmlab/mmsegmentation) -[![license](https://img.shields.io/github/license/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/blob/1.x/LICENSE) +[![license](https://img.shields.io/github/license/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/blob/main/LICENSE) [![issue resolution](https://isitmaintained.com/badge/resolution/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/issues) [![open issues](https://isitmaintained.com/badge/open/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/issues) +[![Open in OpenXLab](https://cdn-static.openxlab.org.cn/app-center/openxlab_demo.svg)](https://openxlab.org.cn/apps?search=mmseg) -Documentation: +Documentation: English | [简体中文](README_zh-CN.md) @@ -35,7 +36,7 @@ English | [简体中文](README_zh-CN.md)
- + @@ -45,6 +46,12 @@ English | [简体中文](README_zh-CN.md) + + + + + +
## Introduction @@ -52,7 +59,13 @@ English | [简体中文](README_zh-CN.md) MMSegmentation is an open source semantic segmentation toolbox based on PyTorch. It is a part of the OpenMMLab project. -The 1.x branch works with **PyTorch 1.6+**. +The [main](https://github.com/open-mmlab/mmsegmentation/tree/main) branch works with PyTorch 1.6+. + +### 🎉 Introducing MMSegmentation v1.0.0 🎉 + +We are thrilled to announce the official release of MMSegmentation's latest version! For this new release, the [main](https://github.com/open-mmlab/mmsegmentation/tree/main) branch serves as the primary branch, while the development branch is [dev-1.x](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x). The stable branch for the previous release remains as the [0.x](https://github.com/open-mmlab/mmsegmentation/tree/0.x) branch. Please note that the [master](https://github.com/open-mmlab/mmsegmentation/tree/master) branch will only be maintained for a limited time before being removed. We encourage you to be mindful of branch selection and updates during use. Thank you for your unwavering support and enthusiasm, and let's work together to make MMSegmentation even more robust and powerful! 💪 + +MMSegmentation v1.x brings remarkable improvements over the 0.x release, offering a more flexible and feature-packed experience. To utilize the new features in v1.x, we kindly invite you to consult our detailed [📚 migration guide](https://mmsegmentation.readthedocs.io/en/latest/migration/interface.html), which will help you seamlessly transition your projects. Your support is invaluable, and we eagerly await your feedback! ![demo image](resources/seg_demo.gif) @@ -76,11 +89,11 @@ The 1.x branch works with **PyTorch 1.6+**. ## What's New -v1.0.0rc6 was released on 03/03/2023. +v1.1.2 was released on 09/20/2023. Please refer to [changelog.md](docs/en/notes/changelog.md) for details and release history. -- Support MMSegInferencer ([#2413](https://github.com/open-mmlab/mmsegmentation/pull/2413), [#2658](https://github.com/open-mmlab/mmsegmentation/pull/2658)) -- Support REFUGE dataset ([#2554](https://github.com/open-mmlab/mmsegmentation/pull/2554)) +- Support monocular depth estimation task, please refer to [VPD](configs/vpd/README.md) for more details. +- Add new projects: [CAT-Seg](projects/CAT-Seg/README.md), [PP-MobileSeg](projects/pp_mobileseg/README.md), [AdaBins](projects/Adabins/README.md) ## Installation @@ -90,12 +103,66 @@ Please refer to [get_started.md](docs/en/get_started.md#installation) for instal Please see [Overview](docs/en/overview.md) for the general introduction of MMSegmentation. -Please see [user guides](https://mmsegmentation.readthedocs.io/en/1.x/user_guides/index.html#) for the basic usage of MMSegmentation. -There are also [advanced tutorials](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/index.html) for in-depth understanding of mmseg design and implementation . +Please see [user guides](https://mmsegmentation.readthedocs.io/en/latest/user_guides/index.html#) for the basic usage of MMSegmentation. +There are also [advanced tutorials](https://mmsegmentation.readthedocs.io/en/latest/advanced_guides/index.html) for in-depth understanding of mmseg design and implementation . + +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/main/demo/MMSegmentation_Tutorial.ipynb) on Colab. + +To migrate from MMSegmentation 0.x, please refer to [migration](docs/en/migration). + +## Tutorial + +
+Get Started + +- [MMSeg overview](docs/en/overview.md) +- [MMSeg Installation](docs/en/get_started.md) +- [FAQ](docs/en/notes/faq.md) + +
+ +
+MMSeg Basic Tutorial + +- [Tutorial 1: Learn about Configs](docs/en/user_guides/1_config.md) +- [Tutorial 2: Prepare datasets](docs/en/user_guides/2_dataset_prepare.md) +- [Tutorial 3: Inference with existing models](docs/en/user_guides/3_inference.md) +- [Tutorial 4: Train and test with existing models](docs/en/user_guides/4_train_test.md) +- [Tutorial 5: Model deployment](docs/en/user_guides/5_deployment.md) +- [Useful Tools](docs/en/user_guides/useful_tools.md) +- [Feature Map Visualization](docs/en/user_guides/visualization_feature_map.md) +- [Visualization](docs/en/user_guides/visualization.md) + +
+ +
+MMSeg Detail Tutorial + +- [MMSeg Dataset](docs/en/advanced_guides/datasets.md) +- [MMSeg Models](docs/en/advanced_guides/models.md) +- [MMSeg Dataset Structures](docs/en/advanced_guides/structures.md) +- [MMSeg Data Transforms](docs/en/advanced_guides/transforms.md) +- [MMSeg Dataflow](docs/en/advanced_guides/data_flow.md) +- [MMSeg Training Engine](docs/en/advanced_guides/engine.md) +- [MMSeg Evaluation](docs/en/advanced_guides/evaluation.md) + +
+ +
+MMSeg Development Tutorial -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/1.x/demo/MMSegmentation_Tutorial.ipynb) on Colab. +- [Add New Datasets](docs/en/advanced_guides/add_datasets.md) +- [Add New Metrics](docs/en/advanced_guides/add_metrics.md) +- [Add New Modules](docs/en/advanced_guides/add_models.md) +- [Add New Data Transforms](docs/en/advanced_guides/add_transforms.md) +- [Customize Runtime Settings](docs/en/advanced_guides/customize_runtime.md) +- [Training Tricks](docs/en/advanced_guides/training_tricks.md) +- [Contribute code to MMSeg](.github/CONTRIBUTING.md) +- [Contribute a standard dataset in projects](docs/zh_cn/advanced_guides/contribute_dataset.md) +- [NPU (HUAWEI Ascend)](docs/en/device/npu.md) +- [0.x → 1.x migration](docs/en/migration/interface.md),[0.x → 1.x package](docs/en/migration/package.md) -To migrate from MMSegmentation 1.x, please refer to [migration](docs/en/migration). +
## Benchmark and model zoo @@ -161,29 +228,34 @@ Results and models are available in the [model zoo](docs/en/model_zoo.md). - [x] [MaskFormer (NeurIPS'2021)](configs/maskformer) - [x] [Mask2Former (CVPR'2022)](configs/mask2former) - [x] [PIDNet (ArXiv'2022)](configs/pidnet) +- [x] [DDRNet (T-ITS'2022)](configs/ddrnet) +- [x] [VPD (ICCV'2023)](configs/vpd)
Supported datasets: -- [x] [Cityscapes](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#cityscapes) -- [x] [PASCAL VOC](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#pascal-voc) -- [x] [ADE20K](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#ade20k) -- [x] [Pascal Context](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#pascal-context) -- [x] [COCO-Stuff 10k](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#coco-stuff-10k) -- [x] [COCO-Stuff 164k](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#coco-stuff-164k) -- [x] [CHASE_DB1](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#chase-db1) -- [x] [DRIVE](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#drive) -- [x] [HRF](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#hrf) -- [x] [STARE](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#stare) -- [x] [Dark Zurich](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#dark-zurich) -- [x] [Nighttime Driving](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#nighttime-driving) -- [x] [LoveDA](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#loveda) -- [x] [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#isprs-potsdam) -- [x] [Vaihingen](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#isprs-vaihingen) -- [x] [iSAID](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#isaid) -- [x] [Mapillary Vistas](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#mapillary-vistas-datasets) +- [x] [Cityscapes](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#cityscapes) +- [x] [PASCAL VOC](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#pascal-voc) +- [x] [ADE20K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#ade20k) +- [x] [Pascal Context](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#pascal-context) +- [x] [COCO-Stuff 10k](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#coco-stuff-10k) +- [x] [COCO-Stuff 164k](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#coco-stuff-164k) +- [x] [CHASE_DB1](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#chase-db1) +- [x] [DRIVE](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#drive) +- [x] [HRF](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#hrf) +- [x] [STARE](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#stare) +- [x] [Dark Zurich](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#dark-zurich) +- [x] [Nighttime Driving](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#nighttime-driving) +- [x] [LoveDA](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#loveda) +- [x] [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#isprs-potsdam) +- [x] [Vaihingen](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#isprs-vaihingen) +- [x] [iSAID](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#isaid) +- [x] [Mapillary Vistas](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#mapillary-vistas-datasets) +- [x] [LEVIR-CD](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#levir-cd) +- [x] [BDD100K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#bdd100K) +- [x] [NYU](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#nyu)
@@ -223,25 +295,23 @@ This project is released under the [Apache 2.0 license](LICENSE). ## OpenMMLab Family -- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab foundational library for training deep learning models +- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab foundational library for training deep learning models. - [MMCV](https://github.com/open-mmlab/mmcv): OpenMMLab foundational library for computer vision. -- [MIM](https://github.com/open-mmlab/mim): MIM installs OpenMMLab packages. -- [MMEval](https://github.com/open-mmlab/mmeval): A unified evaluation library for multiple machine learning libraries. -- [MMClassification](https://github.com/open-mmlab/mmclassification): OpenMMLab image classification toolbox and benchmark. +- [MMPreTrain](https://github.com/open-mmlab/mmpretrain): OpenMMLab pre-training toolbox and benchmark. +- [MMagic](https://github.com/open-mmlab/mmagic): Open**MM**Lab **A**dvanced, **G**enerative and **I**ntelligent **C**reation toolbox. - [MMDetection](https://github.com/open-mmlab/mmdetection): OpenMMLab detection toolbox and benchmark. +- [MMYOLO](https://github.com/open-mmlab/mmyolo): OpenMMLab YOLO series toolbox and benchmark. - [MMDetection3D](https://github.com/open-mmlab/mmdetection3d): OpenMMLab's next-generation platform for general 3D object detection. - [MMRotate](https://github.com/open-mmlab/mmrotate): OpenMMLab rotated object detection toolbox and benchmark. -- [MMYOLO](https://github.com/open-mmlab/mmyolo): OpenMMLab YOLO series toolbox and benchmark. +- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab video perception toolbox and benchmark. - [MMSegmentation](https://github.com/open-mmlab/mmsegmentation): OpenMMLab semantic segmentation toolbox and benchmark. - [MMOCR](https://github.com/open-mmlab/mmocr): OpenMMLab text detection, recognition, and understanding toolbox. - [MMPose](https://github.com/open-mmlab/mmpose): OpenMMLab pose estimation toolbox and benchmark. - [MMHuman3D](https://github.com/open-mmlab/mmhuman3d): OpenMMLab 3D human parametric model toolbox and benchmark. -- [MMSelfSup](https://github.com/open-mmlab/mmselfsup): OpenMMLab self-supervised learning toolbox and benchmark. -- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab model compression toolbox and benchmark. - [MMFewShot](https://github.com/open-mmlab/mmfewshot): OpenMMLab fewshot learning toolbox and benchmark. - [MMAction2](https://github.com/open-mmlab/mmaction2): OpenMMLab's next-generation action understanding toolbox and benchmark. -- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab video perception toolbox and benchmark. - [MMFlow](https://github.com/open-mmlab/mmflow): OpenMMLab optical flow toolbox and benchmark. -- [MMEditing](https://github.com/open-mmlab/mmediting): OpenMMLab image and video editing toolbox. -- [MMGeneration](https://github.com/open-mmlab/mmgeneration): OpenMMLab image and video generative models toolbox. - [MMDeploy](https://github.com/open-mmlab/mmdeploy): OpenMMLab Model Deployment Framework. +- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab model compression toolbox and benchmark. +- [MIM](https://github.com/open-mmlab/mim): MIM installs OpenMMLab packages. +- [Playground](https://github.com/open-mmlab/playground): A central hub for gathering and showcasing amazing projects built upon OpenMMLab. diff --git a/README_zh-CN.md b/README_zh-CN.md index e09b515ab5d..fdedfa8c32b 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -17,27 +17,54 @@
 
- -
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mmsegmentation)](https://pypi.org/project/mmsegmentation/) [![PyPI](https://img.shields.io/pypi/v/mmsegmentation)](https://pypi.org/project/mmsegmentation) -[![docs](https://img.shields.io/badge/docs-latest-blue)](https://mmsegmentation.readthedocs.io/zh_CN/1.x/) +[![docs](https://img.shields.io/badge/docs-latest-blue)](https://mmsegmentation.readthedocs.io/zh_CN/latest/) [![badge](https://github.com/open-mmlab/mmsegmentation/workflows/build/badge.svg)](https://github.com/open-mmlab/mmsegmentation/actions) [![codecov](https://codecov.io/gh/open-mmlab/mmsegmentation/branch/master/graph/badge.svg)](https://codecov.io/gh/open-mmlab/mmsegmentation) -[![license](https://img.shields.io/github/license/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/blob/1.x/LICENSE) +[![license](https://img.shields.io/github/license/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/blob/main/LICENSE) [![issue resolution](https://isitmaintained.com/badge/resolution/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/issues) [![open issues](https://isitmaintained.com/badge/open/open-mmlab/mmsegmentation.svg)](https://github.com/open-mmlab/mmsegmentation/issues) +[![Open in OpenXLab](https://cdn-static.openxlab.org.cn/app-center/openxlab_demo.svg)](https://openxlab.org.cn/apps?search=mmseg) 文档: [English](README.md) | 简体中文 + + +
+ + + + + + + + + + + + + + + + + +
+ ## 简介 MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱。它是 OpenMMLab 项目的一部分。 -1.x 分支代码目前支持 PyTorch 1.6 以上的版本。 +[main](https://github.com/open-mmlab/mmsegmentation/tree/main) 分支代码目前支持 PyTorch 1.6 以上的版本。 + +### 🎉 MMSegmentation v1.0.0 简介 🎉 + +我们非常高兴地宣布 MMSegmentation 最新版本的正式发布!在这个新版本中,主要分支是 [main](https://github.com/open-mmlab/mmsegmentation/tree/main) 分支,开发分支是 [dev-1.x](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x)。而之前版本的稳定分支保留为 [0.x](https://github.com/open-mmlab/mmsegmentation/tree/0.x) 分支。请注意,[master](https://github.com/open-mmlab/mmsegmentation/tree/master) 分支将只在有限的时间内维护,然后将被删除。我们鼓励您在使用过程中注意分支选择和更新。感谢您一如既往的支持和热情,让我们共同努力,使 MMSegmentation 变得更加健壮和强大!💪 + +MMSegmentation v1.x 在 0.x 版本的基础上有了显著的提升,提供了更加灵活和功能丰富的体验。为了更好使用 v1.x 中的新功能,我们诚挚邀请您查阅我们详细的 [📚 迁移指南](https://mmsegmentation.readthedocs.io/zh_CN/latest/migration/interface.html),以帮助您无缝地过渡您的项目。您的支持对我们来说非常宝贵,我们热切期待您的反馈! ![示例图片](resources/seg_demo.gif) @@ -61,7 +88,7 @@ MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱。它是 O ## 更新日志 -最新版本 v1.0.0rc6 在 2023.03.03 发布。 +最新版本 v1.1.2 在 2023.09.20 发布。 如果想了解更多版本更新细节和历史信息,请阅读[更新日志](docs/en/notes/changelog.md)。 ## 安装 @@ -72,11 +99,65 @@ MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱。它是 O 请参考[概述](docs/zh_cn/overview.md)对 MMSegmetation 进行初步了解 -请参考[用户指南](https://mmsegmentation.readthedocs.io/zh_CN/1.x/user_guides/index.html)了解 mmseg 的基本使用,以及[进阶指南](https://mmsegmentation.readthedocs.io/zh_CN/1.x/advanced_guides/index.html)深入了解 mmseg 设计和代码实现。 +请参考[用户指南](https://mmsegmentation.readthedocs.io/zh_CN/latest/user_guides/index.html)了解 mmseg 的基本使用,以及[进阶指南](https://mmsegmentation.readthedocs.io/zh_CN/latest/advanced_guides/index.html)深入了解 mmseg 设计和代码实现。 -同时,我们提供了 Colab 教程。你可以在[这里](demo/MMSegmentation_Tutorial.ipynb)浏览教程,或者直接在 Colab 上[运行](https://colab.research.google.com/github/open-mmlab/mmsegmentation/blob/1.x/demo/MMSegmentation_Tutorial.ipynb)。 +同时,我们提供了 Colab 教程。你可以在[这里](demo/MMSegmentation_Tutorial.ipynb)浏览教程,或者直接在 Colab 上[运行](https://colab.research.google.com/github/open-mmlab/mmsegmentation/blob/main/demo/MMSegmentation_Tutorial.ipynb)。 -若需要将0.x版本的代码迁移至新版,请参考[迁移文档](docs/zh_cn/migration)。 +若需要将 0.x 版本的代码迁移至新版,请参考[迁移文档](docs/zh_cn/migration)。 + +## 教程文档 + +
+开启 MMSeg 之旅 + +- [MMSeg 概述](docs/zh_cn/overview.md) +- [安装和验证](docs/zh_cn/get_started.md) +- [常见问题解答](docs/zh_cn/notes/faq.md) + +
+ +
+MMSeg 快速入门教程 + +- [教程1:了解配置文件](docs/zh_cn/user_guides/1_config.md) +- [教程2:准备数据集](docs/zh_cn/user_guides/2_dataset_prepare.md) +- [教程3:使用预训练模型推理](docs/zh_cn/user_guides/3_inference.md) +- [教程4:使用现有模型进行训练和测试](docs/zh_cn/user_guides/4_train_test.md) +- [教程5:模型部署](docs/zh_cn/user_guides/5_deployment.md) +- [常用工具](docs/zh_cn/user_guides/useful_tools.md) +- [特征图可视化](docs/zh_cn/user_guides/visualization_feature_map.md) +- [可视化](docs/zh_cn/user_guides/visualization.md) + +
+ +
+MMSeg 细节介绍 + +- [MMSeg 数据集介绍](docs/zh_cn/advanced_guides/datasets.md) +- [MMSeg 模型介绍](docs/zh_cn/advanced_guides/models.md) +- [MMSeg 数据结构介绍](docs/zh_cn/advanced_guides/structures.md) +- [MMSeg 数据增强介绍](docs/zh_cn/advanced_guides/transforms.md) +- [MMSeg 数据流介绍](docs/zh_cn/advanced_guides/data_flow.md) +- [MMSeg 训练引擎介绍](docs/zh_cn/advanced_guides/engine.md) +- [MMSeg 模型评测介绍](docs/zh_cn/advanced_guides/evaluation.md) + +
+ +
+MMSeg 开发教程 + +- [新增自定义数据集](docs/zh_cn/advanced_guides/add_datasets.md) +- [新增评测指标](docs/zh_cn/advanced_guides/add_metrics.md) +- [新增自定义模型](docs/zh_cn/advanced_guides/add_models.md) +- [新增自定义数据增强](docs/zh_cn/advanced_guides/add_transforms.md) +- [自定义运行设定](docs/zh_cn/advanced_guides/customize_runtime.md) +- [训练技巧](docs/zh_cn/advanced_guides/training_tricks.md) +- [如何给 MMSeg贡献代码](.github/CONTRIBUTING.md) +- [在 projects 给 MMSeg 贡献一个标准数据集](docs/zh_cn/advanced_guides/contribute_dataset.md) +- [NPU (华为 昇腾)](docs/zh_cn/device/npu.md) +- [0.x → 1.x 迁移文档](docs/zh_cn/migration/interface.md),[0.x → 1.x 库变更文档](docs/zh_cn/migration/package.md) + +
## 基准测试和模型库 @@ -142,29 +223,34 @@ MMSegmentation 是一个基于 PyTorch 的语义分割开源工具箱。它是 O - [x] [MaskFormer (NeurIPS'2021)](configs/maskformer) - [x] [Mask2Former (CVPR'2022)](configs/mask2former) - [x] [PIDNet (ArXiv'2022)](configs/pidnet) +- [x] [DDRNet (T-ITS'2022)](configs/ddrnet) +- [x] [VPD (ICCV'2023)](configs/vpd)
已支持的数据集: -- [x] [Cityscapes](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#cityscapes) -- [x] [PASCAL VOC](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#pascal-voc) -- [x] [ADE20K](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#ade20k) -- [x] [Pascal Context](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#pascal-context) -- [x] [COCO-Stuff 10k](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#coco-stuff-10k) -- [x] [COCO-Stuff 164k](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#coco-stuff-164k) -- [x] [CHASE_DB1](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#chase-db1) -- [x] [DRIVE](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#drive) -- [x] [HRF](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#hrf) -- [x] [STARE](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#stare) -- [x] [Dark Zurich](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#dark-zurich) -- [x] [Nighttime Driving](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#nighttime-driving) -- [x] [LoveDA](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#loveda) -- [x] [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#isprs-potsdam) -- [x] [Vaihingen](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#isprs-vaihingen) -- [x] [iSAID](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/zh_cn/dataset_prepare.md#isaid) -- [x] [Mapillary Vistas](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#mapillary-vistas-datasets) +- [x] [Cityscapes](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#cityscapes) +- [x] [PASCAL VOC](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#pascal-voc) +- [x] [ADE20K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#ade20k) +- [x] [Pascal Context](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#pascal-context) +- [x] [COCO-Stuff 10k](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#coco-stuff-10k) +- [x] [COCO-Stuff 164k](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#coco-stuff-164k) +- [x] [CHASE_DB1](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#chase-db1) +- [x] [DRIVE](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#drive) +- [x] [HRF](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#hrf) +- [x] [STARE](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#stare) +- [x] [Dark Zurich](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#dark-zurich) +- [x] [Nighttime Driving](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#nighttime-driving) +- [x] [LoveDA](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#loveda) +- [x] [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#isprs-potsdam) +- [x] [Vaihingen](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#isprs-vaihingen) +- [x] [iSAID](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#isaid) +- [x] [Mapillary Vistas](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#mapillary-vistas-datasets) +- [x] [LEVIR-CD](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#levir-cd) +- [x] [BDD100K](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/user_guides/2_dataset_prepare.md#bdd100K) +- [x] [NYU](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md#nyu)
@@ -202,36 +288,34 @@ MMSegmentation 是一个由来自不同高校和企业的研发人员共同参 ## OpenMMLab 的其他项目 -- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab 深度学习模型训练库 +- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab 深度学习模型训练基础库 - [MMCV](https://github.com/open-mmlab/mmcv): OpenMMLab 计算机视觉基础库 -- [MIM](https://github.com/open-mmlab/mim): MIM 是 OpenMMlab 项目、算法、模型的统一入口 -- [MMEval](https://github.com/open-mmlab/mmeval): 统一开放的跨框架算法评测库 -- [MMClassification](https://github.com/open-mmlab/mmclassification): OpenMMLab 图像分类工具箱 +- [MMPreTrain](https://github.com/open-mmlab/mmpretrain): OpenMMLab 深度学习预训练工具箱 +- [MMagic](https://github.com/open-mmlab/mmagic): OpenMMLab 新一代人工智能内容生成(AIGC)工具箱 - [MMDetection](https://github.com/open-mmlab/mmdetection): OpenMMLab 目标检测工具箱 +- [MMYOLO](https://github.com/open-mmlab/mmyolo): OpenMMLab YOLO 系列工具箱与测试基准 - [MMDetection3D](https://github.com/open-mmlab/mmdetection3d): OpenMMLab 新一代通用 3D 目标检测平台 - [MMRotate](https://github.com/open-mmlab/mmrotate): OpenMMLab 旋转框检测工具箱与测试基准 -- [MMYOLO](https://github.com/open-mmlab/mmyolo): OpenMMLab YOLO 系列工具箱与测试基准 +- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab 一体化视频目标感知平台 - [MMSegmentation](https://github.com/open-mmlab/mmsegmentation): OpenMMLab 语义分割工具箱 - [MMOCR](https://github.com/open-mmlab/mmocr): OpenMMLab 全流程文字检测识别理解工具包 - [MMPose](https://github.com/open-mmlab/mmpose): OpenMMLab 姿态估计工具箱 - [MMHuman3D](https://github.com/open-mmlab/mmhuman3d): OpenMMLab 人体参数化模型工具箱与测试基准 -- [MMSelfSup](https://github.com/open-mmlab/mmselfsup): OpenMMLab 自监督学习工具箱与测试基准 -- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab 模型压缩工具箱与测试基准 - [MMFewShot](https://github.com/open-mmlab/mmfewshot): OpenMMLab 少样本学习工具箱与测试基准 - [MMAction2](https://github.com/open-mmlab/mmaction2): OpenMMLab 新一代视频理解工具箱 -- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab 一体化视频目标感知平台 - [MMFlow](https://github.com/open-mmlab/mmflow): OpenMMLab 光流估计工具箱与测试基准 -- [MMEditing](https://github.com/open-mmlab/mmediting): OpenMMLab 图像视频编辑工具箱 -- [MMGeneration](https://github.com/open-mmlab/mmgeneration): OpenMMLab 图片视频生成模型工具箱 - [MMDeploy](https://github.com/open-mmlab/mmdeploy): OpenMMLab 模型部署框架 +- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab 模型压缩工具箱与测试基准 +- [MIM](https://github.com/open-mmlab/mim): OpenMMLab 项目、算法、模型的统一入口 +- [Playground](https://github.com/open-mmlab/playground): 收集和展示 OpenMMLab 相关的前沿、有趣的社区项目 ## 欢迎加入 OpenMMLab 社区 -扫描下方的二维码可关注 OpenMMLab 团队的 [知乎官方账号](https://www.zhihu.com/people/openmmlab),加入 [OpenMMLab 团队](https://jq.qq.com/?_wv=1027&k=aCvMxdr3) 以及 [MMSegmentation](https://jq.qq.com/?_wv=1027&k=ukevz6Ie) 的 QQ 群。 +扫描下方的二维码可关注 OpenMMLab 团队的 [知乎官方账号](https://www.zhihu.com/people/openmmlab),扫描下方微信二维码添加喵喵好友,进入 MMSegmentation 微信交流社群。【加好友申请格式:研究方向+地区+学校/公司+姓名】
- -
+ + 我们会在 OpenMMLab 社区为大家 diff --git a/configs/_base_/datasets/bdd100k.py b/configs/_base_/datasets/bdd100k.py new file mode 100644 index 00000000000..24cec69bfeb --- /dev/null +++ b/configs/_base_/datasets/bdd100k.py @@ -0,0 +1,70 @@ +# dataset settings +dataset_type = 'BDD100KDataset' +data_root = 'data/bdd100k/' + +crop_size = (512, 1024) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict( + type='RandomResize', + scale=(2048, 1024), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 1024), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=2, + num_workers=2, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/10k/train', + seg_map_path='labels/sem_seg/masks/train'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/10k/val', + seg_map_path='labels/sem_seg/masks/val'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/configs/_base_/datasets/coco-stuff164k.py b/configs/_base_/datasets/coco-stuff164k.py index baf633f9d6f..a9b9d90117a 100644 --- a/configs/_base_/datasets/coco-stuff164k.py +++ b/configs/_base_/datasets/coco-stuff164k.py @@ -48,7 +48,7 @@ type=dataset_type, data_root=data_root, data_prefix=dict( - img_path='images/train2017', seg_map_path='annotations/val2017'), + img_path='images/train2017', seg_map_path='annotations/train2017'), pipeline=train_pipeline)) val_dataloader = dict( batch_size=1, diff --git a/configs/_base_/datasets/levir_256x256.py b/configs/_base_/datasets/levir_256x256.py new file mode 100644 index 00000000000..a2a69aa9e9c --- /dev/null +++ b/configs/_base_/datasets/levir_256x256.py @@ -0,0 +1,59 @@ +# dataset settings +dataset_type = 'LEVIRCDDataset' +data_root = r'data/LEVIRCD' + +albu_train_transforms = [ + dict(type='RandomBrightnessContrast', p=0.2), + dict(type='HorizontalFlip', p=0.5), + dict(type='VerticalFlip', p=0.5) +] + +train_pipeline = [ + dict(type='LoadMultipleRSImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Albu', transforms=albu_train_transforms), + dict(type='ConcatCDInput'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadMultipleRSImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='ConcatCDInput'), + dict(type='PackSegInputs') +] + +tta_pipeline = [ + dict(type='LoadMultipleRSImageFromFile'), + dict( + type='TestTimeAug', + transforms=[[dict(type='LoadAnnotations')], + [dict(type='ConcatCDInput')], + [dict(type='PackSegInputs')]]) +] +train_dataloader = dict( + batch_size=4, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='train/A', + img_path2='train/B', + seg_map_path='train/label'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='test/A', img_path2='test/B', seg_map_path='test/label'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/configs/_base_/datasets/nyu.py b/configs/_base_/datasets/nyu.py new file mode 100644 index 00000000000..74d57c5fc50 --- /dev/null +++ b/configs/_base_/datasets/nyu.py @@ -0,0 +1,67 @@ +# dataset settings +dataset_type = 'NYUDataset' +data_root = 'data/nyu' + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadDepthAnnotation', depth_rescale_factor=1e-3), + dict(type='RandomDepthMix', prob=0.25), + dict(type='RandomFlip', prob=0.5), + dict(type='RandomCrop', crop_size=(480, 480)), + dict( + type='Albu', + transforms=[ + dict(type='RandomBrightnessContrast'), + dict(type='RandomGamma'), + dict(type='HueSaturationValue'), + ]), + dict( + type='PackSegInputs', + meta_keys=('img_path', 'depth_map_path', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'category_id')), +] + +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2000, 480), keep_ratio=True), + dict(dict(type='LoadDepthAnnotation', depth_rescale_factor=1e-3)), + dict( + type='PackSegInputs', + meta_keys=('img_path', 'depth_map_path', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'category_id')) +] + +train_dataloader = dict( + batch_size=8, + num_workers=8, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/train', depth_map_path='annotations/train'), + pipeline=train_pipeline)) + +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + test_mode=True, + data_prefix=dict( + img_path='images/test', depth_map_path='annotations/test'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict( + type='DepthMetric', + min_depth_eval=0.001, + max_depth_eval=10.0, + crop_type='nyu_crop') +test_evaluator = val_evaluator diff --git a/configs/_base_/datasets/nyu_512x512.py b/configs/_base_/datasets/nyu_512x512.py new file mode 100644 index 00000000000..88e3878d334 --- /dev/null +++ b/configs/_base_/datasets/nyu_512x512.py @@ -0,0 +1,72 @@ +# dataset settings +dataset_type = 'NYUDataset' +data_root = 'data/nyu' + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadDepthAnnotation', depth_rescale_factor=1e-3), + dict(type='RandomDepthMix', prob=0.25), + dict(type='RandomFlip', prob=0.5), + dict( + type='RandomResize', + scale=(768, 512), + ratio_range=(0.8, 1.5), + keep_ratio=True), + dict(type='RandomCrop', crop_size=(512, 512)), + dict( + type='Albu', + transforms=[ + dict(type='RandomBrightnessContrast'), + dict(type='RandomGamma'), + dict(type='HueSaturationValue'), + ]), + dict( + type='PackSegInputs', + meta_keys=('img_path', 'depth_map_path', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'category_id')), +] + +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + dict(dict(type='LoadDepthAnnotation', depth_rescale_factor=1e-3)), + dict( + type='PackSegInputs', + meta_keys=('img_path', 'depth_map_path', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'category_id')) +] + +train_dataloader = dict( + batch_size=8, + num_workers=8, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/train', depth_map_path='annotations/train'), + pipeline=train_pipeline)) + +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + test_mode=True, + data_prefix=dict( + img_path='images/test', depth_map_path='annotations/test'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict( + type='DepthMetric', + min_depth_eval=0.001, + max_depth_eval=10.0, + crop_type='nyu_crop') +test_evaluator = val_evaluator diff --git a/configs/_base_/models/fpn_poolformer_s12.py b/configs/_base_/models/fpn_poolformer_s12.py index b6893f69774..086c804837a 100644 --- a/configs/_base_/models/fpn_poolformer_s12.py +++ b/configs/_base_/models/fpn_poolformer_s12.py @@ -1,10 +1,11 @@ # model settings norm_cfg = dict(type='SyncBN', requires_grad=True) checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/poolformer/poolformer-s12_3rdparty_32xb128_in1k_20220414-f8d83051.pth' # noqa -# TODO: delete custom_imports after mmcls supports auto import -# please install mmcls>=1.0 -# import mmcls.models to trigger register_module in mmcls -custom_imports = dict(imports=['mmcls.models'], allow_failed_imports=False) +# TODO: delete custom_imports after mmpretrain supports auto import +# please install mmpretrain >= 1.0.0rc7 +# import mmpretrain.models to trigger register_module in mmpretrain +custom_imports = dict( + imports=['mmpretrain.models'], allow_failed_imports=False) data_preprocessor = dict( type='SegDataPreProcessor', mean=[123.675, 116.28, 103.53], @@ -16,7 +17,7 @@ type='EncoderDecoder', data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.PoolFormer', + type='mmpretrain.PoolFormer', arch='s12', init_cfg=dict( type='Pretrained', checkpoint=checkpoint_file, prefix='backbone.'), diff --git a/configs/_base_/models/san_vit-b16.py b/configs/_base_/models/san_vit-b16.py new file mode 100644 index 00000000000..96ac41b8dad --- /dev/null +++ b/configs/_base_/models/san_vit-b16.py @@ -0,0 +1,137 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) + +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[122.7709, 116.7460, 104.0937], + std=[68.5005, 66.6322, 70.3232], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255, + size_divisor=640, + test_cfg=dict(size_divisor=32)) + +num_classes = 171 +model = dict( + type='MultimodalEncoderDecoder', + data_preprocessor=data_preprocessor, + pretrained='pretrain/clip_vit_base_patch16_224.pth', + asymetric_input=True, + encoder_resolution=0.5, + image_encoder=dict( + type='VisionTransformer', + img_size=(224, 224), + patch_size=16, + patch_pad=0, + in_channels=3, + embed_dims=768, + num_layers=9, + num_heads=12, + mlp_ratio=4, + out_origin=True, + out_indices=(2, 5, 8), + qkv_bias=True, + drop_rate=0.0, + attn_drop_rate=0.0, + drop_path_rate=0.0, + with_cls_token=True, + output_cls_token=True, + patch_bias=False, + pre_norm=True, + norm_cfg=dict(type='LN', eps=1e-5), + act_cfg=dict(type='QuickGELU'), + norm_eval=False, + interpolate_mode='bicubic', + frozen_exclude=['pos_embed']), + text_encoder=dict( + type='CLIPTextEncoder', + dataset_name=None, + templates='vild', + embed_dims=512, + num_layers=12, + num_heads=8, + mlp_ratio=4, + output_dims=512, + cache_feature=True, + cat_bg=True, + norm_cfg=dict(type='LN', eps=1e-5) + ), + decode_head=dict( + type='SideAdapterCLIPHead', + num_classes=num_classes, + deep_supervision_idxs=[7], + san_cfg=dict( + in_channels=3, + clip_channels=768, + embed_dims=240, + patch_size=16, + patch_bias=True, + num_queries=100, + cfg_encoder=dict( + num_encode_layer=8, + num_heads=6, + mlp_ratio=4 + ), + fusion_index=[0, 1, 2, 3], + cfg_decoder=dict( + num_heads=12, + num_layers=1, + embed_channels=256, + mlp_channels=256, + num_mlp=3, + rescale=True), + norm_cfg=dict(type='LN', eps=1e-6), + ), + maskgen_cfg=dict( + sos_token_format='cls_token', + sos_token_num=100, + cross_attn=False, + num_layers=3, + embed_dims=768, + num_heads=12, + mlp_ratio=4, + qkv_bias=True, + out_dims=512, + final_norm=True, + act_cfg=dict(type='QuickGELU'), + norm_cfg=dict(type='LN', eps=1e-5), + frozen_exclude=[] + ), + align_corners=False, + train_cfg=dict( + num_points=12544, + oversample_ratio=3.0, + importance_sample_ratio=0.75, + assigner=dict( + type='HungarianAssigner', + match_costs=[ + dict(type='ClassificationCost', weight=2.0), + dict( + type='CrossEntropyLossCost', + weight=5.0, + use_sigmoid=True), + dict( + type='DiceCost', + weight=5.0, + pred_act=True, + eps=1.0) + ])), + loss_decode=[dict(type='CrossEntropyLoss', + loss_name='loss_cls_ce', + loss_weight=2.0, + class_weight=[1.0] * num_classes + [0.1]), + dict(type='CrossEntropyLoss', + use_sigmoid=True, + loss_name='loss_mask_ce', + loss_weight=5.0), + dict(type='DiceLoss', + ignore_index=None, + naive_dice=True, + eps=1, + loss_name='loss_mask_dice', + loss_weight=5.0) + ]), + + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) # yapf: disable diff --git a/configs/_base_/models/upernet_convnext.py b/configs/_base_/models/upernet_convnext.py index 7595295871d..958994c91e6 100644 --- a/configs/_base_/models/upernet_convnext.py +++ b/configs/_base_/models/upernet_convnext.py @@ -1,5 +1,5 @@ norm_cfg = dict(type='SyncBN', requires_grad=True) -custom_imports = dict(imports='mmcls.models', allow_failed_imports=False) +custom_imports = dict(imports='mmpretrain.models', allow_failed_imports=False) checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/convnext/downstream/convnext-base_3rdparty_32xb128-noema_in1k_20220301-2a0ee547.pth' # noqa data_preprocessor = dict( type='SegDataPreProcessor', @@ -13,7 +13,7 @@ data_preprocessor=data_preprocessor, pretrained=None, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='base', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, diff --git a/configs/_base_/models/vpd_sd.py b/configs/_base_/models/vpd_sd.py new file mode 100644 index 00000000000..87321e74f04 --- /dev/null +++ b/configs/_base_/models/vpd_sd.py @@ -0,0 +1,86 @@ +# model settings +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[127.5, 127.5, 127.5], + std=[127.5, 127.5, 127.5], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=0) + +# adapted from stable-diffusion/configs/stable-diffusion/v1-inference.yaml +stable_diffusion_cfg = dict( + base_learning_rate=0.0001, + target='ldm.models.diffusion.ddpm.LatentDiffusion', + checkpoint='https://download.openmmlab.com/mmsegmentation/v0.5/' + 'vpd/stable_diffusion_v1-5_pretrain_third_party.pth', + params=dict( + linear_start=0.00085, + linear_end=0.012, + num_timesteps_cond=1, + log_every_t=200, + timesteps=1000, + first_stage_key='jpg', + cond_stage_key='txt', + image_size=64, + channels=4, + cond_stage_trainable=False, + conditioning_key='crossattn', + monitor='val/loss_simple_ema', + scale_factor=0.18215, + use_ema=False, + scheduler_config=dict( + target='ldm.lr_scheduler.LambdaLinearScheduler', + params=dict( + warm_up_steps=[10000], + cycle_lengths=[10000000000000], + f_start=[1e-06], + f_max=[1.0], + f_min=[1.0])), + unet_config=dict( + target='ldm.modules.diffusionmodules.openaimodel.UNetModel', + params=dict( + image_size=32, + in_channels=4, + out_channels=4, + model_channels=320, + attention_resolutions=[4, 2, 1], + num_res_blocks=2, + channel_mult=[1, 2, 4, 4], + num_heads=8, + use_spatial_transformer=True, + transformer_depth=1, + context_dim=768, + use_checkpoint=True, + legacy=False)), + first_stage_config=dict( + target='ldm.models.autoencoder.AutoencoderKL', + params=dict( + embed_dim=4, + monitor='val/rec_loss', + ddconfig=dict( + double_z=True, + z_channels=4, + resolution=256, + in_channels=3, + out_ch=3, + ch=128, + ch_mult=[1, 2, 4, 4], + num_res_blocks=2, + attn_resolutions=[], + dropout=0.0), + lossconfig=dict(target='torch.nn.Identity'))), + cond_stage_config=dict( + target='ldm.modules.encoders.modules.AbstractEncoder'))) + +model = dict( + type='DepthEstimator', + data_preprocessor=data_preprocessor, + backbone=dict( + type='VPD', + diffusion_cfg=stable_diffusion_cfg, + ), +) + +# some of the parameters in stable-diffusion model will not be updated +# during training +find_unused_parameters = True diff --git a/configs/_base_/schedules/schedule_25k.py b/configs/_base_/schedules/schedule_25k.py new file mode 100644 index 00000000000..825e141ed12 --- /dev/null +++ b/configs/_base_/schedules/schedule_25k.py @@ -0,0 +1,28 @@ +# optimizer +optimizer = dict(type='AdamW', lr=0.001, weight_decay=0.1) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='LinearLR', start_factor=3e-2, begin=0, end=12000, + by_epoch=False), + dict( + type='PolyLRRatio', + eta_min_ratio=3e-2, + power=0.9, + begin=12000, + end=24000, + by_epoch=False), + dict(type='ConstantLR', by_epoch=False, factor=1, begin=24000, end=25000) +] +# training schedule for 25k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=25000, val_interval=1000) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=2000), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) diff --git a/configs/ann/README.md b/configs/ann/README.md index cbc1be2dc15..1281a9ee14f 100644 --- a/configs/ann/README.md +++ b/configs/ann/README.md @@ -26,34 +26,34 @@ The non-local module works as a particularly useful technique for semantic segme ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ANN | R-50-D8 | 512x1024 | 40000 | 6 | 3.71 | V100 | 77.40 | 78.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_40k_cityscapes/ann_r50-d8_512x1024_40k_cityscapes_20200605_095211-049fc292.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_40k_cityscapes/ann_r50-d8_512x1024_40k_cityscapes_20200605_095211.log.json) | -| ANN | R-101-D8 | 512x1024 | 40000 | 9.5 | 2.55 | V100 | 76.55 | 78.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_40k_cityscapes/ann_r101-d8_512x1024_40k_cityscapes_20200605_095243-adf6eece.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_40k_cityscapes/ann_r101-d8_512x1024_40k_cityscapes_20200605_095243.log.json) | -| ANN | R-50-D8 | 769x769 | 40000 | 6.8 | 1.70 | V100 | 78.89 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_40k_cityscapes/ann_r50-d8_769x769_40k_cityscapes_20200530_025712-2b46b04d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_40k_cityscapes/ann_r50-d8_769x769_40k_cityscapes_20200530_025712.log.json) | -| ANN | R-101-D8 | 769x769 | 40000 | 10.7 | 1.15 | V100 | 79.32 | 80.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_40k_cityscapes/ann_r101-d8_769x769_40k_cityscapes_20200530_025720-059bff28.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_40k_cityscapes/ann_r101-d8_769x769_40k_cityscapes_20200530_025720.log.json) | -| ANN | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.34 | 78.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_80k_cityscapes/ann_r50-d8_512x1024_80k_cityscapes_20200607_101911-5a9ad545.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_80k_cityscapes/ann_r50-d8_512x1024_80k_cityscapes_20200607_101911.log.json) | -| ANN | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 77.14 | 78.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_80k_cityscapes/ann_r101-d8_512x1024_80k_cityscapes_20200607_013728-aceccc6e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_80k_cityscapes/ann_r101-d8_512x1024_80k_cityscapes_20200607_013728.log.json) | -| ANN | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.88 | 80.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_80k_cityscapes/ann_r50-d8_769x769_80k_cityscapes_20200607_044426-cc7ff323.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_80k_cityscapes/ann_r50-d8_769x769_80k_cityscapes_20200607_044426.log.json) | -| ANN | R-101-D8 | 769x769 | 80000 | - | - | V100 | 78.80 | 80.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_80k_cityscapes/ann_r101-d8_769x769_80k_cityscapes_20200607_013713-a9d4be8d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_80k_cityscapes/ann_r101-d8_769x769_80k_cityscapes_20200607_013713.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ANN | R-50-D8 | 512x1024 | 40000 | 6 | 3.71 | V100 | 77.40 | 78.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_40k_cityscapes/ann_r50-d8_512x1024_40k_cityscapes_20200605_095211-049fc292.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_40k_cityscapes/ann_r50-d8_512x1024_40k_cityscapes_20200605_095211.log.json) | +| ANN | R-101-D8 | 512x1024 | 40000 | 9.5 | 2.55 | V100 | 76.55 | 78.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_40k_cityscapes/ann_r101-d8_512x1024_40k_cityscapes_20200605_095243-adf6eece.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_40k_cityscapes/ann_r101-d8_512x1024_40k_cityscapes_20200605_095243.log.json) | +| ANN | R-50-D8 | 769x769 | 40000 | 6.8 | 1.70 | V100 | 78.89 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_40k_cityscapes/ann_r50-d8_769x769_40k_cityscapes_20200530_025712-2b46b04d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_40k_cityscapes/ann_r50-d8_769x769_40k_cityscapes_20200530_025712.log.json) | +| ANN | R-101-D8 | 769x769 | 40000 | 10.7 | 1.15 | V100 | 79.32 | 80.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_40k_cityscapes/ann_r101-d8_769x769_40k_cityscapes_20200530_025720-059bff28.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_40k_cityscapes/ann_r101-d8_769x769_40k_cityscapes_20200530_025720.log.json) | +| ANN | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.34 | 78.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_80k_cityscapes/ann_r50-d8_512x1024_80k_cityscapes_20200607_101911-5a9ad545.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x1024_80k_cityscapes/ann_r50-d8_512x1024_80k_cityscapes_20200607_101911.log.json) | +| ANN | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 77.14 | 78.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_80k_cityscapes/ann_r101-d8_512x1024_80k_cityscapes_20200607_013728-aceccc6e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x1024_80k_cityscapes/ann_r101-d8_512x1024_80k_cityscapes_20200607_013728.log.json) | +| ANN | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.88 | 80.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_80k_cityscapes/ann_r50-d8_769x769_80k_cityscapes_20200607_044426-cc7ff323.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_769x769_80k_cityscapes/ann_r50-d8_769x769_80k_cityscapes_20200607_044426.log.json) | +| ANN | R-101-D8 | 769x769 | 80000 | - | - | V100 | 78.80 | 80.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_80k_cityscapes/ann_r101-d8_769x769_80k_cityscapes_20200607_013713-a9d4be8d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_769x769_80k_cityscapes/ann_r101-d8_769x769_80k_cityscapes_20200607_013713.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ANN | R-50-D8 | 512x512 | 80000 | 9.1 | 21.01 | V100 | 41.01 | 42.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_80k_ade20k/ann_r50-d8_512x512_80k_ade20k_20200615_014818-26f75e11.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_80k_ade20k/ann_r50-d8_512x512_80k_ade20k_20200615_014818.log.json) | -| ANN | R-101-D8 | 512x512 | 80000 | 12.5 | 14.12 | V100 | 42.94 | 44.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_80k_ade20k/ann_r101-d8_512x512_80k_ade20k_20200615_014818-c0153543.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_80k_ade20k/ann_r101-d8_512x512_80k_ade20k_20200615_014818.log.json) | -| ANN | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.74 | 42.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_160k_ade20k/ann_r50-d8_512x512_160k_ade20k_20200615_231733-892247bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_160k_ade20k/ann_r50-d8_512x512_160k_ade20k_20200615_231733.log.json) | -| ANN | R-101-D8 | 512x512 | 160000 | - | - | V100 | 42.94 | 44.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_160k_ade20k/ann_r101-d8_512x512_160k_ade20k_20200615_231733-955eb1ec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_160k_ade20k/ann_r101-d8_512x512_160k_ade20k_20200615_231733.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ANN | R-50-D8 | 512x512 | 80000 | 9.1 | 21.01 | V100 | 41.01 | 42.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_80k_ade20k/ann_r50-d8_512x512_80k_ade20k_20200615_014818-26f75e11.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_80k_ade20k/ann_r50-d8_512x512_80k_ade20k_20200615_014818.log.json) | +| ANN | R-101-D8 | 512x512 | 80000 | 12.5 | 14.12 | V100 | 42.94 | 44.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_80k_ade20k/ann_r101-d8_512x512_80k_ade20k_20200615_014818-c0153543.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_80k_ade20k/ann_r101-d8_512x512_80k_ade20k_20200615_014818.log.json) | +| ANN | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.74 | 42.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_160k_ade20k/ann_r50-d8_512x512_160k_ade20k_20200615_231733-892247bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_160k_ade20k/ann_r50-d8_512x512_160k_ade20k_20200615_231733.log.json) | +| ANN | R-101-D8 | 512x512 | 160000 | - | - | V100 | 42.94 | 44.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_160k_ade20k/ann_r101-d8_512x512_160k_ade20k_20200615_231733-955eb1ec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_160k_ade20k/ann_r101-d8_512x512_160k_ade20k_20200615_231733.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ANN | R-50-D8 | 512x512 | 20000 | 6 | 20.92 | V100 | 74.86 | 76.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_20k_voc12aug/ann_r50-d8_512x512_20k_voc12aug_20200617_222246-dfcb1c62.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_20k_voc12aug/ann_r50-d8_512x512_20k_voc12aug_20200617_222246.log.json) | -| ANN | R-101-D8 | 512x512 | 20000 | 9.5 | 13.94 | V100 | 77.47 | 78.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_20k_voc12aug/ann_r101-d8_512x512_20k_voc12aug_20200617_222246-2fad0042.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_20k_voc12aug/ann_r101-d8_512x512_20k_voc12aug_20200617_222246.log.json) | -| ANN | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.56 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_40k_voc12aug/ann_r50-d8_512x512_40k_voc12aug_20200613_231314-b5dac322.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_40k_voc12aug/ann_r50-d8_512x512_40k_voc12aug_20200613_231314.log.json) | -| ANN | R-101-D8 | 512x512 | 40000 | - | - | V100 | 76.70 | 78.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ann/ann_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_40k_voc12aug/ann_r101-d8_512x512_40k_voc12aug_20200613_231314-bd205bbe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_40k_voc12aug/ann_r101-d8_512x512_40k_voc12aug_20200613_231314.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ANN | R-50-D8 | 512x512 | 20000 | 6 | 20.92 | V100 | 74.86 | 76.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_20k_voc12aug/ann_r50-d8_512x512_20k_voc12aug_20200617_222246-dfcb1c62.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_20k_voc12aug/ann_r50-d8_512x512_20k_voc12aug_20200617_222246.log.json) | +| ANN | R-101-D8 | 512x512 | 20000 | 9.5 | 13.94 | V100 | 77.47 | 78.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_20k_voc12aug/ann_r101-d8_512x512_20k_voc12aug_20200617_222246-2fad0042.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_20k_voc12aug/ann_r101-d8_512x512_20k_voc12aug_20200617_222246.log.json) | +| ANN | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.56 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_40k_voc12aug/ann_r50-d8_512x512_40k_voc12aug_20200613_231314-b5dac322.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r50-d8_512x512_40k_voc12aug/ann_r50-d8_512x512_40k_voc12aug_20200613_231314.log.json) | +| ANN | R-101-D8 | 512x512 | 40000 | - | - | V100 | 76.70 | 78.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann/ann_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_40k_voc12aug/ann_r101-d8_512x512_40k_voc12aug_20200613_231314-bd205bbe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ann/ann_r101-d8_512x512_40k_voc12aug/ann_r101-d8_512x512_40k_voc12aug_20200613_231314.log.json) | ## Citation diff --git a/configs/apcnet/README.md b/configs/apcnet/README.md index 0d7f1d66149..9104f3c87f5 100644 --- a/configs/apcnet/README.md +++ b/configs/apcnet/README.md @@ -26,25 +26,25 @@ Recent studies witnessed that context features can significantly improve the per ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| APCNet | R-50-D8 | 512x1024 | 40000 | 7.7 | 3.57 | V100 | 78.02 | 79.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_40k_cityscapes/apcnet_r50-d8_512x1024_40k_cityscapes_20201214_115717-5e88fa33.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_40k_cityscapes/apcnet_r50-d8_512x1024_40k_cityscapes-20201214_115717.log.json) | -| APCNet | R-101-D8 | 512x1024 | 40000 | 11.2 | 2.15 | V100 | 79.08 | 80.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_40k_cityscapes/apcnet_r101-d8_512x1024_40k_cityscapes_20201214_115716-abc9d111.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_40k_cityscapes/apcnet_r101-d8_512x1024_40k_cityscapes-20201214_115716.log.json) | -| APCNet | R-50-D8 | 769x769 | 40000 | 8.7 | 1.52 | V100 | 77.89 | 79.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_40k_cityscapes/apcnet_r50-d8_769x769_40k_cityscapes_20201214_115717-2a2628d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_40k_cityscapes/apcnet_r50-d8_769x769_40k_cityscapes-20201214_115717.log.json) | -| APCNet | R-101-D8 | 769x769 | 40000 | 12.7 | 1.03 | V100 | 77.96 | 79.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_40k_cityscapes/apcnet_r101-d8_769x769_40k_cityscapes_20201214_115718-b650de90.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_40k_cityscapes/apcnet_r101-d8_769x769_40k_cityscapes-20201214_115718.log.json) | -| APCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.96 | 79.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_80k_cityscapes/apcnet_r50-d8_512x1024_80k_cityscapes_20201214_115716-987f51e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_80k_cityscapes/apcnet_r50-d8_512x1024_80k_cityscapes-20201214_115716.log.json) | -| APCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.64 | 80.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_80k_cityscapes/apcnet_r101-d8_512x1024_80k_cityscapes_20201214_115705-b1ff208a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_80k_cityscapes/apcnet_r101-d8_512x1024_80k_cityscapes-20201214_115705.log.json) | -| APCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.79 | 80.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_80k_cityscapes/apcnet_r50-d8_769x769_80k_cityscapes_20201214_115718-7ea9fa12.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_80k_cityscapes/apcnet_r50-d8_769x769_80k_cityscapes-20201214_115718.log.json) | -| APCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 78.45 | 79.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_80k_cityscapes/apcnet_r101-d8_769x769_80k_cityscapes_20201214_115716-a7fbc2ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_80k_cityscapes/apcnet_r101-d8_769x769_80k_cityscapes-20201214_115716.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| APCNet | R-50-D8 | 512x1024 | 40000 | 7.7 | 3.57 | V100 | 78.02 | 79.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_40k_cityscapes/apcnet_r50-d8_512x1024_40k_cityscapes_20201214_115717-5e88fa33.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_40k_cityscapes/apcnet_r50-d8_512x1024_40k_cityscapes-20201214_115717.log.json) | +| APCNet | R-101-D8 | 512x1024 | 40000 | 11.2 | 2.15 | V100 | 79.08 | 80.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_40k_cityscapes/apcnet_r101-d8_512x1024_40k_cityscapes_20201214_115716-abc9d111.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_40k_cityscapes/apcnet_r101-d8_512x1024_40k_cityscapes-20201214_115716.log.json) | +| APCNet | R-50-D8 | 769x769 | 40000 | 8.7 | 1.52 | V100 | 77.89 | 79.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_40k_cityscapes/apcnet_r50-d8_769x769_40k_cityscapes_20201214_115717-2a2628d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_40k_cityscapes/apcnet_r50-d8_769x769_40k_cityscapes-20201214_115717.log.json) | +| APCNet | R-101-D8 | 769x769 | 40000 | 12.7 | 1.03 | V100 | 77.96 | 79.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_40k_cityscapes/apcnet_r101-d8_769x769_40k_cityscapes_20201214_115718-b650de90.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_40k_cityscapes/apcnet_r101-d8_769x769_40k_cityscapes-20201214_115718.log.json) | +| APCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.96 | 79.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_80k_cityscapes/apcnet_r50-d8_512x1024_80k_cityscapes_20201214_115716-987f51e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x1024_80k_cityscapes/apcnet_r50-d8_512x1024_80k_cityscapes-20201214_115716.log.json) | +| APCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.64 | 80.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_80k_cityscapes/apcnet_r101-d8_512x1024_80k_cityscapes_20201214_115705-b1ff208a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x1024_80k_cityscapes/apcnet_r101-d8_512x1024_80k_cityscapes-20201214_115705.log.json) | +| APCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.79 | 80.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_80k_cityscapes/apcnet_r50-d8_769x769_80k_cityscapes_20201214_115718-7ea9fa12.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_769x769_80k_cityscapes/apcnet_r50-d8_769x769_80k_cityscapes-20201214_115718.log.json) | +| APCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 78.45 | 79.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_80k_cityscapes/apcnet_r101-d8_769x769_80k_cityscapes_20201214_115716-a7fbc2ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_769x769_80k_cityscapes/apcnet_r101-d8_769x769_80k_cityscapes-20201214_115716.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| APCNet | R-50-D8 | 512x512 | 80000 | 10.1 | 19.61 | V100 | 42.20 | 43.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_80k_ade20k/apcnet_r50-d8_512x512_80k_ade20k_20201214_115705-a8626293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_80k_ade20k/apcnet_r50-d8_512x512_80k_ade20k-20201214_115705.log.json) | -| APCNet | R-101-D8 | 512x512 | 80000 | 13.6 | 13.10 | V100 | 45.54 | 46.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_80k_ade20k/apcnet_r101-d8_512x512_80k_ade20k_20201214_115704-c656c3fb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_80k_ade20k/apcnet_r101-d8_512x512_80k_ade20k-20201214_115704.log.json) | -| APCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.40 | 43.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_160k_ade20k/apcnet_r50-d8_512x512_160k_ade20k_20201214_115706-25fb92c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_160k_ade20k/apcnet_r50-d8_512x512_160k_ade20k-20201214_115706.log.json) | -| APCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.41 | 46.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/apcnet/apcnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_160k_ade20k/apcnet_r101-d8_512x512_160k_ade20k_20201214_115705-73f9a8d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_160k_ade20k/apcnet_r101-d8_512x512_160k_ade20k-20201214_115705.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| APCNet | R-50-D8 | 512x512 | 80000 | 10.1 | 19.61 | V100 | 42.20 | 43.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_80k_ade20k/apcnet_r50-d8_512x512_80k_ade20k_20201214_115705-a8626293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_80k_ade20k/apcnet_r50-d8_512x512_80k_ade20k-20201214_115705.log.json) | +| APCNet | R-101-D8 | 512x512 | 80000 | 13.6 | 13.10 | V100 | 45.54 | 46.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_80k_ade20k/apcnet_r101-d8_512x512_80k_ade20k_20201214_115704-c656c3fb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_80k_ade20k/apcnet_r101-d8_512x512_80k_ade20k-20201214_115704.log.json) | +| APCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.40 | 43.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_160k_ade20k/apcnet_r50-d8_512x512_160k_ade20k_20201214_115706-25fb92c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r50-d8_512x512_160k_ade20k/apcnet_r50-d8_512x512_160k_ade20k-20201214_115706.log.json) | +| APCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.41 | 46.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet/apcnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_160k_ade20k/apcnet_r101-d8_512x512_160k_ade20k_20201214_115705-73f9a8d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/apcnet/apcnet_r101-d8_512x512_160k_ade20k/apcnet_r101-d8_512x512_160k_ade20k-20201214_115705.log.json) | ## Citation diff --git a/configs/beit/README.md b/configs/beit/README.md index 8e34e294101..b005c88c501 100644 --- a/configs/beit/README.md +++ b/configs/beit/README.md @@ -67,10 +67,10 @@ upernet_beit-large_fp16_8x1_640x640_160k_ade20k-8fc0dd5d.pth $GPUS --eval mIoU ### ADE20K -| Method | Backbone | Crop Size | pretrain | pretrain img size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ------------ | ----------------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | BEiT-B | 640x640 | ImageNet-22K | 224x224 | 16 | 160000 | 15.88 | 2.00 | V100 | 53.08 | 53.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/beit/beit-base_upernet_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-base_8x2_640x640_160k_ade20k/upernet_beit-base_8x2_640x640_160k_ade20k-eead221d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-base_8x2_640x640_160k_ade20k/upernet_beit-base_8x2_640x640_160k_ade20k.log.json) | -| UPerNet | BEiT-L | 640x640 | ImageNet-22K | 224x224 | 8 | 320000 | 22.64 | 0.96 | V100 | 56.33 | 56.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-large_fp16_8x1_640x640_160k_ade20k/upernet_beit-large_fp16_8x1_640x640_160k_ade20k-8fc0dd5d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-large_fp16_8x1_640x640_160k_ade20k/upernet_beit-large_fp16_8x1_640x640_160k_ade20k.log.json) | +| Method | Backbone | Crop Size | pretrain | pretrain img size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ------------ | ----------------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | BEiT-B | 640x640 | ImageNet-22K | 224x224 | 16 | 160000 | 15.88 | 2.00 | V100 | 53.08 | 53.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/beit/beit-base_upernet_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-base_8x2_640x640_160k_ade20k/upernet_beit-base_8x2_640x640_160k_ade20k-eead221d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-base_8x2_640x640_160k_ade20k/upernet_beit-base_8x2_640x640_160k_ade20k.log.json) | +| UPerNet | BEiT-L | 640x640 | ImageNet-22K | 224x224 | 8 | 320000 | 22.64 | 0.96 | V100 | 56.33 | 56.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/beit/beit-large_upernet_8xb1-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-large_fp16_8x1_640x640_160k_ade20k/upernet_beit-large_fp16_8x1_640x640_160k_ade20k-8fc0dd5d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/beit/upernet_beit-large_fp16_8x1_640x640_160k_ade20k/upernet_beit-large_fp16_8x1_640x640_160k_ade20k.log.json) | ## Citation diff --git a/configs/bisenetv1/README.md b/configs/bisenetv1/README.md index c895fdfe63f..a5058957f0c 100644 --- a/configs/bisenetv1/README.md +++ b/configs/bisenetv1/README.md @@ -26,24 +26,24 @@ Semantic segmentation requires both rich spatial information and sizeable recept ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | ---------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| BiSeNetV1 | R-18-D32 (No Pretrain) | 1024x1024 | 160000 | 5.69 | 31.77 | V100 | 74.44 | 77.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r18-d32_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes_20210922_172239-c55e78e2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes_20210922_172239.log.json) | -| BiSeNetV1 | R-18-D32 | 1024x1024 | 160000 | 5.69 | 31.77 | V100 | 74.37 | 76.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210905_220251-8ba80eff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210905_220251.log.json) | -| BiSeNetV1 | R-18-D32 (4x8) | 1024x1024 | 160000 | 11.17 | 31.77 | V100 | 75.16 | 77.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb8-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes_20210905_220322-bb8db75f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes_20210905_220322.log.json) | -| BiSeNetV1 | R-50-D32 (No Pretrain) | 1024x1024 | 160000 | 15.39 | 7.71 | V100 | 76.92 | 78.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r50-d32_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes_20210923_222639-7b28a2a6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes_20210923_222639.log.json) | -| BiSeNetV1 | R-50-D32 | 1024x1024 | 160000 | 15.39 | 7.71 | V100 | 77.68 | 79.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210917_234628-8b304447.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210917_234628.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | ---------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| BiSeNetV1 | R-18-D32 (No Pretrain) | 1024x1024 | 160000 | 5.69 | 31.77 | V100 | 74.44 | 77.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r18-d32_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes_20210922_172239-c55e78e2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_4x4_1024x1024_160k_cityscapes_20210922_172239.log.json) | +| BiSeNetV1 | R-18-D32 | 1024x1024 | 160000 | 5.69 | 31.77 | V100 | 74.37 | 76.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210905_220251-8ba80eff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210905_220251.log.json) | +| BiSeNetV1 | R-18-D32 (4x8) | 1024x1024 | 160000 | 11.17 | 31.77 | V100 | 75.16 | 77.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb8-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes_20210905_220322-bb8db75f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes/bisenetv1_r18-d32_in1k-pre_4x8_1024x1024_160k_cityscapes_20210905_220322.log.json) | +| BiSeNetV1 | R-50-D32 (No Pretrain) | 1024x1024 | 160000 | 15.39 | 7.71 | V100 | 76.92 | 78.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r50-d32_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes_20210923_222639-7b28a2a6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_4x4_1024x1024_160k_cityscapes_20210923_222639.log.json) | +| BiSeNetV1 | R-50-D32 | 1024x1024 | 160000 | 15.39 | 7.71 | V100 | 77.68 | 79.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210917_234628-8b304447.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes/bisenetv1_r50-d32_in1k-pre_4x4_1024x1024_160k_cityscapes_20210917_234628.log.json) | ### COCO-Stuff 164k -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | ----------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| BiSeNetV1 | R-18-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 25.45 | 26.15 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r18-d32_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211022_054328-046aa2f2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211022_054328.log.json) | -| BiSeNetV1 | R-18-D32 | 512x512 | 160000 | 6.33 | 74.24 | V100 | 28.55 | 29.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211023_013100-f700dbf7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211023_013100.log.json) | -| BiSeNetV1 | R-50-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 29.82 | 30.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r50-d32_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_040616-d2bb0df4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_040616.log.json) | -| BiSeNetV1 | R-50-D32 | 512x512 | 160000 | 9.28 | 32.60 | V100 | 34.88 | 35.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_181932-66747911.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_181932.log.json) | -| BiSeNetV1 | R-101-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 31.14 | 31.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211102_164147-c6b32c3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211102_164147.log.json) | -| BiSeNetV1 | R-101-D32 | 512x512 | 160000 | 10.36 | 25.25 | V100 | 37.38 | 37.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv1/bisenetv1_r101-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_225220-28c8f092.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_225220.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | ----------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| BiSeNetV1 | R-18-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 25.45 | 26.15 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r18-d32_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211022_054328-046aa2f2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211022_054328.log.json) | +| BiSeNetV1 | R-18-D32 | 512x512 | 160000 | 6.33 | 74.24 | V100 | 28.55 | 29.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r18-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211023_013100-f700dbf7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r18-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211023_013100.log.json) | +| BiSeNetV1 | R-50-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 29.82 | 30.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r50-d32_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_040616-d2bb0df4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_040616.log.json) | +| BiSeNetV1 | R-50-D32 | 512x512 | 160000 | 9.28 | 32.60 | V100 | 34.88 | 35.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_181932-66747911.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r50-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_181932.log.json) | +| BiSeNetV1 | R-101-D32 (No Pretrain) | 512x512 | 160000 | - | - | V100 | 31.14 | 31.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r50-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211102_164147-c6b32c3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211102_164147.log.json) | +| BiSeNetV1 | R-101-D32 | 512x512 | 160000 | 10.36 | 25.25 | V100 | 37.38 | 37.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1/bisenetv1_r101-d32-in1k-pre_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_225220-28c8f092.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv1/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k/bisenetv1_r101-d32_in1k-pre_lr5e-3_4x4_512x512_160k_coco-stuff164k_20211101_225220.log.json) | Note: diff --git a/configs/bisenetv2/README.md b/configs/bisenetv2/README.md index 1f44c01f36a..a5871dfeb98 100644 --- a/configs/bisenetv2/README.md +++ b/configs/bisenetv2/README.md @@ -26,12 +26,12 @@ The low-level details and high-level semantics are both essential to the semanti ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | ---------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| BiSeNetV2 | BiSeNetV2 | 1024x1024 | 160000 | 7.64 | 31.77 | V100 | 73.21 | 75.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv2/bisenetv2_fcn_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes_20210902_015551-bcf10f09.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes_20210902_015551.log.json) | -| BiSeNetV2 | BiSeNetV2 (OHEM) | 1024x1024 | 160000 | 7.64 | - | V100 | 73.57 | 75.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv2/bisenetv2_fcn_4xb4-ohem-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes_20210902_112947-5f8103b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes_20210902_112947.log.json) | -| BiSeNetV2 | BiSeNetV2 (4x8) | 1024x1024 | 160000 | 15.05 | - | V100 | 75.76 | 77.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv2/bisenetv2_fcn_4xb8-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes_20210903_000032-e1a2eed6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes_20210903_000032.log.json) | -| BiSeNetV2 | BiSeNetV2 (FP16) | 1024x1024 | 160000 | 5.77 | 36.65 | V100 | 73.07 | 75.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/bisenetv2/bisenetv2_fcn_4xb4-amp-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes_20210902_045942-b979777b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes_20210902_045942.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | ---------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| BiSeNetV2 | BiSeNetV2 | 1024x1024 | 160000 | 7.64 | 31.77 | V100 | 73.21 | 75.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2/bisenetv2_fcn_4xb4-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes_20210902_015551-bcf10f09.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_4x4_1024x1024_160k_cityscapes_20210902_015551.log.json) | +| BiSeNetV2 | BiSeNetV2 (OHEM) | 1024x1024 | 160000 | 7.64 | - | V100 | 73.57 | 75.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2/bisenetv2_fcn_4xb4-ohem-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes_20210902_112947-5f8103b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_ohem_4x4_1024x1024_160k_cityscapes_20210902_112947.log.json) | +| BiSeNetV2 | BiSeNetV2 (4x8) | 1024x1024 | 160000 | 15.05 | - | V100 | 75.76 | 77.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2/bisenetv2_fcn_4xb8-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes_20210903_000032-e1a2eed6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes/bisenetv2_fcn_4x8_1024x1024_160k_cityscapes_20210903_000032.log.json) | +| BiSeNetV2 | BiSeNetV2 (FP16) | 1024x1024 | 160000 | 5.77 | 36.65 | V100 | 73.07 | 75.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2/bisenetv2_fcn_4xb4-amp-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes_20210902_045942-b979777b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/bisenetv2/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes_20210902_045942.log.json) | Note: diff --git a/configs/ccnet/README.md b/configs/ccnet/README.md index c7a0163495d..64dd5f0298a 100644 --- a/configs/ccnet/README.md +++ b/configs/ccnet/README.md @@ -26,34 +26,34 @@ Contextual information is vital in visual understanding problems, such as semant ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| CCNet | R-50-D8 | 512x1024 | 40000 | 6 | 3.32 | V100 | 77.76 | 78.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_40k_cityscapes/ccnet_r50-d8_512x1024_40k_cityscapes_20200616_142517-4123f401.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_40k_cityscapes/ccnet_r50-d8_512x1024_40k_cityscapes_20200616_142517.log.json) | -| CCNet | R-101-D8 | 512x1024 | 40000 | 9.5 | 2.31 | V100 | 76.35 | 78.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_40k_cityscapes/ccnet_r101-d8_512x1024_40k_cityscapes_20200616_142540-a3b84ba6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_40k_cityscapes/ccnet_r101-d8_512x1024_40k_cityscapes_20200616_142540.log.json) | -| CCNet | R-50-D8 | 769x769 | 40000 | 6.8 | 1.43 | V100 | 78.46 | 79.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_40k_cityscapes/ccnet_r50-d8_769x769_40k_cityscapes_20200616_145125-76d11884.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_40k_cityscapes/ccnet_r50-d8_769x769_40k_cityscapes_20200616_145125.log.json) | -| CCNet | R-101-D8 | 769x769 | 40000 | 10.7 | 1.01 | V100 | 76.94 | 78.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_40k_cityscapes/ccnet_r101-d8_769x769_40k_cityscapes_20200617_101428-4f57c8d0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_40k_cityscapes/ccnet_r101-d8_769x769_40k_cityscapes_20200617_101428.log.json) | -| CCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.03 | 80.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_80k_cityscapes/ccnet_r50-d8_512x1024_80k_cityscapes_20200617_010421-869a3423.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_80k_cityscapes/ccnet_r50-d8_512x1024_80k_cityscapes_20200617_010421.log.json) | -| CCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.87 | 79.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_80k_cityscapes/ccnet_r101-d8_512x1024_80k_cityscapes_20200617_203935-ffae8917.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_80k_cityscapes/ccnet_r101-d8_512x1024_80k_cityscapes_20200617_203935.log.json) | -| CCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.29 | 81.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_80k_cityscapes/ccnet_r50-d8_769x769_80k_cityscapes_20200617_010421-73eed8ca.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_80k_cityscapes/ccnet_r50-d8_769x769_80k_cityscapes_20200617_010421.log.json) | -| CCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.45 | 80.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_80k_cityscapes/ccnet_r101-d8_769x769_80k_cityscapes_20200618_011502-ad3cd481.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_80k_cityscapes/ccnet_r101-d8_769x769_80k_cityscapes_20200618_011502.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CCNet | R-50-D8 | 512x1024 | 40000 | 6 | 3.32 | V100 | 77.76 | 78.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_40k_cityscapes/ccnet_r50-d8_512x1024_40k_cityscapes_20200616_142517-4123f401.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_40k_cityscapes/ccnet_r50-d8_512x1024_40k_cityscapes_20200616_142517.log.json) | +| CCNet | R-101-D8 | 512x1024 | 40000 | 9.5 | 2.31 | V100 | 76.35 | 78.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_40k_cityscapes/ccnet_r101-d8_512x1024_40k_cityscapes_20200616_142540-a3b84ba6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_40k_cityscapes/ccnet_r101-d8_512x1024_40k_cityscapes_20200616_142540.log.json) | +| CCNet | R-50-D8 | 769x769 | 40000 | 6.8 | 1.43 | V100 | 78.46 | 79.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_40k_cityscapes/ccnet_r50-d8_769x769_40k_cityscapes_20200616_145125-76d11884.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_40k_cityscapes/ccnet_r50-d8_769x769_40k_cityscapes_20200616_145125.log.json) | +| CCNet | R-101-D8 | 769x769 | 40000 | 10.7 | 1.01 | V100 | 76.94 | 78.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_40k_cityscapes/ccnet_r101-d8_769x769_40k_cityscapes_20200617_101428-4f57c8d0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_40k_cityscapes/ccnet_r101-d8_769x769_40k_cityscapes_20200617_101428.log.json) | +| CCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.03 | 80.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_80k_cityscapes/ccnet_r50-d8_512x1024_80k_cityscapes_20200617_010421-869a3423.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x1024_80k_cityscapes/ccnet_r50-d8_512x1024_80k_cityscapes_20200617_010421.log.json) | +| CCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.87 | 79.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_80k_cityscapes/ccnet_r101-d8_512x1024_80k_cityscapes_20200617_203935-ffae8917.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x1024_80k_cityscapes/ccnet_r101-d8_512x1024_80k_cityscapes_20200617_203935.log.json) | +| CCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.29 | 81.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_80k_cityscapes/ccnet_r50-d8_769x769_80k_cityscapes_20200617_010421-73eed8ca.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_769x769_80k_cityscapes/ccnet_r50-d8_769x769_80k_cityscapes_20200617_010421.log.json) | +| CCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.45 | 80.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_80k_cityscapes/ccnet_r101-d8_769x769_80k_cityscapes_20200618_011502-ad3cd481.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_769x769_80k_cityscapes/ccnet_r101-d8_769x769_80k_cityscapes_20200618_011502.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| CCNet | R-50-D8 | 512x512 | 80000 | 8.8 | 20.89 | V100 | 41.78 | 42.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_80k_ade20k/ccnet_r50-d8_512x512_80k_ade20k_20200615_014848-aa37f61e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_80k_ade20k/ccnet_r50-d8_512x512_80k_ade20k_20200615_014848.log.json) | -| CCNet | R-101-D8 | 512x512 | 80000 | 12.2 | 14.11 | V100 | 43.97 | 45.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_80k_ade20k/ccnet_r101-d8_512x512_80k_ade20k_20200615_014848-1f4929a3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_80k_ade20k/ccnet_r101-d8_512x512_80k_ade20k_20200615_014848.log.json) | -| CCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.08 | 43.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_160k_ade20k/ccnet_r50-d8_512x512_160k_ade20k_20200616_084435-7c97193b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_160k_ade20k/ccnet_r50-d8_512x512_160k_ade20k_20200616_084435.log.json) | -| CCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.71 | 45.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_160k_ade20k/ccnet_r101-d8_512x512_160k_ade20k_20200616_000644-e849e007.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_160k_ade20k/ccnet_r101-d8_512x512_160k_ade20k_20200616_000644.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CCNet | R-50-D8 | 512x512 | 80000 | 8.8 | 20.89 | V100 | 41.78 | 42.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_80k_ade20k/ccnet_r50-d8_512x512_80k_ade20k_20200615_014848-aa37f61e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_80k_ade20k/ccnet_r50-d8_512x512_80k_ade20k_20200615_014848.log.json) | +| CCNet | R-101-D8 | 512x512 | 80000 | 12.2 | 14.11 | V100 | 43.97 | 45.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_80k_ade20k/ccnet_r101-d8_512x512_80k_ade20k_20200615_014848-1f4929a3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_80k_ade20k/ccnet_r101-d8_512x512_80k_ade20k_20200615_014848.log.json) | +| CCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.08 | 43.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_160k_ade20k/ccnet_r50-d8_512x512_160k_ade20k_20200616_084435-7c97193b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_160k_ade20k/ccnet_r50-d8_512x512_160k_ade20k_20200616_084435.log.json) | +| CCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.71 | 45.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_160k_ade20k/ccnet_r101-d8_512x512_160k_ade20k_20200616_000644-e849e007.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_160k_ade20k/ccnet_r101-d8_512x512_160k_ade20k_20200616_000644.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| CCNet | R-50-D8 | 512x512 | 20000 | 6 | 20.45 | V100 | 76.17 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_20k_voc12aug/ccnet_r50-d8_512x512_20k_voc12aug_20200617_193212-fad81784.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_20k_voc12aug/ccnet_r50-d8_512x512_20k_voc12aug_20200617_193212.log.json) | -| CCNet | R-101-D8 | 512x512 | 20000 | 9.5 | 13.64 | V100 | 77.27 | 79.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_20k_voc12aug/ccnet_r101-d8_512x512_20k_voc12aug_20200617_193212-0007b61d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_20k_voc12aug/ccnet_r101-d8_512x512_20k_voc12aug_20200617_193212.log.json) | -| CCNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 75.96 | 77.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_40k_voc12aug/ccnet_r50-d8_512x512_40k_voc12aug_20200613_232127-c2a15f02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_40k_voc12aug/ccnet_r50-d8_512x512_40k_voc12aug_20200613_232127.log.json) | -| CCNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.87 | 78.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ccnet/ccnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_40k_voc12aug/ccnet_r101-d8_512x512_40k_voc12aug_20200613_232127-c30da577.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_40k_voc12aug/ccnet_r101-d8_512x512_40k_voc12aug_20200613_232127.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| CCNet | R-50-D8 | 512x512 | 20000 | 6 | 20.45 | V100 | 76.17 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_20k_voc12aug/ccnet_r50-d8_512x512_20k_voc12aug_20200617_193212-fad81784.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_20k_voc12aug/ccnet_r50-d8_512x512_20k_voc12aug_20200617_193212.log.json) | +| CCNet | R-101-D8 | 512x512 | 20000 | 9.5 | 13.64 | V100 | 77.27 | 79.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_20k_voc12aug/ccnet_r101-d8_512x512_20k_voc12aug_20200617_193212-0007b61d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_20k_voc12aug/ccnet_r101-d8_512x512_20k_voc12aug_20200617_193212.log.json) | +| CCNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 75.96 | 77.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_40k_voc12aug/ccnet_r50-d8_512x512_40k_voc12aug_20200613_232127-c2a15f02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r50-d8_512x512_40k_voc12aug/ccnet_r50-d8_512x512_40k_voc12aug_20200613_232127.log.json) | +| CCNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.87 | 78.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet/ccnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_40k_voc12aug/ccnet_r101-d8_512x512_40k_voc12aug_20200613_232127-c30da577.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ccnet/ccnet_r101-d8_512x512_40k_voc12aug/ccnet_r101-d8_512x512_40k_voc12aug_20200613_232127.log.json) | ## Citation diff --git a/configs/cgnet/README.md b/configs/cgnet/README.md index 60cde582918..96c9fcf515c 100644 --- a/configs/cgnet/README.md +++ b/configs/cgnet/README.md @@ -26,10 +26,10 @@ The demand of applying semantic segmentation model on mobile devices has been in ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| CGNet | M3N21 | 680x680 | 60000 | 7.5 | 30.51 | V100 | 65.63 | 68.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/cgnet/cgnet_fcn_4xb4-60k_cityscapes-680x680.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_680x680_60k_cityscapes/cgnet_680x680_60k_cityscapes_20201101_110253-4c0b2f2d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_680x680_60k_cityscapes/cgnet_680x680_60k_cityscapes-20201101_110253.log.json) | -| CGNet | M3N21 | 512x1024 | 60000 | 8.3 | 31.14 | V100 | 68.27 | 70.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/cgnet/cgnet_fcn_4xb8-60k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_512x1024_60k_cityscapes/cgnet_512x1024_60k_cityscapes_20201101_110254-124ea03b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_512x1024_60k_cityscapes/cgnet_512x1024_60k_cityscapes-20201101_110254.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| CGNet | M3N21 | 680x680 | 60000 | 7.5 | 30.51 | V100 | 65.63 | 68.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/cgnet/cgnet_fcn_4xb4-60k_cityscapes-680x680.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_680x680_60k_cityscapes/cgnet_680x680_60k_cityscapes_20201101_110253-4c0b2f2d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_680x680_60k_cityscapes/cgnet_680x680_60k_cityscapes-20201101_110253.log.json) | +| CGNet | M3N21 | 512x1024 | 60000 | 8.3 | 31.14 | V100 | 68.27 | 70.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/cgnet/cgnet_fcn_4xb8-60k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_512x1024_60k_cityscapes/cgnet_512x1024_60k_cityscapes_20201101_110254-124ea03b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/cgnet/cgnet_512x1024_60k_cityscapes/cgnet_512x1024_60k_cityscapes-20201101_110254.log.json) | ## Citation diff --git a/configs/convnext/README.md b/configs/convnext/README.md index 91339377c01..d78fe6ee1bb 100644 --- a/configs/convnext/README.md +++ b/configs/convnext/README.md @@ -27,7 +27,7 @@ The "Roaring 20s" of visual recognition began with the introduction of Vision Tr - ConvNeXt backbone needs to install [MMClassification](https://github.com/open-mmlab/mmclassification) first, which has abundant backbones for downstream tasks. ```shell -pip install mmcls>=0.20.1 +pip install mmpretrain>=1.0.0rc7 ``` ### Pre-trained Models @@ -49,14 +49,14 @@ The pre-trained models on ImageNet-1k or ImageNet-21k are used to fine-tune on t ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | ----------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | ConvNeXt-T | 512x512 | 160000 | 4.23 | 19.90 | V100 | 46.11 | 46.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_tiny_fp16_512x512_160k_ade20k/upernet_convnext_tiny_fp16_512x512_160k_ade20k_20220227_124553-cad485de.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_tiny_fp16_512x512_160k_ade20k/upernet_convnext_tiny_fp16_512x512_160k_ade20k_20220227_124553.log.json) | -| UPerNet | ConvNeXt-S | 512x512 | 160000 | 5.16 | 15.18 | V100 | 48.56 | 49.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_small_fp16_512x512_160k_ade20k/upernet_convnext_small_fp16_512x512_160k_ade20k_20220227_131208-1b1e394f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_small_fp16_512x512_160k_ade20k/upernet_convnext_small_fp16_512x512_160k_ade20k_20220227_131208.log.json) | -| UPerNet | ConvNeXt-B | 512x512 | 160000 | 6.33 | 14.41 | V100 | 48.71 | 49.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_512x512_160k_ade20k/upernet_convnext_base_fp16_512x512_160k_ade20k_20220227_181227-02a24fc6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_512x512_160k_ade20k/upernet_convnext_base_fp16_512x512_160k_ade20k_20220227_181227.log.json) | -| UPerNet | ConvNeXt-B | 640x640 | 160000 | 8.53 | 10.88 | V100 | 52.13 | 52.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_640x640_160k_ade20k/upernet_convnext_base_fp16_640x640_160k_ade20k_20220227_182859-9280e39b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_640x640_160k_ade20k/upernet_convnext_base_fp16_640x640_160k_ade20k_20220227_182859.log.json) | -| UPerNet | ConvNeXt-L | 640x640 | 160000 | 12.08 | 7.69 | V100 | 53.16 | 53.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_large_fp16_640x640_160k_ade20k/upernet_convnext_large_fp16_640x640_160k_ade20k_20220226_040532-e57aa54d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_large_fp16_640x640_160k_ade20k/upernet_convnext_large_fp16_640x640_160k_ade20k_20220226_040532.log.json) | -| UPerNet | ConvNeXt-XL | 640x640 | 160000 | 26.16\* | 6.33 | V100 | 53.58 | 54.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_xlarge_fp16_640x640_160k_ade20k/upernet_convnext_xlarge_fp16_640x640_160k_ade20k_20220226_080344-95fc38c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_xlarge_fp16_640x640_160k_ade20k/upernet_convnext_xlarge_fp16_640x640_160k_ade20k_20220226_080344.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | ----------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | ConvNeXt-T | 512x512 | 160000 | 4.23 | 19.90 | V100 | 46.11 | 46.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_tiny_fp16_512x512_160k_ade20k/upernet_convnext_tiny_fp16_512x512_160k_ade20k_20220227_124553-cad485de.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_tiny_fp16_512x512_160k_ade20k/upernet_convnext_tiny_fp16_512x512_160k_ade20k_20220227_124553.log.json) | +| UPerNet | ConvNeXt-S | 512x512 | 160000 | 5.16 | 15.18 | V100 | 48.56 | 49.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_small_fp16_512x512_160k_ade20k/upernet_convnext_small_fp16_512x512_160k_ade20k_20220227_131208-1b1e394f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_small_fp16_512x512_160k_ade20k/upernet_convnext_small_fp16_512x512_160k_ade20k_20220227_131208.log.json) | +| UPerNet | ConvNeXt-B | 512x512 | 160000 | 6.33 | 14.41 | V100 | 48.71 | 49.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_512x512_160k_ade20k/upernet_convnext_base_fp16_512x512_160k_ade20k_20220227_181227-02a24fc6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_512x512_160k_ade20k/upernet_convnext_base_fp16_512x512_160k_ade20k_20220227_181227.log.json) | +| UPerNet | ConvNeXt-B | 640x640 | 160000 | 8.53 | 10.88 | V100 | 52.13 | 52.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_640x640_160k_ade20k/upernet_convnext_base_fp16_640x640_160k_ade20k_20220227_182859-9280e39b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_base_fp16_640x640_160k_ade20k/upernet_convnext_base_fp16_640x640_160k_ade20k_20220227_182859.log.json) | +| UPerNet | ConvNeXt-L | 640x640 | 160000 | 12.08 | 7.69 | V100 | 53.16 | 53.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_large_fp16_640x640_160k_ade20k/upernet_convnext_large_fp16_640x640_160k_ade20k_20220226_040532-e57aa54d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_large_fp16_640x640_160k_ade20k/upernet_convnext_large_fp16_640x640_160k_ade20k_20220226_040532.log.json) | +| UPerNet | ConvNeXt-XL | 640x640 | 160000 | 26.16\* | 6.33 | V100 | 53.58 | 54.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_xlarge_fp16_640x640_160k_ade20k/upernet_convnext_xlarge_fp16_640x640_160k_ade20k_20220226_080344-95fc38c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/convnext/upernet_convnext_xlarge_fp16_640x640_160k_ade20k/upernet_convnext_xlarge_fp16_640x640_160k_ade20k_20220226_080344.log.json) | Note: diff --git a/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py b/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py index a743e9322ac..06a86431442 100644 --- a/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py +++ b/configs/convnext/convnext-base_upernet_8xb2-amp-160k_ade20k-640x640.py @@ -9,7 +9,7 @@ model = dict( data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='base', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, diff --git a/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py b/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py index 6d94989ee1e..2956e86f042 100644 --- a/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py +++ b/configs/convnext/convnext-large_upernet_8xb2-amp-160k_ade20k-640x640.py @@ -9,7 +9,7 @@ model = dict( data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='large', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, diff --git a/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py b/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py index 3cbf09902dc..dbe45f10e0b 100644 --- a/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py +++ b/configs/convnext/convnext-small_upernet_8xb2-amp-160k_ade20k-512x512.py @@ -8,7 +8,7 @@ model = dict( data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='small', out_indices=[0, 1, 2, 3], drop_path_rate=0.3, diff --git a/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py b/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py index 9d4968df600..d2e545a76d0 100644 --- a/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py +++ b/configs/convnext/convnext-tiny_upernet_8xb2-amp-160k_ade20k-512x512.py @@ -8,7 +8,7 @@ model = dict( data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='tiny', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, diff --git a/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py b/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py index 749391cac12..dfad7345215 100644 --- a/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py +++ b/configs/convnext/convnext-xlarge_upernet_8xb2-amp-160k_ade20k-640x640.py @@ -9,7 +9,7 @@ model = dict( data_preprocessor=data_preprocessor, backbone=dict( - type='mmcls.ConvNeXt', + type='mmpretrain.ConvNeXt', arch='xlarge', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, diff --git a/configs/danet/README.md b/configs/danet/README.md index b5841e23be1..90194f3073e 100644 --- a/configs/danet/README.md +++ b/configs/danet/README.md @@ -26,34 +26,34 @@ In this paper, we address the scene segmentation task by capturing rich contextu ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DANet | R-50-D8 | 512x1024 | 40000 | 7.4 | 2.66 | V100 | 78.74 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_40k_cityscapes/danet_r50-d8_512x1024_40k_cityscapes_20200605_191324-c0dbfa5f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_40k_cityscapes/danet_r50-d8_512x1024_40k_cityscapes_20200605_191324.log.json) | -| DANet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.99 | V100 | 80.52 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_40k_cityscapes/danet_r101-d8_512x1024_40k_cityscapes_20200605_200831-c57a7157.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_40k_cityscapes/danet_r101-d8_512x1024_40k_cityscapes_20200605_200831.log.json) | -| DANet | R-50-D8 | 769x769 | 40000 | 8.8 | 1.56 | V100 | 78.88 | 80.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_40k_cityscapes/danet_r50-d8_769x769_40k_cityscapes_20200530_025703-76681c60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_40k_cityscapes/danet_r50-d8_769x769_40k_cityscapes_20200530_025703.log.json) | -| DANet | R-101-D8 | 769x769 | 40000 | 12.8 | 1.07 | V100 | 79.88 | 81.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_40k_cityscapes/danet_r101-d8_769x769_40k_cityscapes_20200530_025717-dcb7fd4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_40k_cityscapes/danet_r101-d8_769x769_40k_cityscapes_20200530_025717.log.json) | -| DANet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.34 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_80k_cityscapes/danet_r50-d8_512x1024_80k_cityscapes_20200607_133029-2bfa2293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_80k_cityscapes/danet_r50-d8_512x1024_80k_cityscapes_20200607_133029.log.json) | -| DANet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.41 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_80k_cityscapes/danet_r101-d8_512x1024_80k_cityscapes_20200607_132918-955e6350.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_80k_cityscapes/danet_r101-d8_512x1024_80k_cityscapes_20200607_132918.log.json) | -| DANet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.27 | 80.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_80k_cityscapes/danet_r50-d8_769x769_80k_cityscapes_20200607_132954-495689b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_80k_cityscapes/danet_r50-d8_769x769_80k_cityscapes_20200607_132954.log.json) | -| DANet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 80.47 | 82.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_80k_cityscapes/danet_r101-d8_769x769_80k_cityscapes_20200607_132918-f3a929e7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_80k_cityscapes/danet_r101-d8_769x769_80k_cityscapes_20200607_132918.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DANet | R-50-D8 | 512x1024 | 40000 | 7.4 | 2.66 | V100 | 78.74 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_40k_cityscapes/danet_r50-d8_512x1024_40k_cityscapes_20200605_191324-c0dbfa5f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_40k_cityscapes/danet_r50-d8_512x1024_40k_cityscapes_20200605_191324.log.json) | +| DANet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.99 | V100 | 80.52 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_40k_cityscapes/danet_r101-d8_512x1024_40k_cityscapes_20200605_200831-c57a7157.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_40k_cityscapes/danet_r101-d8_512x1024_40k_cityscapes_20200605_200831.log.json) | +| DANet | R-50-D8 | 769x769 | 40000 | 8.8 | 1.56 | V100 | 78.88 | 80.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_40k_cityscapes/danet_r50-d8_769x769_40k_cityscapes_20200530_025703-76681c60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_40k_cityscapes/danet_r50-d8_769x769_40k_cityscapes_20200530_025703.log.json) | +| DANet | R-101-D8 | 769x769 | 40000 | 12.8 | 1.07 | V100 | 79.88 | 81.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_40k_cityscapes/danet_r101-d8_769x769_40k_cityscapes_20200530_025717-dcb7fd4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_40k_cityscapes/danet_r101-d8_769x769_40k_cityscapes_20200530_025717.log.json) | +| DANet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.34 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_80k_cityscapes/danet_r50-d8_512x1024_80k_cityscapes_20200607_133029-2bfa2293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x1024_80k_cityscapes/danet_r50-d8_512x1024_80k_cityscapes_20200607_133029.log.json) | +| DANet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.41 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_80k_cityscapes/danet_r101-d8_512x1024_80k_cityscapes_20200607_132918-955e6350.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x1024_80k_cityscapes/danet_r101-d8_512x1024_80k_cityscapes_20200607_132918.log.json) | +| DANet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.27 | 80.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_80k_cityscapes/danet_r50-d8_769x769_80k_cityscapes_20200607_132954-495689b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_769x769_80k_cityscapes/danet_r50-d8_769x769_80k_cityscapes_20200607_132954.log.json) | +| DANet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 80.47 | 82.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_80k_cityscapes/danet_r101-d8_769x769_80k_cityscapes_20200607_132918-f3a929e7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_769x769_80k_cityscapes/danet_r101-d8_769x769_80k_cityscapes_20200607_132918.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DANet | R-50-D8 | 512x512 | 80000 | 11.5 | 21.20 | V100 | 41.66 | 42.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_80k_ade20k/danet_r50-d8_512x512_80k_ade20k_20200615_015125-edb18e08.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_80k_ade20k/danet_r50-d8_512x512_80k_ade20k_20200615_015125.log.json) | -| DANet | R-101-D8 | 512x512 | 80000 | 15 | 14.18 | V100 | 43.64 | 45.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_80k_ade20k/danet_r101-d8_512x512_80k_ade20k_20200615_015126-d0357c73.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_80k_ade20k/danet_r101-d8_512x512_80k_ade20k_20200615_015126.log.json) | -| DANet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.45 | 43.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_160k_ade20k/danet_r50-d8_512x512_160k_ade20k_20200616_082340-9cb35dcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_160k_ade20k/danet_r50-d8_512x512_160k_ade20k_20200616_082340.log.json) | -| DANet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.17 | 45.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_160k_ade20k/danet_r101-d8_512x512_160k_ade20k_20200616_082348-23bf12f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_160k_ade20k/danet_r101-d8_512x512_160k_ade20k_20200616_082348.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DANet | R-50-D8 | 512x512 | 80000 | 11.5 | 21.20 | V100 | 41.66 | 42.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_80k_ade20k/danet_r50-d8_512x512_80k_ade20k_20200615_015125-edb18e08.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_80k_ade20k/danet_r50-d8_512x512_80k_ade20k_20200615_015125.log.json) | +| DANet | R-101-D8 | 512x512 | 80000 | 15 | 14.18 | V100 | 43.64 | 45.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_80k_ade20k/danet_r101-d8_512x512_80k_ade20k_20200615_015126-d0357c73.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_80k_ade20k/danet_r101-d8_512x512_80k_ade20k_20200615_015126.log.json) | +| DANet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.45 | 43.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_160k_ade20k/danet_r50-d8_512x512_160k_ade20k_20200616_082340-9cb35dcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_160k_ade20k/danet_r50-d8_512x512_160k_ade20k_20200616_082340.log.json) | +| DANet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.17 | 45.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_160k_ade20k/danet_r101-d8_512x512_160k_ade20k_20200616_082348-23bf12f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_160k_ade20k/danet_r101-d8_512x512_160k_ade20k_20200616_082348.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DANet | R-50-D8 | 512x512 | 20000 | 6.5 | 20.94 | V100 | 74.45 | 75.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_20k_voc12aug/danet_r50-d8_512x512_20k_voc12aug_20200618_070026-9e9e3ab3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_20k_voc12aug/danet_r50-d8_512x512_20k_voc12aug_20200618_070026.log.json) | -| DANet | R-101-D8 | 512x512 | 20000 | 9.9 | 13.76 | V100 | 76.02 | 77.23 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_20k_voc12aug/danet_r101-d8_512x512_20k_voc12aug_20200618_070026-d48d23b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_20k_voc12aug/danet_r101-d8_512x512_20k_voc12aug_20200618_070026.log.json) | -| DANet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.37 | 77.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_40k_voc12aug/danet_r50-d8_512x512_40k_voc12aug_20200613_235526-426e3a64.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_40k_voc12aug/danet_r50-d8_512x512_40k_voc12aug_20200613_235526.log.json) | -| DANet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 76.51 | 77.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/danet/danet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_40k_voc12aug/danet_r101-d8_512x512_40k_voc12aug_20200613_223031-788e232a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_40k_voc12aug/danet_r101-d8_512x512_40k_voc12aug_20200613_223031.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DANet | R-50-D8 | 512x512 | 20000 | 6.5 | 20.94 | V100 | 74.45 | 75.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_20k_voc12aug/danet_r50-d8_512x512_20k_voc12aug_20200618_070026-9e9e3ab3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_20k_voc12aug/danet_r50-d8_512x512_20k_voc12aug_20200618_070026.log.json) | +| DANet | R-101-D8 | 512x512 | 20000 | 9.9 | 13.76 | V100 | 76.02 | 77.23 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_20k_voc12aug/danet_r101-d8_512x512_20k_voc12aug_20200618_070026-d48d23b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_20k_voc12aug/danet_r101-d8_512x512_20k_voc12aug_20200618_070026.log.json) | +| DANet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.37 | 77.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_40k_voc12aug/danet_r50-d8_512x512_40k_voc12aug_20200613_235526-426e3a64.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r50-d8_512x512_40k_voc12aug/danet_r50-d8_512x512_40k_voc12aug_20200613_235526.log.json) | +| DANet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 76.51 | 77.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet/danet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_40k_voc12aug/danet_r101-d8_512x512_40k_voc12aug_20200613_223031-788e232a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/danet/danet_r101-d8_512x512_40k_voc12aug/danet_r101-d8_512x512_40k_voc12aug_20200613_223031.log.json) | ## Citation diff --git a/configs/ddrnet/README.md b/configs/ddrnet/README.md new file mode 100644 index 00000000000..ccbfcdff359 --- /dev/null +++ b/configs/ddrnet/README.md @@ -0,0 +1,46 @@ +# DDRNet + +> [Deep Dual-resolution Networks for Real-time and Accurate Semantic Segmentation of Road Scenes](http://arxiv.org/abs/2101.06085) + +## Introduction + + + +Official Repo + +## Abstract + + + +Semantic segmentation is a key technology for autonomous vehicles to understand the surrounding scenes. The appealing performances of contemporary models usually come at the expense of heavy computations and lengthy inference time, which is intolerable for self-driving. Using light-weight architectures (encoder-decoder or two-pathway) or reasoning on low-resolution images, recent methods realize very fast scene parsing, even running at more than 100 FPS on a single 1080Ti GPU. However, there is still a significant gap in performance between these real-time methods and the models based on dilation backbones. To tackle this problem, we proposed a family of efficient backbones specially designed for real-time semantic segmentation. The proposed deep dual-resolution networks (DDRNets) are composed of two deep branches between which multiple bilateral fusions are performed. Additionally, we design a new contextual information extractor named Deep Aggregation Pyramid Pooling Module (DAPPM) to enlarge effective receptive fields and fuse multi-scale context based on low-resolution feature maps. Our method achieves a new state-of-the-art trade-off between accuracy and speed on both Cityscapes and CamVid dataset. In particular, on a single 2080Ti GPU, DDRNet-23-slim yields 77.4% mIoU at 102 FPS on Cityscapes test set and 74.7% mIoU at 230 FPS on CamVid test set. With widely used test augmentation, our method is superior to most state-of-the-art models and requires much less computation. Codes and trained models are available online. + + + +
+ +
+ +## Results and models + +### Cityscapes + +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DDRNet | DDRNet23-slim | 1024x1024 | 120000 | 1.70 | 85.85 | A100 | 77.84 | 80.15 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230426_145312-6a5e5174.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230426_145312.json) | +| DDRNet | DDRNet23 | 1024x1024 | 120000 | 7.26 | 33.41 | A100 | 79.99 | 81.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230425_162633-81601db0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230425_162633.json) | + +## Notes + +The pretrained weights in config files are converted from [the official repo](https://github.com/ydhongHIT/DDRNet#pretrained-models). + +## Citation + +```bibtex +@article{pan2022deep, + title={Deep Dual-Resolution Networks for Real-Time and Accurate Semantic Segmentation of Traffic Scenes}, + author={Pan, Huihui and Hong, Yuanduo and Sun, Weichao and Jia, Yisong}, + journal={IEEE Transactions on Intelligent Transportation Systems}, + year={2022}, + publisher={IEEE} +} +``` diff --git a/configs/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024.py b/configs/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024.py new file mode 100644 index 00000000000..65b0ead547a --- /dev/null +++ b/configs/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024.py @@ -0,0 +1,93 @@ +_base_ = [ + '../_base_/datasets/cityscapes_1024x1024.py', + '../_base_/default_runtime.py', +] + +# The class_weight is borrowed from https://github.com/openseg-group/OCNet.pytorch/issues/14 # noqa +# Licensed under the MIT License +class_weight = [ + 0.8373, 0.918, 0.866, 1.0345, 1.0166, 0.9969, 0.9754, 1.0489, 0.8786, + 1.0023, 0.9539, 0.9843, 1.1116, 0.9037, 1.0865, 1.0955, 1.0865, 1.1529, + 1.0507 +] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/pretrain/ddrnet23s-in1kpre_3rdparty-1ccac5b1.pth' # noqa +crop_size = (1024, 1024) +data_preprocessor = dict( + type='SegDataPreProcessor', + size=crop_size, + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='DDRNet', + in_channels=3, + channels=32, + ppm_channels=128, + norm_cfg=norm_cfg, + align_corners=False, + init_cfg=dict(type='Pretrained', checkpoint=checkpoint)), + decode_head=dict( + type='DDRHead', + in_channels=32 * 4, + channels=64, + dropout_ratio=0., + num_classes=19, + align_corners=False, + norm_cfg=norm_cfg, + loss_decode=[ + dict( + type='OhemCrossEntropy', + thres=0.9, + min_kept=131072, + class_weight=class_weight, + loss_weight=1.0), + dict( + type='OhemCrossEntropy', + thres=0.9, + min_kept=131072, + class_weight=class_weight, + loss_weight=0.4), + ]), + + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) + +train_dataloader = dict(batch_size=6, num_workers=4) + +iters = 120000 +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='PolyLR', + eta_min=0, + power=0.9, + begin=0, + end=iters, + by_epoch=False) +] + +# training schedule for 120k +train_cfg = dict( + type='IterBasedTrainLoop', max_iters=iters, val_interval=iters // 10) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict( + type='CheckpointHook', by_epoch=False, interval=iters // 10), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) + +randomness = dict(seed=304) diff --git a/configs/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024.py b/configs/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024.py new file mode 100644 index 00000000000..444efe2b883 --- /dev/null +++ b/configs/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024.py @@ -0,0 +1,93 @@ +_base_ = [ + '../_base_/datasets/cityscapes_1024x1024.py', + '../_base_/default_runtime.py', +] + +# The class_weight is borrowed from https://github.com/openseg-group/OCNet.pytorch/issues/14 # noqa +# Licensed under the MIT License +class_weight = [ + 0.8373, 0.918, 0.866, 1.0345, 1.0166, 0.9969, 0.9754, 1.0489, 0.8786, + 1.0023, 0.9539, 0.9843, 1.1116, 0.9037, 1.0865, 1.0955, 1.0865, 1.1529, + 1.0507 +] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/pretrain/ddrnet23-in1kpre_3rdparty-9ca29f62.pth' # noqa +crop_size = (1024, 1024) +data_preprocessor = dict( + type='SegDataPreProcessor', + size=crop_size, + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='DDRNet', + in_channels=3, + channels=64, + ppm_channels=128, + norm_cfg=norm_cfg, + align_corners=False, + init_cfg=dict(type='Pretrained', checkpoint=checkpoint)), + decode_head=dict( + type='DDRHead', + in_channels=64 * 4, + channels=128, + dropout_ratio=0., + num_classes=19, + align_corners=False, + norm_cfg=norm_cfg, + loss_decode=[ + dict( + type='OhemCrossEntropy', + thres=0.9, + min_kept=131072, + class_weight=class_weight, + loss_weight=1.0), + dict( + type='OhemCrossEntropy', + thres=0.9, + min_kept=131072, + class_weight=class_weight, + loss_weight=0.4), + ]), + + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) + +train_dataloader = dict(batch_size=6, num_workers=4) + +iters = 120000 +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='PolyLR', + eta_min=0, + power=0.9, + begin=0, + end=iters, + by_epoch=False) +] + +# training schedule for 120k +train_cfg = dict( + type='IterBasedTrainLoop', max_iters=iters, val_interval=iters // 10) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict( + type='CheckpointHook', by_epoch=False, interval=iters // 10), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) + +randomness = dict(seed=304) diff --git a/configs/ddrnet/metafile.yaml b/configs/ddrnet/metafile.yaml new file mode 100644 index 00000000000..07074702c22 --- /dev/null +++ b/configs/ddrnet/metafile.yaml @@ -0,0 +1,64 @@ +Collections: +- Name: DDRNet + License: Apache License 2.0 + Metadata: + Training Data: + - Cityscapes + Paper: + Title: Deep Dual-resolution Networks for Real-time and Accurate Semantic Segmentation + of Road Scenes + URL: http://arxiv.org/abs/2101.06085 + README: configs/ddrnet/README.md + Frameworks: + - PyTorch +Models: +- Name: ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024 + In Collection: DDRNet + Results: + Task: Semantic Segmentation + Dataset: Cityscapes + Metrics: + mIoU: 77.84 + mIoU(ms+flip): 80.15 + Config: configs/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024.py + Metadata: + Training Data: Cityscapes + Batch Size: 12 + Architecture: + - DDRNet23-slim + - DDRNet + Training Resources: 2x A100 GPUS + Memory (GB): 1.7 + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230426_145312-6a5e5174.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23-slim_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230426_145312.json + Paper: + Title: Deep Dual-resolution Networks for Real-time and Accurate Semantic Segmentation + of Road Scenes + URL: http://arxiv.org/abs/2101.06085 + Code: '' + Framework: PyTorch +- Name: ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024 + In Collection: DDRNet + Results: + Task: Semantic Segmentation + Dataset: Cityscapes + Metrics: + mIoU: 79.99 + mIoU(ms+flip): 81.71 + Config: configs/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024.py + Metadata: + Training Data: Cityscapes + Batch Size: 12 + Architecture: + - DDRNet23 + - DDRNet + Training Resources: 2x A100 GPUS + Memory (GB): 7.26 + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230425_162633-81601db0.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/ddrnet/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024/ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024_20230425_162633.json + Paper: + Title: Deep Dual-resolution Networks for Real-time and Accurate Semantic Segmentation + of Road Scenes + URL: http://arxiv.org/abs/2101.06085 + Code: '' + Framework: PyTorch diff --git a/configs/deeplabv3/README.md b/configs/deeplabv3/README.md index 836db6a9a5d..df50b7f90a0 100644 --- a/configs/deeplabv3/README.md +++ b/configs/deeplabv3/README.md @@ -27,79 +27,79 @@ DEEPLABv3_ResNet-D8 model structure ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------------- | --------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| DeepLabV3 | R-50-D8 | 512x1024 | 40000 | 6.1 | 2.57 | V100 | 79.09 | 80.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_40k_cityscapes/deeplabv3_r50-d8_512x1024_40k_cityscapes_20200605_022449-acadc2f8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_40k_cityscapes/deeplabv3_r50-d8_512x1024_40k_cityscapes_20200605_022449.log.json) | -| DeepLabV3 | R-101-D8 | 512x1024 | 40000 | 9.6 | 1.92 | V100 | 77.12 | 79.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_40k_cityscapes/deeplabv3_r101-d8_512x1024_40k_cityscapes_20200605_012241-7fd3f799.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_40k_cityscapes/deeplabv3_r101-d8_512x1024_40k_cityscapes_20200605_012241.log.json) | -| DeepLabV3 | R-50-D8 | 769x769 | 40000 | 6.9 | 1.11 | V100 | 78.58 | 79.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_40k_cityscapes/deeplabv3_r50-d8_769x769_40k_cityscapes_20200606_113723-7eda553c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_40k_cityscapes/deeplabv3_r50-d8_769x769_40k_cityscapes_20200606_113723.log.json) | -| DeepLabV3 | R-101-D8 | 769x769 | 40000 | 10.9 | 0.83 | V100 | 79.27 | 80.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_40k_cityscapes/deeplabv3_r101-d8_769x769_40k_cityscapes_20200606_113809-c64f889f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_40k_cityscapes/deeplabv3_r101-d8_769x769_40k_cityscapes_20200606_113809.log.json) | -| DeepLabV3 | R-18-D8 | 512x1024 | 80000 | 1.7 | 13.78 | V100 | 76.70 | 78.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_512x1024_80k_cityscapes/deeplabv3_r18-d8_512x1024_80k_cityscapes_20201225_021506-23dffbe2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_512x1024_80k_cityscapes/deeplabv3_r18-d8_512x1024_80k_cityscapes-20201225_021506.log.json) | -| DeepLabV3 | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.32 | 80.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_80k_cityscapes/deeplabv3_r50-d8_512x1024_80k_cityscapes_20200606_113404-b92cfdd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_80k_cityscapes/deeplabv3_r50-d8_512x1024_80k_cityscapes_20200606_113404.log.json) | -| DeepLabV3 | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.20 | 81.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_80k_cityscapes/deeplabv3_r101-d8_512x1024_80k_cityscapes_20200606_113503-9e428899.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_80k_cityscapes/deeplabv3_r101-d8_512x1024_80k_cityscapes_20200606_113503.log.json) | -| DeepLabV3 (FP16) | R-101-D8 | 512x1024 | 80000 | 5.75 | 3.86 | V100 | 80.48 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920-774d9cec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920.log.json) | -| DeepLabV3 | R-18-D8 | 769x769 | 80000 | 1.9 | 5.55 | V100 | 76.60 | 78.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_769x769_80k_cityscapes/deeplabv3_r18-d8_769x769_80k_cityscapes_20201225_021506-6452126a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_769x769_80k_cityscapes/deeplabv3_r18-d8_769x769_80k_cityscapes-20201225_021506.log.json) | -| DeepLabV3 | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.89 | 81.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_80k_cityscapes/deeplabv3_r50-d8_769x769_80k_cityscapes_20200606_221338-788d6228.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_80k_cityscapes/deeplabv3_r50-d8_769x769_80k_cityscapes_20200606_221338.log.json) | -| DeepLabV3 | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.67 | 80.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_80k_cityscapes/deeplabv3_r101-d8_769x769_80k_cityscapes_20200607_013353-60e95418.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_80k_cityscapes/deeplabv3_r101-d8_769x769_80k_cityscapes_20200607_013353.log.json) | -| DeepLabV3 | R-101-D16-MG124 | 512x1024 | 40000 | 4.7 | 6.96 | V100 | 76.71 | 78.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d16-mg124_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes_20200908_005644-67b0c992.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes-20200908_005644.log.json) | -| DeepLabV3 | R-101-D16-MG124 | 512x1024 | 80000 | - | - | V100 | 78.36 | 79.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d16-mg124_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes_20200908_005644-57bb8425.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes-20200908_005644.log.json) | -| DeepLabV3 | R-18b-D8 | 512x1024 | 80000 | 1.6 | 13.93 | V100 | 76.26 | 77.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_512x1024_80k_cityscapes/deeplabv3_r18b-d8_512x1024_80k_cityscapes_20201225_094144-46040cef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_512x1024_80k_cityscapes/deeplabv3_r18b-d8_512x1024_80k_cityscapes-20201225_094144.log.json) | -| DeepLabV3 | R-50b-D8 | 512x1024 | 80000 | 6.0 | 2.74 | V100 | 79.63 | 80.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_512x1024_80k_cityscapes/deeplabv3_r50b-d8_512x1024_80k_cityscapes_20201225_155148-ec368954.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_512x1024_80k_cityscapes/deeplabv3_r50b-d8_512x1024_80k_cityscapes-20201225_155148.log.json) | -| DeepLabV3 | R-101b-D8 | 512x1024 | 80000 | 9.5 | 1.81 | V100 | 80.01 | 81.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_512x1024_80k_cityscapes/deeplabv3_r101b-d8_512x1024_80k_cityscapes_20201226_171821-8fd49503.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_512x1024_80k_cityscapes/deeplabv3_r101b-d8_512x1024_80k_cityscapes-20201226_171821.log.json) | -| DeepLabV3 | R-18b-D8 | 769x769 | 80000 | 1.8 | 5.79 | V100 | 75.63 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_769x769_80k_cityscapes/deeplabv3_r18b-d8_769x769_80k_cityscapes_20201225_094144-fdc985d9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_769x769_80k_cityscapes/deeplabv3_r18b-d8_769x769_80k_cityscapes-20201225_094144.log.json) | -| DeepLabV3 | R-50b-D8 | 769x769 | 80000 | 6.8 | 1.16 | V100 | 78.80 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_769x769_80k_cityscapes/deeplabv3_r50b-d8_769x769_80k_cityscapes_20201225_155404-87fb0cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_769x769_80k_cityscapes/deeplabv3_r50b-d8_769x769_80k_cityscapes-20201225_155404.log.json) | -| DeepLabV3 | R-101b-D8 | 769x769 | 80000 | 10.7 | 0.82 | V100 | 79.41 | 80.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_769x769_80k_cityscapes/deeplabv3_r101b-d8_769x769_80k_cityscapes_20201226_190843-9142ee57.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_769x769_80k_cityscapes/deeplabv3_r101b-d8_769x769_80k_cityscapes-20201226_190843.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------------- | --------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| DeepLabV3 | R-50-D8 | 512x1024 | 40000 | 6.1 | 2.57 | V100 | 79.09 | 80.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_40k_cityscapes/deeplabv3_r50-d8_512x1024_40k_cityscapes_20200605_022449-acadc2f8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_40k_cityscapes/deeplabv3_r50-d8_512x1024_40k_cityscapes_20200605_022449.log.json) | +| DeepLabV3 | R-101-D8 | 512x1024 | 40000 | 9.6 | 1.92 | V100 | 77.12 | 79.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_40k_cityscapes/deeplabv3_r101-d8_512x1024_40k_cityscapes_20200605_012241-7fd3f799.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_40k_cityscapes/deeplabv3_r101-d8_512x1024_40k_cityscapes_20200605_012241.log.json) | +| DeepLabV3 | R-50-D8 | 769x769 | 40000 | 6.9 | 1.11 | V100 | 78.58 | 79.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_40k_cityscapes/deeplabv3_r50-d8_769x769_40k_cityscapes_20200606_113723-7eda553c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_40k_cityscapes/deeplabv3_r50-d8_769x769_40k_cityscapes_20200606_113723.log.json) | +| DeepLabV3 | R-101-D8 | 769x769 | 40000 | 10.9 | 0.83 | V100 | 79.27 | 80.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_40k_cityscapes/deeplabv3_r101-d8_769x769_40k_cityscapes_20200606_113809-c64f889f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_40k_cityscapes/deeplabv3_r101-d8_769x769_40k_cityscapes_20200606_113809.log.json) | +| DeepLabV3 | R-18-D8 | 512x1024 | 80000 | 1.7 | 13.78 | V100 | 76.70 | 78.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_512x1024_80k_cityscapes/deeplabv3_r18-d8_512x1024_80k_cityscapes_20201225_021506-23dffbe2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_512x1024_80k_cityscapes/deeplabv3_r18-d8_512x1024_80k_cityscapes-20201225_021506.log.json) | +| DeepLabV3 | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.32 | 80.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_80k_cityscapes/deeplabv3_r50-d8_512x1024_80k_cityscapes_20200606_113404-b92cfdd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_80k_cityscapes/deeplabv3_r50-d8_512x1024_80k_cityscapes_20200606_113404.log.json) | +| DeepLabV3 | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.20 | 81.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_80k_cityscapes/deeplabv3_r101-d8_512x1024_80k_cityscapes_20200606_113503-9e428899.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x1024_80k_cityscapes/deeplabv3_r101-d8_512x1024_80k_cityscapes_20200606_113503.log.json) | +| DeepLabV3 (FP16) | R-101-D8 | 512x1024 | 80000 | 5.75 | 3.86 | V100 | 80.48 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920-774d9cec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920.log.json) | +| DeepLabV3 | R-18-D8 | 769x769 | 80000 | 1.9 | 5.55 | V100 | 76.60 | 78.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_769x769_80k_cityscapes/deeplabv3_r18-d8_769x769_80k_cityscapes_20201225_021506-6452126a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18-d8_769x769_80k_cityscapes/deeplabv3_r18-d8_769x769_80k_cityscapes-20201225_021506.log.json) | +| DeepLabV3 | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.89 | 81.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_80k_cityscapes/deeplabv3_r50-d8_769x769_80k_cityscapes_20200606_221338-788d6228.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_769x769_80k_cityscapes/deeplabv3_r50-d8_769x769_80k_cityscapes_20200606_221338.log.json) | +| DeepLabV3 | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.67 | 80.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_80k_cityscapes/deeplabv3_r101-d8_769x769_80k_cityscapes_20200607_013353-60e95418.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_769x769_80k_cityscapes/deeplabv3_r101-d8_769x769_80k_cityscapes_20200607_013353.log.json) | +| DeepLabV3 | R-101-D16-MG124 | 512x1024 | 40000 | 4.7 | 6.96 | V100 | 76.71 | 78.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d16-mg124_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes_20200908_005644-67b0c992.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_40k_cityscapes-20200908_005644.log.json) | +| DeepLabV3 | R-101-D16-MG124 | 512x1024 | 80000 | - | - | V100 | 78.36 | 79.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d16-mg124_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes_20200908_005644-57bb8425.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3_r101-d16-mg124_512x1024_80k_cityscapes-20200908_005644.log.json) | +| DeepLabV3 | R-18b-D8 | 512x1024 | 80000 | 1.6 | 13.93 | V100 | 76.26 | 77.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_512x1024_80k_cityscapes/deeplabv3_r18b-d8_512x1024_80k_cityscapes_20201225_094144-46040cef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_512x1024_80k_cityscapes/deeplabv3_r18b-d8_512x1024_80k_cityscapes-20201225_094144.log.json) | +| DeepLabV3 | R-50b-D8 | 512x1024 | 80000 | 6.0 | 2.74 | V100 | 79.63 | 80.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_512x1024_80k_cityscapes/deeplabv3_r50b-d8_512x1024_80k_cityscapes_20201225_155148-ec368954.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_512x1024_80k_cityscapes/deeplabv3_r50b-d8_512x1024_80k_cityscapes-20201225_155148.log.json) | +| DeepLabV3 | R-101b-D8 | 512x1024 | 80000 | 9.5 | 1.81 | V100 | 80.01 | 81.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_512x1024_80k_cityscapes/deeplabv3_r101b-d8_512x1024_80k_cityscapes_20201226_171821-8fd49503.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_512x1024_80k_cityscapes/deeplabv3_r101b-d8_512x1024_80k_cityscapes-20201226_171821.log.json) | +| DeepLabV3 | R-18b-D8 | 769x769 | 80000 | 1.8 | 5.79 | V100 | 75.63 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_769x769_80k_cityscapes/deeplabv3_r18b-d8_769x769_80k_cityscapes_20201225_094144-fdc985d9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r18b-d8_769x769_80k_cityscapes/deeplabv3_r18b-d8_769x769_80k_cityscapes-20201225_094144.log.json) | +| DeepLabV3 | R-50b-D8 | 769x769 | 80000 | 6.8 | 1.16 | V100 | 78.80 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_769x769_80k_cityscapes/deeplabv3_r50b-d8_769x769_80k_cityscapes_20201225_155404-87fb0cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50b-d8_769x769_80k_cityscapes/deeplabv3_r50b-d8_769x769_80k_cityscapes-20201225_155404.log.json) | +| DeepLabV3 | R-101b-D8 | 769x769 | 80000 | 10.7 | 0.82 | V100 | 79.41 | 80.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_769x769_80k_cityscapes/deeplabv3_r101b-d8_769x769_80k_cityscapes_20201226_190843-9142ee57.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101b-d8_769x769_80k_cityscapes/deeplabv3_r101b-d8_769x769_80k_cityscapes-20201226_190843.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-50-D8 | 512x512 | 80000 | 8.9 | 14.76 | V100 | 42.42 | 43.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_80k_ade20k/deeplabv3_r50-d8_512x512_80k_ade20k_20200614_185028-0bb3f844.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_80k_ade20k/deeplabv3_r50-d8_512x512_80k_ade20k_20200614_185028.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 80000 | 12.4 | 10.14 | V100 | 44.08 | 45.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_80k_ade20k/deeplabv3_r101-d8_512x512_80k_ade20k_20200615_021256-d89c7fa4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_80k_ade20k/deeplabv3_r101-d8_512x512_80k_ade20k_20200615_021256.log.json) | -| DeepLabV3 | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.66 | 44.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_160k_ade20k/deeplabv3_r50-d8_512x512_160k_ade20k_20200615_123227-5d0ee427.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_160k_ade20k/deeplabv3_r50-d8_512x512_160k_ade20k_20200615_123227.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.00 | 46.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_160k_ade20k/deeplabv3_r101-d8_512x512_160k_ade20k_20200615_105816-b1f72b3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_160k_ade20k/deeplabv3_r101-d8_512x512_160k_ade20k_20200615_105816.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-50-D8 | 512x512 | 80000 | 8.9 | 14.76 | V100 | 42.42 | 43.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_80k_ade20k/deeplabv3_r50-d8_512x512_80k_ade20k_20200614_185028-0bb3f844.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_80k_ade20k/deeplabv3_r50-d8_512x512_80k_ade20k_20200614_185028.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 80000 | 12.4 | 10.14 | V100 | 44.08 | 45.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_80k_ade20k/deeplabv3_r101-d8_512x512_80k_ade20k_20200615_021256-d89c7fa4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_80k_ade20k/deeplabv3_r101-d8_512x512_80k_ade20k_20200615_021256.log.json) | +| DeepLabV3 | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.66 | 44.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_160k_ade20k/deeplabv3_r50-d8_512x512_160k_ade20k_20200615_123227-5d0ee427.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_160k_ade20k/deeplabv3_r50-d8_512x512_160k_ade20k_20200615_123227.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.00 | 46.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_160k_ade20k/deeplabv3_r101-d8_512x512_160k_ade20k_20200615_105816-b1f72b3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_160k_ade20k/deeplabv3_r101-d8_512x512_160k_ade20k_20200615_105816.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-50-D8 | 512x512 | 20000 | 6.1 | 13.88 | V100 | 76.17 | 77.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_20k_voc12aug/deeplabv3_r50-d8_512x512_20k_voc12aug_20200617_010906-596905ef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_20k_voc12aug/deeplabv3_r50-d8_512x512_20k_voc12aug_20200617_010906.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 20000 | 9.6 | 9.81 | V100 | 78.70 | 79.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_20k_voc12aug/deeplabv3_r101-d8_512x512_20k_voc12aug_20200617_010932-8d13832f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_20k_voc12aug/deeplabv3_r101-d8_512x512_20k_voc12aug_20200617_010932.log.json) | -| DeepLabV3 | R-50-D8 | 512x512 | 40000 | - | - | V100 | 77.68 | 78.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_40k_voc12aug/deeplabv3_r50-d8_512x512_40k_voc12aug_20200613_161546-2ae96e7e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_40k_voc12aug/deeplabv3_r50-d8_512x512_40k_voc12aug_20200613_161546.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.92 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_40k_voc12aug/deeplabv3_r101-d8_512x512_40k_voc12aug_20200613_161432-0017d784.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_40k_voc12aug/deeplabv3_r101-d8_512x512_40k_voc12aug_20200613_161432.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-50-D8 | 512x512 | 20000 | 6.1 | 13.88 | V100 | 76.17 | 77.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_20k_voc12aug/deeplabv3_r50-d8_512x512_20k_voc12aug_20200617_010906-596905ef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_20k_voc12aug/deeplabv3_r50-d8_512x512_20k_voc12aug_20200617_010906.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 20000 | 9.6 | 9.81 | V100 | 78.70 | 79.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_20k_voc12aug/deeplabv3_r101-d8_512x512_20k_voc12aug_20200617_010932-8d13832f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_20k_voc12aug/deeplabv3_r101-d8_512x512_20k_voc12aug_20200617_010932.log.json) | +| DeepLabV3 | R-50-D8 | 512x512 | 40000 | - | - | V100 | 77.68 | 78.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_40k_voc12aug/deeplabv3_r50-d8_512x512_40k_voc12aug_20200613_161546-2ae96e7e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_40k_voc12aug/deeplabv3_r50-d8_512x512_40k_voc12aug_20200613_161546.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.92 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_40k_voc12aug/deeplabv3_r101-d8_512x512_40k_voc12aug_20200613_161432-0017d784.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_40k_voc12aug/deeplabv3_r101-d8_512x512_40k_voc12aug_20200613_161432.log.json) | ### Pascal Context -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-101-D8 | 480x480 | 40000 | 9.2 | 7.09 | V100 | 46.55 | 47.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context/deeplabv3_r101-d8_480x480_40k_pascal_context_20200911_204118-1aa27336.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context/deeplabv3_r101-d8_480x480_40k_pascal_context-20200911_204118.log.json) | -| DeepLabV3 | R-101-D8 | 480x480 | 80000 | - | - | V100 | 46.42 | 47.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context/deeplabv3_r101-d8_480x480_80k_pascal_context_20200911_170155-2a21fff3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context/deeplabv3_r101-d8_480x480_80k_pascal_context-20200911_170155.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-101-D8 | 480x480 | 40000 | 9.2 | 7.09 | V100 | 46.55 | 47.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context/deeplabv3_r101-d8_480x480_40k_pascal_context_20200911_204118-1aa27336.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context/deeplabv3_r101-d8_480x480_40k_pascal_context-20200911_204118.log.json) | +| DeepLabV3 | R-101-D8 | 480x480 | 80000 | - | - | V100 | 46.42 | 47.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context/deeplabv3_r101-d8_480x480_80k_pascal_context_20200911_170155-2a21fff3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context/deeplabv3_r101-d8_480x480_80k_pascal_context-20200911_170155.log.json) | ### Pascal Context 59 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.61 | 54.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context_59/deeplabv3_r101-d8_480x480_40k_pascal_context_59_20210416_110332-cb08ea46.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context_59/deeplabv3_r101-d8_480x480_40k_pascal_context_59-20210416_110332.log.json) | -| DeepLabV3 | R-101-D8 | 480x480 | 80000 | - | - | V100 | 52.46 | 54.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context_59/deeplabv3_r101-d8_480x480_80k_pascal_context_59_20210416_113002-26303993.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context_59/deeplabv3_r101-d8_480x480_80k_pascal_context_59-20210416_113002.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.61 | 54.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context_59/deeplabv3_r101-d8_480x480_40k_pascal_context_59_20210416_110332-cb08ea46.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_40k_pascal_context_59/deeplabv3_r101-d8_480x480_40k_pascal_context_59-20210416_110332.log.json) | +| DeepLabV3 | R-101-D8 | 480x480 | 80000 | - | - | V100 | 52.46 | 54.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context_59/deeplabv3_r101-d8_480x480_80k_pascal_context_59_20210416_113002-26303993.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_480x480_80k_pascal_context_59/deeplabv3_r101-d8_480x480_80k_pascal_context_59-20210416_113002.log.json) | ### COCO-Stuff 10k -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-50-D8 | 512x512 | 20000 | 9.6 | 10.8 | V100 | 34.66 | 36.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025-b35f789d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 20000 | 13.2 | 8.7 | V100 | 37.30 | 38.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025-c49752cb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025.log.json) | -| DeepLabV3 | R-50-D8 | 512x512 | 40000 | - | - | V100 | 35.73 | 37.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305-dc76f3ff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 40000 | - | - | V100 | 37.81 | 38.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305-636cb433.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-50-D8 | 512x512 | 20000 | 9.6 | 10.8 | V100 | 34.66 | 36.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025-b35f789d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 20000 | 13.2 | 8.7 | V100 | 37.30 | 38.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025-c49752cb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_20k_coco-stuff10k_20210821_043025.log.json) | +| DeepLabV3 | R-50-D8 | 512x512 | 40000 | - | - | V100 | 35.73 | 37.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305-dc76f3ff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 40000 | - | - | V100 | 37.81 | 38.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305-636cb433.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k/deeplabv3_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_043305.log.json) | ### COCO-Stuff 164k -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3 | R-50-D8 | 512x512 | 80000 | 9.6 | 10.8 | V100 | 39.38 | 40.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k_20210709_163016-88675c24.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k_20210709_163016.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 80000 | 13.2 | 8.7 | V100 | 40.87 | 41.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k_20210709_201252-13600dc2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k_20210709_201252.log.json) | -| DeepLabV3 | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.09 | 41.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k_20210709_163016-49f2812b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k_20210709_163016.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 160000 | - | - | V100 | 41.82 | 42.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k_20210709_155402-f035acfd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k_20210709_155402.log.json) | -| DeepLabV3 | R-50-D8 | 512x512 | 320000 | - | - | V100 | 41.37 | 42.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r50-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k_20210709_155403-51b21115.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k_20210709_155403.log.json) | -| DeepLabV3 | R-101-D8 | 512x512 | 320000 | - | - | V100 | 42.61 | 43.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3/deeplabv3_r101-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k_20210709_155402-3cbca14d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k_20210709_155402.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3 | R-50-D8 | 512x512 | 80000 | 9.6 | 10.8 | V100 | 39.38 | 40.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k_20210709_163016-88675c24.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_80k_coco-stuff164k_20210709_163016.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 80000 | 13.2 | 8.7 | V100 | 40.87 | 41.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k_20210709_201252-13600dc2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_80k_coco-stuff164k_20210709_201252.log.json) | +| DeepLabV3 | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.09 | 41.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k_20210709_163016-49f2812b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_160k_coco-stuff164k_20210709_163016.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 160000 | - | - | V100 | 41.82 | 42.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k_20210709_155402-f035acfd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_160k_coco-stuff164k_20210709_155402.log.json) | +| DeepLabV3 | R-50-D8 | 512x512 | 320000 | - | - | V100 | 41.37 | 42.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r50-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k_20210709_155403-51b21115.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r50-d8_512x512_4x4_320k_coco-stuff164k_20210709_155403.log.json) | +| DeepLabV3 | R-101-D8 | 512x512 | 320000 | - | - | V100 | 42.61 | 43.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3/deeplabv3_r101-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k_20210709_155402-3cbca14d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k/deeplabv3_r101-d8_512x512_4x4_320k_coco-stuff164k_20210709_155402.log.json) | Note: diff --git a/configs/deeplabv3plus/README.md b/configs/deeplabv3plus/README.md index 15c51a504ad..04d01fa5124 100644 --- a/configs/deeplabv3plus/README.md +++ b/configs/deeplabv3plus/README.md @@ -26,98 +26,98 @@ Spatial pyramid pooling module or encode-decoder structure are used in deep neur ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------------- | --------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| DeepLabV3+ | R-50-D8 | 512x1024 | 40000 | 7.5 | 3.94 | V100 | 79.61 | 81.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_40k_cityscapes/deeplabv3plus_r50-d8_512x1024_40k_cityscapes_20200605_094610-d222ffcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_40k_cityscapes/deeplabv3plus_r50-d8_512x1024_40k_cityscapes_20200605_094610.log.json) | -| DeepLabV3+ | R-101-D8 | 512x1024 | 40000 | 11 | 2.60 | V100 | 80.21 | 81.82 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_40k_cityscapes/deeplabv3plus_r101-d8_512x1024_40k_cityscapes_20200605_094614-3769eecf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_40k_cityscapes/deeplabv3plus_r101-d8_512x1024_40k_cityscapes_20200605_094614.log.json) | -| DeepLabV3+ | R-50-D8 | 769x769 | 40000 | 8.5 | 1.72 | V100 | 78.97 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_40k_cityscapes/deeplabv3plus_r50-d8_769x769_40k_cityscapes_20200606_114143-1dcb0e3c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_40k_cityscapes/deeplabv3plus_r50-d8_769x769_40k_cityscapes_20200606_114143.log.json) | -| DeepLabV3+ | R-101-D8 | 769x769 | 40000 | 12.5 | 1.15 | V100 | 79.46 | 80.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_40k_cityscapes/deeplabv3plus_r101-d8_769x769_40k_cityscapes_20200606_114304-ff414b9e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_40k_cityscapes/deeplabv3plus_r101-d8_769x769_40k_cityscapes_20200606_114304.log.json) | -| DeepLabV3+ | R-18-D8 | 512x1024 | 80000 | 2.2 | 14.27 | V100 | 76.89 | 78.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x1024_80k_cityscapes/deeplabv3plus_r18-d8_512x1024_80k_cityscapes_20201226_080942-cff257fe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x1024_80k_cityscapes/deeplabv3plus_r18-d8_512x1024_80k_cityscapes-20201226_080942.log.json) | -| DeepLabV3+ | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 80.09 | 81.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_80k_cityscapes/deeplabv3plus_r50-d8_512x1024_80k_cityscapes_20200606_114049-f9fb496d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_80k_cityscapes/deeplabv3plus_r50-d8_512x1024_80k_cityscapes_20200606_114049.log.json) | -| DeepLabV3+ | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.97 | 82.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_512x1024_80k_cityscapes_20200606_114143-068fcfe9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_512x1024_80k_cityscapes_20200606_114143.log.json) | -| DeepLabV3+ (FP16) | R-101-D8 | 512x1024 | 80000 | 6.35 | 7.87 | V100 | 80.46 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920-f1104f4b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920.log.json) | -| DeepLabV3+ | R-18-D8 | 769x769 | 80000 | 2.5 | 5.74 | V100 | 76.26 | 77.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_769x769_80k_cityscapes/deeplabv3plus_r18-d8_769x769_80k_cityscapes_20201226_083346-f326e06a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_769x769_80k_cityscapes/deeplabv3plus_r18-d8_769x769_80k_cityscapes-20201226_083346.log.json) | -| DeepLabV3+ | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.83 | 81.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_80k_cityscapes/deeplabv3plus_r50-d8_769x769_80k_cityscapes_20200606_210233-0e9dfdc4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_80k_cityscapes/deeplabv3plus_r50-d8_769x769_80k_cityscapes_20200606_210233.log.json) | -| DeepLabV3+ | R-101-D8 | 769x769 | 80000 | - | - | V100 | 80.65 | 81.47 | [config\[1\]](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_80k_cityscapes/deeplabv3plus_r101-d8_769x769_80k_cityscapes_20220406_154720-dfcc0b68.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_80k_cityscapes/deeplabv3plus_r101-d8_769x769_80k_cityscapes_20220406_154720.log.json) | -| DeepLabV3+ | R-101-D16-MG124 | 512x1024 | 40000 | 5.8 | 7.48 | V100 | 79.09 | 80.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/ddeeplabv3plus_r101-d16-mg124_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes_20200908_005644-cf9ce186.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes-20200908_005644.log.json) | -| DeepLabV3+ | R-101-D16-MG124 | 512x1024 | 80000 | 9.9 | - | V100 | 79.90 | 81.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d16-mg124_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes_20200908_005644-ee6158e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes-20200908_005644.log.json) | -| DeepLabV3+ | R-18b-D8 | 512x1024 | 80000 | 2.1 | 14.95 | V100 | 75.87 | 77.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes_20201226_090828-e451abd9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes-20201226_090828.log.json) | -| DeepLabV3+ | R-50b-D8 | 512x1024 | 80000 | 7.4 | 3.94 | V100 | 80.28 | 81.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes_20201225_213645-a97e4e43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes-20201225_213645.log.json) | -| DeepLabV3+ | R-101b-D8 | 512x1024 | 80000 | 10.9 | 2.60 | V100 | 80.16 | 81.41 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes_20201226_190843-9c3c93a4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes-20201226_190843.log.json) | -| DeepLabV3+ | R-18b-D8 | 769x769 | 80000 | 2.4 | 5.96 | V100 | 76.36 | 78.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_769x769_80k_cityscapes/deeplabv3plus_r18b-d8_769x769_80k_cityscapes_20201226_151312-2c868aff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_769x769_80k_cityscapes/deeplabv3plus_r18b-d8_769x769_80k_cityscapes-20201226_151312.log.json) | -| DeepLabV3+ | R-50b-D8 | 769x769 | 80000 | 8.4 | 1.72 | V100 | 79.41 | 80.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_769x769_80k_cityscapes/deeplabv3plus_r50b-d8_769x769_80k_cityscapes_20201225_224655-8b596d1c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_769x769_80k_cityscapes/deeplabv3plus_r50b-d8_769x769_80k_cityscapes-20201225_224655.log.json) | -| DeepLabV3+ | R-101b-D8 | 769x769 | 80000 | 12.3 | 1.10 | V100 | 79.88 | 81.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_769x769_80k_cityscapes/deeplabv3plus_r101b-d8_769x769_80k_cityscapes_20201226_205041-227cdf7c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_769x769_80k_cityscapes/deeplabv3plus_r101b-d8_769x769_80k_cityscapes-20201226_205041.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------------- | --------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| DeepLabV3+ | R-50-D8 | 512x1024 | 40000 | 7.5 | 3.94 | V100 | 79.61 | 81.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_40k_cityscapes/deeplabv3plus_r50-d8_512x1024_40k_cityscapes_20200605_094610-d222ffcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_40k_cityscapes/deeplabv3plus_r50-d8_512x1024_40k_cityscapes_20200605_094610.log.json) | +| DeepLabV3+ | R-101-D8 | 512x1024 | 40000 | 11 | 2.60 | V100 | 80.21 | 81.82 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_40k_cityscapes/deeplabv3plus_r101-d8_512x1024_40k_cityscapes_20200605_094614-3769eecf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_40k_cityscapes/deeplabv3plus_r101-d8_512x1024_40k_cityscapes_20200605_094614.log.json) | +| DeepLabV3+ | R-50-D8 | 769x769 | 40000 | 8.5 | 1.72 | V100 | 78.97 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_40k_cityscapes/deeplabv3plus_r50-d8_769x769_40k_cityscapes_20200606_114143-1dcb0e3c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_40k_cityscapes/deeplabv3plus_r50-d8_769x769_40k_cityscapes_20200606_114143.log.json) | +| DeepLabV3+ | R-101-D8 | 769x769 | 40000 | 12.5 | 1.15 | V100 | 79.46 | 80.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_40k_cityscapes/deeplabv3plus_r101-d8_769x769_40k_cityscapes_20200606_114304-ff414b9e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_40k_cityscapes/deeplabv3plus_r101-d8_769x769_40k_cityscapes_20200606_114304.log.json) | +| DeepLabV3+ | R-18-D8 | 512x1024 | 80000 | 2.2 | 14.27 | V100 | 76.89 | 78.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x1024_80k_cityscapes/deeplabv3plus_r18-d8_512x1024_80k_cityscapes_20201226_080942-cff257fe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x1024_80k_cityscapes/deeplabv3plus_r18-d8_512x1024_80k_cityscapes-20201226_080942.log.json) | +| DeepLabV3+ | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 80.09 | 81.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_80k_cityscapes/deeplabv3plus_r50-d8_512x1024_80k_cityscapes_20200606_114049-f9fb496d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x1024_80k_cityscapes/deeplabv3plus_r50-d8_512x1024_80k_cityscapes_20200606_114049.log.json) | +| DeepLabV3+ | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.97 | 82.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_512x1024_80k_cityscapes_20200606_114143-068fcfe9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_512x1024_80k_cityscapes_20200606_114143.log.json) | +| DeepLabV3+ (FP16) | R-101-D8 | 512x1024 | 80000 | 6.35 | 7.87 | V100 | 80.46 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920-f1104f4b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes/deeplabv3plus_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230920.log.json) | +| DeepLabV3+ | R-18-D8 | 769x769 | 80000 | 2.5 | 5.74 | V100 | 76.26 | 77.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_769x769_80k_cityscapes/deeplabv3plus_r18-d8_769x769_80k_cityscapes_20201226_083346-f326e06a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_769x769_80k_cityscapes/deeplabv3plus_r18-d8_769x769_80k_cityscapes-20201226_083346.log.json) | +| DeepLabV3+ | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.83 | 81.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_80k_cityscapes/deeplabv3plus_r50-d8_769x769_80k_cityscapes_20200606_210233-0e9dfdc4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_769x769_80k_cityscapes/deeplabv3plus_r50-d8_769x769_80k_cityscapes_20200606_210233.log.json) | +| DeepLabV3+ | R-101-D8 | 769x769 | 80000 | - | - | V100 | 80.65 | 81.47 | [config\[1\]](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_80k_cityscapes/deeplabv3plus_r101-d8_769x769_80k_cityscapes_20220406_154720-dfcc0b68.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_769x769_80k_cityscapes/deeplabv3plus_r101-d8_769x769_80k_cityscapes_20220406_154720.log.json) | +| DeepLabV3+ | R-101-D16-MG124 | 512x1024 | 40000 | 5.8 | 7.48 | V100 | 79.09 | 80.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/ddeeplabv3plus_r101-d16-mg124_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes_20200908_005644-cf9ce186.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_40k_cityscapes-20200908_005644.log.json) | +| DeepLabV3+ | R-101-D16-MG124 | 512x1024 | 80000 | 9.9 | - | V100 | 79.90 | 81.33 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d16-mg124_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes_20200908_005644-ee6158e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes/deeplabv3plus_r101-d16-mg124_512x1024_80k_cityscapes-20200908_005644.log.json) | +| DeepLabV3+ | R-18b-D8 | 512x1024 | 80000 | 2.1 | 14.95 | V100 | 75.87 | 77.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes_20201226_090828-e451abd9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes/deeplabv3plus_r18b-d8_512x1024_80k_cityscapes-20201226_090828.log.json) | +| DeepLabV3+ | R-50b-D8 | 512x1024 | 80000 | 7.4 | 3.94 | V100 | 80.28 | 81.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes_20201225_213645-a97e4e43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes/deeplabv3plus_r50b-d8_512x1024_80k_cityscapes-20201225_213645.log.json) | +| DeepLabV3+ | R-101b-D8 | 512x1024 | 80000 | 10.9 | 2.60 | V100 | 80.16 | 81.41 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes_20201226_190843-9c3c93a4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes/deeplabv3plus_r101b-d8_512x1024_80k_cityscapes-20201226_190843.log.json) | +| DeepLabV3+ | R-18b-D8 | 769x769 | 80000 | 2.4 | 5.96 | V100 | 76.36 | 78.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_769x769_80k_cityscapes/deeplabv3plus_r18b-d8_769x769_80k_cityscapes_20201226_151312-2c868aff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18b-d8_769x769_80k_cityscapes/deeplabv3plus_r18b-d8_769x769_80k_cityscapes-20201226_151312.log.json) | +| DeepLabV3+ | R-50b-D8 | 769x769 | 80000 | 8.4 | 1.72 | V100 | 79.41 | 80.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_769x769_80k_cityscapes/deeplabv3plus_r50b-d8_769x769_80k_cityscapes_20201225_224655-8b596d1c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50b-d8_769x769_80k_cityscapes/deeplabv3plus_r50b-d8_769x769_80k_cityscapes-20201225_224655.log.json) | +| DeepLabV3+ | R-101b-D8 | 769x769 | 80000 | 12.3 | 1.10 | V100 | 79.88 | 81.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_769x769_80k_cityscapes/deeplabv3plus_r101b-d8_769x769_80k_cityscapes_20201226_205041-227cdf7c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101b-d8_769x769_80k_cityscapes/deeplabv3plus_r101b-d8_769x769_80k_cityscapes-20201226_205041.log.json) | \[1\] The training of the model is sensitive to random seed, and the seed to train it is 1111. ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 10.6 | 21.01 | V100 | 42.72 | 43.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_ade20k/deeplabv3plus_r50-d8_512x512_80k_ade20k_20200614_185028-bf1400d8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_ade20k/deeplabv3plus_r50-d8_512x512_80k_ade20k_20200614_185028.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 14.1 | 14.16 | V100 | 44.60 | 46.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_ade20k/deeplabv3plus_r101-d8_512x512_80k_ade20k_20200615_014139-d5730af7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_ade20k/deeplabv3plus_r101-d8_512x512_80k_ade20k_20200615_014139.log.json) | -| DeepLabV3+ | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.95 | 44.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_160k_ade20k/deeplabv3plus_r50-d8_512x512_160k_ade20k_20200615_124504-6135c7e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_160k_ade20k/deeplabv3plus_r50-d8_512x512_160k_ade20k_20200615_124504.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.47 | 46.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_160k_ade20k/deeplabv3plus_r101-d8_512x512_160k_ade20k_20200615_123232-38ed86bb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_160k_ade20k/deeplabv3plus_r101-d8_512x512_160k_ade20k_20200615_123232.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 10.6 | 21.01 | V100 | 42.72 | 43.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_ade20k/deeplabv3plus_r50-d8_512x512_80k_ade20k_20200614_185028-bf1400d8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_ade20k/deeplabv3plus_r50-d8_512x512_80k_ade20k_20200614_185028.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 14.1 | 14.16 | V100 | 44.60 | 46.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_ade20k/deeplabv3plus_r101-d8_512x512_80k_ade20k_20200615_014139-d5730af7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_ade20k/deeplabv3plus_r101-d8_512x512_80k_ade20k_20200615_014139.log.json) | +| DeepLabV3+ | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.95 | 44.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_160k_ade20k/deeplabv3plus_r50-d8_512x512_160k_ade20k_20200615_124504-6135c7e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_160k_ade20k/deeplabv3plus_r50-d8_512x512_160k_ade20k_20200615_124504.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.47 | 46.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_160k_ade20k/deeplabv3plus_r101-d8_512x512_160k_ade20k_20200615_123232-38ed86bb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_160k_ade20k/deeplabv3plus_r101-d8_512x512_160k_ade20k_20200615_123232.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-50-D8 | 512x512 | 20000 | 7.6 | 21 | V100 | 75.93 | 77.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_20k_voc12aug/deeplabv3plus_r50-d8_512x512_20k_voc12aug_20200617_102323-aad58ef1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_20k_voc12aug/deeplabv3plus_r50-d8_512x512_20k_voc12aug_20200617_102323.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 20000 | 11 | 13.88 | V100 | 77.22 | 78.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_20k_voc12aug/deeplabv3plus_r101-d8_512x512_20k_voc12aug_20200617_102345-c7ff3d56.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_20k_voc12aug/deeplabv3plus_r101-d8_512x512_20k_voc12aug_20200617_102345.log.json) | -| DeepLabV3+ | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.81 | 77.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_40k_voc12aug/deeplabv3plus_r50-d8_512x512_40k_voc12aug_20200613_161759-e1b43aa9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_40k_voc12aug/deeplabv3plus_r50-d8_512x512_40k_voc12aug_20200613_161759.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.62 | 79.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_40k_voc12aug/deeplabv3plus_r101-d8_512x512_40k_voc12aug_20200613_205333-faf03387.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_40k_voc12aug/deeplabv3plus_r101-d8_512x512_40k_voc12aug_20200613_205333.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-50-D8 | 512x512 | 20000 | 7.6 | 21 | V100 | 75.93 | 77.50 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_20k_voc12aug/deeplabv3plus_r50-d8_512x512_20k_voc12aug_20200617_102323-aad58ef1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_20k_voc12aug/deeplabv3plus_r50-d8_512x512_20k_voc12aug_20200617_102323.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 20000 | 11 | 13.88 | V100 | 77.22 | 78.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_20k_voc12aug/deeplabv3plus_r101-d8_512x512_20k_voc12aug_20200617_102345-c7ff3d56.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_20k_voc12aug/deeplabv3plus_r101-d8_512x512_20k_voc12aug_20200617_102345.log.json) | +| DeepLabV3+ | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.81 | 77.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_40k_voc12aug/deeplabv3plus_r50-d8_512x512_40k_voc12aug_20200613_161759-e1b43aa9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_40k_voc12aug/deeplabv3plus_r50-d8_512x512_40k_voc12aug_20200613_161759.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.62 | 79.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_40k_voc12aug/deeplabv3plus_r101-d8_512x512_40k_voc12aug_20200613_205333-faf03387.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_40k_voc12aug/deeplabv3plus_r101-d8_512x512_40k_voc12aug_20200613_205333.log.json) | ### Pascal Context -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-101-D8 | 480x480 | 40000 | - | 9.09 | V100 | 47.30 | 48.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context/deeplabv3plus_r101-d8_480x480_40k_pascal_context_20200911_165459-d3c8a29e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context/deeplabv3plus_r101-d8_480x480_40k_pascal_context-20200911_165459.log.json) | -| DeepLabV3+ | R-101-D8 | 480x480 | 80000 | - | - | V100 | 47.23 | 48.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context/deeplabv3plus_r101-d8_480x480_80k_pascal_context_20200911_155322-145d3ee8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context/deeplabv3plus_r101-d8_480x480_80k_pascal_context-20200911_155322.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-101-D8 | 480x480 | 40000 | - | 9.09 | V100 | 47.30 | 48.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context/deeplabv3plus_r101-d8_480x480_40k_pascal_context_20200911_165459-d3c8a29e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context/deeplabv3plus_r101-d8_480x480_40k_pascal_context-20200911_165459.log.json) | +| DeepLabV3+ | R-101-D8 | 480x480 | 80000 | - | - | V100 | 47.23 | 48.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context/deeplabv3plus_r101-d8_480x480_80k_pascal_context_20200911_155322-145d3ee8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context/deeplabv3plus_r101-d8_480x480_80k_pascal_context-20200911_155322.log.json) | ### Pascal Context 59 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.86 | 54.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59_20210416_111233-ed937f15.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59-20210416_111233.log.json) | -| DeepLabV3+ | R-101-D8 | 480x480 | 80000 | - | - | V100 | 53.2 | 54.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59_20210416_111127-7ca0331d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59-20210416_111127.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.86 | 54.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59_20210416_111233-ed937f15.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59/deeplabv3plus_r101-d8_480x480_40k_pascal_context_59-20210416_111233.log.json) | +| DeepLabV3+ | R-101-D8 | 480x480 | 80000 | - | - | V100 | 53.2 | 54.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59_20210416_111127-7ca0331d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59/deeplabv3plus_r101-d8_480x480_80k_pascal_context_59-20210416_111127.log.json) | ### LoveDA -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.93 | 25.57 | V100 | 50.28 | 50.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_loveda/deeplabv3plus_r18-d8_512x512_80k_loveda_20211104_132800-ce0fa0ca.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_loveda/deeplabv3plus_r18-d8_512x512_80k_loveda_20211104_132800.log.json) | -| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.37 | 6.00 | V100 | 50.99 | 50.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_loveda/deeplabv3plus_r50-d8_512x512_80k_loveda_20211105_080442-f0720392.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_loveda/deeplabv3plus_r50-d8_512x512_80k_loveda_20211105_080442.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.84 | 4.33 | V100 | 51.47 | 51.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_loveda/deeplabv3plus_r101-d8_512x512_80k_loveda_20211105_110759-4c1f297e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_loveda/deeplabv3plus_r101-d8_512x512_80k_loveda_20211105_110759.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.93 | 25.57 | V100 | 50.28 | 50.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_loveda/deeplabv3plus_r18-d8_512x512_80k_loveda_20211104_132800-ce0fa0ca.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_loveda/deeplabv3plus_r18-d8_512x512_80k_loveda_20211104_132800.log.json) | +| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.37 | 6.00 | V100 | 50.99 | 50.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_loveda/deeplabv3plus_r50-d8_512x512_80k_loveda_20211105_080442-f0720392.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_loveda/deeplabv3plus_r50-d8_512x512_80k_loveda_20211105_080442.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.84 | 4.33 | V100 | 51.47 | 51.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_loveda/deeplabv3plus_r101-d8_512x512_80k_loveda_20211105_110759-4c1f297e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_loveda/deeplabv3plus_r101-d8_512x512_80k_loveda_20211105_110759.log.json) | ### Potsdam -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.91 | 81.68 | V100 | 77.09 | 78.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_potsdam/deeplabv3plus_r18-d8_512x512_80k_potsdam_20211219_020601-75fd5bc3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_potsdam/deeplabv3plus_r18-d8_512x512_80k_potsdam_20211219_020601.log.json) | -| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.36 | 26.44 | V100 | 78.33 | 79.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_potsdam/deeplabv3plus_r50-d8_512x512_80k_potsdam_20211219_031508-7e7a2b24.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_potsdam/deeplabv3plus_r50-d8_512x512_80k_potsdam_20211219_031508.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.83 | 17.56 | V100 | 78.7 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_potsdam/deeplabv3plus_r101-d8_512x512_80k_potsdam_20211219_031508-8b112708.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_potsdam/deeplabv3plus_r101-d8_512x512_80k_potsdam_20211219_031508.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.91 | 81.68 | V100 | 77.09 | 78.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_potsdam/deeplabv3plus_r18-d8_512x512_80k_potsdam_20211219_020601-75fd5bc3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_512x512_80k_potsdam/deeplabv3plus_r18-d8_512x512_80k_potsdam_20211219_020601.log.json) | +| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.36 | 26.44 | V100 | 78.33 | 79.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_potsdam/deeplabv3plus_r50-d8_512x512_80k_potsdam_20211219_031508-7e7a2b24.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_512x512_80k_potsdam/deeplabv3plus_r50-d8_512x512_80k_potsdam_20211219_031508.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.83 | 17.56 | V100 | 78.7 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_potsdam/deeplabv3plus_r101-d8_512x512_80k_potsdam_20211219_031508-8b112708.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_512x512_80k_potsdam/deeplabv3plus_r101-d8_512x512_80k_potsdam_20211219_031508.log.json) | ### Vaihingen -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.91 | 72.79 | V100 | 72.50 | 74.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen_20211231_230805-7626a263.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen_20211231_230805.log.json) | -| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.36 | 26.91 | V100 | 73.97 | 75.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen_20211231_230816-5040938d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen_20211231_230816.log.json) | -| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.83 | 18.59 | V100 | 73.06 | 74.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen_20211231_230816-8a095afa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen_20211231_230816.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-18-D8 | 512x512 | 80000 | 1.91 | 72.79 | V100 | 72.50 | 74.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen_20211231_230805-7626a263.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r18-d8_4x4_512x512_80k_vaihingen_20211231_230805.log.json) | +| DeepLabV3+ | R-50-D8 | 512x512 | 80000 | 7.36 | 26.91 | V100 | 73.97 | 75.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen_20211231_230816-5040938d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r50-d8_4x4_512x512_80k_vaihingen_20211231_230816.log.json) | +| DeepLabV3+ | R-101-D8 | 512x512 | 80000 | 10.83 | 18.59 | V100 | 73.06 | 74.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r101-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen_20211231_230816-8a095afa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen/deeplabv3plus_r101-d8_4x4_512x512_80k_vaihingen_20211231_230816.log.json) | ### iSAID -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-18-D8 | 896x896 | 80000 | 6.19 | 24.81 | V100 | 61.35 | 62.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid_20220110_180526-7059991d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | -| DeepLabV3+ | R-50-D8 | 896x896 | 80000 | 21.45 | 8.42 | V100 | 67.06 | 68.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid_20220110_180526-598be439.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-18-D8 | 896x896 | 80000 | 6.19 | 24.81 | V100 | 61.35 | 62.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r18-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid_20220110_180526-7059991d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid/deeplabv3plus_r18-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | +| DeepLabV3+ | R-50-D8 | 896x896 | 80000 | 21.45 | 8.42 | V100 | 67.06 | 68.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid_20220110_180526-598be439.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid/deeplabv3plus_r50-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | ### Mapillary Vistas v1.2 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DeepLabV3+ | R-50-D8 | 1280x1280 | 300000 | 24.04 | 17.92 | A100 | 47.35 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280_20230301_110504-655f8e43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280_20230301_110504.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DeepLabV3+ | R-50-D8 | 1280x1280 | 300000 | 24.04 | 17.92 | A100 | 47.35 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280_20230301_110504-655f8e43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3plus/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280/deeplabv3plus_r50-d8_4xb2-300k_mapillay_v1_65-1280x1280_20230301_110504.json) | Note: diff --git a/configs/dmnet/README.md b/configs/dmnet/README.md index 6004c06ccbb..b0cf94455e1 100644 --- a/configs/dmnet/README.md +++ b/configs/dmnet/README.md @@ -26,25 +26,25 @@ Multi-scale representation provides an effective way toaddress scale variation o ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DMNet | R-50-D8 | 512x1024 | 40000 | 7.0 | 3.66 | V100 | 77.78 | 79.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_40k_cityscapes/dmnet_r50-d8_512x1024_40k_cityscapes_20201215_042326-615373cf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_40k_cityscapes/dmnet_r50-d8_512x1024_40k_cityscapes-20201215_042326.log.json) | -| DMNet | R-101-D8 | 512x1024 | 40000 | 10.6 | 2.54 | V100 | 78.37 | 79.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_40k_cityscapes/dmnet_r101-d8_512x1024_40k_cityscapes_20201215_043100-8291e976.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_40k_cityscapes/dmnet_r101-d8_512x1024_40k_cityscapes-20201215_043100.log.json) | -| DMNet | R-50-D8 | 769x769 | 40000 | 7.9 | 1.57 | V100 | 78.49 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_40k_cityscapes/dmnet_r50-d8_769x769_40k_cityscapes_20201215_093706-e7f0e23e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_40k_cityscapes/dmnet_r50-d8_769x769_40k_cityscapes-20201215_093706.log.json) | -| DMNet | R-101-D8 | 769x769 | 40000 | 12.0 | 1.01 | V100 | 77.62 | 78.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_40k_cityscapes/dmnet_r101-d8_769x769_40k_cityscapes_20201215_081348-a74261f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_40k_cityscapes/dmnet_r101-d8_769x769_40k_cityscapes-20201215_081348.log.json) | -| DMNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.07 | 80.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_80k_cityscapes/dmnet_r50-d8_512x1024_80k_cityscapes_20201215_053728-3c8893b9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_80k_cityscapes/dmnet_r50-d8_512x1024_80k_cityscapes-20201215_053728.log.json) | -| DMNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.64 | 80.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_80k_cityscapes/dmnet_r101-d8_512x1024_80k_cityscapes_20201215_031718-fa081cb8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_80k_cityscapes/dmnet_r101-d8_512x1024_80k_cityscapes-20201215_031718.log.json) | -| DMNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.22 | 80.55 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_80k_cityscapes/dmnet_r50-d8_769x769_80k_cityscapes_20201215_034006-6060840e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_80k_cityscapes/dmnet_r50-d8_769x769_80k_cityscapes-20201215_034006.log.json) | -| DMNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.19 | 80.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_80k_cityscapes/dmnet_r101-d8_769x769_80k_cityscapes_20201215_082810-7f0de59a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_80k_cityscapes/dmnet_r101-d8_769x769_80k_cityscapes-20201215_082810.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DMNet | R-50-D8 | 512x1024 | 40000 | 7.0 | 3.66 | V100 | 77.78 | 79.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_40k_cityscapes/dmnet_r50-d8_512x1024_40k_cityscapes_20201215_042326-615373cf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_40k_cityscapes/dmnet_r50-d8_512x1024_40k_cityscapes-20201215_042326.log.json) | +| DMNet | R-101-D8 | 512x1024 | 40000 | 10.6 | 2.54 | V100 | 78.37 | 79.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_40k_cityscapes/dmnet_r101-d8_512x1024_40k_cityscapes_20201215_043100-8291e976.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_40k_cityscapes/dmnet_r101-d8_512x1024_40k_cityscapes-20201215_043100.log.json) | +| DMNet | R-50-D8 | 769x769 | 40000 | 7.9 | 1.57 | V100 | 78.49 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_40k_cityscapes/dmnet_r50-d8_769x769_40k_cityscapes_20201215_093706-e7f0e23e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_40k_cityscapes/dmnet_r50-d8_769x769_40k_cityscapes-20201215_093706.log.json) | +| DMNet | R-101-D8 | 769x769 | 40000 | 12.0 | 1.01 | V100 | 77.62 | 78.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_40k_cityscapes/dmnet_r101-d8_769x769_40k_cityscapes_20201215_081348-a74261f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_40k_cityscapes/dmnet_r101-d8_769x769_40k_cityscapes-20201215_081348.log.json) | +| DMNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.07 | 80.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_80k_cityscapes/dmnet_r50-d8_512x1024_80k_cityscapes_20201215_053728-3c8893b9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x1024_80k_cityscapes/dmnet_r50-d8_512x1024_80k_cityscapes-20201215_053728.log.json) | +| DMNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.64 | 80.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_80k_cityscapes/dmnet_r101-d8_512x1024_80k_cityscapes_20201215_031718-fa081cb8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x1024_80k_cityscapes/dmnet_r101-d8_512x1024_80k_cityscapes-20201215_031718.log.json) | +| DMNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.22 | 80.55 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_80k_cityscapes/dmnet_r50-d8_769x769_80k_cityscapes_20201215_034006-6060840e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_769x769_80k_cityscapes/dmnet_r50-d8_769x769_80k_cityscapes-20201215_034006.log.json) | +| DMNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.19 | 80.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_80k_cityscapes/dmnet_r101-d8_769x769_80k_cityscapes_20201215_082810-7f0de59a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_769x769_80k_cityscapes/dmnet_r101-d8_769x769_80k_cityscapes-20201215_082810.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DMNet | R-50-D8 | 512x512 | 80000 | 9.4 | 20.95 | V100 | 42.37 | 43.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_80k_ade20k/dmnet_r50-d8_512x512_80k_ade20k_20201215_144744-f89092a6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_80k_ade20k/dmnet_r50-d8_512x512_80k_ade20k-20201215_144744.log.json) | -| DMNet | R-101-D8 | 512x512 | 80000 | 13.0 | 13.88 | V100 | 45.34 | 46.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_80k_ade20k/dmnet_r101-d8_512x512_80k_ade20k_20201215_104812-bfa45311.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_80k_ade20k/dmnet_r101-d8_512x512_80k_ade20k-20201215_104812.log.json) | -| DMNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.15 | 44.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_160k_ade20k/dmnet_r50-d8_512x512_160k_ade20k_20201215_115313-025ab3f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_160k_ade20k/dmnet_r50-d8_512x512_160k_ade20k-20201215_115313.log.json) | -| DMNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.42 | 46.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dmnet/dmnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_160k_ade20k/dmnet_r101-d8_512x512_160k_ade20k_20201215_111145-a0bc02ef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_160k_ade20k/dmnet_r101-d8_512x512_160k_ade20k-20201215_111145.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DMNet | R-50-D8 | 512x512 | 80000 | 9.4 | 20.95 | V100 | 42.37 | 43.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_80k_ade20k/dmnet_r50-d8_512x512_80k_ade20k_20201215_144744-f89092a6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_80k_ade20k/dmnet_r50-d8_512x512_80k_ade20k-20201215_144744.log.json) | +| DMNet | R-101-D8 | 512x512 | 80000 | 13.0 | 13.88 | V100 | 45.34 | 46.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_80k_ade20k/dmnet_r101-d8_512x512_80k_ade20k_20201215_104812-bfa45311.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_80k_ade20k/dmnet_r101-d8_512x512_80k_ade20k-20201215_104812.log.json) | +| DMNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 43.15 | 44.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_160k_ade20k/dmnet_r50-d8_512x512_160k_ade20k_20201215_115313-025ab3f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r50-d8_512x512_160k_ade20k/dmnet_r50-d8_512x512_160k_ade20k-20201215_115313.log.json) | +| DMNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 45.42 | 46.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet/dmnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_160k_ade20k/dmnet_r101-d8_512x512_160k_ade20k_20201215_111145-a0bc02ef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dmnet/dmnet_r101-d8_512x512_160k_ade20k/dmnet_r101-d8_512x512_160k_ade20k-20201215_111145.log.json) | ## Citation diff --git a/configs/dnlnet/README.md b/configs/dnlnet/README.md index 12338c730c2..6835ffd1ed9 100644 --- a/configs/dnlnet/README.md +++ b/configs/dnlnet/README.md @@ -26,25 +26,25 @@ The non-local block is a popular module for strengthening the context modeling a ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DNLNet | R-50-D8 | 512x1024 | 40000 | 7.3 | 2.56 | V100 | 78.61 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_40k_cityscapes/dnl_r50-d8_512x1024_40k_cityscapes_20200904_233629-53d4ea93.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_40k_cityscapes/dnl_r50-d8_512x1024_40k_cityscapes-20200904_233629.log.json) | -| DNLNet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.96 | V100 | 78.31 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_40k_cityscapes/dnl_r101-d8_512x1024_40k_cityscapes_20200904_233629-9928ffef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_40k_cityscapes/dnl_r101-d8_512x1024_40k_cityscapes-20200904_233629.log.json) | -| DNLNet | R-50-D8 | 769x769 | 40000 | 9.2 | 1.50 | V100 | 78.44 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_40k_cityscapes/dnl_r50-d8_769x769_40k_cityscapes_20200820_232206-0f283785.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_40k_cityscapes/dnl_r50-d8_769x769_40k_cityscapes-20200820_232206.log.json) | -| DNLNet | R-101-D8 | 769x769 | 40000 | 12.6 | 1.02 | V100 | 76.39 | 77.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_40k_cityscapes/dnl_r101-d8_769x769_40k_cityscapes_20200820_171256-76c596df.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_40k_cityscapes/dnl_r101-d8_769x769_40k_cityscapes-20200820_171256.log.json) | -| DNLNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.33 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_80k_cityscapes/dnl_r50-d8_512x1024_80k_cityscapes_20200904_233629-58b2f778.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_80k_cityscapes/dnl_r50-d8_512x1024_80k_cityscapes-20200904_233629.log.json) | -| DNLNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.41 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_80k_cityscapes/dnl_r101-d8_512x1024_80k_cityscapes_20200904_233629-758e2dd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_80k_cityscapes/dnl_r101-d8_512x1024_80k_cityscapes-20200904_233629.log.json) | -| DNLNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.36 | 80.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_80k_cityscapes/dnl_r50-d8_769x769_80k_cityscapes_20200820_011925-366bc4c7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_80k_cityscapes/dnl_r50-d8_769x769_80k_cityscapes-20200820_011925.log.json) | -| DNLNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.41 | 80.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_80k_cityscapes/dnl_r101-d8_769x769_80k_cityscapes_20200821_051111-95ff84ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_80k_cityscapes/dnl_r101-d8_769x769_80k_cityscapes-20200821_051111.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DNLNet | R-50-D8 | 512x1024 | 40000 | 7.3 | 2.56 | V100 | 78.61 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_40k_cityscapes/dnl_r50-d8_512x1024_40k_cityscapes_20200904_233629-53d4ea93.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_40k_cityscapes/dnl_r50-d8_512x1024_40k_cityscapes-20200904_233629.log.json) | +| DNLNet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.96 | V100 | 78.31 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_40k_cityscapes/dnl_r101-d8_512x1024_40k_cityscapes_20200904_233629-9928ffef.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_40k_cityscapes/dnl_r101-d8_512x1024_40k_cityscapes-20200904_233629.log.json) | +| DNLNet | R-50-D8 | 769x769 | 40000 | 9.2 | 1.50 | V100 | 78.44 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_40k_cityscapes/dnl_r50-d8_769x769_40k_cityscapes_20200820_232206-0f283785.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_40k_cityscapes/dnl_r50-d8_769x769_40k_cityscapes-20200820_232206.log.json) | +| DNLNet | R-101-D8 | 769x769 | 40000 | 12.6 | 1.02 | V100 | 76.39 | 77.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_40k_cityscapes/dnl_r101-d8_769x769_40k_cityscapes_20200820_171256-76c596df.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_40k_cityscapes/dnl_r101-d8_769x769_40k_cityscapes-20200820_171256.log.json) | +| DNLNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 79.33 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_80k_cityscapes/dnl_r50-d8_512x1024_80k_cityscapes_20200904_233629-58b2f778.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x1024_80k_cityscapes/dnl_r50-d8_512x1024_80k_cityscapes-20200904_233629.log.json) | +| DNLNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 80.41 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_80k_cityscapes/dnl_r101-d8_512x1024_80k_cityscapes_20200904_233629-758e2dd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x1024_80k_cityscapes/dnl_r101-d8_512x1024_80k_cityscapes-20200904_233629.log.json) | +| DNLNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.36 | 80.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_80k_cityscapes/dnl_r50-d8_769x769_80k_cityscapes_20200820_011925-366bc4c7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_769x769_80k_cityscapes/dnl_r50-d8_769x769_80k_cityscapes-20200820_011925.log.json) | +| DNLNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.41 | 80.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_80k_cityscapes/dnl_r101-d8_769x769_80k_cityscapes_20200821_051111-95ff84ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_769x769_80k_cityscapes/dnl_r101-d8_769x769_80k_cityscapes-20200821_051111.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DNLNet | R-50-D8 | 512x512 | 80000 | 8.8 | 20.66 | V100 | 41.76 | 42.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_80k_ade20k/dnl_r50-d8_512x512_80k_ade20k_20200826_183354-1cf6e0c1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_80k_ade20k/dnl_r50-d8_512x512_80k_ade20k-20200826_183354.log.json) | -| DNLNet | R-101-D8 | 512x512 | 80000 | 12.8 | 12.54 | V100 | 43.76 | 44.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_80k_ade20k/dnl_r101-d8_512x512_80k_ade20k_20200826_183354-d820d6ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_80k_ade20k/dnl_r101-d8_512x512_80k_ade20k-20200826_183354.log.json) | -| DNLNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.87 | 43.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_160k_ade20k/dnl_r50-d8_512x512_160k_ade20k_20200826_183350-37837798.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_160k_ade20k/dnl_r50-d8_512x512_160k_ade20k-20200826_183350.log.json) | -| DNLNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.25 | 45.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dnlnet/dnl_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_160k_ade20k/dnl_r101-d8_512x512_160k_ade20k_20200826_183350-ed522c61.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_160k_ade20k/dnl_r101-d8_512x512_160k_ade20k-20200826_183350.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DNLNet | R-50-D8 | 512x512 | 80000 | 8.8 | 20.66 | V100 | 41.76 | 42.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_80k_ade20k/dnl_r50-d8_512x512_80k_ade20k_20200826_183354-1cf6e0c1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_80k_ade20k/dnl_r50-d8_512x512_80k_ade20k-20200826_183354.log.json) | +| DNLNet | R-101-D8 | 512x512 | 80000 | 12.8 | 12.54 | V100 | 43.76 | 44.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_80k_ade20k/dnl_r101-d8_512x512_80k_ade20k_20200826_183354-d820d6ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_80k_ade20k/dnl_r101-d8_512x512_80k_ade20k-20200826_183354.log.json) | +| DNLNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.87 | 43.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_160k_ade20k/dnl_r50-d8_512x512_160k_ade20k_20200826_183350-37837798.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r50-d8_512x512_160k_ade20k/dnl_r50-d8_512x512_160k_ade20k-20200826_183350.log.json) | +| DNLNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.25 | 45.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet/dnl_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_160k_ade20k/dnl_r101-d8_512x512_160k_ade20k_20200826_183350-ed522c61.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dnlnet/dnl_r101-d8_512x512_160k_ade20k/dnl_r101-d8_512x512_160k_ade20k-20200826_183350.log.json) | ## Notes diff --git a/configs/dpt/README.md b/configs/dpt/README.md index 432d1dd226e..b3a5573a65f 100644 --- a/configs/dpt/README.md +++ b/configs/dpt/README.md @@ -44,9 +44,9 @@ This script convert model from `PRETRAIN_PATH` and store the converted model in ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| DPT | ViT-B | 512x512 | 160000 | 8.09 | 10.41 | V100 | 46.97 | 48.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/dpt/dpt_vit-b16_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dpt/dpt_vit-b16_512x512_160k_ade20k/dpt_vit-b16_512x512_160k_ade20k-db31cf52.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dpt/dpt_vit-b16_512x512_160k_ade20k/dpt_vit-b16_512x512_160k_ade20k-20210809_172025.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| DPT | ViT-B | 512x512 | 160000 | 8.09 | 10.41 | V100 | 46.97 | 48.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dpt/dpt_vit-b16_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/dpt/dpt_vit-b16_512x512_160k_ade20k/dpt_vit-b16_512x512_160k_ade20k-db31cf52.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/dpt/dpt_vit-b16_512x512_160k_ade20k/dpt_vit-b16_512x512_160k_ade20k-20210809_172025.log.json) | ## Citation diff --git a/configs/dsdl/README.md b/configs/dsdl/README.md new file mode 100644 index 00000000000..e564cffdb21 --- /dev/null +++ b/configs/dsdl/README.md @@ -0,0 +1,103 @@ +# DSDL: Standard Description Language for DataSet + + + +## Abstract + + + +Data is the cornerstone of artificial intelligence. The efficiency of data acquisition, exchange, and application directly impacts the advances in technologies and applications. Over the long history of AI, a vast quantity of data sets have been developed and distributed. However, these datasets are defined in very different forms, which incurs significant overhead when it comes to exchange, integration, and utilization -- it is often the case that one needs to develop a new customized tool or script in order to incorporate a new dataset into a workflow. + +To overcome such difficulties, we develop **Data Set Description Language (DSDL)**. More details please visit our [official documents](https://opendatalab.github.io/dsdl-docs/getting_started/overview/), dsdl datasets can be downloaded from our platform [OpenDataLab](https://opendatalab.com/). + + + +## Steps + +- install dsdl and opendatalab: + + ``` + pip install dsdl + pip install opendatalab + ``` + +- install mmseg and pytorch: + please refer this [installation documents](https://mmsegmentation.readthedocs.io/en/latest/get_started.html). + +- prepare dsdl dataset (take voc2012 as an example) + + - dowaload dsdl dataset (you will need an opendatalab account to do so. [register one now](https://opendatalab.com/)) + + ``` + cd data + + odl login + odl get PASCAL_VOC2012 + ``` + + usually, dataset is compressed on opendatalab platform, the downloaded voc 2012 dataset should be like this: + + ``` + data/ + ├── PASCAL_VOC2012 + │   ├── dsdl + │   │   ├── dsdl_Det_full.zip + │   │   └── dsdl_SemSeg_full.zip + │   ├── raw + │   │   ├── VOC2012test.tar + │   │   ├── VOCdevkit_18-May-2011.tar + │   │   └── VOCtrainval_11-May-2012.tar + │   └── README.md + └── ... + ``` + + - decompress dataset + + ``` + cd dsdl + unzip dsdl_SemSeg_full.zip + ``` + + as we do not need detection dsdl files, we only decompress the semantic segmentation files here. + + ``` + cd ../raw + tar -xvf VOCtrainval_11-May-2012.tar + tar -xvf VOC2012test.tar + + cd ../../ + ``` + +- change traning config + + open the [voc config file](voc.py) and set some file paths as below: + + ``` + data_root = 'data/PASCAL_VOC2012' + img_prefix = 'raw/VOCdevkit/VOC2012' + train_ann = 'dsdl/dsdl_SemSeg_full/set-train/train.yaml' + val_ann = 'dsdl/dsdl_SemSeg_full/set-val/val.yaml' + ``` + + as dsdl datasets with one task using one dataloader, we can simplly change these file paths to train a model on a different dataset. + +- train: + + - using single gpu: + + ``` + python tools/train.py {config_file} + ``` + + - using slrum: + + ``` + ./tools/slurm_train.sh {partition} {job_name} {config_file} {work_dir} {gpu_nums} + ``` + +## Test Results + +| Datasets | Model | mIoU(%) | Config | +| :--------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----: | :-----------------------: | +| voc2012 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x512_20k_voc12aug/deeplabv3_r50-d8_512x512_20k_voc12aug_20200617_010906-596905ef.pth) | 76.73 | [config](./voc.py) | +| cityscapes | [model](https://download.openmmlab.com/mmsegmentation/v0.5/deeplabv3/deeplabv3_r50-d8_512x1024_40k_cityscapes/deeplabv3_r50-d8_512x1024_40k_cityscapes_20200605_022449-acadc2f8.pth) | 79.01 | [config](./cityscapes.py) | diff --git a/configs/dsdl/cityscapes.py b/configs/dsdl/cityscapes.py new file mode 100644 index 00000000000..94ccc068e06 --- /dev/null +++ b/configs/dsdl/cityscapes.py @@ -0,0 +1,70 @@ +_base_ = [ + '../_base_/models/deeplabv3_r50-d8.py', '../_base_/default_runtime.py', + '../_base_/schedules/schedule_40k.py' +] + +crop_size = (512, 1024) +data_preprocessor = dict(size=crop_size) +model = dict(data_preprocessor=data_preprocessor) +# dataset settings +dataset_type = 'DSDLSegDataset' +data_root = 'data/CityScapes' +img_prefix = 'raw/CityScapes' +train_ann = 'dsdl/dsdl_SemSeg_full/set-train/train.yaml' +val_ann = 'dsdl/dsdl_SemSeg_full/set-val/val.yaml' + +used_labels = [ + 'road', 'sidewalk', 'building', 'wall', 'fence', 'pole', 'traffic_light', + 'traffic_sign', 'vegetation', 'terrain', 'sky', 'person', 'rider', 'car', + 'truck', 'bus', 'train', 'motorcycle', 'bicycle' +] + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict( + type='RandomResize', + scale=(2048, 1024), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 1024), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=2, + num_workers=2, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path=img_prefix, seg_map_path=img_prefix), + ann_file=train_ann, + used_labels=used_labels, + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path=img_prefix, seg_map_path=img_prefix), + ann_file=val_ann, + used_labels=used_labels, + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/configs/dsdl/voc.py b/configs/dsdl/voc.py new file mode 100644 index 00000000000..c1895f7c7d3 --- /dev/null +++ b/configs/dsdl/voc.py @@ -0,0 +1,65 @@ +_base_ = [ + '../_base_/models/deeplabv3_r50-d8.py', '../_base_/default_runtime.py', + '../_base_/schedules/schedule_20k.py' +] + +# dataset settings +dataset_type = 'DSDLSegDataset' +data_root = 'data/PASCAL_VOC2012' +img_prefix = 'raw/VOCdevkit/VOC2012' +train_ann = 'dsdl/dsdl_SemSeg_full/set-train/train.yaml' +val_ann = 'dsdl/dsdl_SemSeg_full/set-val/val.yaml' +crop_size = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict( + type='RandomResize', + scale=(2048, 512), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=4, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path=img_prefix, seg_map_path=img_prefix), + ann_file=train_ann, + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path=img_prefix, seg_map_path=img_prefix), + ann_file=val_ann, + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator + +data_preprocessor = dict(size=crop_size) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=21), + auxiliary_head=dict(num_classes=21)) diff --git a/configs/encnet/README.md b/configs/encnet/README.md index 31bbd98c6ba..ff09bc32f86 100644 --- a/configs/encnet/README.md +++ b/configs/encnet/README.md @@ -26,25 +26,25 @@ Recent work has made significant progress in improving spatial resolution for pi ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| EncNet | R-50-D8 | 512x1024 | 40000 | 8.6 | 4.58 | V100 | 75.67 | 77.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_40k_cityscapes/encnet_r50-d8_512x1024_40k_cityscapes_20200621_220958-68638a47.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_40k_cityscapes/encnet_r50-d8_512x1024_40k_cityscapes-20200621_220958.log.json) | -| EncNet | R-101-D8 | 512x1024 | 40000 | 12.1 | 2.66 | V100 | 75.81 | 77.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_40k_cityscapes/encnet_r101-d8_512x1024_40k_cityscapes_20200621_220933-35e0a3e8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_40k_cityscapes/encnet_r101-d8_512x1024_40k_cityscapes-20200621_220933.log.json) | -| EncNet | R-50-D8 | 769x769 | 40000 | 9.8 | 1.82 | V100 | 76.24 | 77.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_40k_cityscapes/encnet_r50-d8_769x769_40k_cityscapes_20200621_220958-3bcd2884.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_40k_cityscapes/encnet_r50-d8_769x769_40k_cityscapes-20200621_220958.log.json) | -| EncNet | R-101-D8 | 769x769 | 40000 | 13.7 | 1.26 | V100 | 74.25 | 76.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_40k_cityscapes/encnet_r101-d8_769x769_40k_cityscapes_20200621_220933-2fafed55.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_40k_cityscapes/encnet_r101-d8_769x769_40k_cityscapes-20200621_220933.log.json) | -| EncNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.94 | 79.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_80k_cityscapes/encnet_r50-d8_512x1024_80k_cityscapes_20200622_003554-fc5c5624.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_80k_cityscapes/encnet_r50-d8_512x1024_80k_cityscapes-20200622_003554.log.json) | -| EncNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.55 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_80k_cityscapes/encnet_r101-d8_512x1024_80k_cityscapes_20200622_003555-1de64bec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_80k_cityscapes/encnet_r101-d8_512x1024_80k_cityscapes-20200622_003555.log.json) | -| EncNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 77.44 | 78.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_80k_cityscapes/encnet_r50-d8_769x769_80k_cityscapes_20200622_003554-55096dcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_80k_cityscapes/encnet_r50-d8_769x769_80k_cityscapes-20200622_003554.log.json) | -| EncNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 76.10 | 76.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_80k_cityscapes/encnet_r101-d8_769x769_80k_cityscapes_20200622_003555-470ef79d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_80k_cityscapes/encnet_r101-d8_769x769_80k_cityscapes-20200622_003555.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| EncNet | R-50-D8 | 512x1024 | 40000 | 8.6 | 4.58 | V100 | 75.67 | 77.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_40k_cityscapes/encnet_r50-d8_512x1024_40k_cityscapes_20200621_220958-68638a47.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_40k_cityscapes/encnet_r50-d8_512x1024_40k_cityscapes-20200621_220958.log.json) | +| EncNet | R-101-D8 | 512x1024 | 40000 | 12.1 | 2.66 | V100 | 75.81 | 77.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_40k_cityscapes/encnet_r101-d8_512x1024_40k_cityscapes_20200621_220933-35e0a3e8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_40k_cityscapes/encnet_r101-d8_512x1024_40k_cityscapes-20200621_220933.log.json) | +| EncNet | R-50-D8 | 769x769 | 40000 | 9.8 | 1.82 | V100 | 76.24 | 77.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_40k_cityscapes/encnet_r50-d8_769x769_40k_cityscapes_20200621_220958-3bcd2884.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_40k_cityscapes/encnet_r50-d8_769x769_40k_cityscapes-20200621_220958.log.json) | +| EncNet | R-101-D8 | 769x769 | 40000 | 13.7 | 1.26 | V100 | 74.25 | 76.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_40k_cityscapes/encnet_r101-d8_769x769_40k_cityscapes_20200621_220933-2fafed55.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_40k_cityscapes/encnet_r101-d8_769x769_40k_cityscapes-20200621_220933.log.json) | +| EncNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.94 | 79.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_80k_cityscapes/encnet_r50-d8_512x1024_80k_cityscapes_20200622_003554-fc5c5624.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x1024_80k_cityscapes/encnet_r50-d8_512x1024_80k_cityscapes-20200622_003554.log.json) | +| EncNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.55 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_80k_cityscapes/encnet_r101-d8_512x1024_80k_cityscapes_20200622_003555-1de64bec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x1024_80k_cityscapes/encnet_r101-d8_512x1024_80k_cityscapes-20200622_003555.log.json) | +| EncNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 77.44 | 78.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_80k_cityscapes/encnet_r50-d8_769x769_80k_cityscapes_20200622_003554-55096dcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_769x769_80k_cityscapes/encnet_r50-d8_769x769_80k_cityscapes-20200622_003554.log.json) | +| EncNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 76.10 | 76.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_80k_cityscapes/encnet_r101-d8_769x769_80k_cityscapes_20200622_003555-470ef79d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_769x769_80k_cityscapes/encnet_r101-d8_769x769_80k_cityscapes-20200622_003555.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| EncNet | R-50-D8 | 512x512 | 80000 | 10.1 | 22.81 | V100 | 39.53 | 41.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_80k_ade20k/encnet_r50-d8_512x512_80k_ade20k_20200622_042412-44b46b04.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_80k_ade20k/encnet_r50-d8_512x512_80k_ade20k-20200622_042412.log.json) | -| EncNet | R-101-D8 | 512x512 | 80000 | 13.6 | 14.87 | V100 | 42.11 | 43.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_80k_ade20k/encnet_r101-d8_512x512_80k_ade20k_20200622_101128-dd35e237.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_80k_ade20k/encnet_r101-d8_512x512_80k_ade20k-20200622_101128.log.json) | -| EncNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 40.10 | 41.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_160k_ade20k/encnet_r50-d8_512x512_160k_ade20k_20200622_101059-b2db95e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_160k_ade20k/encnet_r50-d8_512x512_160k_ade20k-20200622_101059.log.json) | -| EncNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 42.61 | 44.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet/encnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_160k_ade20k/encnet_r101-d8_512x512_160k_ade20k_20200622_073348-7989641f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_160k_ade20k/encnet_r101-d8_512x512_160k_ade20k-20200622_073348.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| EncNet | R-50-D8 | 512x512 | 80000 | 10.1 | 22.81 | V100 | 39.53 | 41.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_80k_ade20k/encnet_r50-d8_512x512_80k_ade20k_20200622_042412-44b46b04.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_80k_ade20k/encnet_r50-d8_512x512_80k_ade20k-20200622_042412.log.json) | +| EncNet | R-101-D8 | 512x512 | 80000 | 13.6 | 14.87 | V100 | 42.11 | 43.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_80k_ade20k/encnet_r101-d8_512x512_80k_ade20k_20200622_101128-dd35e237.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_80k_ade20k/encnet_r101-d8_512x512_80k_ade20k-20200622_101128.log.json) | +| EncNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 40.10 | 41.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_160k_ade20k/encnet_r50-d8_512x512_160k_ade20k_20200622_101059-b2db95e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r50-d8_512x512_160k_ade20k/encnet_r50-d8_512x512_160k_ade20k-20200622_101059.log.json) | +| EncNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 42.61 | 44.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet/encnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_160k_ade20k/encnet_r101-d8_512x512_160k_ade20k_20200622_073348-7989641f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/encnet/encnet_r101-d8_512x512_160k_ade20k/encnet_r101-d8_512x512_160k_ade20k-20200622_073348.log.json) | ## Citation diff --git a/configs/erfnet/README.md b/configs/erfnet/README.md index e29afc485d7..55d71973a3e 100644 --- a/configs/erfnet/README.md +++ b/configs/erfnet/README.md @@ -26,9 +26,9 @@ Semantic segmentation is a challenging task that addresses most of the perceptio ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ---: | ------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| ERFNet | ERFNet | 512x1024 | 160000 | 6.04 | 15.26 | V100 | 72.5 | 74.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/erfnet/erfnet_fcn_4x4_512x1024_160k_cityscapes/erfnet_fcn_4x4_512x1024_160k_cityscapes_20220704_162145-dc90157a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/erfnet/erfnet_fcn_4x4_512x1024_160k_cityscapes/erfnet_fcn_4x4_512x1024_160k_cityscapes_20220704_162145.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ---: | ------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| ERFNet | ERFNet | 512x1024 | 160000 | 6.04 | 15.26 | V100 | 72.5 | 74.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/erfnet/erfnet_fcn_4xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/erfnet/erfnet_fcn_4x4_512x1024_160k_cityscapes/erfnet_fcn_4x4_512x1024_160k_cityscapes_20220704_162145-dc90157a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/erfnet/erfnet_fcn_4x4_512x1024_160k_cityscapes/erfnet_fcn_4x4_512x1024_160k_cityscapes_20220704_162145.log.json) | Note: diff --git a/configs/fastfcn/README.md b/configs/fastfcn/README.md index 0b26a33edd8..48644e57e3a 100644 --- a/configs/fastfcn/README.md +++ b/configs/fastfcn/README.md @@ -26,30 +26,30 @@ Modern approaches for semantic segmentation usually employ dilated convolutions ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------------------- | -------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 80000 | 5.67 | 2.64 | V100 | 79.12 | 80.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes_20210928_053722-5d1a2648.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes_20210928_053722.log.json) | -| FastFCN + DeepLabV3 | R-50-D32 (4x4) | 512x1024 | 80000 | 9.79 | - | V100 | 79.52 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes_20210924_214357-72220849.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes_20210924_214357.log.json) | -| FastFCN + PSPNet | R-50-D32 | 512x1024 | 80000 | 5.67 | 4.40 | V100 | 79.26 | 80.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes_20210928_053722-57749bed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes_20210928_053722.log.json) | -| FastFCN + PSPNet | R-50-D32 (4x4) | 512x1024 | 80000 | 9.94 | - | V100 | 78.76 | 80.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes_20210925_061841-77e87b0a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes_20210925_061841.log.json) | -| FastFCN + EncNet | R-50-D32 | 512x1024 | 80000 | 8.15 | 4.77 | V100 | 77.97 | 79.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes_20210928_030036-78da5046.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes_20210928_030036.log.json) | -| FastFCN + EncNet | R-50-D32 (4x4) | 512x1024 | 80000 | 15.45 | - | V100 | 78.6 | 80.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes_20210926_093217-e1eb6dbb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes_20210926_093217.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------------------- | -------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 80000 | 5.67 | 2.64 | V100 | 79.12 | 80.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes_20210928_053722-5d1a2648.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_512x1024_80k_cityscapes_20210928_053722.log.json) | +| FastFCN + DeepLabV3 | R-50-D32 (4x4) | 512x1024 | 80000 | 9.79 | - | V100 | 79.52 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes_20210924_214357-72220849.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_aspp_4x4_512x1024_80k_cityscapes_20210924_214357.log.json) | +| FastFCN + PSPNet | R-50-D32 | 512x1024 | 80000 | 5.67 | 4.40 | V100 | 79.26 | 80.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes_20210928_053722-57749bed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_512x1024_80k_cityscapes_20210928_053722.log.json) | +| FastFCN + PSPNet | R-50-D32 (4x4) | 512x1024 | 80000 | 9.94 | - | V100 | 78.76 | 80.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes_20210925_061841-77e87b0a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_psp_4x4_512x1024_80k_cityscapes_20210925_061841.log.json) | +| FastFCN + EncNet | R-50-D32 | 512x1024 | 80000 | 8.15 | 4.77 | V100 | 77.97 | 79.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes_20210928_030036-78da5046.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_512x1024_80k_cityscapes_20210928_030036.log.json) | +| FastFCN + EncNet | R-50-D32 (4x4) | 512x1024 | 80000 | 15.45 | - | V100 | 78.6 | 80.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes_20210926_093217-e1eb6dbb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes/fastfcn_r50-d32_jpu_enc_4x4_512x1024_80k_cityscapes_20210926_093217.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------------------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 80000 | 8.46 | 12.06 | V100 | 41.88 | 42.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k_20211013_190619-3aa40f2d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k_20211013_190619.log.json) | -| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 43.58 | 44.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k_20211008_152246-27036aee.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k_20211008_152246.log.json) | -| FastFCN + PSPNet | R-50-D32 | 512x1024 | 80000 | 8.02 | 19.21 | V100 | 41.40 | 42.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k_20210930_225137-993d07c8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k_20210930_225137.log.json) | -| FastFCN + PSPNet | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 42.63 | 43.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k_20211008_105455-e8f5a2fd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k_20211008_105455.log.json) | -| FastFCN + EncNet | R-50-D32 | 512x1024 | 80000 | 9.67 | 17.23 | V100 | 40.88 | 42.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k_20210930_225214-65aef6dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k_20210930_225214.log.json) | -| FastFCN + EncNet | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 42.50 | 44.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k_20211008_105456-d875ce3c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k_20211008_105456.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------------------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 80000 | 8.46 | 12.06 | V100 | 41.88 | 42.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k_20211013_190619-3aa40f2d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_80k_ade20k_20211013_190619.log.json) | +| FastFCN + DeepLabV3 | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 43.58 | 44.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_aspp_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k_20211008_152246-27036aee.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_aspp_512x512_160k_ade20k_20211008_152246.log.json) | +| FastFCN + PSPNet | R-50-D32 | 512x1024 | 80000 | 8.02 | 19.21 | V100 | 41.40 | 42.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k_20210930_225137-993d07c8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_80k_ade20k_20210930_225137.log.json) | +| FastFCN + PSPNet | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 42.63 | 43.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_psp_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k_20211008_105455-e8f5a2fd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k/fastfcn_r50-d32_jpu_psp_512x512_160k_ade20k_20211008_105455.log.json) | +| FastFCN + EncNet | R-50-D32 | 512x1024 | 80000 | 9.67 | 17.23 | V100 | 40.88 | 42.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k_20210930_225214-65aef6dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_80k_ade20k_20210930_225214.log.json) | +| FastFCN + EncNet | R-50-D32 | 512x1024 | 160000 | - | - | V100 | 42.50 | 44.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn/fastfcn_r50-d32_jpu_enc_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k_20211008_105456-d875ce3c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fastfcn/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k/fastfcn_r50-d32_jpu_enc_512x512_160k_ade20k_20211008_105456.log.json) | Note: - `4x4` means 4 GPUs with 4 samples per GPU in training, default setting is 4 GPUs with 2 samples per GPU in training. -- Results of [DeepLabV3 (mIoU: 79.32)](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/deeplabv3), [PSPNet (mIoU: 78.55)](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet) and [ENCNet (mIoU: 77.94)](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/encnet) can be found in each original repository. +- Results of [DeepLabV3 (mIoU: 79.32)](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3), [PSPNet (mIoU: 78.55)](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet) and [ENCNet (mIoU: 77.94)](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet) can be found in each original repository. ## Citation diff --git a/configs/fastscnn/README.md b/configs/fastscnn/README.md index ea3449fd2cd..6be981462ab 100644 --- a/configs/fastscnn/README.md +++ b/configs/fastscnn/README.md @@ -26,9 +26,9 @@ The encoder-decoder framework is state-of-the-art for offline semantic image seg ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| -------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FastSCNN | FastSCNN | 512x1024 | 160000 | 3.3 | 56.45 | V100 | 70.96 | 72.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fast_scnn/fast_scnn_lr0.12_8x4_160k_cityscapes/fast_scnn_lr0.12_8x4_160k_cityscapes_20210630_164853-0cec9937.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fast_scnn/fast_scnn_lr0.12_8x4_160k_cityscapes/fast_scnn_lr0.12_8x4_160k_cityscapes_20210630_164853.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| -------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FastSCNN | FastSCNN | 512x1024 | 160000 | 3.3 | 56.45 | V100 | 70.96 | 72.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastscnn/fast_scnn_8xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fast_scnn/fast_scnn_lr0.12_8x4_160k_cityscapes/fast_scnn_lr0.12_8x4_160k_cityscapes_20210630_164853-0cec9937.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fast_scnn/fast_scnn_lr0.12_8x4_160k_cityscapes/fast_scnn_lr0.12_8x4_160k_cityscapes_20210630_164853.log.json) | ## Citation diff --git a/configs/fcn/README.md b/configs/fcn/README.md index 6134933710b..cf7379ff3db 100644 --- a/configs/fcn/README.md +++ b/configs/fcn/README.md @@ -26,69 +26,69 @@ Convolutional networks are powerful visual models that yield hierarchies of feat ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | ---------- | --------- | ------: | -------- | -------------- | -------- | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | R-50-D8 | 512x1024 | 40000 | 5.7 | 4.17 | V100 | 72.25 | 73.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_40k_cityscapes/fcn_r50-d8_512x1024_40k_cityscapes_20200604_192608-efe53f0d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_40k_cityscapes/fcn_r50-d8_512x1024_40k_cityscapes_20200604_192608.log.json) | -| FCN | R-101-D8 | 512x1024 | 40000 | 9.2 | 2.66 | V100 | 75.45 | 76.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_40k_cityscapes/fcn_r101-d8_512x1024_40k_cityscapes_20200604_181852-a883d3a1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_40k_cityscapes/fcn_r101-d8_512x1024_40k_cityscapes_20200604_181852.log.json) | -| FCN | R-50-D8 | 769x769 | 40000 | 6.5 | 1.80 | V100 | 71.47 | 72.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_40k_cityscapes/fcn_r50-d8_769x769_40k_cityscapes_20200606_113104-977b5d02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_40k_cityscapes/fcn_r50-d8_769x769_40k_cityscapes_20200606_113104.log.json) | -| FCN | R-101-D8 | 769x769 | 40000 | 10.4 | 1.19 | V100 | 73.93 | 75.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_40k_cityscapes/fcn_r101-d8_769x769_40k_cityscapes_20200606_113208-7d4ab69c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_40k_cityscapes/fcn_r101-d8_769x769_40k_cityscapes_20200606_113208.log.json) | -| FCN | R-18-D8 | 512x1024 | 80000 | 1.7 | 14.65 | V100 | 71.11 | 72.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_512x1024_80k_cityscapes/fcn_r18-d8_512x1024_80k_cityscapes_20201225_021327-6c50f8b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_512x1024_80k_cityscapes/fcn_r18-d8_512x1024_80k_cityscapes-20201225_021327.log.json) | -| FCN | R-50-D8 | 512x1024 | 80000 | - | | V100 | 73.61 | 74.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_80k_cityscapes/fcn_r50-d8_512x1024_80k_cityscapes_20200606_113019-03aa804d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_80k_cityscapes/fcn_r50-d8_512x1024_80k_cityscapes_20200606_113019.log.json) | -| FCN | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 75.13 | 75.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_80k_cityscapes/fcn_r101-d8_512x1024_80k_cityscapes_20200606_113038-3fb937eb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_80k_cityscapes/fcn_r101-d8_512x1024_80k_cityscapes_20200606_113038.log.json) | -| FCN (FP16) | R-101-D8 | 512x1024 | 80000 | 5.37 | 8.64 | V100 | 76.80 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_fp16_512x1024_80k_cityscapes/fcn_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230921-fb13e883.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_fp16_512x1024_80k_cityscapes/fcn_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230921.log.json) | -| FCN | R-18-D8 | 769x769 | 80000 | 1.9 | 6.40 | V100 | 70.80 | 73.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_769x769_80k_cityscapes/fcn_r18-d8_769x769_80k_cityscapes_20201225_021451-9739d1b8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_769x769_80k_cityscapes/fcn_r18-d8_769x769_80k_cityscapes-20201225_021451.log.json) | -| FCN | R-50-D8 | 769x769 | 80000 | - | - | V100 | 72.64 | 73.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_80k_cityscapes/fcn_r50-d8_769x769_80k_cityscapes_20200606_195749-f5caeabc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_80k_cityscapes/fcn_r50-d8_769x769_80k_cityscapes_20200606_195749.log.json) | -| FCN | R-101-D8 | 769x769 | 80000 | - | - | V100 | 75.52 | 76.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_80k_cityscapes/fcn_r101-d8_769x769_80k_cityscapes_20200606_214354-45cbac68.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_80k_cityscapes/fcn_r101-d8_769x769_80k_cityscapes_20200606_214354.log.json) | -| FCN | R-18b-D8 | 512x1024 | 80000 | 1.6 | 16.74 | V100 | 70.24 | 72.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_512x1024_80k_cityscapes/fcn_r18b-d8_512x1024_80k_cityscapes_20201225_230143-92c0f445.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_512x1024_80k_cityscapes/fcn_r18b-d8_512x1024_80k_cityscapes-20201225_230143.log.json) | -| FCN | R-50b-D8 | 512x1024 | 80000 | 5.6 | 4.20 | V100 | 75.65 | 77.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_512x1024_80k_cityscapes/fcn_r50b-d8_512x1024_80k_cityscapes_20201225_094221-82957416.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_512x1024_80k_cityscapes/fcn_r50b-d8_512x1024_80k_cityscapes-20201225_094221.log.json) | -| FCN | R-101b-D8 | 512x1024 | 80000 | 9.1 | 2.73 | V100 | 77.37 | 78.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_512x1024_80k_cityscapes/fcn_r101b-d8_512x1024_80k_cityscapes_20201226_160213-4543858f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_512x1024_80k_cityscapes/fcn_r101b-d8_512x1024_80k_cityscapes-20201226_160213.log.json) | -| FCN | R-18b-D8 | 769x769 | 80000 | 1.7 | 6.70 | V100 | 69.66 | 72.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_769x769_80k_cityscapes/fcn_r18b-d8_769x769_80k_cityscapes_20201226_004430-32d504e5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_769x769_80k_cityscapes/fcn_r18b-d8_769x769_80k_cityscapes-20201226_004430.log.json) | -| FCN | R-50b-D8 | 769x769 | 80000 | 6.3 | 1.82 | V100 | 73.83 | 76.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_769x769_80k_cityscapes/fcn_r50b-d8_769x769_80k_cityscapes_20201225_094223-94552d38.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_769x769_80k_cityscapes/fcn_r50b-d8_769x769_80k_cityscapes-20201225_094223.log.json) | -| FCN | R-101b-D8 | 769x769 | 80000 | 10.3 | 1.15 | V100 | 77.02 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_769x769_80k_cityscapes/fcn_r101b-d8_769x769_80k_cityscapes_20201226_170012-82be37e2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_769x769_80k_cityscapes/fcn_r101b-d8_769x769_80k_cityscapes-20201226_170012.log.json) | -| FCN (D6) | R-50-D16 | 512x1024 | 40000 | 3.4 | 10.22 | TITAN Xp | 77.06 | 78.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50-d16_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_40k_cityscapes/fcn_d6_r50-d16_512x1024_40k_cityscapes_20210305_130133-98d5d1bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_40k_cityscapes/fcn_d6_r50-d16_512x1024_40k_cityscapes-20210305_130133.log.json) | -| FCN (D6) | R-50-D16 | 512x1024 | 80000 | - | 10.35 | TITAN Xp | 77.27 | 78.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_80k_cityscapes/fcn_d6_r50-d16_512x1024_80k_cityscapes_20210306_115604-133c292f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_80k_cityscapes/fcn_d6_r50-d16_512x1024_80k_cityscapes-20210306_115604.log.json) | -| FCN (D6) | R-50-D16 | 769x769 | 40000 | 3.7 | 4.17 | TITAN Xp | 76.82 | 78.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50-d16_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_40k_cityscapes/fcn_d6_r50-d16_769x769_40k_cityscapes_20210305_185744-1aab18ed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_40k_cityscapes/fcn_d6_r50-d16_769x769_40k_cityscapes-20210305_185744.log.json) | -| FCN (D6) | R-50-D16 | 769x769 | 80000 | - | 4.15 | TITAN Xp | 77.04 | 78.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_80k_cityscapes/fcn_d6_r50-d16_769x769_80k_cityscapes_20210305_200413-109d88eb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_80k_cityscapes/fcn_d6_r50-d16_769x769_80k_cityscapes-20210305_200413.log.json) | -| FCN (D6) | R-101-D16 | 512x1024 | 40000 | 4.5 | 8.04 | TITAN Xp | 77.36 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101-d16_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_40k_cityscapes/fcn_d6_r101-d16_512x1024_40k_cityscapes_20210305_130337-9cf2b450.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_40k_cityscapes/fcn_d6_r101-d16_512x1024_40k_cityscapes-20210305_130337.log.json) | -| FCN (D6) | R-101-D16 | 512x1024 | 80000 | - | 8.26 | TITAN Xp | 78.46 | 80.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_80k_cityscapes/fcn_d6_r101-d16_512x1024_80k_cityscapes_20210308_102747-cb336445.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_80k_cityscapes/fcn_d6_r101-d16_512x1024_80k_cityscapes-20210308_102747.log.json) | -| FCN (D6) | R-101-D16 | 769x769 | 40000 | 5.0 | 3.12 | TITAN Xp | 77.28 | 78.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101-d16_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_40k_cityscapes/fcn_d6_r101-d16_769x769_40k_cityscapes_20210308_102453-60b114e9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_40k_cityscapes/fcn_d6_r101-d16_769x769_40k_cityscapes-20210308_102453.log.json) | -| FCN (D6) | R-101-D16 | 769x769 | 80000 | - | 3.21 | TITAN Xp | 78.06 | 79.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_80k_cityscapes/fcn_d6_r101-d16_769x769_80k_cityscapes_20210306_120016-e33adc4f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_80k_cityscapes/fcn_d6_r101-d16_769x769_80k_cityscapes-20210306_120016.log.json) | -| FCN (D6) | R-50b-D16 | 512x1024 | 80000 | 3.2 | 10.16 | TITAN Xp | 76.99 | 79.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50b-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b-d16_512x1024_80k_cityscapes/fcn_d6_r50b-d16_512x1024_80k_cityscapes_20210311_125550-6a0b62e9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b_d16_512x1024_80k_cityscapes/fcn_d6_r50b_d16_512x1024_80k_cityscapes-20210311_125550.log.json) | -| FCN (D6) | R-50b-D16 | 769x769 | 80000 | 3.6 | 4.17 | TITAN Xp | 76.86 | 78.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r50b-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b-d16_769x769_80k_cityscapes/fcn_d6_r50b-d16_769x769_80k_cityscapes_20210311_131012-d665f231.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b_d16_769x769_80k_cityscapes/fcn_d6_r50b_d16_769x769_80k_cityscapes-20210311_131012.log.json) | -| FCN (D6) | R-101b-D16 | 512x1024 | 80000 | 4.3 | 8.46 | TITAN Xp | 77.72 | 79.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101b-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b-d16_512x1024_80k_cityscapes/fcn_d6_r101b-d16_512x1024_80k_cityscapes_20210311_144305-3f2eb5b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b_d16_512x1024_80k_cityscapes/fcn_d6_r101b_d16_512x1024_80k_cityscapes-20210311_144305.log.json) | -| FCN (D6) | R-101b-D16 | 769x769 | 80000 | 4.8 | 3.32 | TITAN Xp | 77.34 | 78.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn-d6_r101b-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b-d16_769x769_80k_cityscapes/fcn_d6_r101b-d16_769x769_80k_cityscapes_20210311_154527-c4d8bfbc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b_d16_769x769_80k_cityscapes/fcn_d6_r101b_d16_769x769_80k_cityscapes-20210311_154527.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | ---------- | --------- | ------: | -------- | -------------- | -------- | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | R-50-D8 | 512x1024 | 40000 | 5.7 | 4.17 | V100 | 72.25 | 73.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_40k_cityscapes/fcn_r50-d8_512x1024_40k_cityscapes_20200604_192608-efe53f0d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_40k_cityscapes/fcn_r50-d8_512x1024_40k_cityscapes_20200604_192608.log.json) | +| FCN | R-101-D8 | 512x1024 | 40000 | 9.2 | 2.66 | V100 | 75.45 | 76.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_40k_cityscapes/fcn_r101-d8_512x1024_40k_cityscapes_20200604_181852-a883d3a1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_40k_cityscapes/fcn_r101-d8_512x1024_40k_cityscapes_20200604_181852.log.json) | +| FCN | R-50-D8 | 769x769 | 40000 | 6.5 | 1.80 | V100 | 71.47 | 72.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_40k_cityscapes/fcn_r50-d8_769x769_40k_cityscapes_20200606_113104-977b5d02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_40k_cityscapes/fcn_r50-d8_769x769_40k_cityscapes_20200606_113104.log.json) | +| FCN | R-101-D8 | 769x769 | 40000 | 10.4 | 1.19 | V100 | 73.93 | 75.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_40k_cityscapes/fcn_r101-d8_769x769_40k_cityscapes_20200606_113208-7d4ab69c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_40k_cityscapes/fcn_r101-d8_769x769_40k_cityscapes_20200606_113208.log.json) | +| FCN | R-18-D8 | 512x1024 | 80000 | 1.7 | 14.65 | V100 | 71.11 | 72.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_512x1024_80k_cityscapes/fcn_r18-d8_512x1024_80k_cityscapes_20201225_021327-6c50f8b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_512x1024_80k_cityscapes/fcn_r18-d8_512x1024_80k_cityscapes-20201225_021327.log.json) | +| FCN | R-50-D8 | 512x1024 | 80000 | - | | V100 | 73.61 | 74.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_80k_cityscapes/fcn_r50-d8_512x1024_80k_cityscapes_20200606_113019-03aa804d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x1024_80k_cityscapes/fcn_r50-d8_512x1024_80k_cityscapes_20200606_113019.log.json) | +| FCN | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 75.13 | 75.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_80k_cityscapes/fcn_r101-d8_512x1024_80k_cityscapes_20200606_113038-3fb937eb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x1024_80k_cityscapes/fcn_r101-d8_512x1024_80k_cityscapes_20200606_113038.log.json) | +| FCN (FP16) | R-101-D8 | 512x1024 | 80000 | 5.37 | 8.64 | V100 | 76.80 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_fp16_512x1024_80k_cityscapes/fcn_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230921-fb13e883.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_fp16_512x1024_80k_cityscapes/fcn_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230921.log.json) | +| FCN | R-18-D8 | 769x769 | 80000 | 1.9 | 6.40 | V100 | 70.80 | 73.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_769x769_80k_cityscapes/fcn_r18-d8_769x769_80k_cityscapes_20201225_021451-9739d1b8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18-d8_769x769_80k_cityscapes/fcn_r18-d8_769x769_80k_cityscapes-20201225_021451.log.json) | +| FCN | R-50-D8 | 769x769 | 80000 | - | - | V100 | 72.64 | 73.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_80k_cityscapes/fcn_r50-d8_769x769_80k_cityscapes_20200606_195749-f5caeabc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_769x769_80k_cityscapes/fcn_r50-d8_769x769_80k_cityscapes_20200606_195749.log.json) | +| FCN | R-101-D8 | 769x769 | 80000 | - | - | V100 | 75.52 | 76.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_80k_cityscapes/fcn_r101-d8_769x769_80k_cityscapes_20200606_214354-45cbac68.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_769x769_80k_cityscapes/fcn_r101-d8_769x769_80k_cityscapes_20200606_214354.log.json) | +| FCN | R-18b-D8 | 512x1024 | 80000 | 1.6 | 16.74 | V100 | 70.24 | 72.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_512x1024_80k_cityscapes/fcn_r18b-d8_512x1024_80k_cityscapes_20201225_230143-92c0f445.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_512x1024_80k_cityscapes/fcn_r18b-d8_512x1024_80k_cityscapes-20201225_230143.log.json) | +| FCN | R-50b-D8 | 512x1024 | 80000 | 5.6 | 4.20 | V100 | 75.65 | 77.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_512x1024_80k_cityscapes/fcn_r50b-d8_512x1024_80k_cityscapes_20201225_094221-82957416.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_512x1024_80k_cityscapes/fcn_r50b-d8_512x1024_80k_cityscapes-20201225_094221.log.json) | +| FCN | R-101b-D8 | 512x1024 | 80000 | 9.1 | 2.73 | V100 | 77.37 | 78.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_512x1024_80k_cityscapes/fcn_r101b-d8_512x1024_80k_cityscapes_20201226_160213-4543858f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_512x1024_80k_cityscapes/fcn_r101b-d8_512x1024_80k_cityscapes-20201226_160213.log.json) | +| FCN | R-18b-D8 | 769x769 | 80000 | 1.7 | 6.70 | V100 | 69.66 | 72.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_769x769_80k_cityscapes/fcn_r18b-d8_769x769_80k_cityscapes_20201226_004430-32d504e5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r18b-d8_769x769_80k_cityscapes/fcn_r18b-d8_769x769_80k_cityscapes-20201226_004430.log.json) | +| FCN | R-50b-D8 | 769x769 | 80000 | 6.3 | 1.82 | V100 | 73.83 | 76.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_769x769_80k_cityscapes/fcn_r50b-d8_769x769_80k_cityscapes_20201225_094223-94552d38.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50b-d8_769x769_80k_cityscapes/fcn_r50b-d8_769x769_80k_cityscapes-20201225_094223.log.json) | +| FCN | R-101b-D8 | 769x769 | 80000 | 10.3 | 1.15 | V100 | 77.02 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_769x769_80k_cityscapes/fcn_r101b-d8_769x769_80k_cityscapes_20201226_170012-82be37e2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101b-d8_769x769_80k_cityscapes/fcn_r101b-d8_769x769_80k_cityscapes-20201226_170012.log.json) | +| FCN (D6) | R-50-D16 | 512x1024 | 40000 | 3.4 | 10.22 | TITAN Xp | 77.06 | 78.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50-d16_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_40k_cityscapes/fcn_d6_r50-d16_512x1024_40k_cityscapes_20210305_130133-98d5d1bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_40k_cityscapes/fcn_d6_r50-d16_512x1024_40k_cityscapes-20210305_130133.log.json) | +| FCN (D6) | R-50-D16 | 512x1024 | 80000 | - | 10.35 | TITAN Xp | 77.27 | 78.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_80k_cityscapes/fcn_d6_r50-d16_512x1024_80k_cityscapes_20210306_115604-133c292f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_512x1024_80k_cityscapes/fcn_d6_r50-d16_512x1024_80k_cityscapes-20210306_115604.log.json) | +| FCN (D6) | R-50-D16 | 769x769 | 40000 | 3.7 | 4.17 | TITAN Xp | 76.82 | 78.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50-d16_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_40k_cityscapes/fcn_d6_r50-d16_769x769_40k_cityscapes_20210305_185744-1aab18ed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_40k_cityscapes/fcn_d6_r50-d16_769x769_40k_cityscapes-20210305_185744.log.json) | +| FCN (D6) | R-50-D16 | 769x769 | 80000 | - | 4.15 | TITAN Xp | 77.04 | 78.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_80k_cityscapes/fcn_d6_r50-d16_769x769_80k_cityscapes_20210305_200413-109d88eb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50-d16_769x769_80k_cityscapes/fcn_d6_r50-d16_769x769_80k_cityscapes-20210305_200413.log.json) | +| FCN (D6) | R-101-D16 | 512x1024 | 40000 | 4.5 | 8.04 | TITAN Xp | 77.36 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101-d16_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_40k_cityscapes/fcn_d6_r101-d16_512x1024_40k_cityscapes_20210305_130337-9cf2b450.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_40k_cityscapes/fcn_d6_r101-d16_512x1024_40k_cityscapes-20210305_130337.log.json) | +| FCN (D6) | R-101-D16 | 512x1024 | 80000 | - | 8.26 | TITAN Xp | 78.46 | 80.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_80k_cityscapes/fcn_d6_r101-d16_512x1024_80k_cityscapes_20210308_102747-cb336445.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_512x1024_80k_cityscapes/fcn_d6_r101-d16_512x1024_80k_cityscapes-20210308_102747.log.json) | +| FCN (D6) | R-101-D16 | 769x769 | 40000 | 5.0 | 3.12 | TITAN Xp | 77.28 | 78.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101-d16_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_40k_cityscapes/fcn_d6_r101-d16_769x769_40k_cityscapes_20210308_102453-60b114e9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_40k_cityscapes/fcn_d6_r101-d16_769x769_40k_cityscapes-20210308_102453.log.json) | +| FCN (D6) | R-101-D16 | 769x769 | 80000 | - | 3.21 | TITAN Xp | 78.06 | 79.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_80k_cityscapes/fcn_d6_r101-d16_769x769_80k_cityscapes_20210306_120016-e33adc4f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101-d16_769x769_80k_cityscapes/fcn_d6_r101-d16_769x769_80k_cityscapes-20210306_120016.log.json) | +| FCN (D6) | R-50b-D16 | 512x1024 | 80000 | 3.2 | 10.16 | TITAN Xp | 76.99 | 79.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50b-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b-d16_512x1024_80k_cityscapes/fcn_d6_r50b-d16_512x1024_80k_cityscapes_20210311_125550-6a0b62e9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b_d16_512x1024_80k_cityscapes/fcn_d6_r50b_d16_512x1024_80k_cityscapes-20210311_125550.log.json) | +| FCN (D6) | R-50b-D16 | 769x769 | 80000 | 3.6 | 4.17 | TITAN Xp | 76.86 | 78.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r50b-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b-d16_769x769_80k_cityscapes/fcn_d6_r50b-d16_769x769_80k_cityscapes_20210311_131012-d665f231.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r50b_d16_769x769_80k_cityscapes/fcn_d6_r50b_d16_769x769_80k_cityscapes-20210311_131012.log.json) | +| FCN (D6) | R-101b-D16 | 512x1024 | 80000 | 4.3 | 8.46 | TITAN Xp | 77.72 | 79.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101b-d16_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b-d16_512x1024_80k_cityscapes/fcn_d6_r101b-d16_512x1024_80k_cityscapes_20210311_144305-3f2eb5b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b_d16_512x1024_80k_cityscapes/fcn_d6_r101b_d16_512x1024_80k_cityscapes-20210311_144305.log.json) | +| FCN (D6) | R-101b-D16 | 769x769 | 80000 | 4.8 | 3.32 | TITAN Xp | 77.34 | 78.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn-d6_r101b-d16_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b-d16_769x769_80k_cityscapes/fcn_d6_r101b-d16_769x769_80k_cityscapes_20210311_154527-c4d8bfbc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_d6_r101b_d16_769x769_80k_cityscapes/fcn_d6_r101b_d16_769x769_80k_cityscapes-20210311_154527.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | R-50-D8 | 512x512 | 80000 | 8.5 | 23.49 | V100 | 35.94 | 37.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_80k_ade20k/fcn_r50-d8_512x512_80k_ade20k_20200614_144016-f8ac5082.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_80k_ade20k/fcn_r50-d8_512x512_80k_ade20k_20200614_144016.log.json) | -| FCN | R-101-D8 | 512x512 | 80000 | 12 | 14.78 | V100 | 39.61 | 40.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-80k_ade20k-512x512.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_80k_ade20k/fcn_r101-d8_512x512_80k_ade20k_20200615_014143-bc1809f7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_80k_ade20k/fcn_r101-d8_512x512_80k_ade20k_20200615_014143.log.json) | -| FCN | R-50-D8 | 512x512 | 160000 | - | - | V100 | 36.10 | 38.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_160k_ade20k/fcn_r50-d8_512x512_160k_ade20k_20200615_100713-4edbc3b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_160k_ade20k/fcn_r50-d8_512x512_160k_ade20k_20200615_100713.log.json) | -| FCN | R-101-D8 | 512x512 | 160000 | - | - | V100 | 39.91 | 41.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_160k_ade20k/fcn_r101-d8_512x512_160k_ade20k_20200615_105816-fd192bd5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_160k_ade20k/fcn_r101-d8_512x512_160k_ade20k_20200615_105816.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | R-50-D8 | 512x512 | 80000 | 8.5 | 23.49 | V100 | 35.94 | 37.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_80k_ade20k/fcn_r50-d8_512x512_80k_ade20k_20200614_144016-f8ac5082.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_80k_ade20k/fcn_r50-d8_512x512_80k_ade20k_20200614_144016.log.json) | +| FCN | R-101-D8 | 512x512 | 80000 | 12 | 14.78 | V100 | 39.61 | 40.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-80k_ade20k-512x512.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_80k_ade20k/fcn_r101-d8_512x512_80k_ade20k_20200615_014143-bc1809f7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_80k_ade20k/fcn_r101-d8_512x512_80k_ade20k_20200615_014143.log.json) | +| FCN | R-50-D8 | 512x512 | 160000 | - | - | V100 | 36.10 | 38.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_160k_ade20k/fcn_r50-d8_512x512_160k_ade20k_20200615_100713-4edbc3b4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_160k_ade20k/fcn_r50-d8_512x512_160k_ade20k_20200615_100713.log.json) | +| FCN | R-101-D8 | 512x512 | 160000 | - | - | V100 | 39.91 | 41.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_160k_ade20k/fcn_r101-d8_512x512_160k_ade20k_20200615_105816-fd192bd5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_160k_ade20k/fcn_r101-d8_512x512_160k_ade20k_20200615_105816.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | R-50-D8 | 512x512 | 20000 | 5.7 | 23.28 | V100 | 67.08 | 69.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_20k_voc12aug/fcn_r50-d8_512x512_20k_voc12aug_20200617_010715-52dc5306.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_20k_voc12aug/fcn_r50-d8_512x512_20k_voc12aug_20200617_010715.log.json) | -| FCN | R-101-D8 | 512x512 | 20000 | 9.2 | 14.81 | V100 | 71.16 | 73.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_20k_voc12aug/fcn_r101-d8_512x512_20k_voc12aug_20200617_010842-0bb4e798.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_20k_voc12aug/fcn_r101-d8_512x512_20k_voc12aug_20200617_010842.log.json) | -| FCN | R-50-D8 | 512x512 | 40000 | - | - | V100 | 66.97 | 69.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_40k_voc12aug/fcn_r50-d8_512x512_40k_voc12aug_20200613_161222-5e2dbf40.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_40k_voc12aug/fcn_r50-d8_512x512_40k_voc12aug_20200613_161222.log.json) | -| FCN | R-101-D8 | 512x512 | 40000 | - | - | V100 | 69.91 | 72.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_40k_voc12aug/fcn_r101-d8_512x512_40k_voc12aug_20200613_161240-4c8bcefd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_40k_voc12aug/fcn_r101-d8_512x512_40k_voc12aug_20200613_161240.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | R-50-D8 | 512x512 | 20000 | 5.7 | 23.28 | V100 | 67.08 | 69.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_20k_voc12aug/fcn_r50-d8_512x512_20k_voc12aug_20200617_010715-52dc5306.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_20k_voc12aug/fcn_r50-d8_512x512_20k_voc12aug_20200617_010715.log.json) | +| FCN | R-101-D8 | 512x512 | 20000 | 9.2 | 14.81 | V100 | 71.16 | 73.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_20k_voc12aug/fcn_r101-d8_512x512_20k_voc12aug_20200617_010842-0bb4e798.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_20k_voc12aug/fcn_r101-d8_512x512_20k_voc12aug_20200617_010842.log.json) | +| FCN | R-50-D8 | 512x512 | 40000 | - | - | V100 | 66.97 | 69.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_40k_voc12aug/fcn_r50-d8_512x512_40k_voc12aug_20200613_161222-5e2dbf40.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r50-d8_512x512_40k_voc12aug/fcn_r50-d8_512x512_40k_voc12aug_20200613_161222.log.json) | +| FCN | R-101-D8 | 512x512 | 40000 | - | - | V100 | 69.91 | 72.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_40k_voc12aug/fcn_r101-d8_512x512_40k_voc12aug_20200613_161240-4c8bcefd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_512x512_40k_voc12aug/fcn_r101-d8_512x512_40k_voc12aug_20200613_161240.log.json) | ### Pascal Context -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | R-101-D8 | 480x480 | 40000 | - | 9.93 | V100 | 44.43 | 45.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context/fcn_r101-d8_480x480_40k_pascal_context_20210421_154757-b5e97937.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context/fcn_r101-d8_480x480_40k_pascal_context-20210421_154757.log.json) | -| FCN | R-101-D8 | 480x480 | 80000 | - | - | V100 | 44.13 | 45.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context/fcn_r101-d8_480x480_80k_pascal_context_20210421_163310-4711813f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context/fcn_r101-d8_480x480_80k_pascal_context-20210421_163310.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | R-101-D8 | 480x480 | 40000 | - | 9.93 | V100 | 44.43 | 45.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context/fcn_r101-d8_480x480_40k_pascal_context_20210421_154757-b5e97937.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context/fcn_r101-d8_480x480_40k_pascal_context-20210421_154757.log.json) | +| FCN | R-101-D8 | 480x480 | 80000 | - | - | V100 | 44.13 | 45.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context/fcn_r101-d8_480x480_80k_pascal_context_20210421_163310-4711813f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context/fcn_r101-d8_480x480_80k_pascal_context-20210421_163310.log.json) | ### Pascal Context 59 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | R-101-D8 | 480x480 | 40000 | - | - | V100 | 48.42 | 50.4 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context_59/fcn_r101-d8_480x480_40k_pascal_context_59_20210415_230724-8cf83682.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context_59/fcn_r101-d8_480x480_40k_pascal_context_59-20210415_230724.log.json) | -| FCN | R-101-D8 | 480x480 | 80000 | - | - | V100 | 49.35 | 51.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context_59/fcn_r101-d8_480x480_80k_pascal_context_59_20210416_110804-9a6f2c94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context_59/fcn_r101-d8_480x480_80k_pascal_context_59-20210416_110804.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | R-101-D8 | 480x480 | 40000 | - | - | V100 | 48.42 | 50.4 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context_59/fcn_r101-d8_480x480_40k_pascal_context_59_20210415_230724-8cf83682.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_40k_pascal_context_59/fcn_r101-d8_480x480_40k_pascal_context_59-20210415_230724.log.json) | +| FCN | R-101-D8 | 480x480 | 80000 | - | - | V100 | 49.35 | 51.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context_59/fcn_r101-d8_480x480_80k_pascal_context_59_20210416_110804-9a6f2c94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/fcn/fcn_r101-d8_480x480_80k_pascal_context_59/fcn_r101-d8_480x480_80k_pascal_context_59-20210416_110804.log.json) | Note: diff --git a/configs/gcnet/README.md b/configs/gcnet/README.md index 26a478808fc..ba1a21e8512 100644 --- a/configs/gcnet/README.md +++ b/configs/gcnet/README.md @@ -26,34 +26,34 @@ The Non-Local Network (NLNet) presents a pioneering approach for capturing long- ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| GCNet | R-50-D8 | 512x1024 | 40000 | 5.8 | 3.93 | V100 | 77.69 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_40k_cityscapes/gcnet_r50-d8_512x1024_40k_cityscapes_20200618_074436-4b0fd17b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_40k_cityscapes/gcnet_r50-d8_512x1024_40k_cityscapes_20200618_074436.log.json) | -| GCNet | R-101-D8 | 512x1024 | 40000 | 9.2 | 2.61 | V100 | 78.28 | 79.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_40k_cityscapes/gcnet_r101-d8_512x1024_40k_cityscapes_20200618_074436-5e62567f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_40k_cityscapes/gcnet_r101-d8_512x1024_40k_cityscapes_20200618_074436.log.json) | -| GCNet | R-50-D8 | 769x769 | 40000 | 6.5 | 1.67 | V100 | 78.12 | 80.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_40k_cityscapes/gcnet_r50-d8_769x769_40k_cityscapes_20200618_182814-a26f4471.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_40k_cityscapes/gcnet_r50-d8_769x769_40k_cityscapes_20200618_182814.log.json) | -| GCNet | R-101-D8 | 769x769 | 40000 | 10.5 | 1.13 | V100 | 78.95 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_40k_cityscapes/gcnet_r101-d8_769x769_40k_cityscapes_20200619_092550-ca4f0a84.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_40k_cityscapes/gcnet_r101-d8_769x769_40k_cityscapes_20200619_092550.log.json) | -| GCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.48 | 80.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_80k_cityscapes/gcnet_r50-d8_512x1024_80k_cityscapes_20200618_074450-ef8f069b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_80k_cityscapes/gcnet_r50-d8_512x1024_80k_cityscapes_20200618_074450.log.json) | -| GCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.03 | 79.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb2-80k_cityscapes-512x1024.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_80k_cityscapes/gcnet_r101-d8_512x1024_80k_cityscapes_20200618_074450-778ebf69.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_80k_cityscapes/gcnet_r101-d8_512x1024_80k_cityscapes_20200618_074450.log.json) | -| GCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.68 | 80.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_80k_cityscapes/gcnet_r50-d8_769x769_80k_cityscapes_20200619_092516-4839565b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_80k_cityscapes/gcnet_r50-d8_769x769_80k_cityscapes_20200619_092516.log.json) | -| GCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.18 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_80k_cityscapes/gcnet_r101-d8_769x769_80k_cityscapes_20200619_092628-8e043423.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_80k_cityscapes/gcnet_r101-d8_769x769_80k_cityscapes_20200619_092628.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| GCNet | R-50-D8 | 512x1024 | 40000 | 5.8 | 3.93 | V100 | 77.69 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_40k_cityscapes/gcnet_r50-d8_512x1024_40k_cityscapes_20200618_074436-4b0fd17b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_40k_cityscapes/gcnet_r50-d8_512x1024_40k_cityscapes_20200618_074436.log.json) | +| GCNet | R-101-D8 | 512x1024 | 40000 | 9.2 | 2.61 | V100 | 78.28 | 79.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_40k_cityscapes/gcnet_r101-d8_512x1024_40k_cityscapes_20200618_074436-5e62567f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_40k_cityscapes/gcnet_r101-d8_512x1024_40k_cityscapes_20200618_074436.log.json) | +| GCNet | R-50-D8 | 769x769 | 40000 | 6.5 | 1.67 | V100 | 78.12 | 80.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_40k_cityscapes/gcnet_r50-d8_769x769_40k_cityscapes_20200618_182814-a26f4471.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_40k_cityscapes/gcnet_r50-d8_769x769_40k_cityscapes_20200618_182814.log.json) | +| GCNet | R-101-D8 | 769x769 | 40000 | 10.5 | 1.13 | V100 | 78.95 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_40k_cityscapes/gcnet_r101-d8_769x769_40k_cityscapes_20200619_092550-ca4f0a84.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_40k_cityscapes/gcnet_r101-d8_769x769_40k_cityscapes_20200619_092550.log.json) | +| GCNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.48 | 80.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_80k_cityscapes/gcnet_r50-d8_512x1024_80k_cityscapes_20200618_074450-ef8f069b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x1024_80k_cityscapes/gcnet_r50-d8_512x1024_80k_cityscapes_20200618_074450.log.json) | +| GCNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.03 | 79.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb2-80k_cityscapes-512x1024.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_80k_cityscapes/gcnet_r101-d8_512x1024_80k_cityscapes_20200618_074450-778ebf69.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x1024_80k_cityscapes/gcnet_r101-d8_512x1024_80k_cityscapes_20200618_074450.log.json) | +| GCNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 78.68 | 80.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_80k_cityscapes/gcnet_r50-d8_769x769_80k_cityscapes_20200619_092516-4839565b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_769x769_80k_cityscapes/gcnet_r50-d8_769x769_80k_cityscapes_20200619_092516.log.json) | +| GCNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.18 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_80k_cityscapes/gcnet_r101-d8_769x769_80k_cityscapes_20200619_092628-8e043423.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_769x769_80k_cityscapes/gcnet_r101-d8_769x769_80k_cityscapes_20200619_092628.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| GCNet | R-50-D8 | 512x512 | 80000 | 8.5 | 23.38 | V100 | 41.47 | 42.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_80k_ade20k/gcnet_r50-d8_512x512_80k_ade20k_20200614_185146-91a6da41.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_80k_ade20k/gcnet_r50-d8_512x512_80k_ade20k_20200614_185146.log.json) | -| GCNet | R-101-D8 | 512x512 | 80000 | 12 | 15.20 | V100 | 42.82 | 44.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_80k_ade20k/gcnet_r101-d8_512x512_80k_ade20k_20200615_020811-c3fcb6dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_80k_ade20k/gcnet_r101-d8_512x512_80k_ade20k_20200615_020811.log.json) | -| GCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.37 | 43.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_160k_ade20k/gcnet_r50-d8_512x512_160k_ade20k_20200615_224122-d95f3e1f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_160k_ade20k/gcnet_r50-d8_512x512_160k_ade20k_20200615_224122.log.json) | -| GCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.69 | 45.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_160k_ade20k/gcnet_r101-d8_512x512_160k_ade20k_20200615_225406-615528d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_160k_ade20k/gcnet_r101-d8_512x512_160k_ade20k_20200615_225406.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| GCNet | R-50-D8 | 512x512 | 80000 | 8.5 | 23.38 | V100 | 41.47 | 42.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_80k_ade20k/gcnet_r50-d8_512x512_80k_ade20k_20200614_185146-91a6da41.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_80k_ade20k/gcnet_r50-d8_512x512_80k_ade20k_20200614_185146.log.json) | +| GCNet | R-101-D8 | 512x512 | 80000 | 12 | 15.20 | V100 | 42.82 | 44.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_80k_ade20k/gcnet_r101-d8_512x512_80k_ade20k_20200615_020811-c3fcb6dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_80k_ade20k/gcnet_r101-d8_512x512_80k_ade20k_20200615_020811.log.json) | +| GCNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.37 | 43.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_160k_ade20k/gcnet_r50-d8_512x512_160k_ade20k_20200615_224122-d95f3e1f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_160k_ade20k/gcnet_r50-d8_512x512_160k_ade20k_20200615_224122.log.json) | +| GCNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.69 | 45.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_160k_ade20k/gcnet_r101-d8_512x512_160k_ade20k_20200615_225406-615528d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_160k_ade20k/gcnet_r101-d8_512x512_160k_ade20k_20200615_225406.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| GCNet | R-50-D8 | 512x512 | 20000 | 5.8 | 23.35 | V100 | 76.42 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_20k_voc12aug/gcnet_r50-d8_512x512_20k_voc12aug_20200617_165701-3cbfdab1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_20k_voc12aug/gcnet_r50-d8_512x512_20k_voc12aug_20200617_165701.log.json) | -| GCNet | R-101-D8 | 512x512 | 20000 | 9.2 | 14.80 | V100 | 77.41 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_20k_voc12aug/gcnet_r101-d8_512x512_20k_voc12aug_20200617_165713-6c720aa9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_20k_voc12aug/gcnet_r101-d8_512x512_20k_voc12aug_20200617_165713.log.json) | -| GCNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.24 | 77.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_40k_voc12aug/gcnet_r50-d8_512x512_40k_voc12aug_20200613_195105-9797336d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_40k_voc12aug/gcnet_r50-d8_512x512_40k_voc12aug_20200613_195105.log.json) | -| GCNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.84 | 78.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/gcnet/gcnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_40k_voc12aug/gcnet_r101-d8_512x512_40k_voc12aug_20200613_185806-1e38208d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_40k_voc12aug/gcnet_r101-d8_512x512_40k_voc12aug_20200613_185806.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| GCNet | R-50-D8 | 512x512 | 20000 | 5.8 | 23.35 | V100 | 76.42 | 77.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_20k_voc12aug/gcnet_r50-d8_512x512_20k_voc12aug_20200617_165701-3cbfdab1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_20k_voc12aug/gcnet_r50-d8_512x512_20k_voc12aug_20200617_165701.log.json) | +| GCNet | R-101-D8 | 512x512 | 20000 | 9.2 | 14.80 | V100 | 77.41 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_20k_voc12aug/gcnet_r101-d8_512x512_20k_voc12aug_20200617_165713-6c720aa9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_20k_voc12aug/gcnet_r101-d8_512x512_20k_voc12aug_20200617_165713.log.json) | +| GCNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.24 | 77.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_40k_voc12aug/gcnet_r50-d8_512x512_40k_voc12aug_20200613_195105-9797336d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r50-d8_512x512_40k_voc12aug/gcnet_r50-d8_512x512_40k_voc12aug_20200613_195105.log.json) | +| GCNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.84 | 78.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet/gcnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_40k_voc12aug/gcnet_r101-d8_512x512_40k_voc12aug_20200613_185806-1e38208d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/gcnet/gcnet_r101-d8_512x512_40k_voc12aug/gcnet_r101-d8_512x512_40k_voc12aug_20200613_185806.log.json) | ## Citation diff --git a/configs/hrnet/README.md b/configs/hrnet/README.md index 38a6bd0e764..b529fc895ed 100644 --- a/configs/hrnet/README.md +++ b/configs/hrnet/README.md @@ -26,85 +26,85 @@ High-resolution representations are essential for position-sensitive vision prob ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | HRNetV2p-W18-Small | 512x1024 | 40000 | 1.7 | 23.74 | V100 | 73.86 | 75.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_40k_cityscapes/fcn_hr18s_512x1024_40k_cityscapes_20200601_014216-93db27d0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_40k_cityscapes/fcn_hr18s_512x1024_40k_cityscapes_20200601_014216.log.json) | -| FCN | HRNetV2p-W18 | 512x1024 | 40000 | 2.9 | 12.97 | V100 | 77.19 | 78.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_40k_cityscapes/fcn_hr18_512x1024_40k_cityscapes_20200601_014216-f196fb4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_40k_cityscapes/fcn_hr18_512x1024_40k_cityscapes_20200601_014216.log.json) | -| FCN | HRNetV2p-W48 | 512x1024 | 40000 | 6.2 | 6.42 | V100 | 78.48 | 79.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_40k_cityscapes/fcn_hr48_512x1024_40k_cityscapes_20200601_014240-a989b146.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_40k_cityscapes/fcn_hr48_512x1024_40k_cityscapes_20200601_014240.log.json) | -| FCN | HRNetV2p-W18-Small | 512x1024 | 80000 | - | - | V100 | 75.31 | 77.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_80k_cityscapes/fcn_hr18s_512x1024_80k_cityscapes_20200601_202700-1462b75d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_80k_cityscapes/fcn_hr18s_512x1024_80k_cityscapes_20200601_202700.log.json) | -| FCN | HRNetV2p-W18 | 512x1024 | 80000 | - | - | V100 | 78.65 | 80.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_80k_cityscapes/fcn_hr18_512x1024_80k_cityscapes_20200601_223255-4e7b345e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_80k_cityscapes/fcn_hr18_512x1024_80k_cityscapes_20200601_223255.log.json) | -| FCN | HRNetV2p-W48 | 512x1024 | 80000 | - | - | V100 | 79.93 | 80.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_80k_cityscapes/fcn_hr48_512x1024_80k_cityscapes_20200601_202606-58ea95d6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_80k_cityscapes/fcn_hr48_512x1024_80k_cityscapes_20200601_202606.log.json) | -| FCN | HRNetV2p-W18-Small | 512x1024 | 160000 | - | - | V100 | 76.31 | 78.31 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_160k_cityscapes/fcn_hr18s_512x1024_160k_cityscapes_20200602_190901-4a0797ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_160k_cityscapes/fcn_hr18s_512x1024_160k_cityscapes_20200602_190901.log.json) | -| FCN | HRNetV2p-W18 | 512x1024 | 160000 | - | - | V100 | 78.80 | 80.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_160k_cityscapes/fcn_hr18_512x1024_160k_cityscapes_20200602_190822-221e4a4f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_160k_cityscapes/fcn_hr18_512x1024_160k_cityscapes_20200602_190822.log.json) | -| FCN | HRNetV2p-W48 | 512x1024 | 160000 | - | - | V100 | 80.65 | 81.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_160k_cityscapes/fcn_hr48_512x1024_160k_cityscapes_20200602_190946-59b7973e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_160k_cityscapes/fcn_hr48_512x1024_160k_cityscapes_20200602_190946.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | HRNetV2p-W18-Small | 512x1024 | 40000 | 1.7 | 23.74 | V100 | 73.86 | 75.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_40k_cityscapes/fcn_hr18s_512x1024_40k_cityscapes_20200601_014216-93db27d0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_40k_cityscapes/fcn_hr18s_512x1024_40k_cityscapes_20200601_014216.log.json) | +| FCN | HRNetV2p-W18 | 512x1024 | 40000 | 2.9 | 12.97 | V100 | 77.19 | 78.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_40k_cityscapes/fcn_hr18_512x1024_40k_cityscapes_20200601_014216-f196fb4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_40k_cityscapes/fcn_hr18_512x1024_40k_cityscapes_20200601_014216.log.json) | +| FCN | HRNetV2p-W48 | 512x1024 | 40000 | 6.2 | 6.42 | V100 | 78.48 | 79.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_40k_cityscapes/fcn_hr48_512x1024_40k_cityscapes_20200601_014240-a989b146.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_40k_cityscapes/fcn_hr48_512x1024_40k_cityscapes_20200601_014240.log.json) | +| FCN | HRNetV2p-W18-Small | 512x1024 | 80000 | - | - | V100 | 75.31 | 77.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_80k_cityscapes/fcn_hr18s_512x1024_80k_cityscapes_20200601_202700-1462b75d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_80k_cityscapes/fcn_hr18s_512x1024_80k_cityscapes_20200601_202700.log.json) | +| FCN | HRNetV2p-W18 | 512x1024 | 80000 | - | - | V100 | 78.65 | 80.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_80k_cityscapes/fcn_hr18_512x1024_80k_cityscapes_20200601_223255-4e7b345e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_80k_cityscapes/fcn_hr18_512x1024_80k_cityscapes_20200601_223255.log.json) | +| FCN | HRNetV2p-W48 | 512x1024 | 80000 | - | - | V100 | 79.93 | 80.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_80k_cityscapes/fcn_hr48_512x1024_80k_cityscapes_20200601_202606-58ea95d6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_80k_cityscapes/fcn_hr48_512x1024_80k_cityscapes_20200601_202606.log.json) | +| FCN | HRNetV2p-W18-Small | 512x1024 | 160000 | - | - | V100 | 76.31 | 78.31 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_160k_cityscapes/fcn_hr18s_512x1024_160k_cityscapes_20200602_190901-4a0797ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x1024_160k_cityscapes/fcn_hr18s_512x1024_160k_cityscapes_20200602_190901.log.json) | +| FCN | HRNetV2p-W18 | 512x1024 | 160000 | - | - | V100 | 78.80 | 80.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_160k_cityscapes/fcn_hr18_512x1024_160k_cityscapes_20200602_190822-221e4a4f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x1024_160k_cityscapes/fcn_hr18_512x1024_160k_cityscapes_20200602_190822.log.json) | +| FCN | HRNetV2p-W48 | 512x1024 | 160000 | - | - | V100 | 80.65 | 81.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_160k_cityscapes/fcn_hr48_512x1024_160k_cityscapes_20200602_190946-59b7973e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x1024_160k_cityscapes/fcn_hr48_512x1024_160k_cityscapes_20200602_190946.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 3.8 | 38.66 | V100 | 31.38 | 32.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_ade20k/fcn_hr18s_512x512_80k_ade20k_20200614_144345-77fc814a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_ade20k/fcn_hr18s_512x512_80k_ade20k_20200614_144345.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 80000 | 4.9 | 22.57 | V100 | 36.27 | 37.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_ade20k/fcn_hr18_512x512_80k_ade20k_20210827_114910-6c9382c0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_ade20k/fcn_hr18_512x512_80k_ade20k_20210827_114910.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 80000 | 8.2 | 21.23 | V100 | 41.90 | 43.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_ade20k/fcn_hr48_512x512_80k_ade20k_20200614_193946-7ba5258d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_ade20k/fcn_hr48_512x512_80k_ade20k_20200614_193946.log.json) | -| FCN | HRNetV2p-W18-Small | 512x512 | 160000 | - | - | V100 | 33.07 | 34.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_160k_ade20k/fcn_hr18s_512x512_160k_ade20k_20210829_174739-f1e7c2e7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_160k_ade20k/fcn_hr18s_512x512_160k_ade20k_20210829_174739.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 160000 | - | - | V100 | 36.79 | 38.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_160k_ade20k/fcn_hr18_512x512_160k_ade20k_20200614_214426-ca961836.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_160k_ade20k/fcn_hr18_512x512_160k_ade20k_20200614_214426.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 160000 | - | - | V100 | 42.02 | 43.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_160k_ade20k/fcn_hr48_512x512_160k_ade20k_20200614_214407-a52fc02c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_160k_ade20k/fcn_hr48_512x512_160k_ade20k_20200614_214407.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 3.8 | 38.66 | V100 | 31.38 | 32.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_ade20k/fcn_hr18s_512x512_80k_ade20k_20200614_144345-77fc814a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_ade20k/fcn_hr18s_512x512_80k_ade20k_20200614_144345.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 80000 | 4.9 | 22.57 | V100 | 36.27 | 37.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_ade20k/fcn_hr18_512x512_80k_ade20k_20210827_114910-6c9382c0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_ade20k/fcn_hr18_512x512_80k_ade20k_20210827_114910.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 80000 | 8.2 | 21.23 | V100 | 41.90 | 43.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_ade20k/fcn_hr48_512x512_80k_ade20k_20200614_193946-7ba5258d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_ade20k/fcn_hr48_512x512_80k_ade20k_20200614_193946.log.json) | +| FCN | HRNetV2p-W18-Small | 512x512 | 160000 | - | - | V100 | 33.07 | 34.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_160k_ade20k/fcn_hr18s_512x512_160k_ade20k_20210829_174739-f1e7c2e7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_160k_ade20k/fcn_hr18s_512x512_160k_ade20k_20210829_174739.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 160000 | - | - | V100 | 36.79 | 38.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_160k_ade20k/fcn_hr18_512x512_160k_ade20k_20200614_214426-ca961836.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_160k_ade20k/fcn_hr18_512x512_160k_ade20k_20200614_214426.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 160000 | - | - | V100 | 42.02 | 43.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_160k_ade20k/fcn_hr48_512x512_160k_ade20k_20200614_214407-a52fc02c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_160k_ade20k/fcn_hr48_512x512_160k_ade20k_20200614_214407.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | HRNetV2p-W18-Small | 512x512 | 20000 | 1.8 | 43.36 | V100 | 65.5 | 68.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_20k_voc12aug/fcn_hr18s_512x512_20k_voc12aug_20210829_174910-0aceadb4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_20k_voc12aug/fcn_hr18s_512x512_20k_voc12aug_20210829_174910.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 20000 | 2.9 | 23.48 | V100 | 72.30 | 74.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_20k_voc12aug/fcn_hr18_512x512_20k_voc12aug_20200617_224503-488d45f7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_20k_voc12aug/fcn_hr18_512x512_20k_voc12aug_20200617_224503.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 20000 | 6.2 | 22.05 | V100 | 75.87 | 78.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_20k_voc12aug/fcn_hr48_512x512_20k_voc12aug_20200617_224419-89de05cd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_20k_voc12aug/fcn_hr48_512x512_20k_voc12aug_20200617_224419.log.json) | -| FCN | HRNetV2p-W18-Small | 512x512 | 40000 | - | - | V100 | 66.61 | 70.00 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_40k_voc12aug/fcn_hr18s_512x512_40k_voc12aug_20200614_000648-4f8d6e7f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_40k_voc12aug/fcn_hr18s_512x512_40k_voc12aug_20200614_000648.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 40000 | - | - | V100 | 72.90 | 75.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_40k_voc12aug/fcn_hr18_512x512_40k_voc12aug_20200613_224401-1b4b76cd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_40k_voc12aug/fcn_hr18_512x512_40k_voc12aug_20200613_224401.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 40000 | - | - | V100 | 76.24 | 78.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_40k_voc12aug/fcn_hr48_512x512_40k_voc12aug_20200613_222111-1b0f18bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_40k_voc12aug/fcn_hr48_512x512_40k_voc12aug_20200613_222111.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | HRNetV2p-W18-Small | 512x512 | 20000 | 1.8 | 43.36 | V100 | 65.5 | 68.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_20k_voc12aug/fcn_hr18s_512x512_20k_voc12aug_20210829_174910-0aceadb4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_20k_voc12aug/fcn_hr18s_512x512_20k_voc12aug_20210829_174910.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 20000 | 2.9 | 23.48 | V100 | 72.30 | 74.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_20k_voc12aug/fcn_hr18_512x512_20k_voc12aug_20200617_224503-488d45f7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_20k_voc12aug/fcn_hr18_512x512_20k_voc12aug_20200617_224503.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 20000 | 6.2 | 22.05 | V100 | 75.87 | 78.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_20k_voc12aug/fcn_hr48_512x512_20k_voc12aug_20200617_224419-89de05cd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_20k_voc12aug/fcn_hr48_512x512_20k_voc12aug_20200617_224419.log.json) | +| FCN | HRNetV2p-W18-Small | 512x512 | 40000 | - | - | V100 | 66.61 | 70.00 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_40k_voc12aug/fcn_hr18s_512x512_40k_voc12aug_20200614_000648-4f8d6e7f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_40k_voc12aug/fcn_hr18s_512x512_40k_voc12aug_20200614_000648.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 40000 | - | - | V100 | 72.90 | 75.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_40k_voc12aug/fcn_hr18_512x512_40k_voc12aug_20200613_224401-1b4b76cd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_40k_voc12aug/fcn_hr18_512x512_40k_voc12aug_20200613_224401.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 40000 | - | - | V100 | 76.24 | 78.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_40k_voc12aug/fcn_hr48_512x512_40k_voc12aug_20200613_222111-1b0f18bc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_40k_voc12aug/fcn_hr48_512x512_40k_voc12aug_20200613_222111.log.json) | ### Pascal Context -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FCN | HRNetV2p-W48 | 480x480 | 40000 | 6.1 | 8.86 | V100 | 45.14 | 47.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context/fcn_hr48_480x480_40k_pascal_context_20200911_164852-667d00b0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context/fcn_hr48_480x480_40k_pascal_context-20200911_164852.log.json) | -| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 45.84 | 47.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context/fcn_hr48_480x480_80k_pascal_context_20200911_155322-847a6711.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context/fcn_hr48_480x480_80k_pascal_context-20200911_155322.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FCN | HRNetV2p-W48 | 480x480 | 40000 | 6.1 | 8.86 | V100 | 45.14 | 47.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context/fcn_hr48_480x480_40k_pascal_context_20200911_164852-667d00b0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context/fcn_hr48_480x480_40k_pascal_context-20200911_164852.log.json) | +| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 45.84 | 47.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context/fcn_hr48_480x480_80k_pascal_context_20200911_155322-847a6711.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context/fcn_hr48_480x480_80k_pascal_context-20200911_155322.log.json) | ### Pascal Context 59 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FCN | HRNetV2p-W48 | 480x480 | 40000 | - | - | V100 | 50.33 | 52.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context_59/fcn_hr48_480x480_40k_pascal_context_59_20210410_122738-b808b8b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context_59/fcn_hr48_480x480_40k_pascal_context_59-20210410_122738.log.json) | -| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 51.12 | 53.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context_59/fcn_hr48_480x480_80k_pascal_context_59_20210411_003240-3ae7081e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context_59/fcn_hr48_480x480_80k_pascal_context_59-20210411_003240.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FCN | HRNetV2p-W48 | 480x480 | 40000 | - | - | V100 | 50.33 | 52.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context_59/fcn_hr48_480x480_40k_pascal_context_59_20210410_122738-b808b8b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_40k_pascal_context_59/fcn_hr48_480x480_40k_pascal_context_59-20210410_122738.log.json) | +| FCN | HRNetV2p-W48 | 480x480 | 80000 | - | - | V100 | 51.12 | 53.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context_59/fcn_hr48_480x480_80k_pascal_context_59_20210411_003240-3ae7081e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_480x480_80k_pascal_context_59/fcn_hr48_480x480_80k_pascal_context_59-20210411_003240.log.json) | ### LoveDA -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.59 | 24.87 | V100 | 49.28 | 49.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-80k_loveda-512x512.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_loveda/fcn_hr18s_512x512_80k_loveda_20211210_203228-60a86a7a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_loveda/fcn_hr18s_512x512_80k_loveda_20211210_203228.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 12.92 | V100 | 50.81 | 50.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_loveda/fcn_hr18_512x512_80k_loveda_20211210_203952-93d9c3b3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_loveda/fcn_hr18_512x512_80k_loveda_20211210_203952.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 9.61 | V100 | 51.42 | 51.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_loveda/fcn_hr48_512x512_80k_loveda_20211211_044756-67072f55.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_loveda/fcn_hr48_512x512_80k_loveda_20211211_044756.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.59 | 24.87 | V100 | 49.28 | 49.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-80k_loveda-512x512.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_loveda/fcn_hr18s_512x512_80k_loveda_20211210_203228-60a86a7a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_loveda/fcn_hr18s_512x512_80k_loveda_20211210_203228.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 12.92 | V100 | 50.81 | 50.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_loveda/fcn_hr18_512x512_80k_loveda_20211210_203952-93d9c3b3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_loveda/fcn_hr18_512x512_80k_loveda_20211210_203952.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 9.61 | V100 | 51.42 | 51.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_loveda/fcn_hr48_512x512_80k_loveda_20211211_044756-67072f55.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_loveda/fcn_hr48_512x512_80k_loveda_20211211_044756.log.json) | ### Potsdam -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 36.00 | V100 | 77.64 | 78.8 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_potsdam/fcn_hr18s_512x512_80k_potsdam_20211218_205517-ba32af63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_potsdam/fcn_hr18s_512x512_80k_potsdam_20211218_205517.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.25 | V100 | 78.26 | 79.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_potsdam/fcn_hr18_512x512_80k_potsdam_20211218_205517-5d0387ad.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_potsdam/fcn_hr18_512x512_80k_potsdam_20211218_205517.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 16.42 | V100 | 78.39 | 79.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_potsdam/fcn_hr48_512x512_80k_potsdam_20211219_020601-97434c78.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_potsdam/fcn_hr48_512x512_80k_potsdam_20211219_020601.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 36.00 | V100 | 77.64 | 78.8 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_potsdam/fcn_hr18s_512x512_80k_potsdam_20211218_205517-ba32af63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_512x512_80k_potsdam/fcn_hr18s_512x512_80k_potsdam_20211218_205517.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.25 | V100 | 78.26 | 79.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_potsdam/fcn_hr18_512x512_80k_potsdam_20211218_205517-5d0387ad.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_512x512_80k_potsdam/fcn_hr18_512x512_80k_potsdam_20211218_205517.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 16.42 | V100 | 78.39 | 79.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_potsdam/fcn_hr48_512x512_80k_potsdam_20211219_020601-97434c78.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_512x512_80k_potsdam/fcn_hr48_512x512_80k_potsdam_20211219_020601.log.json) | ### Vaihingen -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 38.11 | V100 | 71.81 | 73.1 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_512x512_80k_vaihingen/fcn_hr18s_4x4_512x512_80k_vaihingen_20211231_230909-b23aae02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_512x512_80k_vaihingen/fcn_hr18s_4x4_512x512_80k_vaihingen_20211231_230909.log.json) | -| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.55 | V100 | 72.57 | 74.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_512x512_80k_vaihingen/fcn_hr18_4x4_512x512_80k_vaihingen_20211231_231216-2ec3ae8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_512x512_80k_vaihingen/fcn_hr18_4x4_512x512_80k_vaihingen_20211231_231216.log.json) | -| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 17.25 | V100 | 72.50 | 73.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_512x512_80k_vaihingen/fcn_hr48_4x4_512x512_80k_vaihingen_20211231_231244-7133cb22.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_512x512_80k_vaihingen/fcn_hr48_4x4_512x512_80k_vaihingen_20211231_231244.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FCN | HRNetV2p-W18-Small | 512x512 | 80000 | 1.58 | 38.11 | V100 | 71.81 | 73.1 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_512x512_80k_vaihingen/fcn_hr18s_4x4_512x512_80k_vaihingen_20211231_230909-b23aae02.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_512x512_80k_vaihingen/fcn_hr18s_4x4_512x512_80k_vaihingen_20211231_230909.log.json) | +| FCN | HRNetV2p-W18 | 512x512 | 80000 | 2.76 | 19.55 | V100 | 72.57 | 74.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_512x512_80k_vaihingen/fcn_hr18_4x4_512x512_80k_vaihingen_20211231_231216-2ec3ae8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_512x512_80k_vaihingen/fcn_hr18_4x4_512x512_80k_vaihingen_20211231_231216.log.json) | +| FCN | HRNetV2p-W48 | 512x512 | 80000 | 6.20 | 17.25 | V100 | 72.50 | 73.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_512x512_80k_vaihingen/fcn_hr48_4x4_512x512_80k_vaihingen_20211231_231244-7133cb22.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_512x512_80k_vaihingen/fcn_hr48_4x4_512x512_80k_vaihingen_20211231_231244.log.json) | ### iSAID -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | HRNetV2p-W18-Small | 896x896 | 80000 | 4.95 | 13.84 | V100 | 62.30 | 62.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18s_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_896x896_80k_isaid/fcn_hr18s_4x4_896x896_80k_isaid_20220118_001603-3cc0769b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_896x896_80k_isaid/fcn_hr18s_4x4_896x896_80k_isaid_20220118_001603.log.json) | -| FCN | HRNetV2p-W18 | 896x896 | 80000 | 8.30 | 7.71 | V100 | 65.06 | 65.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr18_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_896x896_80k_isaid/fcn_hr18_4x4_896x896_80k_isaid_20220110_182230-49bf752e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_896x896_80k_isaid/fcn_hr18_4x4_896x896_80k_isaid_20220110_182230.log.json) | -| FCN | HRNetV2p-W48 | 896x896 | 80000 | 16.89 | 7.34 | V100 | 67.80 | 68.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/hrnet/fcn_hr48_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_896x896_80k_isaid/fcn_hr48_4x4_896x896_80k_isaid_20220114_174643-547fc420.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_896x896_80k_isaid/fcn_hr48_4x4_896x896_80k_isaid_20220114_174643.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | HRNetV2p-W18-Small | 896x896 | 80000 | 4.95 | 13.84 | V100 | 62.30 | 62.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18s_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_896x896_80k_isaid/fcn_hr18s_4x4_896x896_80k_isaid_20220118_001603-3cc0769b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18s_4x4_896x896_80k_isaid/fcn_hr18s_4x4_896x896_80k_isaid_20220118_001603.log.json) | +| FCN | HRNetV2p-W18 | 896x896 | 80000 | 8.30 | 7.71 | V100 | 65.06 | 65.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr18_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_896x896_80k_isaid/fcn_hr18_4x4_896x896_80k_isaid_20220110_182230-49bf752e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr18_4x4_896x896_80k_isaid/fcn_hr18_4x4_896x896_80k_isaid_20220110_182230.log.json) | +| FCN | HRNetV2p-W48 | 896x896 | 80000 | 16.89 | 7.34 | V100 | 67.80 | 68.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet/fcn_hr48_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_896x896_80k_isaid/fcn_hr48_4x4_896x896_80k_isaid_20220114_174643-547fc420.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/hrnet/fcn_hr48_4x4_896x896_80k_isaid/fcn_hr48_4x4_896x896_80k_isaid_20220114_174643.log.json) | Note: diff --git a/configs/icnet/README.md b/configs/icnet/README.md index 2b58c2eed84..fa2327fc391 100644 --- a/configs/icnet/README.md +++ b/configs/icnet/README.md @@ -26,20 +26,20 @@ We focus on the challenging task of real-time semantic segmentation in this pape ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ICNet | R-18-D8 | 832x832 | 80000 | 1.70 | 27.12 | V100 | 68.14 | 70.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r18-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_80k_cityscapes/icnet_r18-d8_832x832_80k_cityscapes_20210925_225521-2e36638d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_80k_cityscapes/icnet_r18-d8_832x832_80k_cityscapes_20210925_225521.log.json) | -| ICNet | R-18-D8 | 832x832 | 160000 | - | - | V100 | 71.64 | 74.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r18-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_160k_cityscapes/icnet_r18-d8_832x832_160k_cityscapes_20210925_230153-2c6eb6e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_160k_cityscapes/icnet_r18-d8_832x832_160k_cityscapes_20210925_230153.log.json) | -| ICNet (in1k-pre) | R-18-D8 | 832x832 | 80000 | - | - | V100 | 72.51 | 74.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r18-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes_20210925_230354-1cbe3022.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes_20210925_230354.log.json) | -| ICNet (in1k-pre) | R-18-D8 | 832x832 | 160000 | - | - | V100 | 74.43 | 76.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r18-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes_20210926_052702-619c8ae1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes_20210926_052702.log.json) | -| ICNet | R-50-D8 | 832x832 | 80000 | 2.53 | 20.08 | V100 | 68.91 | 69.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r50-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_80k_cityscapes/icnet_r50-d8_832x832_80k_cityscapes_20210926_044625-c6407341.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_80k_cityscapes/icnet_r50-d8_832x832_80k_cityscapes_20210926_044625.log.json) | -| ICNet | R-50-D8 | 832x832 | 160000 | - | - | V100 | 73.82 | 75.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r50-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_160k_cityscapes/icnet_r50-d8_832x832_160k_cityscapes_20210925_232612-a95f0d4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_160k_cityscapes/icnet_r50-d8_832x832_160k_cityscapes_20210925_232612.log.json) | -| ICNet (in1k-pre) | R-50-D8 | 832x832 | 80000 | - | - | V100 | 74.58 | 76.41 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r50-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes_20210926_032943-1743dc7b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes_20210926_032943.log.json) | -| ICNet (in1k-pre) | R-50-D8 | 832x832 | 160000 | - | - | V100 | 76.29 | 78.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r50-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes_20210926_042715-ce310aea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes_20210926_042715.log.json) | -| ICNet | R-101-D8 | 832x832 | 80000 | 3.08 | 16.95 | V100 | 70.28 | 71.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r101-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_80k_cityscapes/icnet_r101-d8_832x832_80k_cityscapes_20210926_072447-b52f936e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_80k_cityscapes/icnet_r101-d8_832x832_80k_cityscapes_20210926_072447.log.json) | -| ICNet | R-101-D8 | 832x832 | 160000 | - | - | V100 | 73.80 | 76.10 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r101-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_160k_cityscapes/icnet_r101-d8_832x832_160k_cityscapes_20210926_092350-3a1ebf1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_160k_cityscapes/icnet_r101-d8_832x832_160k_cityscapes_20210926_092350.log.json) | -| ICNet (in1k-pre) | R-101-D8 | 832x832 | 80000 | - | - | V100 | 75.57 | 77.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r101-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes_20210926_020414-7ceb12c5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes_20210926_020414.log.json) | -| ICNet (in1k-pre) | R-101-D8 | 832x832 | 160000 | - | - | V100 | 76.15 | 77.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/icnet/icnet_r101-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes_20210925_232612-9484ae8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes_20210925_232612.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ICNet | R-18-D8 | 832x832 | 80000 | 1.70 | 27.12 | V100 | 68.14 | 70.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r18-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_80k_cityscapes/icnet_r18-d8_832x832_80k_cityscapes_20210925_225521-2e36638d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_80k_cityscapes/icnet_r18-d8_832x832_80k_cityscapes_20210925_225521.log.json) | +| ICNet | R-18-D8 | 832x832 | 160000 | - | - | V100 | 71.64 | 74.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r18-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_160k_cityscapes/icnet_r18-d8_832x832_160k_cityscapes_20210925_230153-2c6eb6e0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_832x832_160k_cityscapes/icnet_r18-d8_832x832_160k_cityscapes_20210925_230153.log.json) | +| ICNet (in1k-pre) | R-18-D8 | 832x832 | 80000 | - | - | V100 | 72.51 | 74.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r18-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes_20210925_230354-1cbe3022.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes/icnet_r18-d8_in1k-pre_832x832_80k_cityscapes_20210925_230354.log.json) | +| ICNet (in1k-pre) | R-18-D8 | 832x832 | 160000 | - | - | V100 | 74.43 | 76.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r18-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes_20210926_052702-619c8ae1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes/icnet_r18-d8_in1k-pre_832x832_160k_cityscapes_20210926_052702.log.json) | +| ICNet | R-50-D8 | 832x832 | 80000 | 2.53 | 20.08 | V100 | 68.91 | 69.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r50-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_80k_cityscapes/icnet_r50-d8_832x832_80k_cityscapes_20210926_044625-c6407341.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_80k_cityscapes/icnet_r50-d8_832x832_80k_cityscapes_20210926_044625.log.json) | +| ICNet | R-50-D8 | 832x832 | 160000 | - | - | V100 | 73.82 | 75.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r50-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_160k_cityscapes/icnet_r50-d8_832x832_160k_cityscapes_20210925_232612-a95f0d4e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_832x832_160k_cityscapes/icnet_r50-d8_832x832_160k_cityscapes_20210925_232612.log.json) | +| ICNet (in1k-pre) | R-50-D8 | 832x832 | 80000 | - | - | V100 | 74.58 | 76.41 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r50-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes_20210926_032943-1743dc7b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes/icnet_r50-d8_in1k-pre_832x832_80k_cityscapes_20210926_032943.log.json) | +| ICNet (in1k-pre) | R-50-D8 | 832x832 | 160000 | - | - | V100 | 76.29 | 78.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r50-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes_20210926_042715-ce310aea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes/icnet_r50-d8_in1k-pre_832x832_160k_cityscapes_20210926_042715.log.json) | +| ICNet | R-101-D8 | 832x832 | 80000 | 3.08 | 16.95 | V100 | 70.28 | 71.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r101-d8_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_80k_cityscapes/icnet_r101-d8_832x832_80k_cityscapes_20210926_072447-b52f936e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_80k_cityscapes/icnet_r101-d8_832x832_80k_cityscapes_20210926_072447.log.json) | +| ICNet | R-101-D8 | 832x832 | 160000 | - | - | V100 | 73.80 | 76.10 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r101-d8_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_160k_cityscapes/icnet_r101-d8_832x832_160k_cityscapes_20210926_092350-3a1ebf1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_832x832_160k_cityscapes/icnet_r101-d8_832x832_160k_cityscapes_20210926_092350.log.json) | +| ICNet (in1k-pre) | R-101-D8 | 832x832 | 80000 | - | - | V100 | 75.57 | 77.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r101-d8-in1k-pre_4xb2-80k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes_20210926_020414-7ceb12c5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes/icnet_r101-d8_in1k-pre_832x832_80k_cityscapes_20210926_020414.log.json) | +| ICNet (in1k-pre) | R-101-D8 | 832x832 | 160000 | - | - | V100 | 76.15 | 77.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet/icnet_r101-d8-in1k-pre_4xb2-160k_cityscapes-832x832.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes_20210925_232612-9484ae8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/icnet/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes/icnet_r101-d8_in1k-pre_832x832_160k_cityscapes_20210925_232612.log.json) | Note: `in1k-pre` means pretrained model is used. diff --git a/configs/isanet/README.md b/configs/isanet/README.md index da9f0104c5a..c11744ffef8 100644 --- a/configs/isanet/README.md +++ b/configs/isanet/README.md @@ -26,34 +26,34 @@ In this paper, we present a so-called interlaced sparse self-attention approach ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | --------------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ISANet | R-50-D8 | 512x1024 | 40000 | 5.869 | 2.91 | V100 | 78.49 | 79.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_40k_cityscapes/isanet_r50-d8_512x1024_40k_cityscapes_20210901_054739-981bd763.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_40k_cityscapes/isanet_r50-d8_512x1024_40k_cityscapes_20210901_054739.log.json) | -| ISANet | R-50-D8 | 512x1024 | 80000 | 5.869 | 2.91 | V100 | 78.68 | 80.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_80k_cityscapes/isanet_r50-d8_512x1024_80k_cityscapes_20210901_074202-89384497.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_80k_cityscapes/isanet_r50-d8_512x1024_80k_cityscapes_20210901_074202.log.json) | -| ISANet | R-50-D8 | 769x769 | 40000 | 6.759 | 1.54 | V100 | 78.70 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_40k_cityscapes/isanet_r50-d8_769x769_40k_cityscapes_20210903_050200-4ae7e65b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_40k_cityscapes/isanet_r50-d8_769x769_40k_cityscapes_20210903_050200.log.json) | -| ISANet | R-50-D8 | 769x769 | 80000 | 6.759 | 1.54 | V100 | 79.29 | 80.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_80k_cityscapes/isanet_r50-d8_769x769_80k_cityscapes_20210903_101126-99b54519.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_80k_cityscapes/isanet_r50-d8_769x769_80k_cityscapes_20210903_101126.log.json) | -| ISANet | R-101-D8 | 512x1024 | 40000 | 9.425 | 2.35 | V100 | 79.58 | 81.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_40k_cityscapes/isanet_r101-d8_512x1024_40k_cityscapes_20210901_145553-293e6bd6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_40k_cityscapes/isanet_r101-d8_512x1024_40k_cityscapes_20210901_145553.log.json) | -| ISANet | R-101-D8 | 512x1024 | 80000 | 9.425 | 2.35 | V100 | 80.32 | 81.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_80k_cityscapes/isanet_r101-d8_512x1024_80k_cityscapes_20210901_145243-5b99c9b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_80k_cityscapes/isanet_r101-d8_512x1024_80k_cityscapes_20210901_145243.log.json) | -| ISANet | R-101-D8 | 769x769 | 40000 | 10.815 | 0.92 | V100 | 79.68 | 80.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_40k_cityscapes/isanet_r101-d8_769x769_40k_cityscapes_20210903_111320-509e7224.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_40k_cityscapes/isanet_r101-d8_769x769_40k_cityscapes_20210903_111320.log.json) | -| ISANet | R-101-D8 | 769x769 | 80000 | 10.815 | 0.92 | V100 | 80.61 | 81.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_80k_cityscapes/isanet_r101-d8_769x769_80k_cityscapes_20210903_111319-24f71dfa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_80k_cityscapes/isanet_r101-d8_769x769_80k_cityscapes_20210903_111319.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | -----------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ISANet | R-50-D8 | 512x1024 | 40000 | 5.869 | 2.91 | V100 | 78.49 | 79.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_40k_cityscapes/isanet_r50-d8_512x1024_40k_cityscapes_20210901_054739-981bd763.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_40k_cityscapes/isanet_r50-d8_512x1024_40k_cityscapes_20210901_054739.log.json) | +| ISANet | R-50-D8 | 512x1024 | 80000 | 5.869 | 2.91 | V100 | 78.68 | 80.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_80k_cityscapes/isanet_r50-d8_512x1024_80k_cityscapes_20210901_074202-89384497.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x1024_80k_cityscapes/isanet_r50-d8_512x1024_80k_cityscapes_20210901_074202.log.json) | +| ISANet | R-50-D8 | 769x769 | 40000 | 6.759 | 1.54 | V100 | 78.70 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_40k_cityscapes/isanet_r50-d8_769x769_40k_cityscapes_20210903_050200-4ae7e65b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_40k_cityscapes/isanet_r50-d8_769x769_40k_cityscapes_20210903_050200.log.json) | +| ISANet | R-50-D8 | 769x769 | 80000 | 6.759 | 1.54 | V100 | 79.29 | 80.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_80k_cityscapes/isanet_r50-d8_769x769_80k_cityscapes_20210903_101126-99b54519.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_769x769_80k_cityscapes/isanet_r50-d8_769x769_80k_cityscapes_20210903_101126.log.json) | +| ISANet | R-101-D8 | 512x1024 | 40000 | 9.425 | 2.35 | V100 | 79.58 | 81.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_40k_cityscapes/isanet_r101-d8_512x1024_40k_cityscapes_20210901_145553-293e6bd6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_40k_cityscapes/isanet_r101-d8_512x1024_40k_cityscapes_20210901_145553.log.json) | +| ISANet | R-101-D8 | 512x1024 | 80000 | 9.425 | 2.35 | V100 | 80.32 | 81.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_80k_cityscapes/isanet_r101-d8_512x1024_80k_cityscapes_20210901_145243-5b99c9b2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x1024_80k_cityscapes/isanet_r101-d8_512x1024_80k_cityscapes_20210901_145243.log.json) | +| ISANet | R-101-D8 | 769x769 | 40000 | 10.815 | 0.92 | V100 | 79.68 | 80.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_40k_cityscapes/isanet_r101-d8_769x769_40k_cityscapes_20210903_111320-509e7224.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_40k_cityscapes/isanet_r101-d8_769x769_40k_cityscapes_20210903_111320.log.json) | +| ISANet | R-101-D8 | 769x769 | 80000 | 10.815 | 0.92 | V100 | 80.61 | 81.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_80k_cityscapes/isanet_r101-d8_769x769_80k_cityscapes_20210903_111319-24f71dfa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_769x769_80k_cityscapes/isanet_r101-d8_769x769_80k_cityscapes_20210903_111319.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ISANet | R-50-D8 | 512x512 | 80000 | 9.0 | 22.55 | V100 | 41.12 | 42.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_80k_ade20k/isanet_r50-d8_512x512_80k_ade20k_20210903_124557-6ed83a0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_80k_ade20k/isanet_r50-d8_512x512_80k_ade20k_20210903_124557.log.json) | -| ISANet | R-50-D8 | 512x512 | 160000 | 9.0 | 22.55 | V100 | 42.59 | 43.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_160k_ade20k/isanet_r50-d8_512x512_160k_ade20k_20210903_104850-f752d0a3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_160k_ade20k/isanet_r50-d8_512x512_160k_ade20k_20210903_104850.log.json) | -| ISANet | R-101-D8 | 512x512 | 80000 | 12.562 | 10.56 | V100 | 43.51 | 44.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_80k_ade20k/isanet_r101-d8_512x512_80k_ade20k_20210903_162056-68b235c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_80k_ade20k/isanet_r101-d8_512x512_80k_ade20k_20210903_162056.log.json) | -| ISANet | R-101-D8 | 512x512 | 160000 | 12.562 | 10.56 | V100 | 43.80 | 45.4 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_160k_ade20k/isanet_r101-d8_512x512_160k_ade20k_20210903_211431-a7879dcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_160k_ade20k/isanet_r101-d8_512x512_160k_ade20k_20210903_211431.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ISANet | R-50-D8 | 512x512 | 80000 | 9.0 | 22.55 | V100 | 41.12 | 42.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_80k_ade20k/isanet_r50-d8_512x512_80k_ade20k_20210903_124557-6ed83a0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_80k_ade20k/isanet_r50-d8_512x512_80k_ade20k_20210903_124557.log.json) | +| ISANet | R-50-D8 | 512x512 | 160000 | 9.0 | 22.55 | V100 | 42.59 | 43.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_160k_ade20k/isanet_r50-d8_512x512_160k_ade20k_20210903_104850-f752d0a3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_160k_ade20k/isanet_r50-d8_512x512_160k_ade20k_20210903_104850.log.json) | +| ISANet | R-101-D8 | 512x512 | 80000 | 12.562 | 10.56 | V100 | 43.51 | 44.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_80k_ade20k/isanet_r101-d8_512x512_80k_ade20k_20210903_162056-68b235c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_80k_ade20k/isanet_r101-d8_512x512_80k_ade20k_20210903_162056.log.json) | +| ISANet | R-101-D8 | 512x512 | 160000 | 12.562 | 10.56 | V100 | 43.80 | 45.4 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_160k_ade20k/isanet_r101-d8_512x512_160k_ade20k_20210903_211431-a7879dcd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_160k_ade20k/isanet_r101-d8_512x512_160k_ade20k_20210903_211431.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | -----------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ISANet | R-50-D8 | 512x512 | 20000 | 5.9 | 23.08 | V100 | 76.78 | 77.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_20k_voc12aug/isanet_r50-d8_512x512_20k_voc12aug_20210901_164838-79d59b80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_20k_voc12aug/isanet_r50-d8_512x512_20k_voc12aug_20210901_164838.log.json) | -| ISANet | R-50-D8 | 512x512 | 40000 | 5.9 | 23.08 | V100 | 76.20 | 77.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_40k_voc12aug/isanet_r50-d8_512x512_40k_voc12aug_20210901_151349-7d08a54e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_40k_voc12aug/isanet_r50-d8_512x512_40k_voc12aug_20210901_151349.log.json) | -| ISANet | R-101-D8 | 512x512 | 20000 | 9.465 | 7.42 | V100 | 78.46 | 79.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_20k_voc12aug/isanet_r101-d8_512x512_20k_voc12aug_20210901_115805-3ccbf355.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_20k_voc12aug/isanet_r101-d8_512x512_20k_voc12aug_20210901_115805.log.json) | -| ISANet | R-101-D8 | 512x512 | 40000 | 9.465 | 7.42 | V100 | 78.12 | 79.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/isanet/isanet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_40k_voc12aug/isanet_r101-d8_512x512_40k_voc12aug_20210901_145814-bc71233b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_40k_voc12aug/isanet_r101-d8_512x512_40k_voc12aug_20210901_145814.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | --------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| ISANet | R-50-D8 | 512x512 | 20000 | 5.9 | 23.08 | V100 | 76.78 | 77.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_20k_voc12aug/isanet_r50-d8_512x512_20k_voc12aug_20210901_164838-79d59b80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_20k_voc12aug/isanet_r50-d8_512x512_20k_voc12aug_20210901_164838.log.json) | +| ISANet | R-50-D8 | 512x512 | 40000 | 5.9 | 23.08 | V100 | 76.20 | 77.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_40k_voc12aug/isanet_r50-d8_512x512_40k_voc12aug_20210901_151349-7d08a54e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r50-d8_512x512_40k_voc12aug/isanet_r50-d8_512x512_40k_voc12aug_20210901_151349.log.json) | +| ISANet | R-101-D8 | 512x512 | 20000 | 9.465 | 7.42 | V100 | 78.46 | 79.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_20k_voc12aug/isanet_r101-d8_512x512_20k_voc12aug_20210901_115805-3ccbf355.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_20k_voc12aug/isanet_r101-d8_512x512_20k_voc12aug_20210901_115805.log.json) | +| ISANet | R-101-D8 | 512x512 | 40000 | 9.465 | 7.42 | V100 | 78.12 | 79.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet/isanet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_40k_voc12aug/isanet_r101-d8_512x512_40k_voc12aug_20210901_145814-bc71233b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/isanet/isanet_r101-d8_512x512_40k_voc12aug/isanet_r101-d8_512x512_40k_voc12aug_20210901_145814.log.json) | ## Citation diff --git a/configs/knet/README.md b/configs/knet/README.md index 070c7256da9..1f3f2ae268e 100644 --- a/configs/knet/README.md +++ b/configs/knet/README.md @@ -26,15 +26,15 @@ Semantic, instance, and panoptic segmentations have been addressed using differe ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| KNet + FCN | R-50-D8 | 512x512 | 80000 | 7.01 | 19.24 | V100 | 43.60 | 45.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_r50-d8_fcn_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_043751-abcab920.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_043751.log.json) | -| KNet + PSPNet | R-50-D8 | 512x512 | 80000 | 6.98 | 20.04 | V100 | 44.18 | 45.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_r50-d8_pspnet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_054634-d2c72240.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_054634.log.json) | -| KNet + DeepLabV3 | R-50-D8 | 512x512 | 80000 | 7.42 | 12.10 | V100 | 45.06 | 46.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_r50-d8_deeplabv3_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_041642-00c8fbeb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_041642.log.json) | -| KNet + UperNet | R-50-D8 | 512x512 | 80000 | 7.34 | 17.11 | V100 | 43.45 | 44.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_r50-d8_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220304_125657-215753b0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220304_125657.log.json) | -| KNet + UperNet | Swin-T | 512x512 | 80000 | 7.57 | 15.56 | V100 | 45.84 | 46.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_swin-t_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k_20220303_133059-7545e1dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k_20220303_133059.log.json) | -| KNet + UperNet | Swin-L | 512x512 | 80000 | 13.5 | 8.29 | V100 | 52.05 | 53.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k_20220303_154559-d8da9a90.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k_20220303_154559.log.json) | -| KNet + UperNet | Swin-L | 640x640 | 80000 | 13.54 | 8.29 | V100 | 52.21 | 53.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k_20220301_220747-8787fc71.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k_20220301_220747.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| KNet + FCN | R-50-D8 | 512x512 | 80000 | 7.01 | 19.24 | V100 | 43.60 | 45.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_r50-d8_fcn_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_043751-abcab920.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_fcn_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_043751.log.json) | +| KNet + PSPNet | R-50-D8 | 512x512 | 80000 | 6.98 | 20.04 | V100 | 44.18 | 45.58 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_r50-d8_pspnet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_054634-d2c72240.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_pspnet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_054634.log.json) | +| KNet + DeepLabV3 | R-50-D8 | 512x512 | 80000 | 7.42 | 12.10 | V100 | 45.06 | 46.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_r50-d8_deeplabv3_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_041642-00c8fbeb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_deeplabv3_r50-d8_8x2_512x512_adamw_80k_ade20k_20220228_041642.log.json) | +| KNet + UperNet | R-50-D8 | 512x512 | 80000 | 7.34 | 17.11 | V100 | 43.45 | 44.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_r50-d8_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220304_125657-215753b0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_r50-d8_8x2_512x512_adamw_80k_ade20k_20220304_125657.log.json) | +| KNet + UperNet | Swin-T | 512x512 | 80000 | 7.57 | 15.56 | V100 | 45.84 | 46.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_swin-t_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k_20220303_133059-7545e1dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-t_8x2_512x512_adamw_80k_ade20k_20220303_133059.log.json) | +| KNet + UperNet | Swin-L | 512x512 | 80000 | 13.5 | 8.29 | V100 | 52.05 | 53.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k_20220303_154559-d8da9a90.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_512x512_adamw_80k_ade20k_20220303_154559.log.json) | +| KNet + UperNet | Swin-L | 640x640 | 80000 | 13.54 | 8.29 | V100 | 52.21 | 53.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet/knet-s3_swin-l_upernet_8xb2-adamw-80k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k_20220301_220747-8787fc71.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/knet/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k/knet_s3_upernet_swin-l_8x2_640x640_adamw_80k_ade20k_20220301_220747.log.json) | Note: diff --git a/configs/mae/README.md b/configs/mae/README.md index 94ade088239..d14e3830be2 100644 --- a/configs/mae/README.md +++ b/configs/mae/README.md @@ -66,9 +66,9 @@ upernet_mae-base_fp16_8x2_512x512_160k_ade20k_20220426_174752-f92a2975.pth $GPUS ### ADE20K -| Method | Backbone | Crop Size | pretrain | pretrain img size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ----------- | ----------------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| UPerNet | ViT-B | 512x512 | ImageNet-1K | 224x224 | 16 | 160000 | 9.96 | 7.14 | V100 | 48.13 | 48.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mae/mae-base_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mae/upernet_mae-base_fp16_8x2_512x512_160k_ade20k/upernet_mae-base_fp16_8x2_512x512_160k_ade20k_20220426_174752-f92a2975.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mae/upernet_mae-base_fp16_8x2_512x512_160k_ade20k/upernet_mae-base_fp16_8x2_512x512_160k_ade20k_20220426_174752.log.json) | +| Method | Backbone | Crop Size | pretrain | pretrain img size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ----------- | ----------------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| UPerNet | ViT-B | 512x512 | ImageNet-1K | 224x224 | 16 | 160000 | 9.96 | 7.14 | V100 | 48.13 | 48.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mae/mae-base_upernet_8xb2-amp-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mae/upernet_mae-base_fp16_8x2_512x512_160k_ade20k/upernet_mae-base_fp16_8x2_512x512_160k_ade20k_20220426_174752-f92a2975.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mae/upernet_mae-base_fp16_8x2_512x512_160k_ade20k/upernet_mae-base_fp16_8x2_512x512_160k_ade20k_20220426_174752.log.json) | ## Citation diff --git a/configs/mask2former/README.md b/configs/mask2former/README.md index 02639bef58b..c21ab0d0c60 100644 --- a/configs/mask2former/README.md +++ b/configs/mask2former/README.md @@ -28,26 +28,26 @@ pip install "mmdet>=3.0.0rc4" ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------- | -------------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | -----------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Mask2Former | R-50-D32 | 512x1024 | 90000 | 5.67 | 9.17 | A100 | 80.44 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024/mask2former_r50_8xb2-90k_cityscapes-512x1024_20221202_140802-ffd9d750.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024/mask2former_r50_8xb2-90k_cityscapes-512x1024_20221202_140802.json) | -| Mask2Former | R-101-D32 | 512x1024 | 90000 | 6.81 | 7.11 | A100 | 80.80 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024/mask2former_r101_8xb2-90k_cityscapes-512x1024_20221130_031628-43e68666.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024/mask2former_r101_8xb2-90k_cityscapes-512x1024_20221130_031628.json)) | -| Mask2Former | Swin-T | 512x1024 | 90000 | 6.36 | 7.18 | A100 | 81.71 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024/mask2former_swin-t_8xb2-90k_cityscapes-512x1024_20221127_144501-36c59341.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024/mask2former_swin-t_8xb2-90k_cityscapes-512x1024_20221127_144501.json)) | -| Mask2Former | Swin-S | 512x1024 | 90000 | 8.09 | 5.57 | A100 | 82.57 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024/mask2former_swin-s_8xb2-90k_cityscapes-512x1024_20221127_143802-9ab177f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024/mask2former_swin-s_8xb2-90k_cityscapes-512x1024_20221127_143802.json)) | -| Mask2Former | Swin-B (in22k) | 512x1024 | 90000 | 10.89 | 4.32 | A100 | 83.52 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221203_045030-9a86a225.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221203_045030.json)) | -| Mask2Former | Swin-L (in22k) | 512x1024 | 90000 | 15.83 | 2.86 | A100 | 83.65 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221202_141901-28ad20f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221202_141901.json)) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------- | -------------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Mask2Former | R-50-D32 | 512x1024 | 90000 | 5.67 | 9.17 | A100 | 80.44 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024/mask2former_r50_8xb2-90k_cityscapes-512x1024_20221202_140802-ffd9d750.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-90k_cityscapes-512x1024/mask2former_r50_8xb2-90k_cityscapes-512x1024_20221202_140802.json) | +| Mask2Former | R-101-D32 | 512x1024 | 90000 | 6.81 | 7.11 | A100 | 80.80 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024/mask2former_r101_8xb2-90k_cityscapes-512x1024_20221130_031628-43e68666.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-90k_cityscapes-512x1024/mask2former_r101_8xb2-90k_cityscapes-512x1024_20221130_031628.json)) | +| Mask2Former | Swin-T | 512x1024 | 90000 | 6.36 | 7.18 | A100 | 81.71 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024/mask2former_swin-t_8xb2-90k_cityscapes-512x1024_20221127_144501-36c59341.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-90k_cityscapes-512x1024/mask2former_swin-t_8xb2-90k_cityscapes-512x1024_20221127_144501.json)) | +| Mask2Former | Swin-S | 512x1024 | 90000 | 8.09 | 5.57 | A100 | 82.57 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024/mask2former_swin-s_8xb2-90k_cityscapes-512x1024_20221127_143802-9ab177f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-90k_cityscapes-512x1024/mask2former_swin-s_8xb2-90k_cityscapes-512x1024_20221127_143802.json)) | +| Mask2Former | Swin-B (in22k) | 512x1024 | 90000 | 10.89 | 4.32 | A100 | 83.52 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221203_045030-9a86a225.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-b-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221203_045030.json)) | +| Mask2Former | Swin-L (in22k) | 512x1024 | 90000 | 15.83 | 2.86 | A100 | 83.65 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221202_141901-28ad20f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024/mask2former_swin-l-in22k-384x384-pre_8xb2-90k_cityscapes-512x1024_20221202_141901.json)) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------- | -------------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Mask2Former | R-50-D32 | 512x512 | 160000 | 3.31 | 26.59 | A100 | 47.87 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512/mask2former_r50_8xb2-160k_ade20k-512x512_20221204_000055-2d1f55f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512/mask2former_r50_8xb2-160k_ade20k-512x512_20221204_000055.json)) | -| Mask2Former | R-101-D32 | 512x512 | 160000 | 4.09 | 22.97 | A100 | 48.60 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512/mask2former_r101_8xb2-160k_ade20k-512x512_20221203_233905-b7135890.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512/mask2former_r101_8xb2-160k_ade20k-512x512_20221203_233905.json)) | -| Mask2Former | Swin-T | 512x512 | 160000 | 3826 | 23.82 | A100 | 48.66 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512/mask2former_swin-t_8xb2-160k_ade20k-512x512_20221203_234230-7d64e5dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512/mask2former_swin-t_8xb2-160k_ade20k-512x512_20221203_234230.json)) | -| Mask2Former | Swin-S | 512x512 | 160000 | 3.74 | 19.69 | A100 | 51.24 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512/mask2former_swin-s_8xb2-160k_ade20k-512x512_20221204_143905-e715144e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512/mask2former_swin-s_8xb2-160k_ade20k-512x512_20221204_143905.json)) | -| Mask2Former | Swin-B | 640x640 | 160000 | 5.66 | 12.48 | A100 | 52.44 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640_20221129_125118-a4a086d2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640_20221129_125118.json)) | -| Mask2Former | Swin-B (in22k) | 640x640 | 160000 | 5.66 | 12.43 | A100 | 53.90 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235230-7ec0f569.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235230.json)) | -| Mask2Former | Swin-L (in22k) | 640x640 | 160000 | 8.86 | 8.81 | A100 | 56.01 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235933-7120c214.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235933.json)) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------- | -------------- | --------- | ------- | -------: | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Mask2Former | R-50-D32 | 512x512 | 160000 | 3.31 | 26.59 | A100 | 47.87 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512/mask2former_r50_8xb2-160k_ade20k-512x512_20221204_000055-2d1f55f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r50_8xb2-160k_ade20k-512x512/mask2former_r50_8xb2-160k_ade20k-512x512_20221204_000055.json)) | +| Mask2Former | R-101-D32 | 512x512 | 160000 | 4.09 | 22.97 | A100 | 48.60 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512/mask2former_r101_8xb2-160k_ade20k-512x512_20221203_233905-b7135890.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_r101_8xb2-160k_ade20k-512x512/mask2former_r101_8xb2-160k_ade20k-512x512_20221203_233905.json)) | +| Mask2Former | Swin-T | 512x512 | 160000 | 3826 | 23.82 | A100 | 48.66 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512/mask2former_swin-t_8xb2-160k_ade20k-512x512_20221203_234230-7d64e5dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-t_8xb2-160k_ade20k-512x512/mask2former_swin-t_8xb2-160k_ade20k-512x512_20221203_234230.json)) | +| Mask2Former | Swin-S | 512x512 | 160000 | 3.74 | 19.69 | A100 | 51.24 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512/mask2former_swin-s_8xb2-160k_ade20k-512x512_20221204_143905-e715144e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-s_8xb2-160k_ade20k-512x512/mask2former_swin-s_8xb2-160k_ade20k-512x512_20221204_143905.json)) | +| Mask2Former | Swin-B | 640x640 | 160000 | 5.66 | 12.48 | A100 | 52.44 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640_20221129_125118-a4a086d2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in1k-384x384-pre_8xb2-160k_ade20k-640x640_20221129_125118.json)) | +| Mask2Former | Swin-B (in22k) | 640x640 | 160000 | 5.66 | 12.43 | A100 | 53.90 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235230-7ec0f569.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-b-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235230.json)) | +| Mask2Former | Swin-L (in22k) | 640x640 | 160000 | 8.86 | 8.81 | A100 | 56.01 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235933-7120c214.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mask2former/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640/mask2former_swin-l-in22k-384x384-pre_8xb2-160k_ade20k-640x640_20221203_235933.json)) | Note: diff --git a/configs/maskformer/README.md b/configs/maskformer/README.md index aa54a270884..a899bac0909 100644 --- a/configs/maskformer/README.md +++ b/configs/maskformer/README.md @@ -34,12 +34,12 @@ pip install "mmdet>=3.0.0rc4" ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | --------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| MaskFormer | R-50-D32 | 512x512 | 160000 | 3.29 | A100 | 42.20 | 44.29 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512/maskformer_r50-d32_8xb2-160k_ade20k-512x512_20221030_182724-3a9cfe45.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512/maskformer_r50-d32_8xb2-160k_ade20k-512x512_20221030_182724.json) | -| MaskFormer | R-101-D32 | 512x512 | 160000 | 4.12 | A100 | 34.90 | 45.11 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512/maskformer_r101-d32_8xb2-160k_ade20k-512x512_20221031_223053-84adbfcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512/maskformer_r101-d32_8xb2-160k_ade20k-512x512_20221031_223053.json) | -| MaskFormer | Swin-T | 512x512 | 160000 | 3.73 | A100 | 40.53 | 46.69 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512_20221114_232813-f14e7ce0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512_20221114_232813.json) | -| MaskFormer | Swin-S | 512x512 | 160000 | 5.33 | A100 | 26.98 | 49.36 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512_20221115_114710-723512c7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512_20221115_114710.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | --------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| MaskFormer | R-50-D32 | 512x512 | 160000 | 3.29 | A100 | 42.20 | 44.29 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512/maskformer_r50-d32_8xb2-160k_ade20k-512x512_20221030_182724-3a9cfe45.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r50-d32_8xb2-160k_ade20k-512x512/maskformer_r50-d32_8xb2-160k_ade20k-512x512_20221030_182724.json) | +| MaskFormer | R-101-D32 | 512x512 | 160000 | 4.12 | A100 | 34.90 | 45.11 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512/maskformer_r101-d32_8xb2-160k_ade20k-512x512_20221031_223053-84adbfcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_r101-d32_8xb2-160k_ade20k-512x512/maskformer_r101-d32_8xb2-160k_ade20k-512x512_20221031_223053.json) | +| MaskFormer | Swin-T | 512x512 | 160000 | 3.73 | A100 | 40.53 | 46.69 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512_20221114_232813-f14e7ce0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-t_upernet_8xb2-160k_ade20k-512x512_20221114_232813.json) | +| MaskFormer | Swin-S | 512x512 | 160000 | 5.33 | A100 | 26.98 | 49.36 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512_20221115_114710-723512c7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/maskformer/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512/maskformer_swin-s_upernet_8xb2-160k_ade20k-512x512_20221115_114710.json) | Note: diff --git a/configs/mobilenet_v2/README.md b/configs/mobilenet_v2/README.md index 6d8e5945cb2..bff5259129c 100644 --- a/configs/mobilenet_v2/README.md +++ b/configs/mobilenet_v2/README.md @@ -27,21 +27,21 @@ The MobileNetV2 architecture is based on an inverted residual structure where th ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | M-V2-D8 | 512x1024 | 80000 | 3.4 | 14.2 | A100 | 71.19 | 73.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024-20230224_185436-13fef4ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024_20230224_185436.json) | -| PSPNet | M-V2-D8 | 512x1024 | 80000 | 3.6 | 11.2 | V100 | 70.23 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_pspnet_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x1024_80k_cityscapes/pspnet_m-v2-d8_512x1024_80k_cityscapes_20200825_124817-19e81d51.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x1024_80k_cityscapes/pspnet_m-v2-d8_512x1024_80k_cityscapes-20200825_124817.log.json) | -| DeepLabV3 | M-V2-D8 | 512x1024 | 80000 | 3.9 | 8.4 | V100 | 73.84 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x1024_80k_cityscapes/deeplabv3_m-v2-d8_512x1024_80k_cityscapes_20200825_124836-bef03590.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x1024_80k_cityscapes/deeplabv3_m-v2-d8_512x1024_80k_cityscapes-20200825_124836.log.json) | -| DeepLabV3+ | M-V2-D8 | 512x1024 | 80000 | 5.1 | 8.4 | V100 | 75.20 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3plus_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes_20200825_124836-d256dd4b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes-20200825_124836.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | M-V2-D8 | 512x1024 | 80000 | 3.4 | 14.2 | A100 | 71.19 | 73.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024-20230224_185436-13fef4ea.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024/mobilenet-v2-d8_fcn_4xb2-80k_cityscapes-512x1024_20230224_185436.json) | +| PSPNet | M-V2-D8 | 512x1024 | 80000 | 3.6 | 11.2 | V100 | 70.23 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_pspnet_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x1024_80k_cityscapes/pspnet_m-v2-d8_512x1024_80k_cityscapes_20200825_124817-19e81d51.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x1024_80k_cityscapes/pspnet_m-v2-d8_512x1024_80k_cityscapes-20200825_124817.log.json) | +| DeepLabV3 | M-V2-D8 | 512x1024 | 80000 | 3.9 | 8.4 | V100 | 73.84 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x1024_80k_cityscapes/deeplabv3_m-v2-d8_512x1024_80k_cityscapes_20200825_124836-bef03590.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x1024_80k_cityscapes/deeplabv3_m-v2-d8_512x1024_80k_cityscapes-20200825_124836.log.json) | +| DeepLabV3+ | M-V2-D8 | 512x1024 | 80000 | 5.1 | 8.4 | V100 | 75.20 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3plus_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes_20200825_124836-d256dd4b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes/deeplabv3plus_m-v2-d8_512x1024_80k_cityscapes-20200825_124836.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | M-V2-D8 | 512x512 | 160000 | 6.5 | 64.4 | V100 | 19.71 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_fcn_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/fcn_m-v2-d8_512x512_160k_ade20k/fcn_m-v2-d8_512x512_160k_ade20k_20200825_214953-c40e1095.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/fcn_m-v2-d8_512x512_160k_ade20k/fcn_m-v2-d8_512x512_160k_ade20k-20200825_214953.log.json) | -| PSPNet | M-V2-D8 | 512x512 | 160000 | 6.5 | 57.7 | V100 | 29.68 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_pspnet_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x512_160k_ade20k/pspnet_m-v2-d8_512x512_160k_ade20k_20200825_214953-f5942f7a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x512_160k_ade20k/pspnet_m-v2-d8_512x512_160k_ade20k-20200825_214953.log.json) | -| DeepLabV3 | M-V2-D8 | 512x512 | 160000 | 6.8 | 39.9 | V100 | 34.08 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x512_160k_ade20k/deeplabv3_m-v2-d8_512x512_160k_ade20k_20200825_223255-63986343.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x512_160k_ade20k/deeplabv3_m-v2-d8_512x512_160k_ade20k-20200825_223255.log.json) | -| DeepLabV3+ | M-V2-D8 | 512x512 | 160000 | 8.2 | 43.1 | V100 | 34.02 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3plus_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x512_160k_ade20k/deeplabv3plus_m-v2-d8_512x512_160k_ade20k_20200825_223255-465a01d4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x512_160k_ade20k/deeplabv3plus_m-v2-d8_512x512_160k_ade20k-20200825_223255.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | M-V2-D8 | 512x512 | 160000 | 6.5 | 64.4 | V100 | 19.71 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_fcn_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/fcn_m-v2-d8_512x512_160k_ade20k/fcn_m-v2-d8_512x512_160k_ade20k_20200825_214953-c40e1095.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/fcn_m-v2-d8_512x512_160k_ade20k/fcn_m-v2-d8_512x512_160k_ade20k-20200825_214953.log.json) | +| PSPNet | M-V2-D8 | 512x512 | 160000 | 6.5 | 57.7 | V100 | 29.68 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_pspnet_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x512_160k_ade20k/pspnet_m-v2-d8_512x512_160k_ade20k_20200825_214953-f5942f7a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/pspnet_m-v2-d8_512x512_160k_ade20k/pspnet_m-v2-d8_512x512_160k_ade20k-20200825_214953.log.json) | +| DeepLabV3 | M-V2-D8 | 512x512 | 160000 | 6.8 | 39.9 | V100 | 34.08 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x512_160k_ade20k/deeplabv3_m-v2-d8_512x512_160k_ade20k_20200825_223255-63986343.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3_m-v2-d8_512x512_160k_ade20k/deeplabv3_m-v2-d8_512x512_160k_ade20k-20200825_223255.log.json) | +| DeepLabV3+ | M-V2-D8 | 512x512 | 160000 | 8.2 | 43.1 | V100 | 34.02 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2/mobilenet-v2-d8_deeplabv3plus_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x512_160k_ade20k/deeplabv3plus_m-v2-d8_512x512_160k_ade20k_20200825_223255-465a01d4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v2/deeplabv3plus_m-v2-d8_512x512_160k_ade20k/deeplabv3plus_m-v2-d8_512x512_160k_ade20k-20200825_223255.log.json) | ## Citation diff --git a/configs/mobilenet_v3/README.md b/configs/mobilenet_v3/README.md index 3b63db7e500..8ed0a5692a1 100644 --- a/configs/mobilenet_v3/README.md +++ b/configs/mobilenet_v3/README.md @@ -28,12 +28,12 @@ We present the next generation of MobileNets based on a combination of complemen ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| LRASPP | M-V3-D8 | 512x1024 | 320000 | 8.9 | 15.22 | V100 | 69.54 | 70.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v3/mobilenet-v3-d8_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_512x1024_320k_cityscapes/lraspp_m-v3-d8_512x1024_320k_cityscapes_20201224_220337-cfe8fb07.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_512x1024_320k_cityscapes/lraspp_m-v3-d8_512x1024_320k_cityscapes-20201224_220337.log.json) | -| LRASPP | M-V3-D8 (scratch) | 512x1024 | 320000 | 8.9 | 14.77 | V100 | 67.87 | 69.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v3/mobilenet-v3-d8-scratch_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes_20201224_220337-9f29cd72.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes-20201224_220337.log.json) | -| LRASPP | M-V3s-D8 | 512x1024 | 320000 | 5.3 | 23.64 | V100 | 64.11 | 66.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v3/mobilenet-v3-d8-s_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_512x1024_320k_cityscapes/lraspp_m-v3s-d8_512x1024_320k_cityscapes_20201224_223935-61565b34.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_512x1024_320k_cityscapes/lraspp_m-v3s-d8_512x1024_320k_cityscapes-20201224_223935.log.json) | -| LRASPP | M-V3s-D8 (scratch) | 512x1024 | 320000 | 5.3 | 24.50 | V100 | 62.74 | 65.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/mobilenet_v3/mobilenet-v3-d8-scratch-s_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes_20201224_223935-03daeabb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes-20201224_223935.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| LRASPP | M-V3-D8 | 512x1024 | 320000 | 8.9 | 15.22 | V100 | 69.54 | 70.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3/mobilenet-v3-d8_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_512x1024_320k_cityscapes/lraspp_m-v3-d8_512x1024_320k_cityscapes_20201224_220337-cfe8fb07.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_512x1024_320k_cityscapes/lraspp_m-v3-d8_512x1024_320k_cityscapes-20201224_220337.log.json) | +| LRASPP | M-V3-D8 (scratch) | 512x1024 | 320000 | 8.9 | 14.77 | V100 | 67.87 | 69.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3/mobilenet-v3-d8-scratch_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes_20201224_220337-9f29cd72.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3-d8_scratch_512x1024_320k_cityscapes-20201224_220337.log.json) | +| LRASPP | M-V3s-D8 | 512x1024 | 320000 | 5.3 | 23.64 | V100 | 64.11 | 66.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3/mobilenet-v3-d8-s_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_512x1024_320k_cityscapes/lraspp_m-v3s-d8_512x1024_320k_cityscapes_20201224_223935-61565b34.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_512x1024_320k_cityscapes/lraspp_m-v3s-d8_512x1024_320k_cityscapes-20201224_223935.log.json) | +| LRASPP | M-V3s-D8 (scratch) | 512x1024 | 320000 | 5.3 | 24.50 | V100 | 62.74 | 65.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3/mobilenet-v3-d8-scratch-s_lraspp_4xb4-320k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes_20201224_223935-03daeabb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/mobilenet_v3/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes/lraspp_m-v3s-d8_scratch_512x1024_320k_cityscapes-20201224_223935.log.json) | ## Citation diff --git a/configs/nonlocal_net/README.md b/configs/nonlocal_net/README.md index 0a0fcf37258..4c3f49f981e 100644 --- a/configs/nonlocal_net/README.md +++ b/configs/nonlocal_net/README.md @@ -26,34 +26,34 @@ Both convolutional and recurrent operations are building blocks that process one ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| NonLocalNet | R-50-D8 | 512x1024 | 40000 | 7.4 | 2.72 | V100 | 78.24 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_40k_cityscapes/nonlocal_r50-d8_512x1024_40k_cityscapes_20200605_210748-c75e81e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_40k_cityscapes/nonlocal_r50-d8_512x1024_40k_cityscapes_20200605_210748.log.json) | -| NonLocalNet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.95 | V100 | 78.66 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_40k_cityscapes/nonlocal_r101-d8_512x1024_40k_cityscapes_20200605_210748-d63729fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_40k_cityscapes/nonlocal_r101-d8_512x1024_40k_cityscapes_20200605_210748.log.json) | -| NonLocalNet | R-50-D8 | 769x769 | 40000 | 8.9 | 1.52 | V100 | 78.33 | 79.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_40k_cityscapes/nonlocal_r50-d8_769x769_40k_cityscapes_20200530_045243-82ef6749.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_40k_cityscapes/nonlocal_r50-d8_769x769_40k_cityscapes_20200530_045243.log.json) | -| NonLocalNet | R-101-D8 | 769x769 | 40000 | 12.8 | 1.05 | V100 | 78.57 | 80.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_40k_cityscapes/nonlocal_r101-d8_769x769_40k_cityscapes_20200530_045348-8fe9a9dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_40k_cityscapes/nonlocal_r101-d8_769x769_40k_cityscapes_20200530_045348.log.json) | -| NonLocalNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.01 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_80k_cityscapes/nonlocal_r50-d8_512x1024_80k_cityscapes_20200607_193518-d6839fae.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_80k_cityscapes/nonlocal_r50-d8_512x1024_80k_cityscapes_20200607_193518.log.json) | -| NonLocalNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.93 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_80k_cityscapes/nonlocal_r101-d8_512x1024_80k_cityscapes_20200607_183411-32700183.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_80k_cityscapes/nonlocal_r101-d8_512x1024_80k_cityscapes_20200607_183411.log.json) | -| NonLocalNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.05 | 80.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_80k_cityscapes/nonlocal_r50-d8_769x769_80k_cityscapes_20200607_193506-1f9792f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_80k_cityscapes/nonlocal_r50-d8_769x769_80k_cityscapes_20200607_193506.log.json) | -| NonLocalNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.40 | 80.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_80k_cityscapes/nonlocal_r101-d8_769x769_80k_cityscapes_20200607_183428-0e1fa4f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_80k_cityscapes/nonlocal_r101-d8_769x769_80k_cityscapes_20200607_183428.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| NonLocalNet | R-50-D8 | 512x1024 | 40000 | 7.4 | 2.72 | V100 | 78.24 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_40k_cityscapes/nonlocal_r50-d8_512x1024_40k_cityscapes_20200605_210748-c75e81e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_40k_cityscapes/nonlocal_r50-d8_512x1024_40k_cityscapes_20200605_210748.log.json) | +| NonLocalNet | R-101-D8 | 512x1024 | 40000 | 10.9 | 1.95 | V100 | 78.66 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_40k_cityscapes/nonlocal_r101-d8_512x1024_40k_cityscapes_20200605_210748-d63729fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_40k_cityscapes/nonlocal_r101-d8_512x1024_40k_cityscapes_20200605_210748.log.json) | +| NonLocalNet | R-50-D8 | 769x769 | 40000 | 8.9 | 1.52 | V100 | 78.33 | 79.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_40k_cityscapes/nonlocal_r50-d8_769x769_40k_cityscapes_20200530_045243-82ef6749.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_40k_cityscapes/nonlocal_r50-d8_769x769_40k_cityscapes_20200530_045243.log.json) | +| NonLocalNet | R-101-D8 | 769x769 | 40000 | 12.8 | 1.05 | V100 | 78.57 | 80.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_40k_cityscapes/nonlocal_r101-d8_769x769_40k_cityscapes_20200530_045348-8fe9a9dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_40k_cityscapes/nonlocal_r101-d8_769x769_40k_cityscapes_20200530_045348.log.json) | +| NonLocalNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.01 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_80k_cityscapes/nonlocal_r50-d8_512x1024_80k_cityscapes_20200607_193518-d6839fae.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x1024_80k_cityscapes/nonlocal_r50-d8_512x1024_80k_cityscapes_20200607_193518.log.json) | +| NonLocalNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 78.93 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_80k_cityscapes/nonlocal_r101-d8_512x1024_80k_cityscapes_20200607_183411-32700183.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x1024_80k_cityscapes/nonlocal_r101-d8_512x1024_80k_cityscapes_20200607_183411.log.json) | +| NonLocalNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.05 | 80.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_80k_cityscapes/nonlocal_r50-d8_769x769_80k_cityscapes_20200607_193506-1f9792f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_769x769_80k_cityscapes/nonlocal_r50-d8_769x769_80k_cityscapes_20200607_193506.log.json) | +| NonLocalNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.40 | 80.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_80k_cityscapes/nonlocal_r101-d8_769x769_80k_cityscapes_20200607_183428-0e1fa4f9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_769x769_80k_cityscapes/nonlocal_r101-d8_769x769_80k_cityscapes_20200607_183428.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| NonLocalNet | R-50-D8 | 512x512 | 80000 | 9.1 | 21.37 | V100 | 40.75 | 42.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_80k_ade20k/nonlocal_r50-d8_512x512_80k_ade20k_20200615_015801-5ae0aa33.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_80k_ade20k/nonlocal_r50-d8_512x512_80k_ade20k_20200615_015801.log.json) | -| NonLocalNet | R-101-D8 | 512x512 | 80000 | 12.6 | 13.97 | V100 | 42.90 | 44.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_80k_ade20k/nonlocal_r101-d8_512x512_80k_ade20k_20200615_015758-24105919.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_80k_ade20k/nonlocal_r101-d8_512x512_80k_ade20k_20200615_015758.log.json) | -| NonLocalNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.03 | 43.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_160k_ade20k/nonlocal_r50-d8_512x512_160k_ade20k_20200616_005410-baef45e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_160k_ade20k/nonlocal_r50-d8_512x512_160k_ade20k_20200616_005410.log.json) | -| NonLocalNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.63 | 45.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_160k_ade20k/nonlocal_r101-d8_512x512_160k_ade20k_20210827_221502-7881aa1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_160k_ade20k/nonlocal_r101-d8_512x512_160k_ade20k_20210827_221502.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| NonLocalNet | R-50-D8 | 512x512 | 80000 | 9.1 | 21.37 | V100 | 40.75 | 42.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_80k_ade20k/nonlocal_r50-d8_512x512_80k_ade20k_20200615_015801-5ae0aa33.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_80k_ade20k/nonlocal_r50-d8_512x512_80k_ade20k_20200615_015801.log.json) | +| NonLocalNet | R-101-D8 | 512x512 | 80000 | 12.6 | 13.97 | V100 | 42.90 | 44.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_80k_ade20k/nonlocal_r101-d8_512x512_80k_ade20k_20200615_015758-24105919.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_80k_ade20k/nonlocal_r101-d8_512x512_80k_ade20k_20200615_015758.log.json) | +| NonLocalNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.03 | 43.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_160k_ade20k/nonlocal_r50-d8_512x512_160k_ade20k_20200616_005410-baef45e3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_160k_ade20k/nonlocal_r50-d8_512x512_160k_ade20k_20200616_005410.log.json) | +| NonLocalNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.63 | 45.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_160k_ade20k/nonlocal_r101-d8_512x512_160k_ade20k_20210827_221502-7881aa1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_160k_ade20k/nonlocal_r101-d8_512x512_160k_ade20k_20210827_221502.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| NonLocalNet | R-50-D8 | 512x512 | 20000 | 6.4 | 21.21 | V100 | 76.20 | 77.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_20k_voc12aug/nonlocal_r50-d8_512x512_20k_voc12aug_20200617_222613-07f2a57c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_20k_voc12aug/nonlocal_r50-d8_512x512_20k_voc12aug_20200617_222613.log.json) | -| NonLocalNet | R-101-D8 | 512x512 | 20000 | 9.8 | 14.01 | V100 | 78.15 | 78.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_20k_voc12aug/nonlocal_r101-d8_512x512_20k_voc12aug_20200617_222615-948c68ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_20k_voc12aug/nonlocal_r101-d8_512x512_20k_voc12aug_20200617_222615.log.json) | -| NonLocalNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.65 | 77.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_40k_voc12aug/nonlocal_r50-d8_512x512_40k_voc12aug_20200614_000028-0139d4a9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_40k_voc12aug/nonlocal_r50-d8_512x512_40k_voc12aug_20200614_000028.log.json) | -| NonLocalNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.27 | 79.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/nonlocal_net/nonlocal_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_40k_voc12aug/nonlocal_r101-d8_512x512_40k_voc12aug_20200614_000028-7e5ff470.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_40k_voc12aug/nonlocal_r101-d8_512x512_40k_voc12aug_20200614_000028.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ----------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| NonLocalNet | R-50-D8 | 512x512 | 20000 | 6.4 | 21.21 | V100 | 76.20 | 77.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_20k_voc12aug/nonlocal_r50-d8_512x512_20k_voc12aug_20200617_222613-07f2a57c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_20k_voc12aug/nonlocal_r50-d8_512x512_20k_voc12aug_20200617_222613.log.json) | +| NonLocalNet | R-101-D8 | 512x512 | 20000 | 9.8 | 14.01 | V100 | 78.15 | 78.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_20k_voc12aug/nonlocal_r101-d8_512x512_20k_voc12aug_20200617_222615-948c68ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_20k_voc12aug/nonlocal_r101-d8_512x512_20k_voc12aug_20200617_222615.log.json) | +| NonLocalNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.65 | 77.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_40k_voc12aug/nonlocal_r50-d8_512x512_40k_voc12aug_20200614_000028-0139d4a9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r50-d8_512x512_40k_voc12aug/nonlocal_r50-d8_512x512_40k_voc12aug_20200614_000028.log.json) | +| NonLocalNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.27 | 79.12 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net/nonlocal_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_40k_voc12aug/nonlocal_r101-d8_512x512_40k_voc12aug_20200614_000028-7e5ff470.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/nonlocal_net/nonlocal_r101-d8_512x512_40k_voc12aug/nonlocal_r101-d8_512x512_40k_voc12aug_20200614_000028.log.json) | ## Citation diff --git a/configs/ocrnet/README.md b/configs/ocrnet/README.md index 5b078f59c23..628a3b1597c 100644 --- a/configs/ocrnet/README.md +++ b/configs/ocrnet/README.md @@ -28,47 +28,47 @@ In this paper, we address the problem of semantic segmentation and focus on the #### HRNet backbone -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| OCRNet | HRNetV2p-W18-Small | 512x1024 | 40000 | 3.5 | 10.45 | A100 | 76.61 | 78.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024_20230227_145026-6c052a14.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024_20230227_145026.json) | -| OCRNet | HRNetV2p-W18 | 512x1024 | 40000 | 4.7 | 7.50 | V100 | 77.72 | 79.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_40k_cityscapes/ocrnet_hr18_512x1024_40k_cityscapes_20200601_033320-401c5bdd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_40k_cityscapes/ocrnet_hr18_512x1024_40k_cityscapes_20200601_033320.log.json) | -| OCRNet | HRNetV2p-W48 | 512x1024 | 40000 | 8 | 4.22 | V100 | 80.58 | 81.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb2-40k_cityscapes-512x1024.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_40k_cityscapes/ocrnet_hr48_512x1024_40k_cityscapes_20200601_033336-55b32491.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_40k_cityscapes/ocrnet_hr48_512x1024_40k_cityscapes_20200601_033336.log.json) | -| OCRNet | HRNetV2p-W18-Small | 512x1024 | 80000 | - | - | V100 | 77.16 | 78.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_80k_cityscapes/ocrnet_hr18s_512x1024_80k_cityscapes_20200601_222735-55979e63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_80k_cityscapes/ocrnet_hr18s_512x1024_80k_cityscapes_20200601_222735.log.json) | -| OCRNet | HRNetV2p-W18 | 512x1024 | 80000 | - | - | V100 | 78.57 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_80k_cityscapes/ocrnet_hr18_512x1024_80k_cityscapes_20200614_230521-c2e1dd4a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_80k_cityscapes/ocrnet_hr18_512x1024_80k_cityscapes_20200614_230521.log.json) | -| OCRNet | HRNetV2p-W48 | 512x1024 | 80000 | - | - | V100 | 80.70 | 81.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_80k_cityscapes/ocrnet_hr48_512x1024_80k_cityscapes_20200601_222752-9076bcdf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_80k_cityscapes/ocrnet_hr48_512x1024_80k_cityscapes_20200601_222752.log.json) | -| OCRNet | HRNetV2p-W18-Small | 512x1024 | 160000 | - | - | V100 | 78.45 | 79.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_160k_cityscapes/ocrnet_hr18s_512x1024_160k_cityscapes_20200602_191005-f4a7af28.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_160k_cityscapes/ocrnet_hr18s_512x1024_160k_cityscapes_20200602_191005.log.json) | -| OCRNet | HRNetV2p-W18 | 512x1024 | 160000 | - | - | V100 | 79.47 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_160k_cityscapes/ocrnet_hr18_512x1024_160k_cityscapes_20200602_191001-b9172d0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_160k_cityscapes/ocrnet_hr18_512x1024_160k_cityscapes_20200602_191001.log.json) | -| OCRNet | HRNetV2p-W48 | 512x1024 | 160000 | - | - | V100 | 81.35 | 82.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_160k_cityscapes/ocrnet_hr48_512x1024_160k_cityscapes_20200602_191037-dfbf1b0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_160k_cityscapes/ocrnet_hr48_512x1024_160k_cityscapes_20200602_191037.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| OCRNet | HRNetV2p-W18-Small | 512x1024 | 40000 | 3.5 | 10.45 | A100 | 76.61 | 78.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024_20230227_145026-6c052a14.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024/ocrnet_hr18s_4xb2-40k_cityscapes-512x1024_20230227_145026.json) | +| OCRNet | HRNetV2p-W18 | 512x1024 | 40000 | 4.7 | 7.50 | V100 | 77.72 | 79.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_40k_cityscapes/ocrnet_hr18_512x1024_40k_cityscapes_20200601_033320-401c5bdd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_40k_cityscapes/ocrnet_hr18_512x1024_40k_cityscapes_20200601_033320.log.json) | +| OCRNet | HRNetV2p-W48 | 512x1024 | 40000 | 8 | 4.22 | V100 | 80.58 | 81.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb2-40k_cityscapes-512x1024.pyy) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_40k_cityscapes/ocrnet_hr48_512x1024_40k_cityscapes_20200601_033336-55b32491.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_40k_cityscapes/ocrnet_hr48_512x1024_40k_cityscapes_20200601_033336.log.json) | +| OCRNet | HRNetV2p-W18-Small | 512x1024 | 80000 | - | - | V100 | 77.16 | 78.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_80k_cityscapes/ocrnet_hr18s_512x1024_80k_cityscapes_20200601_222735-55979e63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_80k_cityscapes/ocrnet_hr18s_512x1024_80k_cityscapes_20200601_222735.log.json) | +| OCRNet | HRNetV2p-W18 | 512x1024 | 80000 | - | - | V100 | 78.57 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_80k_cityscapes/ocrnet_hr18_512x1024_80k_cityscapes_20200614_230521-c2e1dd4a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_80k_cityscapes/ocrnet_hr18_512x1024_80k_cityscapes_20200614_230521.log.json) | +| OCRNet | HRNetV2p-W48 | 512x1024 | 80000 | - | - | V100 | 80.70 | 81.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_80k_cityscapes/ocrnet_hr48_512x1024_80k_cityscapes_20200601_222752-9076bcdf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_80k_cityscapes/ocrnet_hr48_512x1024_80k_cityscapes_20200601_222752.log.json) | +| OCRNet | HRNetV2p-W18-Small | 512x1024 | 160000 | - | - | V100 | 78.45 | 79.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_160k_cityscapes/ocrnet_hr18s_512x1024_160k_cityscapes_20200602_191005-f4a7af28.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x1024_160k_cityscapes/ocrnet_hr18s_512x1024_160k_cityscapes_20200602_191005.log.json) | +| OCRNet | HRNetV2p-W18 | 512x1024 | 160000 | - | - | V100 | 79.47 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_160k_cityscapes/ocrnet_hr18_512x1024_160k_cityscapes_20200602_191001-b9172d0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x1024_160k_cityscapes/ocrnet_hr18_512x1024_160k_cityscapes_20200602_191001.log.json) | +| OCRNet | HRNetV2p-W48 | 512x1024 | 160000 | - | - | V100 | 81.35 | 82.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb2-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_160k_cityscapes/ocrnet_hr48_512x1024_160k_cityscapes_20200602_191037-dfbf1b0c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x1024_160k_cityscapes/ocrnet_hr48_512x1024_160k_cityscapes_20200602_191037.log.json) | #### ResNet backbone -| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| OCRNet | R-101-D8 | 512x1024 | 8 | 40000 | - | - | V100 | 80.09 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b8_cityscapes/ocrnet_r101-d8_512x1024_40k_b8_cityscapes_20200717_110721-02ac0f13.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b8_cityscapes/ocrnet_r101-d8_512x1024_40k_b8_cityscapes_20200717_110721.log.json) | -| OCRNet | R-101-D8 | 512x1024 | 16 | 40000 | 8.8 | 3.02 | V100 | 80.30 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_r101-d8_8xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b16_cityscapes/ocrnet_r101-d8_512x1024_40k_b16_cityscapes_20200723_193726-db500f80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b16_cityscapes/ocrnet_r101-d8_512x1024_40k_b16_cityscapes_20200723_193726.log.json) | -| OCRNet | R-101-D8 | 512x1024 | 16 | 80000 | 8.8 | 3.02 | V100 | 80.81 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_r101-d8_8xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_80k_b16_cityscapes/ocrnet_r101-d8_512x1024_80k_b16_cityscapes_20200723_192421-78688424.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_80k_b16_cityscapes/ocrnet_r101-d8_512x1024_80k_b16_cityscapes_20200723_192421.log.json) | +| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| OCRNet | R-101-D8 | 512x1024 | 8 | 40000 | - | - | V100 | 80.09 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b8_cityscapes/ocrnet_r101-d8_512x1024_40k_b8_cityscapes_20200717_110721-02ac0f13.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b8_cityscapes/ocrnet_r101-d8_512x1024_40k_b8_cityscapes_20200717_110721.log.json) | +| OCRNet | R-101-D8 | 512x1024 | 16 | 40000 | 8.8 | 3.02 | V100 | 80.30 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_r101-d8_8xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b16_cityscapes/ocrnet_r101-d8_512x1024_40k_b16_cityscapes_20200723_193726-db500f80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_40k_b16_cityscapes/ocrnet_r101-d8_512x1024_40k_b16_cityscapes_20200723_193726.log.json) | +| OCRNet | R-101-D8 | 512x1024 | 16 | 80000 | 8.8 | 3.02 | V100 | 80.81 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_r101-d8_8xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_80k_b16_cityscapes/ocrnet_r101-d8_512x1024_80k_b16_cityscapes_20200723_192421-78688424.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_r101-d8_512x1024_80k_b16_cityscapes/ocrnet_r101-d8_512x1024_80k_b16_cityscapes_20200723_192421.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| OCRNet | HRNetV2p-W18-Small | 512x512 | 80000 | 6.7 | 28.98 | V100 | 35.06 | 35.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_80k_ade20k/ocrnet_hr18s_512x512_80k_ade20k_20200615_055600-e80b62af.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_80k_ade20k/ocrnet_hr18s_512x512_80k_ade20k_20200615_055600.log.json) | -| OCRNet | HRNetV2p-W18 | 512x512 | 80000 | 7.9 | 18.93 | V100 | 37.79 | 39.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_80k_ade20k/ocrnet_hr18_512x512_80k_ade20k_20200615_053157-d173d83b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_80k_ade20k/ocrnet_hr18_512x512_80k_ade20k_20200615_053157.log.json) | -| OCRNet | HRNetV2p-W48 | 512x512 | 80000 | 11.2 | 16.99 | V100 | 43.00 | 44.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_80k_ade20k/ocrnet_hr48_512x512_80k_ade20k_20200615_021518-d168c2d1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_80k_ade20k/ocrnet_hr48_512x512_80k_ade20k_20200615_021518.log.json) | -| OCRNet | HRNetV2p-W18-Small | 512x512 | 160000 | - | - | V100 | 37.19 | 38.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_160k_ade20k/ocrnet_hr18s_512x512_160k_ade20k_20200615_184505-8e913058.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_160k_ade20k/ocrnet_hr18s_512x512_160k_ade20k_20200615_184505.log.json) | -| OCRNet | HRNetV2p-W18 | 512x512 | 160000 | - | - | V100 | 39.32 | 40.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_160k_ade20k/ocrnet_hr18_512x512_160k_ade20k_20200615_200940-d8fcd9d1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_160k_ade20k/ocrnet_hr18_512x512_160k_ade20k_20200615_200940.log.json) | -| OCRNet | HRNetV2p-W48 | 512x512 | 160000 | - | - | V100 | 43.25 | 44.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_160k_ade20k/ocrnet_hr48_512x512_160k_ade20k_20200615_184705-a073726d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_160k_ade20k/ocrnet_hr48_512x512_160k_ade20k_20200615_184705.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| OCRNet | HRNetV2p-W18-Small | 512x512 | 80000 | 6.7 | 28.98 | V100 | 35.06 | 35.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_80k_ade20k/ocrnet_hr18s_512x512_80k_ade20k_20200615_055600-e80b62af.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_80k_ade20k/ocrnet_hr18s_512x512_80k_ade20k_20200615_055600.log.json) | +| OCRNet | HRNetV2p-W18 | 512x512 | 80000 | 7.9 | 18.93 | V100 | 37.79 | 39.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_80k_ade20k/ocrnet_hr18_512x512_80k_ade20k_20200615_053157-d173d83b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_80k_ade20k/ocrnet_hr18_512x512_80k_ade20k_20200615_053157.log.json) | +| OCRNet | HRNetV2p-W48 | 512x512 | 80000 | 11.2 | 16.99 | V100 | 43.00 | 44.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_80k_ade20k/ocrnet_hr48_512x512_80k_ade20k_20200615_021518-d168c2d1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_80k_ade20k/ocrnet_hr48_512x512_80k_ade20k_20200615_021518.log.json) | +| OCRNet | HRNetV2p-W18-Small | 512x512 | 160000 | - | - | V100 | 37.19 | 38.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_160k_ade20k/ocrnet_hr18s_512x512_160k_ade20k_20200615_184505-8e913058.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_160k_ade20k/ocrnet_hr18s_512x512_160k_ade20k_20200615_184505.log.json) | +| OCRNet | HRNetV2p-W18 | 512x512 | 160000 | - | - | V100 | 39.32 | 40.80 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_160k_ade20k/ocrnet_hr18_512x512_160k_ade20k_20200615_200940-d8fcd9d1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_160k_ade20k/ocrnet_hr18_512x512_160k_ade20k_20200615_200940.log.json) | +| OCRNet | HRNetV2p-W48 | 512x512 | 160000 | - | - | V100 | 43.25 | 44.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_160k_ade20k/ocrnet_hr48_512x512_160k_ade20k_20200615_184705-a073726d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_160k_ade20k/ocrnet_hr48_512x512_160k_ade20k_20200615_184705.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| OCRNet | HRNetV2p-W18-Small | 512x512 | 20000 | 3.5 | 31.55 | V100 | 71.70 | 73.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_20k_voc12aug/ocrnet_hr18s_512x512_20k_voc12aug_20200617_233913-02b04fcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_20k_voc12aug/ocrnet_hr18s_512x512_20k_voc12aug_20200617_233913.log.json) | -| OCRNet | HRNetV2p-W18 | 512x512 | 20000 | 4.7 | 19.91 | V100 | 74.75 | 77.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_20k_voc12aug/ocrnet_hr18_512x512_20k_voc12aug_20200617_233932-8954cbb7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_20k_voc12aug/ocrnet_hr18_512x512_20k_voc12aug_20200617_233932.log.json) | -| OCRNet | HRNetV2p-W48 | 512x512 | 20000 | 8.1 | 17.83 | V100 | 77.72 | 79.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_20k_voc12aug/ocrnet_hr48_512x512_20k_voc12aug_20200617_233932-9e82080a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_20k_voc12aug/ocrnet_hr48_512x512_20k_voc12aug_20200617_233932.log.json) | -| OCRNet | HRNetV2p-W18-Small | 512x512 | 40000 | - | - | V100 | 72.76 | 74.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18s_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_40k_voc12aug/ocrnet_hr18s_512x512_40k_voc12aug_20200614_002025-42b587ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_40k_voc12aug/ocrnet_hr18s_512x512_40k_voc12aug_20200614_002025.log.json) | -| OCRNet | HRNetV2p-W18 | 512x512 | 40000 | - | - | V100 | 74.98 | 77.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr18_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_40k_voc12aug/ocrnet_hr18_512x512_40k_voc12aug_20200614_015958-714302be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_40k_voc12aug/ocrnet_hr18_512x512_40k_voc12aug_20200614_015958.log.json) | -| OCRNet | HRNetV2p-W48 | 512x512 | 40000 | - | - | V100 | 77.14 | 79.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/ocrnet/ocrnet_hr48_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_40k_voc12aug/ocrnet_hr48_512x512_40k_voc12aug_20200614_015958-255bc5ce.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_40k_voc12aug/ocrnet_hr48_512x512_40k_voc12aug_20200614_015958.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | ------------------ | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| OCRNet | HRNetV2p-W18-Small | 512x512 | 20000 | 3.5 | 31.55 | V100 | 71.70 | 73.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_20k_voc12aug/ocrnet_hr18s_512x512_20k_voc12aug_20200617_233913-02b04fcb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_20k_voc12aug/ocrnet_hr18s_512x512_20k_voc12aug_20200617_233913.log.json) | +| OCRNet | HRNetV2p-W18 | 512x512 | 20000 | 4.7 | 19.91 | V100 | 74.75 | 77.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_20k_voc12aug/ocrnet_hr18_512x512_20k_voc12aug_20200617_233932-8954cbb7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_20k_voc12aug/ocrnet_hr18_512x512_20k_voc12aug_20200617_233932.log.json) | +| OCRNet | HRNetV2p-W48 | 512x512 | 20000 | 8.1 | 17.83 | V100 | 77.72 | 79.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_20k_voc12aug/ocrnet_hr48_512x512_20k_voc12aug_20200617_233932-9e82080a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_20k_voc12aug/ocrnet_hr48_512x512_20k_voc12aug_20200617_233932.log.json) | +| OCRNet | HRNetV2p-W18-Small | 512x512 | 40000 | - | - | V100 | 72.76 | 74.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18s_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_40k_voc12aug/ocrnet_hr18s_512x512_40k_voc12aug_20200614_002025-42b587ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18s_512x512_40k_voc12aug/ocrnet_hr18s_512x512_40k_voc12aug_20200614_002025.log.json) | +| OCRNet | HRNetV2p-W18 | 512x512 | 40000 | - | - | V100 | 74.98 | 77.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr18_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_40k_voc12aug/ocrnet_hr18_512x512_40k_voc12aug_20200614_015958-714302be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr18_512x512_40k_voc12aug/ocrnet_hr18_512x512_40k_voc12aug_20200614_015958.log.json) | +| OCRNet | HRNetV2p-W48 | 512x512 | 40000 | - | - | V100 | 77.14 | 79.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet/ocrnet_hr48_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_40k_voc12aug/ocrnet_hr48_512x512_40k_voc12aug_20200614_015958-255bc5ce.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/ocrnet/ocrnet_hr48_512x512_40k_voc12aug/ocrnet_hr48_512x512_40k_voc12aug_20200614_015958.log.json) | ## Citation diff --git a/configs/pidnet/README.md b/configs/pidnet/README.md index c8c3f247993..e23efbd3f3a 100644 --- a/configs/pidnet/README.md +++ b/configs/pidnet/README.md @@ -8,7 +8,7 @@ Official Repo -Code Snippet +Code Snippet ## Abstract @@ -26,11 +26,11 @@ Two-branch network architecture has shown its efficiency and effectiveness for r ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PIDNet | PIDNet-S | 1024x1024 | 120000 | 3.38 | 80.82 | A100 | 78.74 | 80.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes/pidnet-s_2xb6-120k_1024x1024-cityscapes_20230302_191700-bb8e3bcc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes/pidnet-s_2xb6-120k_1024x1024-cityscapes_20230302_191700.json) | -| PIDNet | PIDNet-M | 1024x1024 | 120000 | 5.14 | 71.98 | A100 | 80.22 | 82.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes/pidnet-m_2xb6-120k_1024x1024-cityscapes_20230301_143452-f9bcdbf3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes/pidnet-m_2xb6-120k_1024x1024-cityscapes_20230301_143452.json) | -| PIDNet | PIDNet-L | 1024x1024 | 120000 | 5.83 | 60.06 | A100 | 80.89 | 82.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes/pidnet-l_2xb6-120k_1024x1024-cityscapes_20230303_114514-0783ca6b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes/pidnet-l_2xb6-120k_1024x1024-cityscapes_20230303_114514.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PIDNet | PIDNet-S | 1024x1024 | 120000 | 3.38 | 80.82 | A100 | 78.74 | 80.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes/pidnet-s_2xb6-120k_1024x1024-cityscapes_20230302_191700-bb8e3bcc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-s_2xb6-120k_1024x1024-cityscapes/pidnet-s_2xb6-120k_1024x1024-cityscapes_20230302_191700.json) | +| PIDNet | PIDNet-M | 1024x1024 | 120000 | 5.14 | 71.98 | A100 | 80.22 | 82.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes/pidnet-m_2xb6-120k_1024x1024-cityscapes_20230301_143452-f9bcdbf3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-m_2xb6-120k_1024x1024-cityscapes/pidnet-m_2xb6-120k_1024x1024-cityscapes_20230301_143452.json) | +| PIDNet | PIDNet-L | 1024x1024 | 120000 | 5.83 | 60.06 | A100 | 80.89 | 82.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes/pidnet-l_2xb6-120k_1024x1024-cityscapes_20230303_114514-0783ca6b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pidnet/pidnet-l_2xb6-120k_1024x1024-cityscapes/pidnet-l_2xb6-120k_1024x1024-cityscapes_20230303_114514.json) | ## Notes diff --git a/configs/pidnet/metafile.yaml b/configs/pidnet/metafile.yaml index 9102ec51c5c..51b514a487d 100644 --- a/configs/pidnet/metafile.yaml +++ b/configs/pidnet/metafile.yaml @@ -33,7 +33,7 @@ Models: Paper: Title: 'PIDNet: A Real-time Semantic Segmentation Network Inspired from PID Controller' URL: https://arxiv.org/pdf/2206.02066.pdf - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/pidnet.py + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/pidnet.py Framework: PyTorch - Name: pidnet-m_2xb6-120k_1024x1024-cityscapes In Collection: PIDNet @@ -57,7 +57,7 @@ Models: Paper: Title: 'PIDNet: A Real-time Semantic Segmentation Network Inspired from PID Controller' URL: https://arxiv.org/pdf/2206.02066.pdf - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/pidnet.py + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/pidnet.py Framework: PyTorch - Name: pidnet-l_2xb6-120k_1024x1024-cityscapes In Collection: PIDNet @@ -81,5 +81,5 @@ Models: Paper: Title: 'PIDNet: A Real-time Semantic Segmentation Network Inspired from PID Controller' URL: https://arxiv.org/pdf/2206.02066.pdf - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/pidnet.py + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/pidnet.py Framework: PyTorch diff --git a/configs/point_rend/README.md b/configs/point_rend/README.md index 9aab8e03ee4..487d3bcc7f9 100644 --- a/configs/point_rend/README.md +++ b/configs/point_rend/README.md @@ -26,17 +26,17 @@ We present a new method for efficient high-quality image segmentation of objects ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PointRend | R-50 | 512x1024 | 80000 | 3.1 | 8.48 | V100 | 76.47 | 78.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x1024_80k_cityscapes/pointrend_r50_512x1024_80k_cityscapes_20200711_015821-bb1ff523.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x1024_80k_cityscapes/pointrend_r50_512x1024_80k_cityscapes-20200715_214714.log.json) | -| PointRend | R-101 | 512x1024 | 80000 | 4.2 | 7.00 | V100 | 78.30 | 79.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/point_rend/pointrend_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x1024_80k_cityscapes/pointrend_r101_512x1024_80k_cityscapes_20200711_170850-d0ca84be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x1024_80k_cityscapes/pointrend_r101_512x1024_80k_cityscapes-20200715_214824.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PointRend | R-50 | 512x1024 | 80000 | 3.1 | 8.48 | V100 | 76.47 | 78.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend/pointrend_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x1024_80k_cityscapes/pointrend_r50_512x1024_80k_cityscapes_20200711_015821-bb1ff523.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x1024_80k_cityscapes/pointrend_r50_512x1024_80k_cityscapes-20200715_214714.log.json) | +| PointRend | R-101 | 512x1024 | 80000 | 4.2 | 7.00 | V100 | 78.30 | 79.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend/pointrend_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x1024_80k_cityscapes/pointrend_r101_512x1024_80k_cityscapes_20200711_170850-d0ca84be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x1024_80k_cityscapes/pointrend_r101_512x1024_80k_cityscapes-20200715_214824.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| PointRend | R-50 | 512x512 | 160000 | 5.1 | 17.31 | V100 | 37.64 | 39.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/point_rend/pointrend_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x512_160k_ade20k/pointrend_r50_512x512_160k_ade20k_20200807_232644-ac3febf2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x512_160k_ade20k/pointrend_r50_512x512_160k_ade20k-20200807_232644.log.json) | -| PointRend | R-101 | 512x512 | 160000 | 6.1 | 15.50 | V100 | 40.02 | 41.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/point_rend/pointrend_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x512_160k_ade20k/pointrend_r101_512x512_160k_ade20k_20200808_030852-8834902a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x512_160k_ade20k/pointrend_r101_512x512_160k_ade20k-20200808_030852.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| PointRend | R-50 | 512x512 | 160000 | 5.1 | 17.31 | V100 | 37.64 | 39.17 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend/pointrend_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x512_160k_ade20k/pointrend_r50_512x512_160k_ade20k_20200807_232644-ac3febf2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r50_512x512_160k_ade20k/pointrend_r50_512x512_160k_ade20k-20200807_232644.log.json) | +| PointRend | R-101 | 512x512 | 160000 | 6.1 | 15.50 | V100 | 40.02 | 41.60 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend/pointrend_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x512_160k_ade20k/pointrend_r101_512x512_160k_ade20k_20200808_030852-8834902a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/point_rend/pointrend_r101_512x512_160k_ade20k/pointrend_r101_512x512_160k_ade20k-20200808_030852.log.json) | ## Citation diff --git a/configs/poolformer/README.md b/configs/poolformer/README.md index ba563a99280..e6e2eac210e 100644 --- a/configs/poolformer/README.md +++ b/configs/poolformer/README.md @@ -39,7 +39,7 @@ Transformers have shown great potential in computer vision tasks. A common belie - PoolFormer backbone needs to install [MMClassification](https://github.com/open-mmlab/mmclassification) first, which has abundant backbones for downstream tasks. ```shell -pip install "mmcls>=1.0.0rc0" +pip install "mmpretrain>=1.0.0rc7" ``` - The pretrained models could also be downloaded from [PoolFormer config of MMClassification](https://github.com/open-mmlab/mmclassification/tree/master/configs/poolformer). @@ -48,13 +48,13 @@ pip install "mmcls>=1.0.0rc0" ### ADE20K -| Method | Backbone | Crop Size | pretrain | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | mIoU\* | mIoU\*(ms+flip) | config | download | -| ------ | -------------- | --------- | ----------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ------ | --------------: | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FPN | PoolFormer-S12 | 512x512 | ImageNet-1K | 32 | 40000 | 4.17 | 23.48 | V100 | 36.68 | - | 37.07 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/poolformer/fpn_poolformer_s12_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s12_8x4_512x512_40k_ade20k/fpn_poolformer_s12_8x4_512x512_40k_ade20k_20220501_115154-b5aa2f49.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s12_8x4_512x512_40k_ade20k/fpn_poolformer_s12_8x4_512x512_40k_ade20k_20220501_115154.log.json) | -| FPN | PoolFormer-S24 | 512x512 | ImageNet-1K | 32 | 40000 | 5.47 | 15.74 | V100 | 40.12 | - | 40.36 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/poolformer/fpn_poolformer_s24_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s24_8x4_512x512_40k_ade20k/fpn_poolformer_s24_8x4_512x512_40k_ade20k_20220503_222049-394a7cf7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s24_8x4_512x512_40k_ade20k/fpn_poolformer_s24_8x4_512x512_40k_ade20k_20220503_222049.log.json) | -| FPN | PoolFormer-S36 | 512x512 | ImageNet-1K | 32 | 40000 | 6.77 | 11.34 | V100 | 41.61 | - | 41.81 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/poolformer/fpn_poolformer_s36_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s36_8x4_512x512_40k_ade20k/fpn_poolformer_s36_8x4_512x512_40k_ade20k_20220501_151122-b47e607d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s36_8x4_512x512_40k_ade20k/fpn_poolformer_s36_8x4_512x512_40k_ade20k_20220501_151122.log.json) | -| FPN | PoolFormer-M36 | 512x512 | ImageNet-1K | 32 | 40000 | 8.59 | 8.97 | V100 | 41.95 | - | 42.35 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/poolformer/fpn_poolformer_m36_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m36_8x4_512x512_40k_ade20k/fpn_poolformer_m36_8x4_512x512_40k_ade20k_20220501_164230-3dc83921.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m36_8x4_512x512_40k_ade20k/fpn_poolformer_m36_8x4_512x512_40k_ade20k_20220501_164230.log.json) | -| FPN | PoolFormer-M48 | 512x512 | ImageNet-1K | 32 | 40000 | 10.48 | 6.69 | V100 | 42.43 | - | 42.76 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/poolformer/fpn_poolformer_m48_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m48_8x4_512x512_40k_ade20k/fpn_poolformer_m48_8x4_512x512_40k_ade20k_20220504_003923-64168d3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m48_8x4_512x512_40k_ade20k/fpn_poolformer_m48_8x4_512x512_40k_ade20k_20220504_003923.log.json) | +| Method | Backbone | Crop Size | pretrain | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | mIoU\* | mIoU\*(ms+flip) | config | download | +| ------ | -------------- | --------- | ----------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ------ | --------------: | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FPN | PoolFormer-S12 | 512x512 | ImageNet-1K | 32 | 40000 | 4.17 | 23.48 | V100 | 36.68 | - | 37.07 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer/fpn_poolformer_s12_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s12_8x4_512x512_40k_ade20k/fpn_poolformer_s12_8x4_512x512_40k_ade20k_20220501_115154-b5aa2f49.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s12_8x4_512x512_40k_ade20k/fpn_poolformer_s12_8x4_512x512_40k_ade20k_20220501_115154.log.json) | +| FPN | PoolFormer-S24 | 512x512 | ImageNet-1K | 32 | 40000 | 5.47 | 15.74 | V100 | 40.12 | - | 40.36 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer/fpn_poolformer_s24_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s24_8x4_512x512_40k_ade20k/fpn_poolformer_s24_8x4_512x512_40k_ade20k_20220503_222049-394a7cf7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s24_8x4_512x512_40k_ade20k/fpn_poolformer_s24_8x4_512x512_40k_ade20k_20220503_222049.log.json) | +| FPN | PoolFormer-S36 | 512x512 | ImageNet-1K | 32 | 40000 | 6.77 | 11.34 | V100 | 41.61 | - | 41.81 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer/fpn_poolformer_s36_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s36_8x4_512x512_40k_ade20k/fpn_poolformer_s36_8x4_512x512_40k_ade20k_20220501_151122-b47e607d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_s36_8x4_512x512_40k_ade20k/fpn_poolformer_s36_8x4_512x512_40k_ade20k_20220501_151122.log.json) | +| FPN | PoolFormer-M36 | 512x512 | ImageNet-1K | 32 | 40000 | 8.59 | 8.97 | V100 | 41.95 | - | 42.35 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer/fpn_poolformer_m36_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m36_8x4_512x512_40k_ade20k/fpn_poolformer_m36_8x4_512x512_40k_ade20k_20220501_164230-3dc83921.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m36_8x4_512x512_40k_ade20k/fpn_poolformer_m36_8x4_512x512_40k_ade20k_20220501_164230.log.json) | +| FPN | PoolFormer-M48 | 512x512 | ImageNet-1K | 32 | 40000 | 10.48 | 6.69 | V100 | 42.43 | - | 42.76 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer/fpn_poolformer_m48_8xb4-40k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m48_8x4_512x512_40k_ade20k/fpn_poolformer_m48_8x4_512x512_40k_ade20k_20220504_003923-64168d3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/poolformer/fpn_poolformer_m48_8x4_512x512_40k_ade20k/fpn_poolformer_m48_8x4_512x512_40k_ade20k_20220504_003923.log.json) | Note: diff --git a/configs/psanet/README.md b/configs/psanet/README.md index d6573261209..1f5680fbabc 100644 --- a/configs/psanet/README.md +++ b/configs/psanet/README.md @@ -26,34 +26,34 @@ We notice information flow in convolutional neural networksis restricted insid ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSANet | R-50-D8 | 512x1024 | 40000 | 7 | 3.17 | V100 | 77.63 | 79.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_40k_cityscapes/psanet_r50-d8_512x1024_40k_cityscapes_20200606_103117-99fac37c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_40k_cityscapes/psanet_r50-d8_512x1024_40k_cityscapes_20200606_103117.log.json) | -| PSANet | R-101-D8 | 512x1024 | 40000 | 10.5 | 2.20 | V100 | 79.14 | 80.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_40k_cityscapes/psanet_r101-d8_512x1024_40k_cityscapes_20200606_001418-27b9cfa7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_40k_cityscapes/psanet_r101-d8_512x1024_40k_cityscapes_20200606_001418.log.json) | -| PSANet | R-50-D8 | 769x769 | 40000 | 7.9 | 1.40 | V100 | 77.99 | 79.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_40k_cityscapes/psanet_r50-d8_769x769_40k_cityscapes_20200530_033717-d5365506.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_40k_cityscapes/psanet_r50-d8_769x769_40k_cityscapes_20200530_033717.log.json) | -| PSANet | R-101-D8 | 769x769 | 40000 | 11.9 | 0.98 | V100 | 78.43 | 80.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_40k_cityscapes/psanet_r101-d8_769x769_40k_cityscapes_20200530_035107-997da1e6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_40k_cityscapes/psanet_r101-d8_769x769_40k_cityscapes_20200530_035107.log.json) | -| PSANet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.24 | 78.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_80k_cityscapes/psanet_r50-d8_512x1024_80k_cityscapes_20200606_161842-ab60a24f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_80k_cityscapes/psanet_r50-d8_512x1024_80k_cityscapes_20200606_161842.log.json) | -| PSANet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.31 | 80.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_80k_cityscapes/psanet_r101-d8_512x1024_80k_cityscapes_20200606_161823-0f73a169.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_80k_cityscapes/psanet_r101-d8_512x1024_80k_cityscapes_20200606_161823.log.json) | -| PSANet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.31 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_80k_cityscapes/psanet_r50-d8_769x769_80k_cityscapes_20200606_225134-fe42f49e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_80k_cityscapes/psanet_r50-d8_769x769_80k_cityscapes_20200606_225134.log.json) | -| PSANet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.69 | 80.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_80k_cityscapes/psanet_r101-d8_769x769_80k_cityscapes_20200606_214550-7665827b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_80k_cityscapes/psanet_r101-d8_769x769_80k_cityscapes_20200606_214550.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSANet | R-50-D8 | 512x1024 | 40000 | 7 | 3.17 | V100 | 77.63 | 79.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_40k_cityscapes/psanet_r50-d8_512x1024_40k_cityscapes_20200606_103117-99fac37c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_40k_cityscapes/psanet_r50-d8_512x1024_40k_cityscapes_20200606_103117.log.json) | +| PSANet | R-101-D8 | 512x1024 | 40000 | 10.5 | 2.20 | V100 | 79.14 | 80.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_40k_cityscapes/psanet_r101-d8_512x1024_40k_cityscapes_20200606_001418-27b9cfa7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_40k_cityscapes/psanet_r101-d8_512x1024_40k_cityscapes_20200606_001418.log.json) | +| PSANet | R-50-D8 | 769x769 | 40000 | 7.9 | 1.40 | V100 | 77.99 | 79.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_40k_cityscapes/psanet_r50-d8_769x769_40k_cityscapes_20200530_033717-d5365506.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_40k_cityscapes/psanet_r50-d8_769x769_40k_cityscapes_20200530_033717.log.json) | +| PSANet | R-101-D8 | 769x769 | 40000 | 11.9 | 0.98 | V100 | 78.43 | 80.26 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_40k_cityscapes/psanet_r101-d8_769x769_40k_cityscapes_20200530_035107-997da1e6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_40k_cityscapes/psanet_r101-d8_769x769_40k_cityscapes_20200530_035107.log.json) | +| PSANet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 77.24 | 78.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_80k_cityscapes/psanet_r50-d8_512x1024_80k_cityscapes_20200606_161842-ab60a24f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x1024_80k_cityscapes/psanet_r50-d8_512x1024_80k_cityscapes_20200606_161842.log.json) | +| PSANet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.31 | 80.53 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_80k_cityscapes/psanet_r101-d8_512x1024_80k_cityscapes_20200606_161823-0f73a169.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x1024_80k_cityscapes/psanet_r101-d8_512x1024_80k_cityscapes_20200606_161823.log.json) | +| PSANet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.31 | 80.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_80k_cityscapes/psanet_r50-d8_769x769_80k_cityscapes_20200606_225134-fe42f49e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_769x769_80k_cityscapes/psanet_r50-d8_769x769_80k_cityscapes_20200606_225134.log.json) | +| PSANet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.69 | 80.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_80k_cityscapes/psanet_r101-d8_769x769_80k_cityscapes_20200606_214550-7665827b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_769x769_80k_cityscapes/psanet_r101-d8_769x769_80k_cityscapes_20200606_214550.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSANet | R-50-D8 | 512x512 | 80000 | 9 | 18.91 | V100 | 41.14 | 41.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_80k_ade20k/psanet_r50-d8_512x512_80k_ade20k_20200614_144141-835e4b97.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_80k_ade20k/psanet_r50-d8_512x512_80k_ade20k_20200614_144141.log.json) | -| PSANet | R-101-D8 | 512x512 | 80000 | 12.5 | 13.13 | V100 | 43.80 | 44.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_80k_ade20k/psanet_r101-d8_512x512_80k_ade20k_20200614_185117-1fab60d4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_80k_ade20k/psanet_r101-d8_512x512_80k_ade20k_20200614_185117.log.json) | -| PSANet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.67 | 42.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_160k_ade20k/psanet_r50-d8_512x512_160k_ade20k_20200615_161258-148077dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_160k_ade20k/psanet_r50-d8_512x512_160k_ade20k_20200615_161258.log.json) | -| PSANet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.74 | 45.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_160k_ade20k/psanet_r101-d8_512x512_160k_ade20k_20200615_161537-dbfa564c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_160k_ade20k/psanet_r101-d8_512x512_160k_ade20k_20200615_161537.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSANet | R-50-D8 | 512x512 | 80000 | 9 | 18.91 | V100 | 41.14 | 41.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_80k_ade20k/psanet_r50-d8_512x512_80k_ade20k_20200614_144141-835e4b97.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_80k_ade20k/psanet_r50-d8_512x512_80k_ade20k_20200614_144141.log.json) | +| PSANet | R-101-D8 | 512x512 | 80000 | 12.5 | 13.13 | V100 | 43.80 | 44.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_80k_ade20k/psanet_r101-d8_512x512_80k_ade20k_20200614_185117-1fab60d4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_80k_ade20k/psanet_r101-d8_512x512_80k_ade20k_20200614_185117.log.json) | +| PSANet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 41.67 | 42.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_160k_ade20k/psanet_r50-d8_512x512_160k_ade20k_20200615_161258-148077dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_160k_ade20k/psanet_r50-d8_512x512_160k_ade20k_20200615_161258.log.json) | +| PSANet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 43.74 | 45.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_160k_ade20k/psanet_r101-d8_512x512_160k_ade20k_20200615_161537-dbfa564c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_160k_ade20k/psanet_r101-d8_512x512_160k_ade20k_20200615_161537.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSANet | R-50-D8 | 512x512 | 20000 | 6.9 | 18.24 | V100 | 76.39 | 77.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_20k_voc12aug/psanet_r50-d8_512x512_20k_voc12aug_20200617_102413-2f1bbaa1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_20k_voc12aug/psanet_r50-d8_512x512_20k_voc12aug_20200617_102413.log.json) | -| PSANet | R-101-D8 | 512x512 | 20000 | 10.4 | 12.63 | V100 | 77.91 | 79.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_20k_voc12aug/psanet_r101-d8_512x512_20k_voc12aug_20200617_110624-946fef11.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_20k_voc12aug/psanet_r101-d8_512x512_20k_voc12aug_20200617_110624.log.json) | -| PSANet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.30 | 77.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_40k_voc12aug/psanet_r50-d8_512x512_40k_voc12aug_20200613_161946-f596afb5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_40k_voc12aug/psanet_r50-d8_512x512_40k_voc12aug_20200613_161946.log.json) | -| PSANet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.73 | 79.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/psanet/psanet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_40k_voc12aug/psanet_r101-d8_512x512_40k_voc12aug_20200613_161946-1f560f9e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_40k_voc12aug/psanet_r101-d8_512x512_40k_voc12aug_20200613_161946.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSANet | R-50-D8 | 512x512 | 20000 | 6.9 | 18.24 | V100 | 76.39 | 77.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_20k_voc12aug/psanet_r50-d8_512x512_20k_voc12aug_20200617_102413-2f1bbaa1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_20k_voc12aug/psanet_r50-d8_512x512_20k_voc12aug_20200617_102413.log.json) | +| PSANet | R-101-D8 | 512x512 | 20000 | 10.4 | 12.63 | V100 | 77.91 | 79.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_20k_voc12aug/psanet_r101-d8_512x512_20k_voc12aug_20200617_110624-946fef11.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_20k_voc12aug/psanet_r101-d8_512x512_20k_voc12aug_20200617_110624.log.json) | +| PSANet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 76.30 | 77.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_40k_voc12aug/psanet_r50-d8_512x512_40k_voc12aug_20200613_161946-f596afb5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r50-d8_512x512_40k_voc12aug/psanet_r50-d8_512x512_40k_voc12aug_20200613_161946.log.json) | +| PSANet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 77.73 | 79.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet/psanet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_40k_voc12aug/psanet_r101-d8_512x512_40k_voc12aug_20200613_161946-1f560f9e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/psanet/psanet_r101-d8_512x512_40k_voc12aug/psanet_r101-d8_512x512_40k_voc12aug_20200613_161946.log.json) | ## Citation diff --git a/configs/pspnet/README.md b/configs/pspnet/README.md index e1c2c112cbe..4209d259b7e 100644 --- a/configs/pspnet/README.md +++ b/configs/pspnet/README.md @@ -31,128 +31,128 @@ PSPNet-R50 D8 model structure ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------------- | ------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| PSPNet | R-50-D8 | 512x1024 | 40000 | 6.1 | 4.07 | V100 | 77.85 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | -| PSPNet | R-101-D8 | 512x1024 | 40000 | 9.6 | 2.68 | V100 | 78.34 | 79.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | -| PSPNet | R-50-D8 | 769x769 | 40000 | 6.9 | 1.76 | V100 | 78.26 | 79.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_40k_cityscapes/pspnet_r50-d8_769x769_40k_cityscapes_20200606_112725-86638686.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_40k_cityscapes/pspnet_r50-d8_769x769_40k_cityscapes_20200606_112725.log.json) | -| PSPNet | R-101-D8 | 769x769 | 40000 | 10.9 | 1.15 | V100 | 79.08 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_40k_cityscapes/pspnet_r101-d8_769x769_40k_cityscapes_20200606_112753-61c6f5be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_40k_cityscapes/pspnet_r101-d8_769x769_40k_cityscapes_20200606_112753.log.json) | -| PSPNet | R-18-D8 | 512x1024 | 80000 | 1.7 | 15.71 | V100 | 74.87 | 76.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x1024_80k_cityscapes/pspnet_r18-d8_512x1024_80k_cityscapes_20201225_021458-09ffa746.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x1024_80k_cityscapes/pspnet_r18-d8_512x1024_80k_cityscapes-20201225_021458.log.json) | -| PSPNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.55 | 79.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_512x1024_80k_cityscapes_20200606_112131-2376f12b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_512x1024_80k_cityscapes_20200606_112131.log.json) | -| PSPNet | R-50b-D8 rsb | 512x1024 | 80000 | 6.2 | 3.82 | V100 | 78.47 | 79.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8-rsb_4xb2-adamw-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220315_123238-588c30be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220315_123238.log.json) | -| PSPNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.76 | 81.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_80k_cityscapes/pspnet_r101-d8_512x1024_80k_cityscapes_20200606_112211-e1e1100f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_80k_cityscapes/pspnet_r101-d8_512x1024_80k_cityscapes_20200606_112211.log.json) | -| PSPNet (FP16) | R-101-D8 | 512x1024 | 80000 | 5.34 | 8.77 | V100 | 79.46 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_fp16_512x1024_80k_cityscapes/pspnet_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230919-a0875e5c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_fp16_512x1024_80k_cityscapes/pspnet_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230919.log.json) | -| PSPNet | R-18-D8 | 769x769 | 80000 | 1.9 | 6.20 | V100 | 75.90 | 77.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_769x769_80k_cityscapes/pspnet_r18-d8_769x769_80k_cityscapes_20201225_021458-3deefc62.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_769x769_80k_cityscapes/pspnet_r18-d8_769x769_80k_cityscapes-20201225_021458.log.json) | -| PSPNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.59 | 80.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_80k_cityscapes/pspnet_r50-d8_769x769_80k_cityscapes_20200606_210121-5ccf03dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_80k_cityscapes/pspnet_r50-d8_769x769_80k_cityscapes_20200606_210121.log.json) | -| PSPNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.77 | 81.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.oz1z1penmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_80k_cityscapes/pspnet_r101-d8_769x769_80k_cityscapes_20200606_225055-dba412fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_80k_cityscapes/pspnet_r101-d8_769x769_80k_cityscapes_20200606_225055.log.json) | -| PSPNet | R-18b-D8 | 512x1024 | 80000 | 1.5 | 16.28 | V100 | 74.23 | 75.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_512x1024_80k_cityscapes/pspnet_r18b-d8_512x1024_80k_cityscapes_20201226_063116-26928a60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_512x1024_80k_cityscapes/pspnet_r18b-d8_512x1024_80k_cityscapes-20201226_063116.log.json) | -| PSPNet | R-50b-D8 | 512x1024 | 80000 | 6.0 | 4.30 | V100 | 78.22 | 79.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_512x1024_80k_cityscapes/pspnet_r50b-d8_512x1024_80k_cityscapes_20201225_094315-6344287a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_512x1024_80k_cityscapes/pspnet_r50b-d8_512x1024_80k_cityscapes-20201225_094315.log.json) | -| PSPNet | R-101b-D8 | 512x1024 | 80000 | 9.5 | 2.76 | V100 | 79.69 | 80.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | -| PSPNet | R-18b-D8 | 769x769 | 80000 | 1.7 | 6.41 | V100 | 74.92 | 76.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_769x769_80k_cityscapes/pspnet_r18b-d8_769x769_80k_cityscapes_20201226_080942-bf98d186.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_769x769_80k_cityscapes/pspnet_r18b-d8_769x769_80k_cityscapes-20201226_080942.log.json) | -| PSPNet | R-50b-D8 | 769x769 | 80000 | 6.8 | 1.88 | V100 | 78.50 | 79.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_769x769_80k_cityscapes/pspnet_r50b-d8_769x769_80k_cityscapes_20201225_094316-4c643cf6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_769x769_80k_cityscapes/pspnet_r50b-d8_769x769_80k_cityscapes-20201225_094316.log.json) | -| PSPNet | R-101b-D8 | 769x769 | 80000 | 10.8 | 1.17 | V100 | 78.87 | 80.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_769x769_80k_cityscapes/pspnet_r101b-d8_769x769_80k_cityscapes_20201226_171823-f0e7c293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_769x769_80k_cityscapes/pspnet_r101b-d8_769x769_80k_cityscapes-20201226_171823.log.json) | -| PSPNet | R-50-D32 | 512x1024 | 80000 | 3.0 | 15.21 | V100 | 73.88 | 76.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50b-d32_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_512x1024_80k_cityscapes/pspnet_r50-d32_512x1024_80k_cityscapes_20220316_224840-9092b254.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_512x1024_80k_cityscapes/pspnet_r50-d32_512x1024_80k_cityscapes_20220316_224840.log.json) | -| PSPNet | R-50b-D32 rsb | 512x1024 | 80000 | 3.1 | 16.08 | V100 | 74.09 | 77.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d32_rsb_4xb2-adamw-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220316_141229-dd9c9610.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220316_141229.log.json) | -| PSPNet | R-50b-D32 | 512x1024 | 80000 | 2.9 | 15.41 | V100 | 72.61 | 75.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50b-d32_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d32_512x1024_80k_cityscapes/pspnet_r50b-d32_512x1024_80k_cityscapes_20220311_152152-23bcaf8c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d32_512x1024_80k_cityscapes/pspnet_r50b-d32_512x1024_80k_cityscapes_20220311_152152.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------------- | ------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| PSPNet | R-50-D8 | 512x1024 | 40000 | 6.1 | 4.07 | V100 | 77.85 | 79.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | +| PSPNet | R-101-D8 | 512x1024 | 40000 | 9.6 | 2.68 | V100 | 78.34 | 79.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | +| PSPNet | R-50-D8 | 769x769 | 40000 | 6.9 | 1.76 | V100 | 78.26 | 79.88 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_40k_cityscapes/pspnet_r50-d8_769x769_40k_cityscapes_20200606_112725-86638686.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_40k_cityscapes/pspnet_r50-d8_769x769_40k_cityscapes_20200606_112725.log.json) | +| PSPNet | R-101-D8 | 769x769 | 40000 | 10.9 | 1.15 | V100 | 79.08 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_40k_cityscapes/pspnet_r101-d8_769x769_40k_cityscapes_20200606_112753-61c6f5be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_40k_cityscapes/pspnet_r101-d8_769x769_40k_cityscapes_20200606_112753.log.json) | +| PSPNet | R-18-D8 | 512x1024 | 80000 | 1.7 | 15.71 | V100 | 74.87 | 76.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x1024_80k_cityscapes/pspnet_r18-d8_512x1024_80k_cityscapes_20201225_021458-09ffa746.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x1024_80k_cityscapes/pspnet_r18-d8_512x1024_80k_cityscapes-20201225_021458.log.json) | +| PSPNet | R-50-D8 | 512x1024 | 80000 | - | - | V100 | 78.55 | 79.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_512x1024_80k_cityscapes_20200606_112131-2376f12b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_512x1024_80k_cityscapes_20200606_112131.log.json) | +| PSPNet | R-50b-D8 rsb | 512x1024 | 80000 | 6.2 | 3.82 | V100 | 78.47 | 79.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8-rsb_4xb2-adamw-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220315_123238-588c30be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_80k_cityscapes/pspnet_r50-d8_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220315_123238.log.json) | +| PSPNet | R-101-D8 | 512x1024 | 80000 | - | - | V100 | 79.76 | 81.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_80k_cityscapes/pspnet_r101-d8_512x1024_80k_cityscapes_20200606_112211-e1e1100f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_80k_cityscapes/pspnet_r101-d8_512x1024_80k_cityscapes_20200606_112211.log.json) | +| PSPNet (FP16) | R-101-D8 | 512x1024 | 80000 | 5.34 | 8.77 | V100 | 79.46 | - | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-amp-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_fp16_512x1024_80k_cityscapes/pspnet_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230919-a0875e5c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_fp16_512x1024_80k_cityscapes/pspnet_r101-d8_fp16_512x1024_80k_cityscapes_20200717_230919.log.json) | +| PSPNet | R-18-D8 | 769x769 | 80000 | 1.9 | 6.20 | V100 | 75.90 | 77.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_769x769_80k_cityscapes/pspnet_r18-d8_769x769_80k_cityscapes_20201225_021458-3deefc62.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_769x769_80k_cityscapes/pspnet_r18-d8_769x769_80k_cityscapes-20201225_021458.log.json) | +| PSPNet | R-50-D8 | 769x769 | 80000 | - | - | V100 | 79.59 | 80.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_80k_cityscapes/pspnet_r50-d8_769x769_80k_cityscapes_20200606_210121-5ccf03dd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_769x769_80k_cityscapes/pspnet_r50-d8_769x769_80k_cityscapes_20200606_210121.log.json) | +| PSPNet | R-101-D8 | 769x769 | 80000 | - | - | V100 | 79.77 | 81.06 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.oz1z1penmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_80k_cityscapes/pspnet_r101-d8_769x769_80k_cityscapes_20200606_225055-dba412fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_769x769_80k_cityscapes/pspnet_r101-d8_769x769_80k_cityscapes_20200606_225055.log.json) | +| PSPNet | R-18b-D8 | 512x1024 | 80000 | 1.5 | 16.28 | V100 | 74.23 | 75.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_512x1024_80k_cityscapes/pspnet_r18b-d8_512x1024_80k_cityscapes_20201226_063116-26928a60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_512x1024_80k_cityscapes/pspnet_r18b-d8_512x1024_80k_cityscapes-20201226_063116.log.json) | +| PSPNet | R-50b-D8 | 512x1024 | 80000 | 6.0 | 4.30 | V100 | 78.22 | 79.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_512x1024_80k_cityscapes/pspnet_r50b-d8_512x1024_80k_cityscapes_20201225_094315-6344287a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_512x1024_80k_cityscapes/pspnet_r50b-d8_512x1024_80k_cityscapes-20201225_094315.log.json) | +| PSPNet | R-101b-D8 | 512x1024 | 80000 | 9.5 | 2.76 | V100 | 79.69 | 80.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | +| PSPNet | R-18b-D8 | 769x769 | 80000 | 1.7 | 6.41 | V100 | 74.92 | 76.90 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_769x769_80k_cityscapes/pspnet_r18b-d8_769x769_80k_cityscapes_20201226_080942-bf98d186.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18b-d8_769x769_80k_cityscapes/pspnet_r18b-d8_769x769_80k_cityscapes-20201226_080942.log.json) | +| PSPNet | R-50b-D8 | 769x769 | 80000 | 6.8 | 1.88 | V100 | 78.50 | 79.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_769x769_80k_cityscapes/pspnet_r50b-d8_769x769_80k_cityscapes_20201225_094316-4c643cf6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d8_769x769_80k_cityscapes/pspnet_r50b-d8_769x769_80k_cityscapes-20201225_094316.log.json) | +| PSPNet | R-101b-D8 | 769x769 | 80000 | 10.8 | 1.17 | V100 | 78.87 | 80.04 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_769x769_80k_cityscapes/pspnet_r101b-d8_769x769_80k_cityscapes_20201226_171823-f0e7c293.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_769x769_80k_cityscapes/pspnet_r101b-d8_769x769_80k_cityscapes-20201226_171823.log.json) | +| PSPNet | R-50-D32 | 512x1024 | 80000 | 3.0 | 15.21 | V100 | 73.88 | 76.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50b-d32_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_512x1024_80k_cityscapes/pspnet_r50-d32_512x1024_80k_cityscapes_20220316_224840-9092b254.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_512x1024_80k_cityscapes/pspnet_r50-d32_512x1024_80k_cityscapes_20220316_224840.log.json) | +| PSPNet | R-50b-D32 rsb | 512x1024 | 80000 | 3.1 | 16.08 | V100 | 74.09 | 77.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d32_rsb_4xb2-adamw-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220316_141229-dd9c9610.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes/pspnet_r50-d32_rsb-pretrain_512x1024_adamw_80k_cityscapes_20220316_141229.log.json) | +| PSPNet | R-50b-D32 | 512x1024 | 80000 | 2.9 | 15.41 | V100 | 72.61 | 75.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50b-d32_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d32_512x1024_80k_cityscapes/pspnet_r50b-d32_512x1024_80k_cityscapes_20220311_152152-23bcaf8c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50b-d32_512x1024_80k_cityscapes/pspnet_r50b-d32_512x1024_80k_cityscapes_20220311_152152.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-50-D8 | 512x512 | 80000 | 8.5 | 23.53 | V100 | 41.13 | 41.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_ade20k/pspnet_r50-d8_512x512_80k_ade20k_20200615_014128-15a8b914.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_ade20k/pspnet_r50-d8_512x512_80k_ade20k_20200615_014128.log.json) | -| PSPNet | R-101-D8 | 512x512 | 80000 | 12 | 15.30 | V100 | 43.57 | 44.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_ade20k/pspnet_r101-d8_512x512_80k_ade20k_20200614_031423-b6e782f0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_ade20k/pspnet_r101-d8_512x512_80k_ade20k_20200614_031423.log.json) | -| PSPNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.48 | 43.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_160k_ade20k/pspnet_r50-d8_512x512_160k_ade20k_20200615_184358-1890b0bd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_160k_ade20k/pspnet_r50-d8_512x512_160k_ade20k_20200615_184358.log.json) | -| PSPNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.39 | 45.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_160k_ade20k/pspnet_r101-d8_512x512_160k_ade20k_20200615_100650-967c316f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_160k_ade20k/pspnet_r101-d8_512x512_160k_ade20k_20200615_100650.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-50-D8 | 512x512 | 80000 | 8.5 | 23.53 | V100 | 41.13 | 41.94 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_ade20k/pspnet_r50-d8_512x512_80k_ade20k_20200615_014128-15a8b914.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_ade20k/pspnet_r50-d8_512x512_80k_ade20k_20200615_014128.log.json) | +| PSPNet | R-101-D8 | 512x512 | 80000 | 12 | 15.30 | V100 | 43.57 | 44.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_ade20k/pspnet_r101-d8_512x512_80k_ade20k_20200614_031423-b6e782f0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_ade20k/pspnet_r101-d8_512x512_80k_ade20k_20200614_031423.log.json) | +| PSPNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 42.48 | 43.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_160k_ade20k/pspnet_r50-d8_512x512_160k_ade20k_20200615_184358-1890b0bd.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_160k_ade20k/pspnet_r50-d8_512x512_160k_ade20k_20200615_184358.log.json) | +| PSPNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 44.39 | 45.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_160k_ade20k/pspnet_r101-d8_512x512_160k_ade20k_20200615_100650-967c316f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_160k_ade20k/pspnet_r101-d8_512x512_160k_ade20k_20200615_100650.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-50-D8 | 512x512 | 20000 | 6.1 | 23.59 | V100 | 76.78 | 77.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_20k_voc12aug/pspnet_r50-d8_512x512_20k_voc12aug_20200617_101958-ed5dfbd9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_20k_voc12aug/pspnet_r50-d8_512x512_20k_voc12aug_20200617_101958.log.json) | -| PSPNet | R-101-D8 | 512x512 | 20000 | 9.6 | 15.02 | V100 | 78.47 | 79.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_20k_voc12aug/pspnet_r101-d8_512x512_20k_voc12aug_20200617_102003-4aef3c9a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_20k_voc12aug/pspnet_r101-d8_512x512_20k_voc12aug_20200617_102003.log.json) | -| PSPNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 77.29 | 78.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_40k_voc12aug/pspnet_r50-d8_512x512_40k_voc12aug_20200613_161222-ae9c1b8c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_40k_voc12aug/pspnet_r50-d8_512x512_40k_voc12aug_20200613_161222.log.json) | -| PSPNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.52 | 79.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_40k_voc12aug/pspnet_r101-d8_512x512_40k_voc12aug_20200613_161222-bc933b18.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_40k_voc12aug/pspnet_r101-d8_512x512_40k_voc12aug_20200613_161222.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-50-D8 | 512x512 | 20000 | 6.1 | 23.59 | V100 | 76.78 | 77.61 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_20k_voc12aug/pspnet_r50-d8_512x512_20k_voc12aug_20200617_101958-ed5dfbd9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_20k_voc12aug/pspnet_r50-d8_512x512_20k_voc12aug_20200617_101958.log.json) | +| PSPNet | R-101-D8 | 512x512 | 20000 | 9.6 | 15.02 | V100 | 78.47 | 79.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_20k_voc12aug/pspnet_r101-d8_512x512_20k_voc12aug_20200617_102003-4aef3c9a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_20k_voc12aug/pspnet_r101-d8_512x512_20k_voc12aug_20200617_102003.log.json) | +| PSPNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 77.29 | 78.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_40k_voc12aug/pspnet_r50-d8_512x512_40k_voc12aug_20200613_161222-ae9c1b8c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_40k_voc12aug/pspnet_r50-d8_512x512_40k_voc12aug_20200613_161222.log.json) | +| PSPNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 78.52 | 79.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_40k_voc12aug/pspnet_r101-d8_512x512_40k_voc12aug_20200613_161222-bc933b18.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_40k_voc12aug/pspnet_r101-d8_512x512_40k_voc12aug_20200613_161222.log.json) | ### Pascal Context -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-101-D8 | 480x480 | 40000 | 8.8 | 9.68 | V100 | 46.60 | 47.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context/pspnet_r101-d8_480x480_40k_pascal_context_20200911_211210-bf0f5d7c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context/pspnet_r101-d8_480x480_40k_pascal_context-20200911_211210.log.json) | -| PSPNet | R-101-D8 | 480x480 | 80000 | - | - | V100 | 46.03 | 47.15 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context/pspnet_r101-d8_480x480_80k_pascal_context_20200911_190530-c86d6233.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context/pspnet_r101-d8_480x480_80k_pascal_context-20200911_190530.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-101-D8 | 480x480 | 40000 | 8.8 | 9.68 | V100 | 46.60 | 47.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-40k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context/pspnet_r101-d8_480x480_40k_pascal_context_20200911_211210-bf0f5d7c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context/pspnet_r101-d8_480x480_40k_pascal_context-20200911_211210.log.json) | +| PSPNet | R-101-D8 | 480x480 | 80000 | - | - | V100 | 46.03 | 47.15 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_pascal-context-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context/pspnet_r101-d8_480x480_80k_pascal_context_20200911_190530-c86d6233.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context/pspnet_r101-d8_480x480_80k_pascal_context-20200911_190530.log.json) | ### Pascal Context 59 -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.02 | 53.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context_59/pspnet_r101-d8_480x480_40k_pascal_context_59_20210416_114524-86d44cd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context_59/pspnet_r101-d8_480x480_40k_pascal_context_59-20210416_114524.log.json) | -| PSPNet | R-101-D8 | 480x480 | 80000 | - | - | V100 | 52.47 | 53.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context_59/pspnet_r101-d8_480x480_80k_pascal_context_59_20210416_114418-fa6caaa2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context_59/pspnet_r101-d8_480x480_80k_pascal_context_59-20210416_114418.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-101-D8 | 480x480 | 40000 | - | - | V100 | 52.02 | 53.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-40k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context_59/pspnet_r101-d8_480x480_40k_pascal_context_59_20210416_114524-86d44cd4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_40k_pascal_context_59/pspnet_r101-d8_480x480_40k_pascal_context_59-20210416_114524.log.json) | +| PSPNet | R-101-D8 | 480x480 | 80000 | - | - | V100 | 52.47 | 53.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_pascal-context-59-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context_59/pspnet_r101-d8_480x480_80k_pascal_context_59_20210416_114418-fa6caaa2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_480x480_80k_pascal_context_59/pspnet_r101-d8_480x480_80k_pascal_context_59-20210416_114418.log.json) | ### Dark Zurich and Nighttime Driving We support evaluation results on these two datasets using models above trained on Cityscapes training set. -| Method | Backbone | Training Dataset | Test Dataset | mIoU | config | evaluation checkpoint | -| ------ | --------- | ----------------------- | ------------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| PSPNet | R-50-D8 | Cityscapes Training set | Dark Zurich | 10.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | -| PSPNet | R-50-D8 | Cityscapes Training set | Nighttime Driving | 23.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | -| PSPNet | R-50-D8 | Cityscapes Training set | Cityscapes Validation set | 77.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | -| PSPNet | R-101-D8 | Cityscapes Training set | Dark Zurich | 10.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | -| PSPNet | R-101-D8 | Cityscapes Training set | Nighttime Driving | 20.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | -| PSPNet | R-101-D8 | Cityscapes Training set | Cityscapes Validation set | 78.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | -| PSPNet | R-101b-D8 | Cityscapes Training set | Dark Zurich | 15.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | -| PSPNet | R-101b-D8 | Cityscapes Training set | Nighttime Driving | 22.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | -| PSPNet | R-101b-D8 | Cityscapes Training set | Cityscapes Validation set | 79.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | +| Method | Backbone | Training Dataset | Test Dataset | mIoU | config | evaluation checkpoint | +| ------ | --------- | ----------------------- | ------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| PSPNet | R-50-D8 | Cityscapes Training set | Dark Zurich | 10.91 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | +| PSPNet | R-50-D8 | Cityscapes Training set | Nighttime Driving | 23.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | +| PSPNet | R-50-D8 | Cityscapes Training set | Cityscapes Validation set | 77.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338.log.json) | +| PSPNet | R-101-D8 | Cityscapes Training set | Dark Zurich | 10.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | +| PSPNet | R-101-D8 | Cityscapes Training set | Nighttime Driving | 20.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | +| PSPNet | R-101-D8 | Cityscapes Training set | Cityscapes Validation set | 78.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751-467e7cf4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x1024_40k_cityscapes/pspnet_r101-d8_512x1024_40k_cityscapes_20200604_232751.log.json) | +| PSPNet | R-101b-D8 | Cityscapes Training set | Dark Zurich | 15.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024_dark-zurich-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | +| PSPNet | R-101b-D8 | Cityscapes Training set | Nighttime Driving | 22.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024_night-driving-1920x1080.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | +| PSPNet | R-101b-D8 | Cityscapes Training set | Cityscapes Validation set | 79.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101b-d8_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes_20201226_170012-3a4d38ab.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101b-d8_512x1024_80k_cityscapes/pspnet_r101b-d8_512x1024_80k_cityscapes-20201226_170012.log.json) | ### COCO-Stuff 10k -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-50-D8 | 512x512 | 20000 | 9.6 | 20.5 | V100 | 35.69 | 36.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k_20210820_203258-b88df27f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k_20210820_203258.log.json) | -| PSPNet | R-101-D8 | 512x512 | 20000 | 13.2 | 11.1 | V100 | 37.26 | 38.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k_20210820_232135-76aae482.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k_20210820_232135.log.json) | -| PSPNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 36.33 | 37.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_030857-92e2902b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_030857.log.json) | -| PSPNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 37.76 | 38.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_014022-831aec95.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_014022.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-50-D8 | 512x512 | 20000 | 9.6 | 20.5 | V100 | 35.69 | 36.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k_20210820_203258-b88df27f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_20k_coco-stuff10k_20210820_203258.log.json) | +| PSPNet | R-101-D8 | 512x512 | 20000 | 13.2 | 11.1 | V100 | 37.26 | 38.52 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-20k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k_20210820_232135-76aae482.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_20k_coco-stuff10k_20210820_232135.log.json) | +| PSPNet | R-50-D8 | 512x512 | 40000 | - | - | V100 | 36.33 | 37.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_030857-92e2902b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r50-d8_512x512_4x4_40k_coco-stuff10k_20210821_030857.log.json) | +| PSPNet | R-101-D8 | 512x512 | 40000 | - | - | V100 | 37.76 | 38.86 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-40k_coco-stuff10k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_014022-831aec95.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k/pspnet_r101-d8_512x512_4x4_40k_coco-stuff10k_20210821_014022.log.json) | ### COCO-Stuff 164k -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-50-D8 | 512x512 | 80000 | 9.6 | 20.5 | V100 | 38.80 | 39.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034-0e41b2db.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034.log.json) | -| PSPNet | R-101-D8 | 512x512 | 80000 | 13.2 | 11.1 | V100 | 40.34 | 40.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034-7eb41789.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034.log.json) | -| PSPNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 39.64 | 39.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004-51276a57.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004.log.json) | -| PSPNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 41.28 | 41.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004-4af9621b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004.log.json) | -| PSPNet | R-50-D8 | 512x512 | 320000 | - | - | V100 | 40.53 | 40.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004-be9610cc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004.log.json) | -| PSPNet | R-101-D8 | 512x512 | 320000 | - | - | V100 | 41.95 | 42.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004-72220c60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-50-D8 | 512x512 | 80000 | 9.6 | 20.5 | V100 | 38.80 | 39.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034-0e41b2db.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034.log.json) | +| PSPNet | R-101-D8 | 512x512 | 80000 | 13.2 | 11.1 | V100 | 40.34 | 40.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034-7eb41789.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_80k_coco-stuff164k_20210707_152034.log.json) | +| PSPNet | R-50-D8 | 512x512 | 160000 | - | - | V100 | 39.64 | 39.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004-51276a57.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004.log.json) | +| PSPNet | R-101-D8 | 512x512 | 160000 | - | - | V100 | 41.28 | 41.66 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-160k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004-4af9621b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_160k_coco-stuff164k_20210707_152004.log.json) | +| PSPNet | R-50-D8 | 512x512 | 320000 | - | - | V100 | 40.53 | 40.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004-be9610cc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r50-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004.log.json) | +| PSPNet | R-101-D8 | 512x512 | 320000 | - | - | V100 | 41.95 | 42.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-320k_coco-stuff164k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004-72220c60.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k/pspnet_r101-d8_512x512_4x4_320k_coco-stuff164k_20210707_152004.log.json) | ### LoveDA -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| PSPNet | R-18-D8 | 512x512 | 80000 | 1.45 | 26.87 | V100 | 48.62 | 47.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x512_80k_loveda/pspnet_r18-d8_512x512_80k_loveda_20211105_052100-b97697f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x512_80k_loveda/pspnet_r18-d8_512x512_80k_loveda_20211105_052100.log.json) | -| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 6.60 | V100 | 50.46 | 50.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_loveda/pspnet_r50-d8_512x512_80k_loveda_20211104_155728-88610f9f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_loveda/pspnet_r50-d8_512x512_80k_loveda_20211104_155728.log.json) | -| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 4.58 | V100 | 51.86 | 51.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_loveda/pspnet_r101-d8_512x512_80k_loveda_20211104_153212-1c06c6a8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_loveda/pspnet_r101-d8_512x512_80k_loveda_20211104_153212.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| PSPNet | R-18-D8 | 512x512 | 80000 | 1.45 | 26.87 | V100 | 48.62 | 47.57 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x512_80k_loveda/pspnet_r18-d8_512x512_80k_loveda_20211105_052100-b97697f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_512x512_80k_loveda/pspnet_r18-d8_512x512_80k_loveda_20211105_052100.log.json) | +| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 6.60 | V100 | 50.46 | 50.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_loveda/pspnet_r50-d8_512x512_80k_loveda_20211104_155728-88610f9f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x512_80k_loveda/pspnet_r50-d8_512x512_80k_loveda_20211104_155728.log.json) | +| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 4.58 | V100 | 51.86 | 51.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_loveda-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_loveda/pspnet_r101-d8_512x512_80k_loveda_20211104_153212-1c06c6a8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_512x512_80k_loveda/pspnet_r101-d8_512x512_80k_loveda_20211104_153212.log.json) | ### Potsdam -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-18-D8 | 512x512 | 80000 | 1.50 | 85.12 | V100 | 77.09 | 78.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_potsdam/pspnet_r18-d8_4x4_512x512_80k_potsdam_20211220_125612-7cd046e1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_potsdam/pspnet_r18-d8_4x4_512x512_80k_potsdam_20211220_125612.log.json) | -| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 30.21 | V100 | 78.12 | 78.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_potsdam/pspnet_r50-d8_4x4_512x512_80k_potsdam_20211219_043541-2dd5fe67.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_potsdam/pspnet_r50-d8_4x4_512x512_80k_potsdam_20211219_043541.log.json) | -| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 19.40 | V100 | 78.62 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_potsdam/pspnet_r101-d8_4x4_512x512_80k_potsdam_20211220_125612-aed036c4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_potsdam/pspnet_r101-d8_4x4_512x512_80k_potsdam_20211220_125612.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-18-D8 | 512x512 | 80000 | 1.50 | 85.12 | V100 | 77.09 | 78.30 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_potsdam/pspnet_r18-d8_4x4_512x512_80k_potsdam_20211220_125612-7cd046e1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_potsdam/pspnet_r18-d8_4x4_512x512_80k_potsdam_20211220_125612.log.json) | +| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 30.21 | V100 | 78.12 | 78.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_potsdam/pspnet_r50-d8_4x4_512x512_80k_potsdam_20211219_043541-2dd5fe67.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_potsdam/pspnet_r50-d8_4x4_512x512_80k_potsdam_20211219_043541.log.json) | +| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 19.40 | V100 | 78.62 | 79.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_potsdam-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_potsdam/pspnet_r101-d8_4x4_512x512_80k_potsdam_20211220_125612-aed036c4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_potsdam/pspnet_r101-d8_4x4_512x512_80k_potsdam_20211220_125612.log.json) | ### Vaihingen -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-18-D8 | 512x512 | 80000 | 1.45 | 85.06 | V100 | 71.46 | 73.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_vaihingen/pspnet_r18-d8_4x4_512x512_80k_vaihingen_20211228_160355-52a8a6f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_vaihingen/pspnet_r18-d8_4x4_512x512_80k_vaihingen_20211228_160355.log.json) | -| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 30.29 | V100 | 72.36 | 73.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_vaihingen/pspnet_r50-d8_4x4_512x512_80k_vaihingen_20211228_160355-382f8f5b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_vaihingen/pspnet_r50-d8_4x4_512x512_80k_vaihingen_20211228_160355.log.json) | -| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 19.97 | V100 | 72.61 | 74.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r101-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_vaihingen/pspnet_r101-d8_4x4_512x512_80k_vaihingen_20211231_230806-8eba0a09.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_vaihingen/pspnet_r101-d8_4x4_512x512_80k_vaihingen_20211231_230806.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-18-D8 | 512x512 | 80000 | 1.45 | 85.06 | V100 | 71.46 | 73.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_vaihingen/pspnet_r18-d8_4x4_512x512_80k_vaihingen_20211228_160355-52a8a6f6.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_512x512_80k_vaihingen/pspnet_r18-d8_4x4_512x512_80k_vaihingen_20211228_160355.log.json) | +| PSPNet | R-50-D8 | 512x512 | 80000 | 6.14 | 30.29 | V100 | 72.36 | 73.75 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_vaihingen/pspnet_r50-d8_4x4_512x512_80k_vaihingen_20211228_160355-382f8f5b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_512x512_80k_vaihingen/pspnet_r50-d8_4x4_512x512_80k_vaihingen_20211228_160355.log.json) | +| PSPNet | R-101-D8 | 512x512 | 80000 | 9.61 | 19.97 | V100 | 72.61 | 74.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r101-d8_4xb4-80k_vaihingen-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_vaihingen/pspnet_r101-d8_4x4_512x512_80k_vaihingen_20211231_230806-8eba0a09.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r101-d8_4x4_512x512_80k_vaihingen/pspnet_r101-d8_4x4_512x512_80k_vaihingen_20211231_230806.log.json) | ### iSAID -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| PSPNet | R-18-D8 | 896x896 | 80000 | 4.52 | 26.91 | V100 | 60.22 | 61.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r18-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_896x896_80k_isaid/pspnet_r18-d8_4x4_896x896_80k_isaid_20220110_180526-e84c0b6a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_896x896_80k_isaid/pspnet_r18-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | -| PSPNet | R-50-D8 | 896x896 | 80000 | 16.58 | 8.88 | V100 | 65.36 | 66.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/pspnet/pspnet_r50-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_896x896_80k_isaid/pspnet_r50-d8_4x4_896x896_80k_isaid_20220110_180629-1f21dc32.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_896x896_80k_isaid/pspnet_r50-d8_4x4_896x896_80k_isaid_20220110_180629.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PSPNet | R-18-D8 | 896x896 | 80000 | 4.52 | 26.91 | V100 | 60.22 | 61.25 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r18-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_896x896_80k_isaid/pspnet_r18-d8_4x4_896x896_80k_isaid_20220110_180526-e84c0b6a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r18-d8_4x4_896x896_80k_isaid/pspnet_r18-d8_4x4_896x896_80k_isaid_20220110_180526.log.json) | +| PSPNet | R-50-D8 | 896x896 | 80000 | 16.58 | 8.88 | V100 | 65.36 | 66.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet/pspnet_r50-d8_4xb4-80k_isaid-896x896.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_896x896_80k_isaid/pspnet_r50-d8_4x4_896x896_80k_isaid_20220110_180629-1f21dc32.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_4x4_896x896_80k_isaid/pspnet_r50-d8_4x4_896x896_80k_isaid_20220110_180629.log.json) | Note: diff --git a/configs/resnest/README.md b/configs/resnest/README.md index d27bbe28076..304791abe96 100644 --- a/configs/resnest/README.md +++ b/configs/resnest/README.md @@ -26,21 +26,21 @@ It is well known that featuremap attention and multi-path representation are imp ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | S-101-D8 | 512x1024 | 80000 | 11.4 | 2.39 | V100 | 77.56 | 78.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_fcn_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x1024_80k_cityscapes/fcn_s101-d8_512x1024_80k_cityscapes_20200807_140631-f8d155b3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x1024_80k_cityscapes/fcn_s101-d8_512x1024_80k_cityscapes-20200807_140631.log.json) | -| PSPNet | S-101-D8 | 512x1024 | 80000 | 11.8 | 2.52 | V100 | 78.57 | 79.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_pspnet_4xb2-80k_cityscapes512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x1024_80k_cityscapes/pspnet_s101-d8_512x1024_80k_cityscapes_20200807_140631-c75f3b99.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x1024_80k_cityscapes/pspnet_s101-d8_512x1024_80k_cityscapes-20200807_140631.log.json) | -| DeepLabV3 | S-101-D8 | 512x1024 | 80000 | 11.9 | 1.88 | V100 | 79.67 | 80.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_deeplabv3_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x1024_80k_cityscapes/deeplabv3_s101-d8_512x1024_80k_cityscapes_20200807_144429-b73c4270.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x1024_80k_cityscapes/deeplabv3_s101-d8_512x1024_80k_cityscapes-20200807_144429.log.json) | -| DeepLabV3+ | S-101-D8 | 512x1024 | 80000 | 13.2 | 2.36 | V100 | 79.62 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_deeplabv3plus_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x1024_80k_cityscapes/deeplabv3plus_s101-d8_512x1024_80k_cityscapes_20200807_144429-1239eb43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x1024_80k_cityscapes/deeplabv3plus_s101-d8_512x1024_80k_cityscapes-20200807_144429.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | S-101-D8 | 512x1024 | 80000 | 11.4 | 2.39 | V100 | 77.56 | 78.98 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_fcn_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x1024_80k_cityscapes/fcn_s101-d8_512x1024_80k_cityscapes_20200807_140631-f8d155b3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x1024_80k_cityscapes/fcn_s101-d8_512x1024_80k_cityscapes-20200807_140631.log.json) | +| PSPNet | S-101-D8 | 512x1024 | 80000 | 11.8 | 2.52 | V100 | 78.57 | 79.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_pspnet_4xb2-80k_cityscapes512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x1024_80k_cityscapes/pspnet_s101-d8_512x1024_80k_cityscapes_20200807_140631-c75f3b99.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x1024_80k_cityscapes/pspnet_s101-d8_512x1024_80k_cityscapes-20200807_140631.log.json) | +| DeepLabV3 | S-101-D8 | 512x1024 | 80000 | 11.9 | 1.88 | V100 | 79.67 | 80.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_deeplabv3_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x1024_80k_cityscapes/deeplabv3_s101-d8_512x1024_80k_cityscapes_20200807_144429-b73c4270.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x1024_80k_cityscapes/deeplabv3_s101-d8_512x1024_80k_cityscapes-20200807_144429.log.json) | +| DeepLabV3+ | S-101-D8 | 512x1024 | 80000 | 13.2 | 2.36 | V100 | 79.62 | 80.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_deeplabv3plus_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x1024_80k_cityscapes/deeplabv3plus_s101-d8_512x1024_80k_cityscapes_20200807_144429-1239eb43.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x1024_80k_cityscapes/deeplabv3plus_s101-d8_512x1024_80k_cityscapes-20200807_144429.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FCN | S-101-D8 | 512x512 | 160000 | 14.2 | 12.86 | V100 | 45.62 | 46.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_fcn_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x512_160k_ade20k/fcn_s101-d8_512x512_160k_ade20k_20200807_145416-d3160329.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x512_160k_ade20k/fcn_s101-d8_512x512_160k_ade20k-20200807_145416.log.json) | -| PSPNet | S-101-D8 | 512x512 | 160000 | 14.2 | 13.02 | V100 | 45.44 | 46.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_pspnet_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x512_160k_ade20k/pspnet_s101-d8_512x512_160k_ade20k_20200807_145416-a6daa92a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x512_160k_ade20k/pspnet_s101-d8_512x512_160k_ade20k-20200807_145416.log.json) | -| DeepLabV3 | S-101-D8 | 512x512 | 160000 | 14.6 | 9.28 | V100 | 45.71 | 46.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_deeplabv3_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x512_160k_ade20k/deeplabv3_s101-d8_512x512_160k_ade20k_20200807_144503-17ecabe5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x512_160k_ade20k/deeplabv3_s101-d8_512x512_160k_ade20k-20200807_144503.log.json) | -| DeepLabV3+ | S-101-D8 | 512x512 | 160000 | 16.2 | 11.96 | V100 | 46.47 | 47.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/resnest/resnest_s101-d8_deeplabv3plus_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x512_160k_ade20k/deeplabv3plus_s101-d8_512x512_160k_ade20k_20200807_144503-27b26226.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x512_160k_ade20k/deeplabv3plus_s101-d8_512x512_160k_ade20k-20200807_144503.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FCN | S-101-D8 | 512x512 | 160000 | 14.2 | 12.86 | V100 | 45.62 | 46.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_fcn_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x512_160k_ade20k/fcn_s101-d8_512x512_160k_ade20k_20200807_145416-d3160329.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/fcn_s101-d8_512x512_160k_ade20k/fcn_s101-d8_512x512_160k_ade20k-20200807_145416.log.json) | +| PSPNet | S-101-D8 | 512x512 | 160000 | 14.2 | 13.02 | V100 | 45.44 | 46.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_pspnet_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x512_160k_ade20k/pspnet_s101-d8_512x512_160k_ade20k_20200807_145416-a6daa92a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/pspnet_s101-d8_512x512_160k_ade20k/pspnet_s101-d8_512x512_160k_ade20k-20200807_145416.log.json) | +| DeepLabV3 | S-101-D8 | 512x512 | 160000 | 14.6 | 9.28 | V100 | 45.71 | 46.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_deeplabv3_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x512_160k_ade20k/deeplabv3_s101-d8_512x512_160k_ade20k_20200807_144503-17ecabe5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3_s101-d8_512x512_160k_ade20k/deeplabv3_s101-d8_512x512_160k_ade20k-20200807_144503.log.json) | +| DeepLabV3+ | S-101-D8 | 512x512 | 160000 | 16.2 | 11.96 | V100 | 46.47 | 47.27 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest/resnest_s101-d8_deeplabv3plus_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x512_160k_ade20k/deeplabv3plus_s101-d8_512x512_160k_ade20k_20200807_144503-27b26226.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/resnest/deeplabv3plus_s101-d8_512x512_160k_ade20k/deeplabv3plus_s101-d8_512x512_160k_ade20k-20200807_144503.log.json) | ## Citation diff --git a/configs/san/README.md b/configs/san/README.md new file mode 100644 index 00000000000..23e72aa65fe --- /dev/null +++ b/configs/san/README.md @@ -0,0 +1,47 @@ +# SAN + +> [Side Adapter Network for Open-Vocabulary Semantic Segmentation](https://arxiv.org/abs/2302.12242) + +## Introduction + + + +Official Repo + +## Abstract + + + +This paper presents a new framework for open-vocabulary semantic segmentation with the pre-trained vision-language model, named Side Adapter Network (SAN). Our approach models the semantic segmentation task as a region recognition problem. A side network is attached to a frozen CLIP model with two branches: one for predicting mask proposals, and the other for predicting attention bias which is applied in the CLIP model to recognize the class of masks. This decoupled design has the benefit CLIP in recognizing the class of mask proposals. Since the attached side network can reuse CLIP features, it can be very light. In addition, the entire network can be trained end-to-end, allowing the side network to be adapted to the frozen CLIP model, which makes the predicted mask proposals CLIP-aware. Our approach is fast, accurate, and only adds a few additional trainable parameters. We evaluate our approach on multiple semantic segmentation benchmarks. Our method significantly outperforms other counterparts, with up to 18 times fewer trainable parameters and 19 times faster inference speed. We hope our approach will serve as a solid baseline and help ease future research in open-vocabulary semantic segmentation. + + + +
+ +
+ +## Results and models + +### COCO-Stuff164k + +| Method | Backbone | Pretrained | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | ------------ | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| SAN | ViT-B_16 | CLIP_ViT-B16 | 640x640 | 60000 | 12.61 | - | V100 | 41.93 | 41.77 | - | [model](https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-b16_20230906-fd0a7684.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-b16_20230906.log) | +| SAN | ViT-L_14 | CLIP_ViT-L14 | 640x640 | 60000 | 22.84 | - | V100 | 45.78 | 43.99 | - | [model](https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-l14_20230907-a11e098f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-l14_20230907.log) | + +## Notes + +git push +The pretrained weights in config files are converted from open_clip models using tools/model_converters/clip2mmseg.py. + +## Citation + +```bibtex +@inproceedings{xu2023side, + title={Side adapter network for open-vocabulary semantic segmentation}, + author={Xu, Mengde and Zhang, Zheng and Wei, Fangyun and Hu, Han and Bai, Xiang}, + booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition}, + pages={2945--2954}, + year={2023} +} +``` diff --git a/configs/san/metafile.yaml b/configs/san/metafile.yaml new file mode 100644 index 00000000000..117d088af03 --- /dev/null +++ b/configs/san/metafile.yaml @@ -0,0 +1,61 @@ +Collections: +- Name: SAN + License: Apache License 2.0 + Metadata: + Training Data: + - COCO-Stuff 164k + Paper: + Title: 'Side Adapter Network for Open-Vocabulary Semantic Segmentation' + URL: https://arxiv.org/abs/2302.12242 + README: configs/san/README.md + Frameworks: + - PyTorch +Models: +- Name: san-vit-b16_coco-stuff164k-640x640 + In Collection: SAN + Results: + Task: Semantic Segmentation + Dataset: COCO-Stuff 164k + Metrics: + mIoU: 41.93 + mIoU(ms+flip): 41.77 + Config: configs/san/san-vit-b16_coco-stuff164k-640x640.py + Metadata: + Training Data: COCO-Stuff 164k + Batch Size: 16 + Architecture: + - SAN + - ViT + Training Resources: 8x V100 GPUS + Memory (GB): 12.61 + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-b16_20230906-fd0a7684.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-b16_20230906.log + Paper: + Title: 'Side Adapter Network for Open-Vocabulary Semantic Segmentation' + URL: https://arxiv.org/abs/2302.12242 + Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/san_head.py#L470 + Framework: PyTorch +- Name: san-vit-l14_coco-stuff164k-640x640 + In Collection: SAN + Results: + Task: Semantic Segmentation + Dataset: COCO-Stuff 164k + Metrics: + mIoU: 45.78 + mIoU(ms+flip): 43.99 + Config: configs/san/san-vit-l14_coco-stuff164k-640x640.py + Metadata: + Training Data: COCO-Stuff 164k + Batch Size: 16 + Architecture: + - SAN + - ViT + Training Resources: 8x V100 GPUS + Memory (GB): 12.61 + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-l14_20230907-a11e098f.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/san/san-vit-l14_20230907.log + Paper: + Title: 'Side Adapter Network for Open-Vocabulary Semantic Segmentation' + URL: https://arxiv.org/abs/2302.12242 + Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/san_head.py#L470 + Framework: PyTorch diff --git a/configs/san/san-vit-b16_coco-stuff164k-640x640.py b/configs/san/san-vit-b16_coco-stuff164k-640x640.py new file mode 100644 index 00000000000..40592486d1e --- /dev/null +++ b/configs/san/san-vit-b16_coco-stuff164k-640x640.py @@ -0,0 +1,82 @@ +_base_ = [ + '../_base_/models/san_vit-b16.py', '../_base_/datasets/coco-stuff164k.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_160k.py' +] +crop_size = (640, 640) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict( + type='RandomChoiceResize', + scales=[int(640 * x * 0.1) for x in range(5, 16)], + resize_type='ResizeShortestEdge', + max_size=2560), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=1.0), + dict(type='PhotoMetricDistortion'), + dict(type='RandomFlip', prob=0.5), + dict(type='PackSegInputs') +] + +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='ResizeShortestEdge', scale=crop_size, max_size=2560), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] + +# By default, models are trained on 4 GPUs with 8 images per GPU +train_dataloader = dict(batch_size=8, dataset=dict(pipeline=train_pipeline)) +val_dataloader = dict(batch_size=1, dataset=dict(pipeline=test_pipeline)) +test_dataloader = val_dataloader + +pretrained = 'https://download.openmmlab.com/mmsegmentation/v0.5/san/clip_vit-base-patch16-224_3rdparty-d08f8887.pth' # noqa +data_preprocessor = dict( + mean=[122.7709, 116.7460, 104.0937], + std=[68.5005, 66.6322, 70.3232], + size_divisor=640, + test_cfg=dict(size_divisor=32)) +model = dict( + pretrained=pretrained, + text_encoder=dict(dataset_name='coco-stuff164k'), + decode_head=dict(num_classes=171)) + +# training schedule for 60k +train_cfg = dict( + type='IterBasedTrainLoop', + max_iters=60000, + val_interval=500, + val_begin=55000) +default_hooks = dict( + checkpoint=dict( + type='CheckpointHook', + by_epoch=False, + interval=10000, + save_best='mIoU')) + +# AdamW optimizer, no weight decay for position embedding & layer norm +# in backbone +optim_wrapper = dict( + _delete_=True, + type='AmpOptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0001, betas=(0.9, 0.999), weight_decay=0.0001), + paramwise_cfg=dict( + custom_keys={ + 'img_encoder': dict(lr_mult=0.1, decay_mult=1.0), + 'pos_embed': dict(decay_mult=0.), + 'cls_token': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + }), + loss_scale='dynamic', + clip_grad=dict(max_norm=0.01, norm_type=2)) + +param_scheduler = [ + dict( + type='PolyLR', + eta_min=0.0, + power=1.0, + begin=0, + end=60000, + by_epoch=False, + ) +] diff --git a/configs/san/san-vit-b16_pascal_context-640x640.py b/configs/san/san-vit-b16_pascal_context-640x640.py new file mode 100644 index 00000000000..b164fe41fd9 --- /dev/null +++ b/configs/san/san-vit-b16_pascal_context-640x640.py @@ -0,0 +1,56 @@ +_base_ = [ + '../_base_/models/san_vit-b16.py', + '../_base_/datasets/pascal_context_59.py', '../_base_/default_runtime.py', + '../_base_/schedules/schedule_160k.py' +] +crop_size = (640, 640) + +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='ResizeShortestEdge', scale=crop_size, max_size=2560), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] + +# By default, models are trained on 8 GPUs with 2 images per GPU +train_dataloader = dict(batch_size=2) +val_dataloader = dict(batch_size=1, dataset=dict(pipeline=test_pipeline)) +test_dataloader = val_dataloader + +data_preprocessor = dict( + mean=[122.7709, 116.7460, 104.0937], + std=[68.5005, 66.6322, 70.3232], + size_divisor=640, + test_cfg=dict(size_divisor=32)) +model = dict( + data_preprocessor=data_preprocessor, + pretrained='pretrain/vit_base_patch16_224.pth', + text_encoder=dict(dataset_name='pascal_context'), + decode_head=dict(num_classes=59)) + +# AdamW optimizer, no weight decay for position embedding & layer norm +# in backbone +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01), + paramwise_cfg=dict( + custom_keys={ + 'pos_embed': dict(decay_mult=0.), + 'cls_token': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + })) + +param_scheduler = [ + dict( + type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500), + dict( + type='PolyLR', + eta_min=0.0, + power=1.0, + begin=1500, + end=160000, + by_epoch=False, + ) +] diff --git a/configs/san/san-vit-b16_voc12aug-640x640.py b/configs/san/san-vit-b16_voc12aug-640x640.py new file mode 100644 index 00000000000..62e9b26f0af --- /dev/null +++ b/configs/san/san-vit-b16_voc12aug-640x640.py @@ -0,0 +1,65 @@ +_base_ = [ + '../_base_/models/san_vit-b16.py', + '../_base_/datasets/pascal_voc12_aug.py', '../_base_/default_runtime.py', + '../_base_/schedules/schedule_160k.py' +] +crop_size = (640, 640) + +metainfo = dict( + classes=('aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', + 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', + 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'), + palette=[[128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], + [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0], + [192, 0, 0], [64, 128, 0], [192, 128, 0], [64, 0, 128], + [192, 0, 128], [64, 128, 128], [192, 128, 128], [0, 64, 0], + [128, 64, 0], [0, 192, 0], [128, 192, 0], [0, 64, 128]]) +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='ResizeShortestEdge', scale=crop_size, max_size=2560), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +# By default, models are trained on 8 GPUs with 2 images per GPU +train_dataloader = dict(batch_size=2) +val_dataloader = dict( + batch_size=1, dataset=dict(metainfo=metainfo, pipeline=test_pipeline)) +test_dataloader = val_dataloader + +data_preprocessor = dict( + mean=[122.7709, 116.7460, 104.0937], + std=[68.5005, 66.6322, 70.3232], + size_divisor=640, + test_cfg=dict(size_divisor=32)) +model = dict( + data_preprocessor=data_preprocessor, + pretrained='pretrain/vit_base_patch16_224.pth', + text_encoder=dict(dataset_name='voc'), + decode_head=dict(num_classes=20)) + +# AdamW optimizer, no weight decay for position embedding & layer norm +# in backbone +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01), + paramwise_cfg=dict( + custom_keys={ + 'pos_embed': dict(decay_mult=0.), + 'cls_token': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + })) + +param_scheduler = [ + dict( + type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500), + dict( + type='PolyLR', + eta_min=0.0, + power=1.0, + begin=1500, + end=160000, + by_epoch=False, + ) +] diff --git a/configs/san/san-vit-l14_coco-stuff164k-640x640.py b/configs/san/san-vit-l14_coco-stuff164k-640x640.py new file mode 100644 index 00000000000..c34328db3fe --- /dev/null +++ b/configs/san/san-vit-l14_coco-stuff164k-640x640.py @@ -0,0 +1,36 @@ +_base_ = ['./san-vit-b16_coco-stuff164k-640x640.py'] + +pretrained = 'https://download.openmmlab.com/mmsegmentation/v0.5/san/clip_vit-large-patch14-336_3rdparty-0b5df9cb.pth' # noqa +model = dict( + type='MultimodalEncoderDecoder', + pretrained=pretrained, + encoder_resolution=0.7, + image_encoder=dict( + type='VisionTransformer', + img_size=(336, 336), + patch_size=14, + patch_pad=0, + embed_dims=1024, + num_layers=18, + num_heads=16, + out_indices=(5, 11, 17), + ), + text_encoder=dict( + type='CLIPTextEncoder', + embed_dims=768, + num_layers=12, + num_heads=12, + output_dims=768, + ), + decode_head=dict( + type='SideAdapterCLIPHead', + san_cfg=dict(clip_channels=1024, cfg_decoder=dict(num_heads=16)), + maskgen_cfg=dict( + num_layers=6, + embed_dims=1024, + num_heads=16, + out_dims=768, + ))) + +# By default, models are trained on 8 GPUs with 4 images per GPU +train_dataloader = dict(batch_size=4) diff --git a/configs/san/san-vit-l14_pascal_context-640x640.py b/configs/san/san-vit-l14_pascal_context-640x640.py new file mode 100644 index 00000000000..a9545fac8e0 --- /dev/null +++ b/configs/san/san-vit-l14_pascal_context-640x640.py @@ -0,0 +1,32 @@ +_base_ = ['./san-vit-b16_pascal_context-640x640.py'] + +model = dict( + type='MultimodalEncoderDecoder', + pretrained='pretrain/jx_vit_base_p16_224-80ecf9dd.pth', + encoder_resolution=0.7, + image_encoder=dict( + type='VisionTransformer', + img_size=(336, 336), + patch_size=14, + patch_pad=0, + embed_dims=1024, + num_layers=18, + num_heads=16, + out_indices=(5, 11, 17), + ), + text_encoder=dict( + type='CLIPTextEncoder', + embed_dims=768, + num_layers=12, + num_heads=12, + output_dims=768, + ), + decode_head=dict( + type='SideAdapterCLIPHead', + san_cfg=dict(clip_channels=1024, cfg_decoder=dict(num_heads=16)), + maskgen_cfg=dict( + num_layers=6, + embed_dims=1024, + num_heads=16, + out_dims=768, + ))) diff --git a/configs/san/san-vit-l14_voc12aug-640x640.py b/configs/san/san-vit-l14_voc12aug-640x640.py new file mode 100644 index 00000000000..2f377150394 --- /dev/null +++ b/configs/san/san-vit-l14_voc12aug-640x640.py @@ -0,0 +1,32 @@ +_base_ = ['./san-vit-b16_voc12aug-640x640.py'] + +model = dict( + type='MultimodalEncoderDecoder', + pretrained='pretrain/jx_vit_base_p16_224-80ecf9dd.pth', + encoder_resolution=0.7, + image_encoder=dict( + type='VisionTransformer', + img_size=(336, 336), + patch_size=14, + patch_pad=0, + embed_dims=1024, + num_layers=18, + num_heads=16, + out_indices=(5, 11, 17), + ), + text_encoder=dict( + type='CLIPTextEncoder', + embed_dims=768, + num_layers=12, + num_heads=12, + output_dims=768, + ), + decode_head=dict( + type='SideAdapterCLIPHead', + san_cfg=dict(clip_channels=1024, cfg_decoder=dict(num_heads=16)), + maskgen_cfg=dict( + num_layers=6, + embed_dims=1024, + num_heads=16, + out_dims=768, + ))) diff --git a/configs/segformer/README.md b/configs/segformer/README.md index 5dbf1215bc3..f8999b0efa5 100644 --- a/configs/segformer/README.md +++ b/configs/segformer/README.md @@ -38,15 +38,15 @@ This script convert model from `PRETRAIN_PATH` and store the converted model in ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------: | -------------- | -------- | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Segformer | MIT-B0 | 512x512 | 160000 | 2.1 | 51.32 | 1080 Ti | 37.41 | 38.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_512x512_160k_ade20k/segformer_mit-b0_512x512_160k_ade20k_20210726_101530-8ffa8fda.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_512x512_160k_ade20k/segformer_mit-b0_512x512_160k_ade20k_20210726_101530.log.json) | -| Segformer | MIT-B1 | 512x512 | 160000 | 2.6 | 47.66 | TITAN Xp | 40.97 | 42.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_512x512_160k_ade20k/segformer_mit-b1_512x512_160k_ade20k_20210726_112106-d70e859d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_512x512_160k_ade20k/segformer_mit-b1_512x512_160k_ade20k_20210726_112106.log.json) | -| Segformer | MIT-B2 | 512x512 | 160000 | 3.6 | 30.88 | TITAN Xp | 45.58 | 47.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_512x512_160k_ade20k/segformer_mit-b2_512x512_160k_ade20k_20210726_112103-cbd414ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_512x512_160k_ade20k/segformer_mit-b2_512x512_160k_ade20k_20210726_112103.log.json) | -| Segformer | MIT-B3 | 512x512 | 160000 | 4.8 | 22.11 | V100 | 47.82 | 48.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_512x512_160k_ade20k/segformer_mit-b3_512x512_160k_ade20k_20210726_081410-962b98d2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_512x512_160k_ade20k/segformer_mit-b3_512x512_160k_ade20k_20210726_081410.log.json) | -| Segformer | MIT-B4 | 512x512 | 160000 | 6.1 | 15.45 | V100 | 48.46 | 49.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_512x512_160k_ade20k/segformer_mit-b4_512x512_160k_ade20k_20210728_183055-7f509d7d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_512x512_160k_ade20k/segformer_mit-b4_512x512_160k_ade20k_20210728_183055.log.json) | -| Segformer | MIT-B5 | 512x512 | 160000 | 7.2 | 11.89 | V100 | 49.13 | 50.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_512x512_160k_ade20k/segformer_mit-b5_512x512_160k_ade20k_20210726_145235-94cedf59.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_512x512_160k_ade20k/segformer_mit-b5_512x512_160k_ade20k_20210726_145235.log.json) | -| Segformer | MIT-B5 | 640x640 | 160000 | 11.5 | 11.30 | V100 | 49.62 | 50.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_640x640_160k_ade20k/segformer_mit-b5_640x640_160k_ade20k_20210801_121243-41d2845b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_640x640_160k_ade20k/segformer_mit-b5_640x640_160k_ade20k_20210801_121243.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------: | -------------- | -------- | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Segformer | MIT-B0 | 512x512 | 160000 | 2.1 | 51.32 | 1080 Ti | 37.41 | 38.34 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_512x512_160k_ade20k/segformer_mit-b0_512x512_160k_ade20k_20210726_101530-8ffa8fda.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_512x512_160k_ade20k/segformer_mit-b0_512x512_160k_ade20k_20210726_101530.log.json) | +| Segformer | MIT-B1 | 512x512 | 160000 | 2.6 | 47.66 | TITAN Xp | 40.97 | 42.54 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_512x512_160k_ade20k/segformer_mit-b1_512x512_160k_ade20k_20210726_112106-d70e859d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_512x512_160k_ade20k/segformer_mit-b1_512x512_160k_ade20k_20210726_112106.log.json) | +| Segformer | MIT-B2 | 512x512 | 160000 | 3.6 | 30.88 | TITAN Xp | 45.58 | 47.03 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_512x512_160k_ade20k/segformer_mit-b2_512x512_160k_ade20k_20210726_112103-cbd414ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_512x512_160k_ade20k/segformer_mit-b2_512x512_160k_ade20k_20210726_112103.log.json) | +| Segformer | MIT-B3 | 512x512 | 160000 | 4.8 | 22.11 | V100 | 47.82 | 48.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_512x512_160k_ade20k/segformer_mit-b3_512x512_160k_ade20k_20210726_081410-962b98d2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_512x512_160k_ade20k/segformer_mit-b3_512x512_160k_ade20k_20210726_081410.log.json) | +| Segformer | MIT-B4 | 512x512 | 160000 | 6.1 | 15.45 | V100 | 48.46 | 49.76 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_512x512_160k_ade20k/segformer_mit-b4_512x512_160k_ade20k_20210728_183055-7f509d7d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_512x512_160k_ade20k/segformer_mit-b4_512x512_160k_ade20k_20210728_183055.log.json) | +| Segformer | MIT-B5 | 512x512 | 160000 | 7.2 | 11.89 | V100 | 49.13 | 50.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_512x512_160k_ade20k/segformer_mit-b5_512x512_160k_ade20k_20210726_145235-94cedf59.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_512x512_160k_ade20k/segformer_mit-b5_512x512_160k_ade20k_20210726_145235.log.json) | +| Segformer | MIT-B5 | 640x640 | 160000 | 11.5 | 11.30 | V100 | 49.62 | 50.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_640x640_160k_ade20k/segformer_mit-b5_640x640_160k_ade20k_20210801_121243-41d2845b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_640x640_160k_ade20k/segformer_mit-b5_640x640_160k_ade20k_20210801_121243.log.json) | Evaluation with AlignedResize: @@ -80,14 +80,14 @@ test_pipeline = [ The lower fps result is caused by the sliding window inference scheme (window size:1024x1024). -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Segformer | MIT-B0 | 1024x1024 | 160000 | 3.64 | 4.74 | V100 | 76.54 | 78.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes/segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes/segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857.log.json) | -| Segformer | MIT-B1 | 1024x1024 | 160000 | 4.49 | 4.3 | V100 | 78.56 | 79.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_8x1_1024x1024_160k_cityscapes/segformer_mit-b1_8x1_1024x1024_160k_cityscapes_20211208_064213-655c7b3f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_8x1_1024x1024_160k_cityscapes/segformer_mit-b1_8x1_1024x1024_160k_cityscapes_20211208_064213.log.json) | -| Segformer | MIT-B2 | 1024x1024 | 160000 | 7.42 | 3.36 | V100 | 81.08 | 82.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_8x1_1024x1024_160k_cityscapes/segformer_mit-b2_8x1_1024x1024_160k_cityscapes_20211207_134205-6096669a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_8x1_1024x1024_160k_cityscapes/segformer_mit-b2_8x1_1024x1024_160k_cityscapes_20211207_134205.log.json) | -| Segformer | MIT-B3 | 1024x1024 | 160000 | 10.86 | 2.53 | V100 | 81.94 | 83.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_8x1_1024x1024_160k_cityscapes/segformer_mit-b3_8x1_1024x1024_160k_cityscapes_20211206_224823-a8f8a177.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_8x1_1024x1024_160k_cityscapes/segformer_mit-b3_8x1_1024x1024_160k_cityscapes_20211206_224823.log.json) | -| Segformer | MIT-B4 | 1024x1024 | 160000 | 15.07 | 1.88 | V100 | 81.89 | 83.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_8x1_1024x1024_160k_cityscapes/segformer_mit-b4_8x1_1024x1024_160k_cityscapes_20211207_080709-07f6c333.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_8x1_1024x1024_160k_cityscapes/segformer_mit-b4_8x1_1024x1024_160k_cityscapes_20211207_080709.log.json) | -| Segformer | MIT-B5 | 1024x1024 | 160000 | 18.00 | 1.39 | V100 | 82.25 | 83.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_8x1_1024x1024_160k_cityscapes/segformer_mit-b5_8x1_1024x1024_160k_cityscapes_20211206_072934-87a052ec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_8x1_1024x1024_160k_cityscapes/segformer_mit-b5_8x1_1024x1024_160k_cityscapes_20211206_072934.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| --------- | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Segformer | MIT-B0 | 1024x1024 | 160000 | 3.64 | 4.74 | V100 | 76.54 | 78.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes/segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857-e7f88502.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b0_8x1_1024x1024_160k_cityscapes/segformer_mit-b0_8x1_1024x1024_160k_cityscapes_20211208_101857.log.json) | +| Segformer | MIT-B1 | 1024x1024 | 160000 | 4.49 | 4.3 | V100 | 78.56 | 79.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_8x1_1024x1024_160k_cityscapes/segformer_mit-b1_8x1_1024x1024_160k_cityscapes_20211208_064213-655c7b3f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b1_8x1_1024x1024_160k_cityscapes/segformer_mit-b1_8x1_1024x1024_160k_cityscapes_20211208_064213.log.json) | +| Segformer | MIT-B2 | 1024x1024 | 160000 | 7.42 | 3.36 | V100 | 81.08 | 82.18 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_8x1_1024x1024_160k_cityscapes/segformer_mit-b2_8x1_1024x1024_160k_cityscapes_20211207_134205-6096669a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b2_8x1_1024x1024_160k_cityscapes/segformer_mit-b2_8x1_1024x1024_160k_cityscapes_20211207_134205.log.json) | +| Segformer | MIT-B3 | 1024x1024 | 160000 | 10.86 | 2.53 | V100 | 81.94 | 83.14 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_8x1_1024x1024_160k_cityscapes/segformer_mit-b3_8x1_1024x1024_160k_cityscapes_20211206_224823-a8f8a177.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b3_8x1_1024x1024_160k_cityscapes/segformer_mit-b3_8x1_1024x1024_160k_cityscapes_20211206_224823.log.json) | +| Segformer | MIT-B4 | 1024x1024 | 160000 | 15.07 | 1.88 | V100 | 81.89 | 83.38 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_8x1_1024x1024_160k_cityscapes/segformer_mit-b4_8x1_1024x1024_160k_cityscapes_20211207_080709-07f6c333.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b4_8x1_1024x1024_160k_cityscapes/segformer_mit-b4_8x1_1024x1024_160k_cityscapes_20211207_080709.log.json) | +| Segformer | MIT-B5 | 1024x1024 | 160000 | 18.00 | 1.39 | V100 | 82.25 | 83.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_8x1_1024x1024_160k_cityscapes/segformer_mit-b5_8x1_1024x1024_160k_cityscapes_20211206_072934-87a052ec.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segformer/segformer_mit-b5_8x1_1024x1024_160k_cityscapes/segformer_mit-b5_8x1_1024x1024_160k_cityscapes_20211206_072934.log.json) | ## Citation diff --git a/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py index 9f6bd1e81d0..1280047c942 100644 --- a/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py @@ -5,10 +5,10 @@ ] crop_size = (1024, 1024) data_preprocessor = dict(size=crop_size) +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b0_20220624-7e0fe6dd.pth' # noqa model = dict( data_preprocessor=data_preprocessor, - backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b0.pth')), + backbone=dict(init_cfg=dict(type='Pretrained', checkpoint=checkpoint)), test_cfg=dict(mode='slide', crop_size=(1024, 1024), stride=(768, 768))) optim_wrapper = dict( diff --git a/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py index 607e2848ee5..4a9476df684 100644 --- a/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b0_8xb2-160k_ade20k-512x512.py @@ -4,9 +4,10 @@ ] crop_size = (512, 512) data_preprocessor = dict(size=crop_size) +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b0_20220624-7e0fe6dd.pth' # noqa model = dict( data_preprocessor=data_preprocessor, - pretrained='pretrain/mit_b0.pth', + backbone=dict(init_cfg=dict(type='Pretrained', checkpoint=checkpoint)), decode_head=dict(num_classes=150)) optim_wrapper = dict( diff --git a/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py index d6977d4678b..85c126ead42 100644 --- a/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b1_8xb1-160k_cityscapes-1024x1024.py @@ -1,7 +1,9 @@ _base_ = ['./segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b1_20220624-02e5a6a1.pth' # noqa + model = dict( backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b1.pth'), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), embed_dims=64), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py index 3bedca98913..1ff21b8becf 100644 --- a/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b1_8xb2-160k_ade20k-512x512.py @@ -1,8 +1,12 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b1_20220624-02e5a6a1.pth' # noqa + # model settings model = dict( - pretrained='pretrain/mit_b1.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[2, 2, 2, 2]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[2, 2, 2, 2]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py index 94f5ad33a56..c802f275b57 100644 --- a/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b2_8xb1-160k_cityscapes-1024x1024.py @@ -1,8 +1,10 @@ _base_ = ['./segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b2_20220624-66e8bf70.pth' # noqa + model = dict( backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b2.pth'), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), embed_dims=64, num_layers=[3, 4, 6, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py index 2c3bb101d3f..0f4c1af061f 100644 --- a/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b2_8xb2-160k_ade20k-512x512.py @@ -1,8 +1,12 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b2_20220624-66e8bf70.pth' # noqa + # model settings model = dict( - pretrained='pretrain/mit_b2.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[3, 4, 6, 3]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[3, 4, 6, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py index 87ec0a599d5..9b41ad0b391 100644 --- a/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b3_8xb1-160k_cityscapes-1024x1024.py @@ -1,8 +1,10 @@ _base_ = ['./segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b3_20220624-13b1141c.pth' # noqa + model = dict( backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b3.pth'), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), embed_dims=64, num_layers=[3, 4, 18, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py index 31f5fc1c12d..a2cc13d847d 100644 --- a/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b3_8xb2-160k_ade20k-512x512.py @@ -1,8 +1,12 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b3_20220624-13b1141c.pth' # noqa + # model settings model = dict( - pretrained='pretrain/mit_b3.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[3, 4, 18, 3]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[3, 4, 18, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py index e4f436b264a..5fb16080dd5 100644 --- a/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b4_8xb1-160k_cityscapes-1024x1024.py @@ -1,8 +1,10 @@ _base_ = ['./segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b4_20220624-d588d980.pth' # noqa + model = dict( backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b4.pth'), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), embed_dims=64, num_layers=[3, 8, 27, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py index 0015e1623a8..5f39c301080 100644 --- a/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b4_8xb2-160k_ade20k-512x512.py @@ -1,8 +1,12 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b4_20220624-d588d980.pth' # noqa + # model settings model = dict( - pretrained='pretrain/mit_b4.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[3, 8, 27, 3]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[3, 8, 27, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py b/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py index 7fb2ea5b4e1..18c3c162588 100644 --- a/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py +++ b/configs/segformer/segformer_mit-b5_8xb1-160k_cityscapes-1024x1024.py @@ -1,8 +1,10 @@ _base_ = ['./segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b5_20220624-658746d9.pth' # noqa + model = dict( backbone=dict( - init_cfg=dict(type='Pretrained', checkpoint='pretrain/mit_b5.pth'), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), embed_dims=64, num_layers=[3, 6, 40, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py b/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py index 09bb260223e..1e9a209ebea 100644 --- a/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py +++ b/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-512x512.py @@ -1,8 +1,12 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b5_20220624-658746d9.pth' # noqa + # model settings model = dict( - pretrained='pretrain/mit_b5.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[3, 6, 40, 3]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[3, 6, 40, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py b/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py index 3bba3716ef6..a32eb7c1e1a 100644 --- a/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py +++ b/configs/segformer/segformer_mit-b5_8xb2-160k_ade20k-640x640.py @@ -1,5 +1,7 @@ _base_ = ['./segformer_mit-b0_8xb2-160k_ade20k-512x512.py'] +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/segformer/mit_b5_20220624-658746d9.pth' # noqa + # dataset settings crop_size = (640, 640) data_preprocessor = dict(size=crop_size) @@ -31,7 +33,9 @@ # model settings model = dict( data_preprocessor=data_preprocessor, - pretrained='pretrain/mit_b5.pth', backbone=dict( - embed_dims=64, num_heads=[1, 2, 5, 8], num_layers=[3, 6, 40, 3]), + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + embed_dims=64, + num_heads=[1, 2, 5, 8], + num_layers=[3, 6, 40, 3]), decode_head=dict(in_channels=[64, 128, 320, 512])) diff --git a/configs/segmenter/README.md b/configs/segmenter/README.md index a9a64ae4211..103b1254729 100644 --- a/configs/segmenter/README.md +++ b/configs/segmenter/README.md @@ -55,13 +55,13 @@ In our default setting, pretrained models and their corresponding [ViT-AugReg](h ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Segmenter Mask | ViT-T_16 | 512x512 | 160000 | 1.21 | 27.98 | V100 | 39.99 | 40.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segmenter/segmenter_vit-t_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-t_mask_8x1_512x512_160k_ade20k/segmenter_vit-t_mask_8x1_512x512_160k_ade20k_20220105_151706-ffcf7509.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-t_mask_8x1_512x512_160k_ade20k/segmenter_vit-t_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | -| Segmenter Linear | ViT-S_16 | 512x512 | 160000 | 1.78 | 28.07 | V100 | 45.75 | 46.82 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segmenter/segmenter_vit-s_fcn_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_linear_8x1_512x512_160k_ade20k/segmenter_vit-s_linear_8x1_512x512_160k_ade20k_20220105_151713-39658c46.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_linear_8x1_512x512_160k_ade20k/segmenter_vit-s_linear_8x1_512x512_160k_ade20k_20220105_151713.log.json) | -| Segmenter Mask | ViT-S_16 | 512x512 | 160000 | 2.03 | 24.80 | V100 | 46.19 | 47.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segmenter/segmenter_vit-s_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_mask_8x1_512x512_160k_ade20k/segmenter_vit-s_mask_8x1_512x512_160k_ade20k_20220105_151706-511bb103.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_mask_8x1_512x512_160k_ade20k/segmenter_vit-s_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | -| Segmenter Mask | ViT-B_16 | 512x512 | 160000 | 4.20 | 13.20 | V100 | 49.60 | 51.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segmenter/segmenter_vit-b_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-b_mask_8x1_512x512_160k_ade20k/segmenter_vit-b_mask_8x1_512x512_160k_ade20k_20220105_151706-bc533b08.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-b_mask_8x1_512x512_160k_ade20k/segmenter_vit-b_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | -| Segmenter Mask | ViT-L_16 | 640x640 | 160000 | 16.56 | 2.62 | V100 | 52.16 | 53.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segmenter/segmenter_vit-l_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-l_mask_8x1_512x512_160k_ade20k/segmenter_vit-l_mask_8x1_512x512_160k_ade20k_20220105_162750-7ef345be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-l_mask_8x1_512x512_160k_ade20k/segmenter_vit-l_mask_8x1_512x512_160k_ade20k_20220105_162750.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Segmenter Mask | ViT-T_16 | 512x512 | 160000 | 1.21 | 27.98 | V100 | 39.99 | 40.83 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter/segmenter_vit-t_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-t_mask_8x1_512x512_160k_ade20k/segmenter_vit-t_mask_8x1_512x512_160k_ade20k_20220105_151706-ffcf7509.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-t_mask_8x1_512x512_160k_ade20k/segmenter_vit-t_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | +| Segmenter Linear | ViT-S_16 | 512x512 | 160000 | 1.78 | 28.07 | V100 | 45.75 | 46.82 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter/segmenter_vit-s_fcn_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_linear_8x1_512x512_160k_ade20k/segmenter_vit-s_linear_8x1_512x512_160k_ade20k_20220105_151713-39658c46.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_linear_8x1_512x512_160k_ade20k/segmenter_vit-s_linear_8x1_512x512_160k_ade20k_20220105_151713.log.json) | +| Segmenter Mask | ViT-S_16 | 512x512 | 160000 | 2.03 | 24.80 | V100 | 46.19 | 47.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter/segmenter_vit-s_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_mask_8x1_512x512_160k_ade20k/segmenter_vit-s_mask_8x1_512x512_160k_ade20k_20220105_151706-511bb103.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-s_mask_8x1_512x512_160k_ade20k/segmenter_vit-s_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | +| Segmenter Mask | ViT-B_16 | 512x512 | 160000 | 4.20 | 13.20 | V100 | 49.60 | 51.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter/segmenter_vit-b_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-b_mask_8x1_512x512_160k_ade20k/segmenter_vit-b_mask_8x1_512x512_160k_ade20k_20220105_151706-bc533b08.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-b_mask_8x1_512x512_160k_ade20k/segmenter_vit-b_mask_8x1_512x512_160k_ade20k_20220105_151706.log.json) | +| Segmenter Mask | ViT-L_16 | 640x640 | 160000 | 16.56 | 2.62 | V100 | 52.16 | 53.65 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter/segmenter_vit-l_mask_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-l_mask_8x1_512x512_160k_ade20k/segmenter_vit-l_mask_8x1_512x512_160k_ade20k_20220105_162750-7ef345be.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segmenter/segmenter_vit-l_mask_8x1_512x512_160k_ade20k/segmenter_vit-l_mask_8x1_512x512_160k_ade20k_20220105_162750.log.json) | ## Citation diff --git a/configs/segnext/README.md b/configs/segnext/README.md index 06b63be5467..d7434a06213 100644 --- a/configs/segnext/README.md +++ b/configs/segnext/README.md @@ -8,7 +8,7 @@ Official Repo -Code Snippet +Code Snippet ## Abstract @@ -26,12 +26,12 @@ We present SegNeXt, a simple convolutional network architecture for semantic seg ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| SegNeXt | MSCAN-T | 512x512 | 160000 | 17.88 | 52.38 | A100 | 41.50 | 42.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segnext/segnext_mscan-t_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k_20230210_140244-05bd8466.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k_20230210_140244.log.json) | -| SegNeXt | MSCAN-S | 512x512 | 160000 | 21.47 | 42.27 | A100 | 44.16 | 45.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segnext/segnext_mscan-s_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k_20230214_113014-43013668.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k_20230214_113014.log.json) | -| SegNeXt | MSCAN-B | 512x512 | 160000 | 31.03 | 35.15 | A100 | 48.03 | 49.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segnext/segnext_mscan-b_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k_20230209_172053-b6f6c70c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k_20230209_172053.log.json) | -| SegNeXt | MSCAN-L | 512x512 | 160000 | 43.32 | 22.91 | A100 | 50.99 | 52.10 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/segnext/segnext_mscan-l_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k_20230209_172055-19b14b63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k_20230209_172055.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| SegNeXt | MSCAN-T | 512x512 | 160000 | 17.88 | 52.38 | A100 | 41.50 | 42.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segnext/segnext_mscan-t_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k_20230210_140244-05bd8466.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k/segnext_mscan-t_1x16_512x512_adamw_160k_ade20k_20230210_140244.log.json) | +| SegNeXt | MSCAN-S | 512x512 | 160000 | 21.47 | 42.27 | A100 | 44.16 | 45.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segnext/segnext_mscan-s_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k_20230214_113014-43013668.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k/segnext_mscan-s_1x16_512x512_adamw_160k_ade20k_20230214_113014.log.json) | +| SegNeXt | MSCAN-B | 512x512 | 160000 | 31.03 | 35.15 | A100 | 48.03 | 49.68 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segnext/segnext_mscan-b_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k_20230209_172053-b6f6c70c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k/segnext_mscan-b_1x16_512x512_adamw_160k_ade20k_20230209_172053.log.json) | +| SegNeXt | MSCAN-L | 512x512 | 160000 | 43.32 | 22.91 | A100 | 50.99 | 52.10 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segnext/segnext_mscan-l_1xb16-adamw-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k_20230209_172055-19b14b63.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/segnext/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k/segnext_mscan-l_1x16_512x512_adamw_160k_ade20k_20230209_172055.log.json) | Note: @@ -39,7 +39,7 @@ Note: - The total batch size is 16. We trained for SegNeXt with a single GPU as the performance degrades significantly when using`SyncBN` (mainly in `OverlapPatchEmbed` modules of `MSCAN`) of PyTorch 1.9. -- There will be subtle differences when model testing as Non-negative Matrix Factorization (NMF) in `LightHamHead` will be initialized randomly. To control this randomness, please set the random seed when model testing. You can modify [`./tools/test.py`](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/tools/test.py) like: +- There will be subtle differences when model testing as Non-negative Matrix Factorization (NMF) in `LightHamHead` will be initialized randomly. To control this randomness, please set the random seed when model testing. You can modify [`./tools/test.py`](https://github.com/open-mmlab/mmsegmentation/blob/main/tools/test.py) like: ```python def main(): diff --git a/configs/segnext/metafile.yaml b/configs/segnext/metafile.yaml index faa11c97846..3c8ff5bb92c 100644 --- a/configs/segnext/metafile.yaml +++ b/configs/segnext/metafile.yaml @@ -33,7 +33,7 @@ Models: Paper: Title: 'SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation' URL: https://arxiv.org/abs/2209.08575 - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/mscan.py#L328 + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/mscan.py#L328 Framework: PyTorch - Name: segnext_mscan-s_1xb16-adamw-160k_ade20k-512x512 In Collection: SegNeXt @@ -57,7 +57,7 @@ Models: Paper: Title: 'SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation' URL: https://arxiv.org/abs/2209.08575 - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/mscan.py#L328 + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/mscan.py#L328 Framework: PyTorch - Name: segnext_mscan-b_1xb16-adamw-160k_ade20k-512x512 In Collection: SegNeXt @@ -81,7 +81,7 @@ Models: Paper: Title: 'SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation' URL: https://arxiv.org/abs/2209.08575 - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/mscan.py#L328 + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/mscan.py#L328 Framework: PyTorch - Name: segnext_mscan-l_1xb16-adamw-160k_ade20k-512x512 In Collection: SegNeXt @@ -105,5 +105,5 @@ Models: Paper: Title: 'SegNeXt: Rethinking Convolutional Attention Design for Semantic Segmentation' URL: https://arxiv.org/abs/2209.08575 - Code: https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/backbones/mscan.py#L328 + Code: https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/backbones/mscan.py#L328 Framework: PyTorch diff --git a/configs/sem_fpn/README.md b/configs/sem_fpn/README.md index 8bbbd0eee06..697cf506e20 100644 --- a/configs/sem_fpn/README.md +++ b/configs/sem_fpn/README.md @@ -26,17 +26,17 @@ The recently introduced panoptic segmentation task has renewed our community's i ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FPN | R-50 | 512x1024 | 80000 | 2.8 | 13.54 | V100 | 74.52 | 76.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x1024_80k_cityscapes/fpn_r50_512x1024_80k_cityscapes_20200717_021437-94018a0d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x1024_80k_cityscapes/fpn_r50_512x1024_80k_cityscapes-20200717_021437.log.json) | -| FPN | R-101 | 512x1024 | 80000 | 3.9 | 10.29 | V100 | 75.80 | 77.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/sem_fpn/fpn_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x1024_80k_cityscapes/fpn_r101_512x1024_80k_cityscapes_20200717_012416-c5800d4c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x1024_80k_cityscapes/fpn_r101_512x1024_80k_cityscapes-20200717_012416.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FPN | R-50 | 512x1024 | 80000 | 2.8 | 13.54 | V100 | 74.52 | 76.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn/fpn_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x1024_80k_cityscapes/fpn_r50_512x1024_80k_cityscapes_20200717_021437-94018a0d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x1024_80k_cityscapes/fpn_r50_512x1024_80k_cityscapes-20200717_021437.log.json) | +| FPN | R-101 | 512x1024 | 80000 | 3.9 | 10.29 | V100 | 75.80 | 77.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn/fpn_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x1024_80k_cityscapes/fpn_r101_512x1024_80k_cityscapes_20200717_012416-c5800d4c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x1024_80k_cityscapes/fpn_r101_512x1024_80k_cityscapes-20200717_012416.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| FPN | R-50 | 512x512 | 160000 | 4.9 | 55.77 | V100 | 37.49 | 39.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/sem_fpn/fpn_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x512_160k_ade20k/fpn_r50_512x512_160k_ade20k_20200718_131734-5b5a6ab9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x512_160k_ade20k/fpn_r50_512x512_160k_ade20k-20200718_131734.log.json) | -| FPN | R-101 | 512x512 | 160000 | 5.9 | 40.58 | V100 | 39.35 | 40.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/sem_fpn/fpn_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x512_160k_ade20k/fpn_r101_512x512_160k_ade20k_20200718_131734-306b5004.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x512_160k_ade20k/fpn_r101_512x512_160k_ade20k-20200718_131734.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------- | --------- | ------: | -------: | -------------- | ------ | ----: | ------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| FPN | R-50 | 512x512 | 160000 | 4.9 | 55.77 | V100 | 37.49 | 39.09 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn/fpn_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x512_160k_ade20k/fpn_r50_512x512_160k_ade20k_20200718_131734-5b5a6ab9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r50_512x512_160k_ade20k/fpn_r50_512x512_160k_ade20k-20200718_131734.log.json) | +| FPN | R-101 | 512x512 | 160000 | 5.9 | 40.58 | V100 | 39.35 | 40.72 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn/fpn_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x512_160k_ade20k/fpn_r101_512x512_160k_ade20k_20200718_131734-306b5004.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/sem_fpn/fpn_r101_512x512_160k_ade20k/fpn_r101_512x512_160k_ade20k-20200718_131734.log.json) | ## Citation diff --git a/configs/setr/README.md b/configs/setr/README.md index 556c625f411..15be6ec099a 100644 --- a/configs/setr/README.md +++ b/configs/setr/README.md @@ -47,20 +47,20 @@ This script convert the model from `PRETRAIN_PATH` and store the converted model ### ADE20K -| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| SETR Naive | ViT-L | 512x512 | 16 | 160000 | 18.40 | 4.72 | V100 | 48.28 | 49.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_naive_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_512x512_160k_b16_ade20k/setr_naive_512x512_160k_b16_ade20k_20210619_191258-061f24f5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_512x512_160k_b16_ade20k/setr_naive_512x512_160k_b16_ade20k_20210619_191258.log.json) | -| SETR PUP | ViT-L | 512x512 | 16 | 160000 | 19.54 | 4.50 | V100 | 48.24 | 49.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_pup_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_512x512_160k_b16_ade20k/setr_pup_512x512_160k_b16_ade20k_20210619_191343-7e0ce826.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_512x512_160k_b16_ade20k/setr_pup_512x512_160k_b16_ade20k_20210619_191343.log.json) | -| SETR MLA | ViT-L | 512x512 | 8 | 160000 | 10.96 | - | V100 | 47.34 | 49.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l-mla_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b8_ade20k/setr_mla_512x512_160k_b8_ade20k_20210619_191118-c6d21df0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b8_ade20k/setr_mla_512x512_160k_b8_ade20k_20210619_191118.log.json) | -| SETR MLA | ViT-L | 512x512 | 16 | 160000 | 17.30 | 5.25 | V100 | 47.39 | 49.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_mla_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b16_ade20k/setr_mla_512x512_160k_b16_ade20k_20210619_191057-f9741de7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b16_ade20k/setr_mla_512x512_160k_b16_ade20k_20210619_191057.log.json) | +| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| SETR Naive | ViT-L | 512x512 | 16 | 160000 | 18.40 | 4.72 | V100 | 48.28 | 49.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_naive_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_512x512_160k_b16_ade20k/setr_naive_512x512_160k_b16_ade20k_20210619_191258-061f24f5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_512x512_160k_b16_ade20k/setr_naive_512x512_160k_b16_ade20k_20210619_191258.log.json) | +| SETR PUP | ViT-L | 512x512 | 16 | 160000 | 19.54 | 4.50 | V100 | 48.24 | 49.99 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_pup_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_512x512_160k_b16_ade20k/setr_pup_512x512_160k_b16_ade20k_20210619_191343-7e0ce826.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_512x512_160k_b16_ade20k/setr_pup_512x512_160k_b16_ade20k_20210619_191343.log.json) | +| SETR MLA | ViT-L | 512x512 | 8 | 160000 | 10.96 | - | V100 | 47.34 | 49.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l-mla_8xb1-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b8_ade20k/setr_mla_512x512_160k_b8_ade20k_20210619_191118-c6d21df0.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b8_ade20k/setr_mla_512x512_160k_b8_ade20k_20210619_191118.log.json) | +| SETR MLA | ViT-L | 512x512 | 16 | 160000 | 17.30 | 5.25 | V100 | 47.39 | 49.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_mla_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b16_ade20k/setr_mla_512x512_160k_b16_ade20k_20210619_191057-f9741de7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_512x512_160k_b16_ade20k/setr_mla_512x512_160k_b16_ade20k_20210619_191057.log.json) | ### Cityscapes -| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| SETR Naive | ViT-L | 768x768 | 8 | 80000 | 24.06 | 0.39 | V100 | 78.10 | 80.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_naive_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_vit-large_8x1_768x768_80k_cityscapes/setr_naive_vit-large_8x1_768x768_80k_cityscapes_20211123_000505-20728e80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_vit-large_8x1_768x768_80k_cityscapes/setr_naive_vit-large_8x1_768x768_80k_cityscapes_20211123_000505.log.json) | -| SETR PUP | ViT-L | 768x768 | 8 | 80000 | 27.96 | 0.37 | V100 | 79.21 | 81.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_pup_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_vit-large_8x1_768x768_80k_cityscapes/setr_pup_vit-large_8x1_768x768_80k_cityscapes_20211122_155115-f6f37b8f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_vit-large_8x1_768x768_80k_cityscapes/setr_pup_vit-large_8x1_768x768_80k_cityscapes_20211122_155115.log.json) | -| SETR MLA | ViT-L | 768x768 | 8 | 80000 | 24.10 | 0.41 | V100 | 77.00 | 79.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/setr/setr_vit-l_mla_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_vit-large_8x1_768x768_80k_cityscapes/setr_mla_vit-large_8x1_768x768_80k_cityscapes_20211119_101003-7f8dccbe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_vit-large_8x1_768x768_80k_cityscapes/setr_mla_vit-large_8x1_768x768_80k_cityscapes_20211119_101003.log.json) | +| Method | Backbone | Crop Size | Batch Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | -------- | --------- | ---------- | ------- | -------- | -------------- | ------ | ----- | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| SETR Naive | ViT-L | 768x768 | 8 | 80000 | 24.06 | 0.39 | V100 | 78.10 | 80.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_naive_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_vit-large_8x1_768x768_80k_cityscapes/setr_naive_vit-large_8x1_768x768_80k_cityscapes_20211123_000505-20728e80.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_naive_vit-large_8x1_768x768_80k_cityscapes/setr_naive_vit-large_8x1_768x768_80k_cityscapes_20211123_000505.log.json) | +| SETR PUP | ViT-L | 768x768 | 8 | 80000 | 27.96 | 0.37 | V100 | 79.21 | 81.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_pup_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_vit-large_8x1_768x768_80k_cityscapes/setr_pup_vit-large_8x1_768x768_80k_cityscapes_20211122_155115-f6f37b8f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_pup_vit-large_8x1_768x768_80k_cityscapes/setr_pup_vit-large_8x1_768x768_80k_cityscapes_20211122_155115.log.json) | +| SETR MLA | ViT-L | 768x768 | 8 | 80000 | 24.10 | 0.41 | V100 | 77.00 | 79.59 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/setr_vit-l_mla_8xb1-80k_cityscapes-768x768.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_vit-large_8x1_768x768_80k_cityscapes/setr_mla_vit-large_8x1_768x768_80k_cityscapes_20211119_101003-7f8dccbe.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/setr/setr_mla_vit-large_8x1_768x768_80k_cityscapes/setr_mla_vit-large_8x1_768x768_80k_cityscapes_20211119_101003.log.json) | ## Citation diff --git a/configs/stdc/README.md b/configs/stdc/README.md index 1efd65482fa..3e8bf606880 100644 --- a/configs/stdc/README.md +++ b/configs/stdc/README.md @@ -46,12 +46,12 @@ This script convert model from `PRETRAIN_PATH` and store the converted model in ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------ | -------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| STDC | STDC1 (No Pretrain) | 512x1024 | 80000 | 7.15 | 23.06 | V100 | 71.82 | 73.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/stdc/stdc1_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_512x1024_80k_cityscapes/stdc1_512x1024_80k_cityscapes_20220224_073048-74e6920a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_512x1024_80k_cityscapes/stdc1_512x1024_80k_cityscapes_20220224_073048.log.json) | -| STDC | STDC1 | 512x1024 | 80000 | - | - | V100 | 74.94 | 76.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/stdc/stdc1_in1k-pre_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_in1k-pre_512x1024_80k_cityscapes/stdc1_in1k-pre_512x1024_80k_cityscapes_20220224_141648-3d4c2981.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_in1k-pre_512x1024_80k_cityscapes/stdc1_in1k-pre_512x1024_80k_cityscapes_20220224_141648.log.json) | -| STDC | STDC2 (No Pretrain) | 512x1024 | 80000 | 8.27 | 23.71 | V100 | 73.15 | 76.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/stdc/stdc2_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_512x1024_80k_cityscapes/stdc2_512x1024_80k_cityscapes_20220222_132015-fb1e3a1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_512x1024_80k_cityscapes/stdc2_512x1024_80k_cityscapes_20220222_132015.log.json) | -| STDC | STDC2 | 512x1024 | 80000 | - | - | V100 | 76.67 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/stdc/stdc2_in1k-pre_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_in1k-pre_512x1024_80k_cityscapes/stdc2_in1k-pre_512x1024_80k_cityscapes_20220224_073048-1f8f0f6c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_in1k-pre_512x1024_80k_cityscapes/stdc2_in1k-pre_512x1024_80k_cityscapes_20220224_073048.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------ | -------------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| STDC | STDC1 (No Pretrain) | 512x1024 | 80000 | 7.15 | 23.06 | V100 | 71.82 | 73.89 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/stdc/stdc1_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_512x1024_80k_cityscapes/stdc1_512x1024_80k_cityscapes_20220224_073048-74e6920a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_512x1024_80k_cityscapes/stdc1_512x1024_80k_cityscapes_20220224_073048.log.json) | +| STDC | STDC1 | 512x1024 | 80000 | - | - | V100 | 74.94 | 76.97 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/stdc/stdc1_in1k-pre_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_in1k-pre_512x1024_80k_cityscapes/stdc1_in1k-pre_512x1024_80k_cityscapes_20220224_141648-3d4c2981.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc1_in1k-pre_512x1024_80k_cityscapes/stdc1_in1k-pre_512x1024_80k_cityscapes_20220224_141648.log.json) | +| STDC | STDC2 (No Pretrain) | 512x1024 | 80000 | 8.27 | 23.71 | V100 | 73.15 | 76.13 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/stdc/stdc2_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_512x1024_80k_cityscapes/stdc2_512x1024_80k_cityscapes_20220222_132015-fb1e3a1a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_512x1024_80k_cityscapes/stdc2_512x1024_80k_cityscapes_20220222_132015.log.json) | +| STDC | STDC2 | 512x1024 | 80000 | - | - | V100 | 76.67 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/stdc/stdc2_in1k-pre_4xb12-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_in1k-pre_512x1024_80k_cityscapes/stdc2_in1k-pre_512x1024_80k_cityscapes_20220224_073048-1f8f0f6c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/stdc/stdc2_in1k-pre_512x1024_80k_cityscapes/stdc2_in1k-pre_512x1024_80k_cityscapes_20220224_073048.log.json) | Note: diff --git a/configs/swin/swin-tiny-patch4-window7_upernet_1xb8-20k_levir-256x256.py b/configs/swin/swin-tiny-patch4-window7_upernet_1xb8-20k_levir-256x256.py new file mode 100644 index 00000000000..663f769d731 --- /dev/null +++ b/configs/swin/swin-tiny-patch4-window7_upernet_1xb8-20k_levir-256x256.py @@ -0,0 +1,56 @@ +_base_ = [ + '../_base_/models/upernet_swin.py', '../_base_/datasets/levir_256x256.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_20k.py' +] +crop_size = (256, 256) +norm_cfg = dict(type='BN', requires_grad=True) +data_preprocessor = dict( + size=crop_size, + type='SegDataPreProcessor', + mean=[123.675, 116.28, 103.53, 123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375, 58.395, 57.12, 57.375]) + +model = dict( + data_preprocessor=data_preprocessor, + backbone=dict( + in_channels=6, + embed_dims=96, + depths=[2, 2, 6, 2], + num_heads=[3, 6, 12, 24], + window_size=7, + use_abs_pos_embed=False, + drop_path_rate=0.3, + patch_norm=True), + decode_head=dict(in_channels=[96, 192, 384, 768], num_classes=2), + auxiliary_head=dict(in_channels=384, num_classes=2)) + +# AdamW optimizer, no weight decay for position embedding & layer norm +# in backbone +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01), + paramwise_cfg=dict( + custom_keys={ + 'absolute_pos_embed': dict(decay_mult=0.), + 'relative_position_bias_table': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + })) + +param_scheduler = [ + dict( + type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500), + dict( + type='PolyLR', + eta_min=0.0, + power=1.0, + begin=1500, + end=20000, + by_epoch=False, + ) +] + +train_dataloader = dict(batch_size=4) +val_dataloader = dict(batch_size=1) +test_dataloader = val_dataloader diff --git a/configs/twins/README.md b/configs/twins/README.md index 306b65fac8c..e4b3735b002 100644 --- a/configs/twins/README.md +++ b/configs/twins/README.md @@ -44,20 +44,20 @@ python tools/model_converters/twins2mmseg.py ./alt_gvt_base.pth ./pretrained/alt ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | ------------------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| FPN | Twins-PCPVT-S | 512x512 | 80000 | 6.60 | 27.15 | V100 | 43.26 | 44.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-s_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_204132-41acd132.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_204132.log.json) | -| UPerNet | Twins-PCPVT-S | 512x512 | 160000 | 9.67 | 14.24 | V100 | 46.04 | 46.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-s_uperhead_8xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k_20211201_233537-8e99c07a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k_20211201_233537.log.json) | -| FPN | Twins-PCPVT-B | 512x512 | 80000 | 8.41 | 19.67 | V100 | 45.66 | 46.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-b_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141019-d396db72.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141019.log.json) | -| UPerNet | Twins-PCPVT-B (8x2) | 512x512 | 160000 | 6.46 | 12.04 | V100 | 47.91 | 48.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-b_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k_20211130_141020-02094ea5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k_20211130_141020.log.json) | -| FPN | Twins-PCPVT-L | 512x512 | 80000 | 10.78 | 14.32 | V100 | 45.94 | 46.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-l_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_105226-bc6d61dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_105226.log.json) | -| UPerNet | Twins-PCPVT-L (8x2) | 512x512 | 160000 | 7.82 | 10.70 | V100 | 49.35 | 50.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-l_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k_20211201_075053-c6095c07.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k_20211201_075053.log.json) | -| FPN | Twins-SVT-S | 512x512 | 80000 | 5.80 | 29.79 | V100 | 44.47 | 45.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_svt-s_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141006-0a0d3317.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141006.log.json) | -| UPerNet | SVT-S (8x2) | 512x512 | 160000 | 4.93 | 15.09 | V100 | 46.08 | 46.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_svt-s_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_uperhead_8x2_512x512_160k_ade20k/twins_svt-s_uperhead_8x2_512x512_160k_ade20k_20211130_141005-e48a2d94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_uperhead_8x2_512x512_160k_ade20k/twins_svt-s_uperhead_8x2_512x512_160k_ade20k_20211130_141005.log.json) | -| FPN | Twins-SVT-B | 512x512 | 80000 | 8.75 | 21.10 | V100 | 46.77 | 47.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_svt-b_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_113849-88b2907c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_113849.log.json) | -| UPerNet | Twins-SVT-B (8x2) | 512x512 | 160000 | 6.77 | 12.66 | V100 | 48.04 | 48.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_svt-b_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_uperhead_8x2_512x512_160k_ade20k/twins_svt-b_uperhead_8x2_512x512_160k_ade20k_20211202_040826-0943a1f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_uperhead_8x2_512x512_160k_ade20k/twins_svt-b_uperhead_8x2_512x512_160k_ade20k_20211202_040826.log.json) | -| FPN | Twins-SVT-L | 512x512 | 80000 | 11.20 | 17.80 | V100 | 46.55 | 47.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_svt-l_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141005-1d59bee2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141005.log.json) | -| UPerNet | Twins-SVT-L (8x2) | 512x512 | 160000 | 8.41 | 10.73 | V100 | 49.65 | 50.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/twins/twins_pcpvt-l_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_uperhead_8x2_512x512_160k_ade20k/twins_svt-l_uperhead_8x2_512x512_160k_ade20k_20211130_141005-3e2cae61.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_uperhead_8x2_512x512_160k_ade20k/twins_svt-l_uperhead_8x2_512x512_160k_ade20k_20211130_141005.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | ------------------- | --------- | ------- | -------- | -------------- | ------ | ----- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FPN | Twins-PCPVT-S | 512x512 | 80000 | 6.60 | 27.15 | V100 | 43.26 | 44.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-s_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_204132-41acd132.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_204132.log.json) | +| UPerNet | Twins-PCPVT-S | 512x512 | 160000 | 9.67 | 14.24 | V100 | 46.04 | 46.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-s_uperhead_8xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k_20211201_233537-8e99c07a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k/twins_pcpvt-s_uperhead_8x4_512x512_160k_ade20k_20211201_233537.log.json) | +| FPN | Twins-PCPVT-B | 512x512 | 80000 | 8.41 | 19.67 | V100 | 45.66 | 46.48 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-b_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141019-d396db72.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141019.log.json) | +| UPerNet | Twins-PCPVT-B (8x2) | 512x512 | 160000 | 6.46 | 12.04 | V100 | 47.91 | 48.64 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-b_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k_20211130_141020-02094ea5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-b_uperhead_8x2_512x512_160k_ade20k_20211130_141020.log.json) | +| FPN | Twins-PCPVT-L | 512x512 | 80000 | 10.78 | 14.32 | V100 | 45.94 | 46.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-l_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_105226-bc6d61dc.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_pcpvt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_105226.log.json) | +| UPerNet | Twins-PCPVT-L (8x2) | 512x512 | 160000 | 7.82 | 10.70 | V100 | 49.35 | 50.08 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-l_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k_20211201_075053-c6095c07.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k/twins_pcpvt-l_uperhead_8x2_512x512_160k_ade20k_20211201_075053.log.json) | +| FPN | Twins-SVT-S | 512x512 | 80000 | 5.80 | 29.79 | V100 | 44.47 | 45.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_svt-s_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141006-0a0d3317.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-s_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141006.log.json) | +| UPerNet | SVT-S (8x2) | 512x512 | 160000 | 4.93 | 15.09 | V100 | 46.08 | 46.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_svt-s_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_uperhead_8x2_512x512_160k_ade20k/twins_svt-s_uperhead_8x2_512x512_160k_ade20k_20211130_141005-e48a2d94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-s_uperhead_8x2_512x512_160k_ade20k/twins_svt-s_uperhead_8x2_512x512_160k_ade20k_20211130_141005.log.json) | +| FPN | Twins-SVT-B | 512x512 | 80000 | 8.75 | 21.10 | V100 | 46.77 | 47.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_svt-b_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_113849-88b2907c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-b_fpn_fpnhead_8x4_512x512_80k_ade20k_20211201_113849.log.json) | +| UPerNet | Twins-SVT-B (8x2) | 512x512 | 160000 | 6.77 | 12.66 | V100 | 48.04 | 48.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_svt-b_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_uperhead_8x2_512x512_160k_ade20k/twins_svt-b_uperhead_8x2_512x512_160k_ade20k_20211202_040826-0943a1f1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-b_uperhead_8x2_512x512_160k_ade20k/twins_svt-b_uperhead_8x2_512x512_160k_ade20k_20211202_040826.log.json) | +| FPN | Twins-SVT-L | 512x512 | 80000 | 11.20 | 17.80 | V100 | 46.55 | 47.74 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_svt-l_fpn_fpnhead_8xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141005-1d59bee2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k/twins_svt-l_fpn_fpnhead_8x4_512x512_80k_ade20k_20211130_141005.log.json) | +| UPerNet | Twins-SVT-L (8x2) | 512x512 | 160000 | 8.41 | 10.73 | V100 | 49.65 | 50.63 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins/twins_pcpvt-l_uperhead_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_uperhead_8x2_512x512_160k_ade20k/twins_svt-l_uperhead_8x2_512x512_160k_ade20k_20211130_141005-3e2cae61.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/twins/twins_svt-l_uperhead_8x2_512x512_160k_ade20k/twins_svt-l_uperhead_8x2_512x512_160k_ade20k_20211130_141005.log.json) | Note: diff --git a/configs/unet/README.md b/configs/unet/README.md index e42cd0f91ec..7225fbbf68f 100644 --- a/configs/unet/README.md +++ b/configs/unet/README.md @@ -26,53 +26,53 @@ There is large consent that successful training of deep networks requires many t ### Cityscapes -| Method | Backbone | Loss | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ---------- | ----------- | ------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UNet + FCN | UNet-S5-D16 | Cross Entropy | 512x1024 | 160000 | 17.91 | 3.05 | V100 | 69.10 | 71.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204-6860854e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204.log.json) | +| Method | Backbone | Loss | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ---------- | ----------- | ------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UNet + FCN | UNet-S5-D16 | Cross Entropy | 512x1024 | 160000 | 17.91 | 3.05 | V100 | 69.10 | 71.05 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204-6860854e.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes/fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204.log.json) | ### DRIVE -| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | -| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UNet + FCN | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.680 | - | V100 | 88.38 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_64x64_40k_drive/fcn_unet_s5-d16_64x64_40k_drive_20201223_191051-5daf6d3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_64x64_40k_drive/unet_s5-d16_64x64_40k_drive-20201223_191051.log.json) | -| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.582 | - | V100 | 88.71 | 79.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201820-785de5c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201820.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.599 | - | V100 | 88.35 | 78.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_64x64_40k_drive/pspnet_unet_s5-d16_64x64_40k_drive_20201227_181818-aac73387.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_64x64_40k_drive/pspnet_unet_s5-d16_64x64_40k_drive-20201227_181818.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.585 | - | V100 | 88.76 | 79.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201821-22b3e3ba.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201821.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.596 | - | V100 | 88.38 | 78.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_64x64_40k_drive/deeplabv3_unet_s5-d16_64x64_40k_drive_20201226_094047-0671ff20.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_64x64_40k_drive/deeplabv3_unet_s5-d16_64x64_40k_drive-20201226_094047.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.582 | - | V100 | 88.84 | 79.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201825-6bf0efd7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201825.log.json) | +| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | +| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UNet + FCN | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.680 | - | V100 | 88.38 | 78.67 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_64x64_40k_drive/fcn_unet_s5-d16_64x64_40k_drive_20201223_191051-5daf6d3b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_64x64_40k_drive/unet_s5-d16_64x64_40k_drive-20201223_191051.log.json) | +| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.582 | - | V100 | 88.71 | 79.32 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201820-785de5c2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/fcn_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201820.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.599 | - | V100 | 88.35 | 78.62 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_64x64_40k_drive/pspnet_unet_s5-d16_64x64_40k_drive_20201227_181818-aac73387.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_64x64_40k_drive/pspnet_unet_s5-d16_64x64_40k_drive-20201227_181818.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.585 | - | V100 | 88.76 | 79.42 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201821-22b3e3ba.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/pspnet_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201821.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 584x565 | 64x64 | 42x42 | 40000 | 0.596 | - | V100 | 88.38 | 78.69 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_64x64_40k_drive/deeplabv3_unet_s5-d16_64x64_40k_drive_20201226_094047-0671ff20.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_64x64_40k_drive/deeplabv3_unet_s5-d16_64x64_40k_drive-20201226_094047.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 584x565 | 64x64 | 42x42 | 40000 | 0.582 | - | V100 | 88.84 | 79.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_drive-64x64.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201825-6bf0efd7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_64x64_40k_drive_20211210_201825.log.json) | ### STARE -| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | -| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| UNet + FCN | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.968 | - | V100 | 89.78 | 81.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_128x128_40k_stare/fcn_unet_s5-d16_128x128_40k_stare_20201223_191051-7d77e78b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_stare/unet_s5-d16_128x128_40k_stare-20201223_191051.log.json) | -| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 0.986 | - | V100 | 90.65 | 82.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201821-f75705a9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201821.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.982 | - | V100 | 89.89 | 81.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_stare/pspnet_unet_s5-d16_128x128_40k_stare_20201227_181818-3c2923c4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_stare/pspnet_unet_s5-d16_128x128_40k_stare-20201227_181818.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 1.028 | - | V100 | 90.72 | 82.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201823-f1063ef7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201823.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.999 | - | V100 | 89.73 | 80.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_stare/deeplabv3_unet_s5-d16_128x128_40k_stare_20201226_094047-93dcb93c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_stare/deeplabv3_unet_s5-d16_128x128_40k_stare-20201226_094047.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 1.010 | - | V100 | 90.65 | 82.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201825-21db614c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201825.log.json) | +| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | +| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| UNet + FCN | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.968 | - | V100 | 89.78 | 81.02 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_128x128_40k_stare/fcn_unet_s5-d16_128x128_40k_stare_20201223_191051-7d77e78b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_stare/unet_s5-d16_128x128_40k_stare-20201223_191051.log.json) | +| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 0.986 | - | V100 | 90.65 | 82.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201821-f75705a9.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201821.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.982 | - | V100 | 89.89 | 81.22 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_stare/pspnet_unet_s5-d16_128x128_40k_stare_20201227_181818-3c2923c4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_stare/pspnet_unet_s5-d16_128x128_40k_stare-20201227_181818.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 1.028 | - | V100 | 90.72 | 82.84 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201823-f1063ef7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201823.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 605x700 | 128x128 | 85x85 | 40000 | 0.999 | - | V100 | 89.73 | 80.93 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_stare/deeplabv3_unet_s5-d16_128x128_40k_stare_20201226_094047-93dcb93c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_stare/deeplabv3_unet_s5-d16_128x128_40k_stare-20201226_094047.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 605x700 | 128x128 | 85x85 | 40000 | 1.010 | - | V100 | 90.65 | 82.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_stare-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201825-21db614c.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_stare_20211210_201825.log.json) | ### CHASE_DB1 -| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | -| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UNet + FCN | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.968 | - | V100 | 89.46 | 80.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_128x128_40k_chase_db1/fcn_unet_s5-d16_128x128_40k_chase_db1_20201223_191051-11543527.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_chase_db1/unet_s5-d16_128x128_40k_chase_db1-20201223_191051.log.json) | -| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 0.986 | - | V100 | 89.52 | 80.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201821-1c4eb7cf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201821.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.982 | - | V100 | 89.52 | 80.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_chase_db1/pspnet_unet_s5-d16_128x128_40k_chase_db1_20201227_181818-68d4e609.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_chase_db1/pspnet_unet_s5-d16_128x128_40k_chase_db1-20201227_181818.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 1.028 | - | V100 | 89.45 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201823-c0802c4d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201823.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.999 | - | V100 | 89.57 | 80.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet_s5-d16_deeplabv3_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_chase_db1/deeplabv3_unet_s5-d16_128x128_40k_chase_db1_20201226_094047-4c5aefa3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_chase_db1/deeplabv3_unet_s5-d16_128x128_40k_chase_db1-20201226_094047.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 1.010 | - | V100 | 89.49 | 80.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201825-4ef29df5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201825.log.json) | +| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | +| ---------------- | ----------- | -------------------- | ---------- | --------- | -----: | ------- | -------- | -------------: | ------ | ----: | ----: | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UNet + FCN | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.968 | - | V100 | 89.46 | 80.24 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_128x128_40k_chase_db1/fcn_unet_s5-d16_128x128_40k_chase_db1_20201223_191051-11543527.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_128x128_40k_chase_db1/unet_s5-d16_128x128_40k_chase_db1-20201223_191051.log.json) | +| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 0.986 | - | V100 | 89.52 | 80.40 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201821-1c4eb7cf.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/fcn_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201821.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.982 | - | V100 | 89.52 | 80.36 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_chase_db1/pspnet_unet_s5-d16_128x128_40k_chase_db1_20201227_181818-68d4e609.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_128x128_40k_chase_db1/pspnet_unet_s5-d16_128x128_40k_chase_db1-20201227_181818.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 1.028 | - | V100 | 89.45 | 80.28 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201823-c0802c4d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/pspnet_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201823.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 960x999 | 128x128 | 85x85 | 40000 | 0.999 | - | V100 | 89.57 | 80.47 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet_s5-d16_deeplabv3_4xb4-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_chase_db1/deeplabv3_unet_s5-d16_128x128_40k_chase_db1_20201226_094047-4c5aefa3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_128x128_40k_chase_db1/deeplabv3_unet_s5-d16_128x128_40k_chase_db1-20201226_094047.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 960x999 | 128x128 | 85x85 | 40000 | 1.010 | - | V100 | 89.49 | 80.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_chase-db1-128x128.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201825-4ef29df5.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_128x128_40k_chase-db1_20211210_201825.log.json) | ### HRF -| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | -| ---------------- | ----------- | -------------------- | ---------- | --------- | ------: | ------- | -------- | -------------: | ------ | ----: | ----: | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UNet + FCN | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.525 | - | V100 | 88.92 | 79.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_256x256_40k_hrf/fcn_unet_s5-d16_256x256_40k_hrf_20201223_173724-d89cf1ed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_256x256_40k_hrf/unet_s5-d16_256x256_40k_hrf-20201223_173724.log.json) | -| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.623 | - | V100 | 89.64 | 80.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201821-c314da8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201821.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.588 | - | V100 | 89.24 | 80.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_256x256_40k_hrf/pspnet_unet_s5-d16_256x256_40k_hrf_20201227_181818-fdb7e29b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_256x256_40k_hrf/pspnet_unet_s5-d16_256x256_40k_hrf-20201227_181818.log.json) | -| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.798 | - | V100 | 89.69 | 80.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201823-53d492fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201823.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.604 | - | V100 | 89.32 | 80.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_256x256_40k_hrf/deeplabv3_unet_s5-d16_256x256_40k_hrf_20201226_094047-3a1fdf85.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_256x256_40k_hrf/deeplabv3_unet_s5-d16_256x256_40k_hrf-20201226_094047.log.json) | -| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.607 | - | V100 | 89.56 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_202032-59daf7a4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_202032.log.json) | +| Method | Backbone | Loss | Image Size | Crop Size | Stride | Lr schd | Mem (GB) | Inf time (fps) | Device | mDice | Dice | config | download | +| ---------------- | ----------- | -------------------- | ---------- | --------- | ------: | ------- | -------- | -------------: | ------ | ----: | ----: | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UNet + FCN | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.525 | - | V100 | 88.92 | 79.45 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_256x256_40k_hrf/fcn_unet_s5-d16_256x256_40k_hrf_20201223_173724-d89cf1ed.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/unet_s5-d16_256x256_40k_hrf/unet_s5-d16_256x256_40k_hrf-20201223_173724.log.json) | +| UNet + FCN | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.623 | - | V100 | 89.64 | 80.87 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_fcn_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201821-c314da8a.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/fcn_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201821.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.588 | - | V100 | 89.24 | 80.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_256x256_40k_hrf/pspnet_unet_s5-d16_256x256_40k_hrf_20201227_181818-fdb7e29b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_256x256_40k_hrf/pspnet_unet_s5-d16_256x256_40k_hrf-20201227_181818.log.json) | +| UNet + PSPNet | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.798 | - | V100 | 89.69 | 80.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_pspnet_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201823-53d492fa.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/pspnet_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_201823.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy | 2336x3504 | 256x256 | 170x170 | 40000 | 2.604 | - | V100 | 89.32 | 80.21 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_256x256_40k_hrf/deeplabv3_unet_s5-d16_256x256_40k_hrf_20201226_094047-3a1fdf85.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_256x256_40k_hrf/deeplabv3_unet_s5-d16_256x256_40k_hrf-20201226_094047.log.json) | +| UNet + DeepLabV3 | UNet-S5-D16 | Cross Entropy + Dice | 2336x3504 | 256x256 | 170x170 | 40000 | 2.607 | - | V100 | 89.56 | 80.71 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/unet-s5-d16_deeplabv3_4xb4-ce-1.0-dice-3.0-40k_hrf-256x256.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_202032-59daf7a4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/unet/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf/deeplabv3_unet_s5-d16_ce-1.0-dice-3.0_256x256_40k_hrf_20211210_202032.log.json) | Note: diff --git a/configs/upernet/README.md b/configs/upernet/README.md index 7d128090bfe..c2babbd2a71 100644 --- a/configs/upernet/README.md +++ b/configs/upernet/README.md @@ -26,34 +26,34 @@ Humans recognize the visual world at multiple levels: we effortlessly categorize ### Cityscapes -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | R-50 | 512x1024 | 40000 | 6.4 | 4.25 | V100 | 77.10 | 78.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_40k_cityscapes/upernet_r50_512x1024_40k_cityscapes_20200605_094827-aa54cb54.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_40k_cityscapes/upernet_r50_512x1024_40k_cityscapes_20200605_094827.log.json) | -| UPerNet | R-101 | 512x1024 | 40000 | 7.4 | 3.79 | V100 | 78.69 | 80.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_40k_cityscapes/upernet_r101_512x1024_40k_cityscapes_20200605_094933-ebce3b10.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_40k_cityscapes/upernet_r101_512x1024_40k_cityscapes_20200605_094933.log.json) | -| UPerNet | R-50 | 769x769 | 40000 | 7.2 | 1.76 | V100 | 77.98 | 79.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_40k_cityscapes/upernet_r50_769x769_40k_cityscapes_20200530_033048-92d21539.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_40k_cityscapes/upernet_r50_769x769_40k_cityscapes_20200530_033048.log.json) | -| UPerNet | R-101 | 769x769 | 40000 | 8.4 | 1.56 | V100 | 79.03 | 80.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_40k_cityscapes/upernet_r101_769x769_40k_cityscapes_20200530_040819-83c95d01.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_40k_cityscapes/upernet_r101_769x769_40k_cityscapes_20200530_040819.log.json) | -| UPerNet | R-50 | 512x1024 | 80000 | - | - | V100 | 78.19 | 79.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_80k_cityscapes/upernet_r50_512x1024_80k_cityscapes_20200607_052207-848beca8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_80k_cityscapes/upernet_r50_512x1024_80k_cityscapes_20200607_052207.log.json) | -| UPerNet | R-101 | 512x1024 | 80000 | - | - | V100 | 79.40 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_80k_cityscapes/upernet_r101_512x1024_80k_cityscapes_20200607_002403-f05f2345.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_80k_cityscapes/upernet_r101_512x1024_80k_cityscapes_20200607_002403.log.json) | -| UPerNet | R-50 | 769x769 | 80000 | - | - | V100 | 79.39 | 80.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_80k_cityscapes/upernet_r50_769x769_80k_cityscapes_20200607_005107-82ae7d15.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_80k_cityscapes/upernet_r50_769x769_80k_cityscapes_20200607_005107.log.json) | -| UPerNet | R-101 | 769x769 | 80000 | - | - | V100 | 80.10 | 81.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_80k_cityscapes/upernet_r101_769x769_80k_cityscapes_20200607_001014-082fc334.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_80k_cityscapes/upernet_r101_769x769_80k_cityscapes_20200607_001014.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | R-50 | 512x1024 | 40000 | 6.4 | 4.25 | V100 | 77.10 | 78.37 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_40k_cityscapes/upernet_r50_512x1024_40k_cityscapes_20200605_094827-aa54cb54.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_40k_cityscapes/upernet_r50_512x1024_40k_cityscapes_20200605_094827.log.json) | +| UPerNet | R-101 | 512x1024 | 40000 | 7.4 | 3.79 | V100 | 78.69 | 80.11 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb2-40k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_40k_cityscapes/upernet_r101_512x1024_40k_cityscapes_20200605_094933-ebce3b10.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_40k_cityscapes/upernet_r101_512x1024_40k_cityscapes_20200605_094933.log.json) | +| UPerNet | R-50 | 769x769 | 40000 | 7.2 | 1.76 | V100 | 77.98 | 79.70 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_40k_cityscapes/upernet_r50_769x769_40k_cityscapes_20200530_033048-92d21539.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_40k_cityscapes/upernet_r50_769x769_40k_cityscapes_20200530_033048.log.json) | +| UPerNet | R-101 | 769x769 | 40000 | 8.4 | 1.56 | V100 | 79.03 | 80.77 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb2-40k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_40k_cityscapes/upernet_r101_769x769_40k_cityscapes_20200530_040819-83c95d01.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_40k_cityscapes/upernet_r101_769x769_40k_cityscapes_20200530_040819.log.json) | +| UPerNet | R-50 | 512x1024 | 80000 | - | - | V100 | 78.19 | 79.19 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_80k_cityscapes/upernet_r50_512x1024_80k_cityscapes_20200607_052207-848beca8.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x1024_80k_cityscapes/upernet_r50_512x1024_80k_cityscapes_20200607_052207.log.json) | +| UPerNet | R-101 | 512x1024 | 80000 | - | - | V100 | 79.40 | 80.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb2-80k_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_80k_cityscapes/upernet_r101_512x1024_80k_cityscapes_20200607_002403-f05f2345.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x1024_80k_cityscapes/upernet_r101_512x1024_80k_cityscapes_20200607_002403.log.json) | +| UPerNet | R-50 | 769x769 | 80000 | - | - | V100 | 79.39 | 80.92 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_80k_cityscapes/upernet_r50_769x769_80k_cityscapes_20200607_005107-82ae7d15.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_769x769_80k_cityscapes/upernet_r50_769x769_80k_cityscapes_20200607_005107.log.json) | +| UPerNet | R-101 | 769x769 | 80000 | - | - | V100 | 80.10 | 81.49 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb2-80k_cityscapes-769x769.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_80k_cityscapes/upernet_r101_769x769_80k_cityscapes_20200607_001014-082fc334.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_769x769_80k_cityscapes/upernet_r101_769x769_80k_cityscapes_20200607_001014.log.json) | ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ---------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | R-50 | 512x512 | 80000 | 8.1 | 23.40 | V100 | 40.70 | 41.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_80k_ade20k/upernet_r50_512x512_80k_ade20k_20200614_144127-ecc8377b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_80k_ade20k/upernet_r50_512x512_80k_ade20k_20200614_144127.log.json) | -| UPerNet | R-101 | 512x512 | 80000 | 9.1 | 20.34 | V100 | 42.91 | 43.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_80k_ade20k/upernet_r101_512x512_80k_ade20k_20200614_185117-32e4db94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_80k_ade20k/upernet_r101_512x512_80k_ade20k_20200614_185117.log.json) | -| UPerNet | R-50 | 512x512 | 160000 | - | - | V100 | 42.05 | 42.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_160k_ade20k/upernet_r50_512x512_160k_ade20k_20200615_184328-8534de8d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_160k_ade20k/upernet_r50_512x512_160k_ade20k_20200615_184328.log.json) | -| UPerNet | R-101 | 512x512 | 160000 | - | - | V100 | 43.82 | 44.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_160k_ade20k/upernet_r101_512x512_160k_ade20k_20200615_161951-91b32684.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_160k_ade20k/upernet_r101_512x512_160k_ade20k_20200615_161951.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | R-50 | 512x512 | 80000 | 8.1 | 23.40 | V100 | 40.70 | 41.81 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_80k_ade20k/upernet_r50_512x512_80k_ade20k_20200614_144127-ecc8377b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_80k_ade20k/upernet_r50_512x512_80k_ade20k_20200614_144127.log.json) | +| UPerNet | R-101 | 512x512 | 80000 | 9.1 | 20.34 | V100 | 42.91 | 43.96 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb4-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_80k_ade20k/upernet_r101_512x512_80k_ade20k_20200614_185117-32e4db94.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_80k_ade20k/upernet_r101_512x512_80k_ade20k_20200614_185117.log.json) | +| UPerNet | R-50 | 512x512 | 160000 | - | - | V100 | 42.05 | 42.78 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_160k_ade20k/upernet_r50_512x512_160k_ade20k_20200615_184328-8534de8d.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_160k_ade20k/upernet_r50_512x512_160k_ade20k_20200615_184328.log.json) | +| UPerNet | R-101 | 512x512 | 160000 | - | - | V100 | 43.82 | 44.85 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb4-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_160k_ade20k/upernet_r101_512x512_160k_ade20k_20200615_161951-91b32684.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_160k_ade20k/upernet_r101_512x512_160k_ade20k_20200615_161951.log.json) | ### Pascal VOC 2012 + Aug -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | R-50 | 512x512 | 20000 | 6.4 | 23.17 | V100 | 74.82 | 76.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_20k_voc12aug/upernet_r50_512x512_20k_voc12aug_20200617_165330-5b5890a7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_20k_voc12aug/upernet_r50_512x512_20k_voc12aug_20200617_165330.log.json) | -| UPerNet | R-101 | 512x512 | 20000 | 7.5 | 19.98 | V100 | 77.10 | 78.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_20k_voc12aug/upernet_r101_512x512_20k_voc12aug_20200617_165629-f14e7f27.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_20k_voc12aug/upernet_r101_512x512_20k_voc12aug_20200617_165629.log.json) | -| UPerNet | R-50 | 512x512 | 40000 | - | - | V100 | 75.92 | 77.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r50_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_40k_voc12aug/upernet_r50_512x512_40k_voc12aug_20200613_162257-ca9bcc6b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_40k_voc12aug/upernet_r50_512x512_40k_voc12aug_20200613_162257.log.json) | -| UPerNet | R-101 | 512x512 | 40000 | - | - | V100 | 77.43 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/upernet/upernet_r101_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_40k_voc12aug/upernet_r101_512x512_40k_voc12aug_20200613_163549-e26476ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_40k_voc12aug/upernet_r101_512x512_40k_voc12aug_20200613_163549.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | -------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | R-50 | 512x512 | 20000 | 6.4 | 23.17 | V100 | 74.82 | 76.35 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_20k_voc12aug/upernet_r50_512x512_20k_voc12aug_20200617_165330-5b5890a7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_20k_voc12aug/upernet_r50_512x512_20k_voc12aug_20200617_165330.log.json) | +| UPerNet | R-101 | 512x512 | 20000 | 7.5 | 19.98 | V100 | 77.10 | 78.29 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb4-20k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_20k_voc12aug/upernet_r101_512x512_20k_voc12aug_20200617_165629-f14e7f27.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_20k_voc12aug/upernet_r101_512x512_20k_voc12aug_20200617_165629.log.json) | +| UPerNet | R-50 | 512x512 | 40000 | - | - | V100 | 75.92 | 77.44 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r50_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_40k_voc12aug/upernet_r50_512x512_40k_voc12aug_20200613_162257-ca9bcc6b.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r50_512x512_40k_voc12aug/upernet_r50_512x512_40k_voc12aug_20200613_162257.log.json) | +| UPerNet | R-101 | 512x512 | 40000 | - | - | V100 | 77.43 | 78.56 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet/upernet_r101_4xb4-40k_voc12aug-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_40k_voc12aug/upernet_r101_512x512_40k_voc12aug_20200613_163549-e26476ac.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/upernet/upernet_r101_512x512_40k_voc12aug/upernet_r101_512x512_40k_voc12aug_20200613_163549.log.json) | ## Citation diff --git a/configs/vit/README.md b/configs/vit/README.md index 26601d498f7..f75326e8e44 100644 --- a/configs/vit/README.md +++ b/configs/vit/README.md @@ -44,19 +44,19 @@ This script convert model from `PRETRAIN_PATH` and store the converted model in ### ADE20K -| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | -| ------- | ----------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| UPerNet | ViT-B + MLN | 512x512 | 80000 | 9.20 | 6.94 | V100 | 47.71 | 49.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_vit-b16_mln_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_80k_ade20k/upernet_vit-b16_mln_512x512_80k_ade20k_20210624_130547-0403cee1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_80k_ade20k/20210624_130547.log.json) | -| UPerNet | ViT-B + MLN | 512x512 | 160000 | 9.20 | 7.58 | V100 | 46.75 | 48.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_vit-b16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_160k_ade20k/upernet_vit-b16_mln_512x512_160k_ade20k_20210624_130547-852fa768.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_160k_ade20k/20210623_192432.log.json) | -| UPerNet | ViT-B + LN + MLN | 512x512 | 160000 | 9.21 | 6.82 | V100 | 47.73 | 49.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_vit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_ln_mln_512x512_160k_ade20k/upernet_vit-b16_ln_mln_512x512_160k_ade20k_20210621_172828-f444c077.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_ln_mln_512x512_160k_ade20k/20210621_172828.log.json) | -| UPerNet | DeiT-S | 512x512 | 80000 | 4.68 | 29.85 | V100 | 42.96 | 43.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-s16_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_80k_ade20k/upernet_deit-s16_512x512_80k_ade20k_20210624_095228-afc93ec2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_80k_ade20k/20210624_095228.log.json) | -| UPerNet | DeiT-S | 512x512 | 160000 | 4.68 | 29.19 | V100 | 42.87 | 43.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-s16_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_160k_ade20k/upernet_deit-s16_512x512_160k_ade20k_20210621_160903-5110d916.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_160k_ade20k/20210621_160903.log.json) | -| UPerNet | DeiT-S + MLN | 512x512 | 160000 | 5.69 | 11.18 | V100 | 43.82 | 45.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-s16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_mln_512x512_160k_ade20k/upernet_deit-s16_mln_512x512_160k_ade20k_20210621_161021-fb9a5dfb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_mln_512x512_160k_ade20k/20210621_161021.log.json) | -| UPerNet | DeiT-S + LN + MLN | 512x512 | 160000 | 5.69 | 12.39 | V100 | 43.52 | 45.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-s16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_ln_mln_512x512_160k_ade20k/upernet_deit-s16_ln_mln_512x512_160k_ade20k_20210621_161021-c0cd652f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_ln_mln_512x512_160k_ade20k/20210621_161021.log.json) | -| UPerNet | DeiT-B | 512x512 | 80000 | 7.75 | 9.69 | V100 | 45.24 | 46.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-b16_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_80k_ade20k/upernet_deit-b16_512x512_80k_ade20k_20210624_130529-1e090789.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_80k_ade20k/20210624_130529.log.json) | -| UPerNet | DeiT-B | 512x512 | 160000 | 7.75 | 10.39 | V100 | 45.36 | 47.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-b16_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_160k_ade20k/upernet_deit-b16_512x512_160k_ade20k_20210621_180100-828705d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_160k_ade20k/20210621_180100.log.json) | -| UPerNet | DeiT-B + MLN | 512x512 | 160000 | 9.21 | 7.78 | V100 | 45.46 | 47.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-b16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_mln_512x512_160k_ade20k/upernet_deit-b16_mln_512x512_160k_ade20k_20210621_191949-4e1450f3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_mln_512x512_160k_ade20k/20210621_191949.log.json) | -| UPerNet | DeiT-B + LN + MLN | 512x512 | 160000 | 9.21 | 7.75 | V100 | 45.37 | 47.23 | [config](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_deit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_ln_mln_512x512_160k_ade20k/upernet_deit-b16_ln_mln_512x512_160k_ade20k_20210623_153535-8a959c14.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_ln_mln_512x512_160k_ade20k/20210623_153535.log.json) | +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | ----------------- | --------- | ------: | -------- | -------------- | ------ | ----: | ------------: | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| UPerNet | ViT-B + MLN | 512x512 | 80000 | 9.20 | 6.94 | V100 | 47.71 | 49.51 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_vit-b16_mln_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_80k_ade20k/upernet_vit-b16_mln_512x512_80k_ade20k_20210624_130547-0403cee1.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_80k_ade20k/20210624_130547.log.json) | +| UPerNet | ViT-B + MLN | 512x512 | 160000 | 9.20 | 7.58 | V100 | 46.75 | 48.46 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_vit-b16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_160k_ade20k/upernet_vit-b16_mln_512x512_160k_ade20k_20210624_130547-852fa768.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_mln_512x512_160k_ade20k/20210623_192432.log.json) | +| UPerNet | ViT-B + LN + MLN | 512x512 | 160000 | 9.21 | 6.82 | V100 | 47.73 | 49.95 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_vit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_ln_mln_512x512_160k_ade20k/upernet_vit-b16_ln_mln_512x512_160k_ade20k_20210621_172828-f444c077.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_vit-b16_ln_mln_512x512_160k_ade20k/20210621_172828.log.json) | +| UPerNet | DeiT-S | 512x512 | 80000 | 4.68 | 29.85 | V100 | 42.96 | 43.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-s16_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_80k_ade20k/upernet_deit-s16_512x512_80k_ade20k_20210624_095228-afc93ec2.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_80k_ade20k/20210624_095228.log.json) | +| UPerNet | DeiT-S | 512x512 | 160000 | 4.68 | 29.19 | V100 | 42.87 | 43.79 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-s16_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_160k_ade20k/upernet_deit-s16_512x512_160k_ade20k_20210621_160903-5110d916.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_512x512_160k_ade20k/20210621_160903.log.json) | +| UPerNet | DeiT-S + MLN | 512x512 | 160000 | 5.69 | 11.18 | V100 | 43.82 | 45.07 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-s16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_mln_512x512_160k_ade20k/upernet_deit-s16_mln_512x512_160k_ade20k_20210621_161021-fb9a5dfb.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_mln_512x512_160k_ade20k/20210621_161021.log.json) | +| UPerNet | DeiT-S + LN + MLN | 512x512 | 160000 | 5.69 | 12.39 | V100 | 43.52 | 45.01 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-s16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_ln_mln_512x512_160k_ade20k/upernet_deit-s16_ln_mln_512x512_160k_ade20k_20210621_161021-c0cd652f.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-s16_ln_mln_512x512_160k_ade20k/20210621_161021.log.json) | +| UPerNet | DeiT-B | 512x512 | 80000 | 7.75 | 9.69 | V100 | 45.24 | 46.73 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-b16_upernet_8xb2-80k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_80k_ade20k/upernet_deit-b16_512x512_80k_ade20k_20210624_130529-1e090789.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_80k_ade20k/20210624_130529.log.json) | +| UPerNet | DeiT-B | 512x512 | 160000 | 7.75 | 10.39 | V100 | 45.36 | 47.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-b16_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_160k_ade20k/upernet_deit-b16_512x512_160k_ade20k_20210621_180100-828705d7.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_512x512_160k_ade20k/20210621_180100.log.json) | +| UPerNet | DeiT-B + MLN | 512x512 | 160000 | 9.21 | 7.78 | V100 | 45.46 | 47.16 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-b16_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_mln_512x512_160k_ade20k/upernet_deit-b16_mln_512x512_160k_ade20k_20210621_191949-4e1450f3.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_mln_512x512_160k_ade20k/20210621_191949.log.json) | +| UPerNet | DeiT-B + LN + MLN | 512x512 | 160000 | 9.21 | 7.75 | V100 | 45.37 | 47.23 | [config](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_deit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_ln_mln_512x512_160k_ade20k/upernet_deit-b16_ln_mln_512x512_160k_ade20k_20210623_153535-8a959c14.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vit/upernet_deit-b16_ln_mln_512x512_160k_ade20k/20210623_153535.log.json) | ## Citation diff --git a/configs/vpd/README.md b/configs/vpd/README.md new file mode 100644 index 00000000000..e90085bec9e --- /dev/null +++ b/configs/vpd/README.md @@ -0,0 +1,50 @@ +# VPD + +> [Unleashing Text-to-Image Diffusion Models for Visual Perception](https://arxiv.org/abs/2303.02153) + +## Introduction + + + +Official Repo + +## Abstract + + + +Diffusion models (DMs) have become the new trend of generative models and have demonstrated a powerful ability of conditional synthesis. Among those, text-to-image diffusion models pre-trained on large-scale image-text pairs are highly controllable by customizable prompts. Unlike the unconditional generative models that focus on low-level attributes and details, text-to-image diffusion models contain more high-level knowledge thanks to the vision-language pre-training. In this paper, we propose VPD (Visual Perception with a pre-trained Diffusion model), a new framework that exploits the semantic information of a pre-trained text-to-image diffusion model in visual perception tasks. Instead of using the pre-trained denoising autoencoder in a diffusion-based pipeline, we simply use it as a backbone and aim to study how to take full advantage of the learned knowledge. Specifically, we prompt the denoising decoder with proper textual inputs and refine the text features with an adapter, leading to a better alignment to the pre-trained stage and making the visual contents interact with the text prompts. We also propose to utilize the cross-attention maps between the visual features and the text features to provide explicit guidance. Compared with other pre-training methods, we show that vision-language pre-trained diffusion models can be faster adapted to downstream visual perception tasks using the proposed VPD. Extensive experiments on semantic segmentation, referring image segmentation and depth estimation demonstrates the effectiveness of our method. Notably, VPD attains 0.254 RMSE on NYUv2 depth estimation and 73.3% oIoU on RefCOCO-val referring image segmentation, establishing new records on these two benchmarks. + + + +
+ +
+ +## Usage + +To run training or inference with VPD model, please install the required packages via + +```sh +pip install -r requirements/albu.txt +pip install -r requirements/optional.txt +``` + +## Results and models + +### NYU + +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | RMSE | d1 | d2 | d3 | REL | log_10 | config | download | +| ------ | --------------------- | --------- | ------- | -------- | -------------- | ------ | ----- | ----- | ----- | ----- | ----- | ------ | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| VPD | Stable-Diffusion-v1-5 | 480x480 | 25000 | - | - | A100 | 0.253 | 0.964 | 0.995 | 0.999 | 0.069 | 0.030 | [config](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/vpd/vpd_sd_4xb8-25k_nyu-480x480.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-480x480_20230908-66144bc4.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-480x480_20230908.json) | +| VPD | Stable-Diffusion-v1-5 | 512x512 | 25000 | - | - | A100 | 0.258 | 0.963 | 0.995 | 0.999 | 0.072 | 0.031 | [config](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/vpd/vpd_sd_4xb8-25k_nyu-512x512.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-512x512_20230918-60cefcff.pth) \| [log](https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-512x512_20230918.json) | + +## Citation + +```bibtex +@article{zhao2023unleashing, + title={Unleashing Text-to-Image Diffusion Models for Visual Perception}, + author={Zhao, Wenliang and Rao, Yongming and Liu, Zuyan and Liu, Benlin and Zhou, Jie and Lu, Jiwen}, + journal={ICCV}, + year={2023} +} +``` diff --git a/configs/vpd/metafile.yaml b/configs/vpd/metafile.yaml new file mode 100644 index 00000000000..ccdc0e81eb2 --- /dev/null +++ b/configs/vpd/metafile.yaml @@ -0,0 +1,56 @@ +Collections: +- Name: VPD + License: Apache License 2.0 + Metadata: + Training Data: + - NYU + Paper: + Title: Unleashing Text-to-Image Diffusion Models for Visual Perception + URL: https://arxiv.org/abs/2303.02153 + README: configs/vpd/README.md + Frameworks: + - PyTorch +Models: +- Name: vpd_sd_4xb8-25k_nyu-480x480 + In Collection: VPD + Results: + Task: Depth Estimation + Dataset: NYU + Metrics: + RMSE: 0.253 + Config: configs/vpd/vpd_sd_4xb8-25k_nyu-480x480.py + Metadata: + Training Data: NYU + Batch Size: 32 + Architecture: + - Stable-Diffusion + Training Resources: 8x A100 GPUS + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-480x480_20230908-66144bc4.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-480x480_20230908.json + Paper: + Title: 'High-Resolution Image Synthesis with Latent Diffusion Models' + URL: https://arxiv.org/abs/2112.10752 + Code: https://github.com/open-mmlab/mmsegmentation/tree/main/mmseg/models/backbones/vpd.py#L333 + Framework: PyTorch +- Name: vpd_sd_4xb8-25k_nyu-512x512 + In Collection: VPD + Alias: vpd_depth + Results: + Task: Depth Estimation + Dataset: NYU + Metrics: + RMSE: 0.258 + Config: configs/vpd/vpd_sd_4xb8-25k_nyu-512x512.py + Metadata: + Training Data: NYU + Batch Size: 32 + Architecture: + - Stable-Diffusion + Training Resources: 8x A100 GPUS + Weights: https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-512x512_20230918-60cefcff.pth + Training log: https://download.openmmlab.com/mmsegmentation/v0.5/vpd/vpd_sd_4xb8-25k_nyu-512x512_20230918.json + Paper: + Title: 'High-Resolution Image Synthesis with Latent Diffusion Models' + URL: https://arxiv.org/abs/2112.10752 + Code: https://github.com/open-mmlab/mmsegmentation/tree/main/mmseg/models/backbones/vpd.py#L333 + Framework: PyTorch diff --git a/configs/vpd/vpd_sd_4xb8-25k_nyu-480x480.py b/configs/vpd/vpd_sd_4xb8-25k_nyu-480x480.py new file mode 100644 index 00000000000..0d14d8dd338 --- /dev/null +++ b/configs/vpd/vpd_sd_4xb8-25k_nyu-480x480.py @@ -0,0 +1,38 @@ +_base_ = [ + '../_base_/models/vpd_sd.py', '../_base_/datasets/nyu.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_25k.py' +] + +crop_size = (480, 480) + +model = dict( + type='DepthEstimator', + data_preprocessor=dict(size=crop_size), + backbone=dict( + class_embed_path='https://download.openmmlab.com/mmsegmentation/' + 'v0.5/vpd/nyu_class_embeddings.pth', + class_embed_select=True, + pad_shape=512, + unet_cfg=dict(use_attn=False), + ), + decode_head=dict( + type='VPDDepthHead', + in_channels=[320, 640, 1280, 1280], + max_depth=10, + fmap_border=(1, 1), + ), + test_cfg=dict(mode='slide_flip', crop_size=crop_size, stride=(160, 160))) + +default_hooks = dict( + checkpoint=dict(save_best='rmse', rule='less', max_keep_ckpts=1)) + +# custom optimizer +optim_wrapper = dict( + constructor='ForceDefaultOptimWrapperConstructor', + paramwise_cfg=dict( + bias_decay_mult=0, + force_default_settings=True, + custom_keys={ + 'backbone.encoder_vq': dict(lr_mult=0), + 'backbone.unet': dict(lr_mult=0.01), + })) diff --git a/configs/vpd/vpd_sd_4xb8-25k_nyu-512x512.py b/configs/vpd/vpd_sd_4xb8-25k_nyu-512x512.py new file mode 100644 index 00000000000..e89eb9c422f --- /dev/null +++ b/configs/vpd/vpd_sd_4xb8-25k_nyu-512x512.py @@ -0,0 +1,37 @@ +_base_ = [ + '../_base_/models/vpd_sd.py', '../_base_/datasets/nyu_512x512.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_25k.py' +] + +crop_size = (512, 512) + +model = dict( + type='DepthEstimator', + data_preprocessor=dict(size=crop_size), + backbone=dict( + class_embed_path='https://download.openmmlab.com/mmsegmentation/' + 'v0.5/vpd/nyu_class_embeddings.pth', + class_embed_select=True, + pad_shape=512, + unet_cfg=dict(use_attn=False), + ), + decode_head=dict( + type='VPDDepthHead', + in_channels=[320, 640, 1280, 1280], + max_depth=10, + ), + test_cfg=dict(mode='slide_flip', crop_size=crop_size, stride=(128, 128))) + +default_hooks = dict( + checkpoint=dict(save_best='rmse', rule='less', max_keep_ckpts=1)) + +# custom optimizer +optim_wrapper = dict( + constructor='ForceDefaultOptimWrapperConstructor', + paramwise_cfg=dict( + bias_decay_mult=0, + force_default_settings=True, + custom_keys={ + 'backbone.encoder_vq': dict(lr_mult=0), + 'backbone.unet': dict(lr_mult=0.01), + })) diff --git a/dataset-index.yml b/dataset-index.yml new file mode 100644 index 00000000000..30ff0ee005a --- /dev/null +++ b/dataset-index.yml @@ -0,0 +1,80 @@ +openxlab: true +ade20k: + dataset: OpenDataLab/ADE20K_2016 + download_root: data + data_root: data/ade + +cityscapes: + dataset: OpenDataLab/CityScapes + download_root: data + data_root: data/cityscapes + +voc2012: + dataset: OpenDataLab/PASCAL_VOC2012 + download_root: data + data_root: data/VOCdevkit/VOC2012 + +cocostuff: + dataset: OpenDataLab/COCO-Stuff + download_root: data + data_root: data/coco_stuff164k + +mapillary: + dataset: OpenDataLab/Mapillary + download_root: data + data_root: data/mapillary + +pascal_context: + dataset: OpenDataLab/VOC2010 + download_root: data + data_root: data/VOCdevkit/VOC2010 + +isaid: + dataset: OpenDataLab/iSAID + download_root: data + data_root: data/iSAID + +isprs_potsdam: + dataset: OpenDataLab/ISPRS_Potsdam + download_root: data + data_root: data/potsdam + +loveda: + dataset: OpenDataLab/LoveDA + download_root: data + data_root: data/loveDA + +chase_db1: + dataset: OpenDataLab/CHASE_DB1 + download_root: data + data_root: data/CHASE_DB1 + +drive: + dataset: OpenDataLab/DRIVE + download_root: data + data_root: data/DRIVE + +hrf: + dataset: OpenDataLab/HRF + download_root: data + data_root: data/HRF + +stare: + dataset: OpenDataLab/STARE + download_root: data + data_root: data/STARE + +synapse: + dataset: OpenDataLab/SurgVisDom + download_root: data + data_root: data/synapse + +refuge: + dataset: OpenDataLab/REFUGE_Challenge + download_root: data + data_root: data/REFUGE + +lip: + dataset: OpenDataLab/LIP + download_root: data + data_root: data/LIP diff --git a/demo/MMSegmentation_Tutorial.ipynb b/demo/MMSegmentation_Tutorial.ipynb index 1d92342ae64..ac8601b321e 100644 --- a/demo/MMSegmentation_Tutorial.ipynb +++ b/demo/MMSegmentation_Tutorial.ipynb @@ -7,7 +7,7 @@ "id": "view-in-github" }, "source": [ - "\"Open" + "\"Open" ] }, { @@ -89,7 +89,7 @@ "outputs": [], "source": [ "!rm -rf mmsegmentation\n", - "!git clone -b dev-1.x https://github.com/open-mmlab/mmsegmentation.git \n", + "!git clone -b main https://github.com/open-mmlab/mmsegmentation.git \n", "%cd mmsegmentation\n", "!pip install -e ." ] diff --git a/demo/classroom__rgb_00283.jpg b/demo/classroom__rgb_00283.jpg new file mode 100644 index 00000000000..1df37e92483 Binary files /dev/null and b/demo/classroom__rgb_00283.jpg differ diff --git a/demo/inference_demo.ipynb b/demo/inference_demo.ipynb index 3a29a964660..455c5df4e1f 100644 --- a/demo/inference_demo.ipynb +++ b/demo/inference_demo.ipynb @@ -2,28 +2,9 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "mkdir: ../checkpoints: File exists\n", - "--2023-02-23 19:23:01-- https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth\n", - "正在解析主机 download.openmmlab.com (download.openmmlab.com)... 116.0.89.205, 116.0.89.209, 116.0.89.207, ...\n", - "正在连接 download.openmmlab.com (download.openmmlab.com)|116.0.89.205|:443... 已连接。\n", - "已发出 HTTP 请求,正在等待回应... 200 OK\n", - "长度:196205945 (187M) [application/octet-stream]\n", - "正在保存至: “../checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth.3”\n", - "\n", - "pspnet_r50-d8_512x1 100%[===================>] 187.12M 861KB/s 用时 2m 56s \n", - "\n", - "2023-02-23 19:25:57 (1.06 MB/s) - 已保存 “../checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth.3” [196205945/196205945])\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "!mkdir ../checkpoints\n", "!wget https://download.openmmlab.com/mmsegmentation/v0.5/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth -P ../checkpoints" @@ -31,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "pycharm": { "is_executing": true @@ -40,7 +21,6 @@ "outputs": [], "source": [ "import torch\n", - "import mmcv\n", "import matplotlib.pyplot as plt\n", "from mmengine.model.utils import revert_sync_batchnorm\n", "from mmseg.apis import init_model, inference_model, show_result_pyplot" @@ -48,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "pycharm": { "is_executing": true @@ -62,35 +42,17 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/xxc/Desktop/pjlab/mmsegv2/mmseg/models/builder.py:36: UserWarning: ``build_loss`` would be deprecated soon, please use ``mmseg.registry.MODELS.build()`` \n", - " warnings.warn('``build_loss`` would be deprecated soon, please use '\n", - "/Users/xxc/Desktop/pjlab/mmsegv2/mmseg/models/losses/cross_entropy_loss.py:235: UserWarning: Default ``avg_non_ignore`` is False, if you would like to ignore the certain label and average loss over non-ignore labels, which is the same with PyTorch official cross_entropy, set ``avg_non_ignore=True``.\n", - " warnings.warn(\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loads checkpoint by local backend from path: ../checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth\n" - ] - } - ], + "outputs": [], "source": [ "# build the model from a config file and a checkpoint file\n", - "model = init_model(config_file, checkpoint_file, device='cuda:0')" + "model = init_model(config_file, checkpoint_file, device='cpu')" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -103,42 +65,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/opt/anaconda3/envs/pt1.13/lib/python3.10/site-packages/mmengine/visualization/visualizer.py:163: UserWarning: `Visualizer` backend is not initialized because save_dir is None.\n", - " warnings.warn('`Visualizer` backend is not initialized '\n" - ] - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# show the results\n", - "vis_result = show_result_pyplot(model, img, result)\n", - "plt.imshow(mmcv.bgr2rgb(vis_result))" + "vis_result = show_result_pyplot(model, img, result, show=False)\n", + "plt.imshow(vis_result)" ] }, { @@ -165,7 +98,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.10.11" }, "pycharm": { "stem_cell": { diff --git a/demo/rs_image_inference.py b/demo/rs_image_inference.py new file mode 100644 index 00000000000..799181f93c7 --- /dev/null +++ b/demo/rs_image_inference.py @@ -0,0 +1,50 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from argparse import ArgumentParser + +from mmseg.apis import RSImage, RSInferencer + + +def main(): + parser = ArgumentParser() + parser.add_argument('image', help='Image file path') + parser.add_argument('config', help='Config file') + parser.add_argument('checkpoint', help='Checkpoint file') + parser.add_argument( + '--output-path', + help='Path to save result image', + default='result.png') + parser.add_argument( + '--batch-size', + type=int, + default=1, + help='maximum number of windows inferred simultaneously') + parser.add_argument( + '--window-size', + help='window xsize,ysize', + default=(224, 224), + type=int, + nargs=2) + parser.add_argument( + '--stride', + help='window xstride,ystride', + default=(224, 224), + type=int, + nargs=2) + parser.add_argument( + '--thread', default=1, type=int, help='number of inference threads') + parser.add_argument( + '--device', default='cuda:0', help='Device used for inference') + args = parser.parse_args() + inferencer = RSInferencer.from_config_path( + args.config, + args.checkpoint, + batch_size=args.batch_size, + thread=args.thread, + device=args.device) + image = RSImage(args.image) + + inferencer.run(image, args.window_size, args.stride, args.output_path) + + +if __name__ == '__main__': + main() diff --git a/docker/Dockerfile b/docker/Dockerfile index 73a0fac1215..26420ddbbb3 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,7 +1,7 @@ ARG PYTORCH="1.11.0" ARG CUDA="11.3" ARG CUDNN="8" -ARG MMCV="2.0.0rc4" +ARG MMCV="2.0.1" FROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel @@ -13,7 +13,7 @@ ENV CMAKE_PREFIX_PATH="$(dirname $(which conda))/../" RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub RUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub -RUN apt-get update && apt-get install -y git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 \ +RUN apt-get update && apt-get install -y git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 libgl1-mesa-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -28,7 +28,7 @@ RUN ["/bin/bash", "-c", "mim install mmengine"] RUN ["/bin/bash", "-c", "mim install mmcv==${MMCV}"] # Install MMSegmentation -RUN git clone -b dev-1.x https://github.com/open-mmlab/mmsegmentation.git /mmsegmentation +RUN git clone -b main https://github.com/open-mmlab/mmsegmentation.git /mmsegmentation WORKDIR /mmsegmentation ENV FORCE_CUDA="1" RUN pip install -r requirements.txt diff --git a/docker/serve/Dockerfile b/docker/serve/Dockerfile index cf127ddbe65..8a6786f1182 100644 --- a/docker/serve/Dockerfile +++ b/docker/serve/Dockerfile @@ -3,8 +3,8 @@ ARG CUDA="11.3" ARG CUDNN="8" FROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel -ARG MMCV="2.0.0rc4" -ARG MMSEG="1.0.0rc6" +ARG MMCV="2.0.1" +ARG MMSEG="1.1.2" ENV PYTHONUNBUFFERED TRUE diff --git a/docs/en/advanced_guides/add_datasets.md b/docs/en/advanced_guides/add_datasets.md index f33f3d32c6d..fbfa36940c4 100644 --- a/docs/en/advanced_guides/add_datasets.md +++ b/docs/en/advanced_guides/add_datasets.md @@ -1,4 +1,62 @@ -# \[WIP\] Add New Datasets +# Add New Datasets + +## Add new custom dataset + +Here we show how to develop a new custom dataset. + +1. Create a new file `mmseg/datasets/example.py` + + ```python + from mmseg.registry import DATASETS + from .basesegdataset import BaseSegDataset + + + @DATASETS.register_module() + class ExampleDataset(BaseSegDataset): + + METAINFO = dict( + classes=('xxx', 'xxx', ...), + palette=[[x, x, x], [x, x, x], ...]) + + def __init__(self, aeg1, arg2): + pass + ``` + +2. Import the module in `mmseg/datasets/__init__.py` + + ```python + from .example import ExampleDataset + ``` + +3. Use it by creating a new new dataset config file `configs/_base_/datasets/example_dataset.py` + + ```python + dataset_type = 'ExampleDataset' + data_root = 'data/example/' + ... + ``` + +4. Add dataset meta information in `mmseg/utils/class_names.py` + + ```python + def example_classes(): + return [ + 'xxx', 'xxx', + ... + ] + + def example_palette(): + return [ + [x, x, x], [x, x, x], + ... + ] + dataset_aliases ={ + 'example': ['example', ...], + ... + } + ``` + +**Note:** If the new dataset does not satisfy the mmseg requirements, a data preprocessing script needs to be prepared in `tools/dataset_converters/` ## Customize datasets by reorganizing data @@ -26,26 +84,12 @@ An example of file structure is as followed. A training pair will consist of the files with same suffix in img_dir/ann_dir. -If `split` argument is given, only part of the files in img_dir/ann_dir will be loaded. -We may specify the prefix of files we would like to be included in the split txt. +Some datasets don't release the test set or don't release the ground truth of the test set, and we cannot evaluate models locally without the ground truth of the test set, so we set the validation set as the default test set in config files. -More specifically, for a split txt like following, +About how to build your own datasets or implement a new dataset class please refer to the [datasets guide](./datasets.md) for more detailed information. -```none -xxx -zzz -``` - -Only -`data/my_dataset/img_dir/train/xxx{img_suffix}`, -`data/my_dataset/img_dir/train/zzz{img_suffix}`, -`data/my_dataset/ann_dir/train/xxx{seg_map_suffix}`, -`data/my_dataset/ann_dir/train/zzz{seg_map_suffix}` will be loaded. - -:::{note} -The annotations are images of shape (H, W), the value pixel should fall in range `[0, num_classes - 1]`. +**Note:** The annotations are images of shape (H, W), the value pixel should fall in range `[0, num_classes - 1]`. You may use `'P'` mode of [pillow](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#palette) to create your annotation image with color. -::: ## Customize datasets by mixing dataset @@ -59,14 +103,14 @@ For example, suppose the original dataset is `Dataset_A`, to repeat it, the conf ```python dataset_A_train = dict( - type='RepeatDataset', - times=N, - dataset=dict( # This is the original config of Dataset_A - type='Dataset_A', - ... - pipeline=train_pipeline - ) + type='RepeatDataset', + times=N, + dataset=dict( # This is the original config of Dataset_A + type='Dataset_A', + ... + pipeline=train_pipeline ) +) ``` ### Concatenate dataset @@ -111,7 +155,9 @@ dataset_B_train = dict( ) ) train_dataloader = dict( - dataset=dict('ConcatDataset', datasets=[dataset_A_train, dataset_B_train])) + dataset=dict( + type='ConcatDataset', + datasets=[dataset_A_train, dataset_B_train])) val_dataloader = dict(dataset=dataset_A_val) test_dataloader = dict(dataset=dataset_A_test) @@ -123,8 +169,7 @@ You can refer base dataset [tutorial](https://mmengine.readthedocs.io/en/latest/ ### Multi-image Mix Dataset We use `MultiImageMixDataset` as a wrapper to mix images from multiple datasets. -`MultiImageMixDataset` can be used by multiple images mixed data augmentation -like mosaic and mixup. +`MultiImageMixDataset` can be used by multiple images mixed data augmentation like mosaic and mixup. An example of using `MultiImageMixDataset` with `Mosaic` data augmentation: @@ -139,8 +184,6 @@ train_pipeline = [ train_dataset = dict( type='MultiImageMixDataset', dataset=dict( - classes=classes, - palette=palette, type=dataset_type, reduce_zero_label=False, img_dir=data_root + "images/train", diff --git a/docs/en/advanced_guides/add_metrics.md b/docs/en/advanced_guides/add_metrics.md index 0a25a81fc47..0298826f05c 100644 --- a/docs/en/advanced_guides/add_metrics.md +++ b/docs/en/advanced_guides/add_metrics.md @@ -1 +1,81 @@ # Add New Metrics + +## Develop with the source code of MMSegmentation + +Here we show how to develop a new metric with an example of `CustomMetric` as the following. + +1. Create a new file `mmseg/evaluation/metrics/custom_metric.py`. + + ```python + from typing import List, Sequence + + from mmengine.evaluator import BaseMetric + + from mmseg.registry import METRICS + + + @METRICS.register_module() + class CustomMetric(BaseMetric): + + def __init__(self, arg1, arg2): + """ + The metric first processes each batch of data_samples and predictions, + and appends the processed results to the results list. Then it + collects all results together from all ranks if distributed training + is used. Finally, it computes the metrics of the entire dataset. + """ + + def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: + pass + + def compute_metrics(self, results: list) -> dict: + pass + + def evaluate(self, size: int) -> dict: + pass + ``` + + In the above example, `CustomMetric` is a subclass of `BaseMetric`. It has three methods: `process`, `compute_metrics` and `evaluate`. + + - `process()` process one batch of data samples and predictions. The processed results are stored in `self.results` which will be used to compute the metrics after all the data samples are processed. Please refer to [MMEngine documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/design/evaluation.md) for more details. + + - `compute_metrics()` is used to compute the metrics from the processed results. + + - `evaluate()` is an interface to compute the metrics and return the results. It will be called by `ValLoop` or `TestLoop` in the `Runner`. In most cases, you don't need to override this method, but you can override it if you want to do some extra work. + + **Note:** You might find the details of calling `evaluate()` method in the `Runner` [here](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py#L366). The `Runner` is the executor of the training and testing process, you can find more details about it at the [engine document](./engine.md). + +2. Import the new metric in `mmseg/evaluation/metrics/__init__.py`. + + ```python + from .custom_metric import CustomMetric + __all__ = ['CustomMetric', ...] + ``` + +3. Add the new metric to the config file. + + ```python + val_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + test_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + ``` + +## Develop with the released version of MMSegmentation + +The above example shows how to develop a new metric with the source code of MMSegmentation. If you want to develop a new metric with the released version of MMSegmentation, you can follow the following steps. + +1. Create a new file `/Path/to/metrics/custom_metric.py`, implement the `process`, `compute_metrics` and `evaluate` methods, `evaluate` method is optional. + +2. Import the new metric in your code or config file. + + ```python + from path.to.metrics import CustomMetric + ``` + + or + + ```python + custom_imports = dict(imports=['/Path/to/metrics'], allow_failed_imports=False) + + val_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + test_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + ``` diff --git a/docs/en/advanced_guides/add_models.md b/docs/en/advanced_guides/add_models.md index e470e48ef20..ed5c9ce6112 100644 --- a/docs/en/advanced_guides/add_models.md +++ b/docs/en/advanced_guides/add_models.md @@ -49,7 +49,7 @@ Here we show how to develop a new backbone with an example of MobileNet. ### Add new heads -In MMSegmentation, we provide a [BaseDecodeHead](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/models/decode_heads/decode_head.py#L17) for developing all segmentation heads. +In MMSegmentation, we provide a [BaseDecodeHead](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/decode_heads/decode_head.py#L17) for developing all segmentation heads. All newly implemented decode heads should be derived from it. Here we show how to develop a new head with the example of [PSPNet](https://arxiv.org/abs/1612.01105) as the following. @@ -166,7 +166,7 @@ loss_decode=dict(type='MyLoss', loss_weight=1.0)) ### Add new data preprocessor -In MMSegmentation 1.x versions, we use [SegDataPreProcessor](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/data_preprocessor.py#L13) to copy data to the target device and preprocess the data into the model input format as default. Here we show how to develop a new data preprocessor. +In MMSegmentation 1.x versions, we use [SegDataPreProcessor](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/data_preprocessor.py#L13) to copy data to the target device and preprocess the data into the model input format as default. Here we show how to develop a new data preprocessor. 1. Create a new file `mmseg/models/my_datapreprocessor.py`. @@ -204,7 +204,7 @@ In MMSegmentation 1.x versions, we use [SegDataPreProcessor](https://github.com/ The segmentor is an algorithmic architecture in which users can customize their algorithms by adding customized components and defining the logic of algorithm execution. Please refer to [the model document](./models.md) for more details. -Since the [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/models/segmentors/base.py#L15) in MMSegmentation unifies three modes for a forward process, to develop a new segmentor, users need to overwrite `loss`, `predict` and `_forward` methods corresponding to the `loss`, `predict` and `tensor` modes. +Since the [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/segmentors/base.py#L15) in MMSegmentation unifies three modes for a forward process, to develop a new segmentor, users need to overwrite `loss`, `predict` and `_forward` methods corresponding to the `loss`, `predict` and `tensor` modes. Here we show how to develop a new segmentor. diff --git a/docs/en/advanced_guides/data_flow.md b/docs/en/advanced_guides/data_flow.md index 20d23084ab0..404035aee45 100644 --- a/docs/en/advanced_guides/data_flow.md +++ b/docs/en/advanced_guides/data_flow.md @@ -16,7 +16,7 @@ val_cfg = dict(type='ValLoop') test_cfg = dict(type='TestLoop') ``` -In the above diagram, the red line indicates the [train_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#train_step). At each training iteration, dataloader loads images from storage and transfer to data preprocessor, data preprocessor would put images to the specific device and stack data to batch, then model accepts the batch data as inputs, finally the outputs of the model would be sent to optimizer. The blue line indicates [val_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#val_step) and [test_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#test_step). The dataflow of these two process is similar to the `train_step` except the outputs of model, since model parameters are freezed when doing evaluation, the model output would be transferred to [Evaluator](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/evaluation.md#ioumetric) to compute metrics. +In the above diagram, the red line indicates the [train_step](./models.md#train_step). At each training iteration, dataloader loads images from storage and transfer to data preprocessor, data preprocessor would put images to the specific device and stack data to batch, then model accepts the batch data as inputs, finally the outputs of the model would be sent to optimizer. The blue line indicates [val_step](./models.md#val_step) and [test_step](./models.md#test_step). The dataflow of these two process is similar to the `train_step` except the outputs of model, since model parameters are freezed when doing evaluation, the model output would be transferred to [Evaluator](./evaluation.md#ioumetric) to compute metrics. ## Dataflow convention in MMSegmentation @@ -26,7 +26,7 @@ From the diagram above, we could see the basic dataflow. In this section, we wou DataLoader is an essential component in training and testing pipelines of MMEngine. Conceptually, it is derived from and consistent with [PyTorch](https://pytorch.org/). DataLoader loads data from filesystem and the original data passes through data preparation pipeline, then it would be sent to Data Preprocessor. -MMSegmentation defines the default data format at [PackSegInputs](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/transforms/formatting.py#L12), it's the last component of `train_pipeline` and `test_pipeline`. Please refer to [data transform documentation](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/transforms.html) for more information about data transform `pipeline`. +MMSegmentation defines the default data format at [PackSegInputs](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/transforms/formatting.py#L12), it's the last component of `train_pipeline` and `test_pipeline`. Please refer to [data transform documentation](./transforms.md) for more information about data transform `pipeline`. Without any modifications, the return value of PackSegInputs is usually a `dict` and has only two keys, `inputs` and `data_samples`. The following pseudo-code shows the data types of the data loader output in mmseg, which is a batch of fetched data samples from the dataset, and data loader packs them into a dictionary of the list. `inputs` is the list of input tensors to the model and `data_samples` contains a list of input images' meta information and corresponding ground truth. @@ -37,11 +37,11 @@ dict( ) ``` -**Note:** [SegDataSample](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/structures/seg_data_sample.py) is a data structure interface of MMSegmentation, it is used as an interface between different components. `SegDataSample` implements the abstract data element `mmengine.structures.BaseDataElement`, please refer to [the SegDataSample documentation](https://mmsegmentation.readthedocs.io/en/1.x/advanced_guides/structures.html) and [data element documentation](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/data_element.html) in [MMEngine](https://github.com/open-mmlab/mmengine) for more information. +**Note:** [SegDataSample](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/structures/seg_data_sample.py) is a data structure interface of MMSegmentation, it is used as an interface between different components. `SegDataSample` implements the abstract data element `mmengine.structures.BaseDataElement`, please refer to [the SegDataSample documentation](./structures.md) and [data element documentation](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/data_element.html) in [MMEngine](https://github.com/open-mmlab/mmengine) for more information. ### Data Preprocessor to Model -Though drawn separately in the diagram [above](#overview-of-dataflow), data_preprocessor is a part of the model and thus can be found in [Model tutorial](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/models.html) at data preprocessor chapter. +Though drawn separately in the diagram [above](#overview-of-dataflow), data_preprocessor is a part of the model and thus can be found in [Model tutorial](./models.md) at data preprocessor chapter. The return value of data preprocessor is a dictionary, containing `inputs` and `data_samples`, `inputs` is batched images, a 4D tensor, and some additional meta info used in data preprocesses would be added to the `data_samples`. When transferred to the network, the dictionary would be unpacked to two values. The following pseudo-codes show the return value of the data preprocessor and the input values of model. @@ -59,21 +59,21 @@ class Network(BaseSegmentor): pass ``` -**Note:** Model forward has 3 kinds of mode, which is controlled by input argumentmode, please refer [model tutorial](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md) for more details. +**Note:** Model forward has 3 kinds of mode, which is controlled by input argumentmode, please refer [model tutorial](./models.md) for more details. ### Model output -As [model tutorial](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#forward) mentioned 3 kinds of mode forward with 3 kinds of output. `train_step`and `test_step`(or `val_step`) correspond to `'loss'` and `'predict'` respectively. +As [model tutorial](./models.md#forward) mentioned 3 kinds of mode forward with 3 kinds of output. `train_step`and `test_step`(or `val_step`) correspond to `'loss'` and `'predict'` respectively. -In `test_step` or `val_step`, the inference results would be transferred to `Evaluator`. You might read the [evaluation document](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/evaluation.html) for more information about `Evaluator`. +In `test_step` or `val_step`, the inference results would be transferred to `Evaluator`. You might read the [evaluation document](./evaluation.md) for more information about `Evaluator`. -After inference, the [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/segmentors/base.py#L15) in MMSegmentation would do a simple post process to pack inference results, the segmentation logits produced by the neural network, segmentation mask after the `argmax` operation and ground truth(if exists) would be packed into a similar `SegDataSample` instance. The return value of [postprocess_result](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/segmentors/base.py#L132) is a **`List` of `SegDataSample`**. Following diagram shows the key properties of these `SegDataSample` instances. +After inference, the [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/segmentors/base.py#L15) in MMSegmentation would do a simple post process to pack inference results, the segmentation logits produced by the neural network, segmentation mask after the `argmax` operation and ground truth(if exists) would be packed into a similar `SegDataSample` instance. The return value of [postprocess_result](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/segmentors/base.py#L132) is a **`List` of `SegDataSample`**. Following diagram shows the key properties of these `SegDataSample` instances. ![SegDataSample](https://user-images.githubusercontent.com/15952744/209912225-ab46a8d9-904a-43cb-8bf1-8bec4938ed29.png) -The same as Data Preprocessor, loss function is also a part of the model, it's a property of [decode head](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py#L142). +The same as Data Preprocessor, loss function is also a part of the model, it's a property of [decode head](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/decode_heads/decode_head.py#L142). -In MMSegmentation, the method [loss_by_feat](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py#L291) of `decode_head` is an unified interface used to compute loss. +In MMSegmentation, the method [loss_by_feat](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/decode_heads/decode_head.py#L291) of `decode_head` is an unified interface used to compute loss. Parameters: @@ -84,4 +84,4 @@ Returns: - dict\[str, Tensor\]: a dictionary of loss components -**Note:** The `train_step` transfers the loss into OptimWrapper to update the weights in model, please refer [train_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#train_step) for more details. +**Note:** The `train_step` transfers the loss into OptimWrapper to update the weights in model, please refer [train_step](./models.md#train_step) for more details. diff --git a/docs/en/advanced_guides/datasets.md b/docs/en/advanced_guides/datasets.md index a1b8044b3d5..1efc3346fd1 100644 --- a/docs/en/advanced_guides/datasets.md +++ b/docs/en/advanced_guides/datasets.md @@ -1,14 +1,14 @@ # Dataset -Dataset classes in MMSegmentation have two functions: (1) load data information after [data preparation](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/2_dataset_prepare.md) -and (2) send data into [dataset transform pipeline](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/basesegdataset.py#L141) to do [data augmentation](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/transforms.md). +Dataset classes in MMSegmentation have two functions: (1) load data information after [data preparation](../user_guides/2_dataset_prepare.md) +and (2) send data into [dataset transform pipeline](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L141) to do [data augmentation](./transforms.md). There are 2 kinds of loaded information: (1) meta information which is original dataset information such as categories (classes) of dataset and their corresponding palette information, (2) data information which includes the path of dataset images and labels. The tutorial includes some main interfaces in MMSegmentation 1.x dataset class: methods of loading data information and modifying dataset classes in base dataset class, and the relationship between dataset and the data transform pipeline. ## Main Interfaces -Take Cityscapes as an example, if you want to run the example, please download and [preprocess](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/2_dataset_prepare.md#cityscapes) +Take Cityscapes as an example, if you want to run the example, please download and [preprocess](../user_guides/2_dataset_prepare.md#cityscapes) Cityscapes dataset in `data` directory, before running the demo code: Instantiate Cityscapes training dataset: @@ -108,7 +108,7 @@ print(dataset.metainfo) ``` The return value of dataset `__getitem__` method is the output of data samples after data augmentation, whose type is also `dict`. It has two fields: `'inputs'` corresponding to images after data augmentation, -and `'data_samples'` corresponding to `SegDataSample`\](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/structures.md) which is new data structures in MMSegmentation 1.x, +and `'data_samples'` corresponding to [`SegDataSample`](./structures.md) which is new data structures in MMSegmentation 1.x, and `gt_sem_seg` of `SegDataSample` has labels after data augmentation operations. ```python @@ -179,19 +179,19 @@ print(dataset[0]) ## BaseSegDataset -As mentioned above, dataset classes have the same functions, we implemented [`BaseSegDataset`](https://mmsegmentation.readthedocs.io/en/dev-1.x/api.html?highlight=BaseSegDataset#mmseg.datasets.BaseSegDataset) to reues the common functions. +As mentioned above, dataset classes have the same functions, we implemented [`BaseSegDataset`](https://mmsegmentation.readthedocs.io/en/latest/api.html?highlight=BaseSegDataset#mmseg.datasets.BaseSegDataset) to reues the common functions. It inherits [`BaseDataset` of MMEngine](https://github.com/open-mmlab/mmengine/blob/main/docs/en/advanced_tutorials/basedataset.md) and follows unified initialization process of OpenMMLab. It supports the highly effective interior storing format, some functions like dataset concatenation and repeatedly sampling. In MMSegmentation `BaseSegDataset`, the **method of loading data information** (`load_data_list`) is redefined and adds new `get_label_map` method to **modify dataset classes information**. ### Loading Dataset Information The loaded data information includes the path of images samples and annotations samples, the detailed implementation could be found in -[`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/163277bfe0fa8fefb63ee5137917fafada1b301c/mmseg/datasets/basesegdataset.py#L231) of `BaseSegDataset` in MMSegmentation. +[`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L231) of `BaseSegDataset` in MMSegmentation. There are two main methods to acquire the path of images and labels: 1. Load file paths according to the dirictory and suffix of input images and annotations -If the dataset directory structure is organized as below, the [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/163277bfe0fa8fefb63ee5137917fafada1b301c/mmseg/datasets/basesegdataset.py#L231) can parse dataset directory Structure: +If the dataset directory structure is organized as below, the [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L231) can parse dataset directory Structure: ``` ├── data @@ -344,7 +344,7 @@ print(dataset.metainfo) ``` Meta information is different from default setting of Cityscapes dataset. Moreover, `label_map` field is also defined, which is used for modifying label index of each pixel on segmentation mask. -The segmentation label would re-map class information by `label_map`, [here](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/basesegdataset.py#L151) is detailed implementation: +The segmentation label would re-map class information by `label_map`, [here](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L151) is detailed implementation: ```python gt_semantic_seg_copy = gt_semantic_seg.copy() diff --git a/docs/en/advanced_guides/engine.md b/docs/en/advanced_guides/engine.md index eaa55b0c8c4..7acfe5ad64c 100644 --- a/docs/en/advanced_guides/engine.md +++ b/docs/en/advanced_guides/engine.md @@ -1 +1,279 @@ -# Engine +# Training Engine + +MMEngine defined some [basic loop controllers](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py) such as epoch-based training loop (`EpochBasedTrainLoop`), iteration-based training loop (`IterBasedTrainLoop`), standard validation loop (`ValLoop`), and standard testing loop (`TestLoop`). + +OpenMMLab's algorithm libraries like MMSegmentation abstract model training, testing, and inference as `Runner` to handle. Users can use the default `Runner` in MMEngine directly or modify the `Runner` to meet customized needs. This document mainly introduces how users can configure existing running settings, hooks, and optimizers' basic concepts and usage methods. + +## Configuring Runtime Settings + +### Configuring Training Iterations + +Loop controllers refer to the execution process during training, validation, and testing. `train_cfg`, `val_cfg`, and `test_cfg` are used to build these processes in the configuration file. MMSegmentation sets commonly used training iterations in `train_cfg` under the `configs/_base_/schedules` folder. +For example, to train for 80,000 iterations using the iteration-based training loop (`IterBasedTrainLoop`) and perform validation every 8,000 iterations, you can set it as follows: + +```python +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=8000) +``` + +### Configuring Training Optimizers + +Here's an example of a SGD optimizer: + +```python +optim_wrapper = dict( + type='OptimWrapper', + optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005), + clip_grad=None) +``` + +OpenMMLab supports all optimizers in PyTorch. For more details, please refer to the [MMEngine optimizer documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/optim_wrapper.md). + +It is worth emphasizing that `optim_wrapper` is a variable of `runner`, so when configuring the optimizer, the field to configure is the `optim_wrapper` field. For more information on using optimizers, see the [Optimizer](#Optimizer) section below. + +### Configuring Training Parameter Schedulers + +Before configuring the training parameter scheduler, it is recommended to first understand the basic concepts of parameter schedulers in the [MMEngine documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/param_scheduler.md). + +Here's an example of a parameter scheduler. During training, a linearly changing learning rate strategy is used for warm-up in the first 1,000 iterations. After the first 1,000 iterations until the 16,000 iterations in the end, the default polynomial learning rate decay is used: + +```python +param_scheduler = [ + dict(type='LinearLR', by_epoch=False, start_factor=0.1, begin=0, end=1000), + dict( + type='PolyLR', + eta_min=1e-4, + power=0.9, + begin=1000, + end=160000, + by_epoch=False, + ) +] +``` + +Note: When modifying the `max_iters` in `train_cfg`, make sure the parameters in the parameter scheduler `param_scheduler` are also modified accordingly. + +## Hook + +### Introduction + +OpenMMLab abstracts the model training and testing process as `Runner`. Inserting hooks can implement the corresponding functionality needed at different training and testing stages (such as "before and after each training iter", "before and after each validation iter", etc.) in `Runner`. For more introduction on hook mechanisms, please refer to [here](https://www.calltutors.com/blog/what-is-hook). + +Hooks used in `Runner` are divided into two categories: + +- Default hooks: + +They implement essential functions during training and are defined in the configuration file by `default_hooks` and passed to `Runner`. `Runner` registers them through the [`register_default_hooks`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/runner.py#L1780) method. + +Hooks have corresponding priorities; the higher the priority, the earlier the runner calls them. If the priorities are the same, the calling order is consistent with the hook registration order. + +It is not recommended for users to modify the default hook priorities. Please refer to the [MMEngine hooks documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/hook.md) to understand the hook priority definitions. + +The following are the default hooks used in MMSegmentation: + +| Hook | Function | Priority | +| :--------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------: | :---------------: | +| [IterTimerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/iter_timer_hook.py) | Record the time spent on each iteration. | NORMAL (50) | +| [LoggerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/logger_hook.py) | Collect log records from different components in `Runner` and output them to terminal, JSON file, tensorboard, wandb, etc. | BELOW_NORMAL (60) | +| [ParamSchedulerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/param_scheduler_hook.py) | Update some hyperparameters in the optimizer, such as learning rate momentum. | LOW (70) | +| [CheckpointHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/checkpoint_hook.py) | Regularly save checkpoint files. | VERY_LOW (90) | +| [DistSamplerSeedHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/sampler_seed_hook.py) | Ensure the distributed sampler shuffle is enabled. | NORMAL (50) | +| [SegVisualizationHook](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/visualization/local_visualizer.py) | Visualize prediction results during validation and testing. | NORMAL (50) | + +MMSegmentation registers some hooks with essential training functions in `default_hooks`: + +```python +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=32000), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) +``` + +All the default hooks mentioned above, except for `SegVisualizationHook`, are implemented in MMEngine. The `SegVisualizationHook` is a hook implemented in MMSegmentation, which will be introduced later. + +- Modifying default hooks + +We will use the `logger` and `checkpoint` in `default_hooks` as examples to demonstrate how to modify the default hooks in `default_hooks`. + +(1) Model saving configuration + +`default_hooks` uses the `checkpoint` field to initialize the [model saving hook (CheckpointHook)](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/checkpoint_hook.py#L19). + +```python +checkpoint = dict(type='CheckpointHook', interval=1) +``` + +Users can set `max_keep_ckpts` to save only a small number of checkpoints or use `save_optimizer` to determine whether to save optimizer information. More details on related parameters can be found [here](https://mmengine.readthedocs.io/en/latest/api/generated/mmengine.hooks.CheckpointHook.html#checkpointhook). + +(2) Logging configuration + +The `LoggerHook` is used to collect log information from different components in `Runner` and write it to terminal, JSON files, tensorboard, wandb, etc. + +```python +logger=dict(type='LoggerHook', interval=10) +``` + +In the latest 1.x version of MMSegmentation, some logger hooks (LoggerHook) such as `TextLoggerHook`, `WandbLoggerHook`, and `TensorboardLoggerHook` will no longer be used. Instead, MMEngine uses `LogProcessor` to handle the information processed by the aforementioned hooks, which are now in [`MessageHub`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/logging/message_hub.py#L17), [`WandbVisBackend`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/visualization/vis_backend.py#L324), and [`TensorboardVisBackend`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/visualization/vis_backend.py#L472). + +Detailed usage is as follows, configuring the visualizer and specifying the visualization backend at the same time, here using Tensorboard as the visualizer's backend: + +```python +# TensorboardVisBackend +visualizer = dict( + type='SegLocalVisualizer', vis_backends=[dict(type='TensorboardVisBackend')], name='visualizer') +``` + +For more related usage, please refer to [MMEngine Visualization Backend User Tutorial](https://github.com/open-mmlab/mmengine/blob/main/docs/en/advanced_tutorials/visualization.md). + +- Custom hooks + +Custom hooks are defined in the configuration through `custom_hooks`, and `Runner` registers them using the [`register_custom_hooks`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/runner.py#L1820) method. + +The priority of custom hooks needs to be set in the configuration file; if not, it will be set to `NORMAL` by default. The following are some custom hooks implemented in MMEngine: + +| Hook | Usage | +| :----------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------: | +| [EMAHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/ema_hook.py) | Use Exponential Moving Average (EMA) during model training. | +| [EmptyCacheHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/empty_cache_hook.py) | Release all GPU memory not occupied by the cache during training | +| [SyncBuffersHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/sync_buffer_hook.py) | Synchronize the parameters in the model buffer, such as `running_mean` and `running_var` in BN, at the end of each training epoch. | + +The following is a use case for `EMAHook`, where the config file includes the configuration of the implemented custom hooks as members of the `custom_hooks` list. + +```python +custom_hooks = [ + dict(type='EMAHook', start_iters=500, priority='NORMAL') +] +``` + +### SegVisualizationHook + +MMSegmentation implemented [`SegVisualizationHook`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/engine/hooks/visualization_hook.py#L17), which is used to visualize prediction results during validation and testing. +`SegVisualizationHook` overrides the `_after_iter` method in the base class `Hook`. During validation or testing, it calls the `add_datasample` method of `visualizer` to draw semantic segmentation results according to the specified iteration interval. The specific implementation is as follows: + +```python +... +@HOOKS.register_module() +class SegVisualizationHook(Hook): +... + def _after_iter(self, + runner: Runner, + batch_idx: int, + data_batch: dict, + outputs: Sequence[SegDataSample], + mode: str = 'val') -> None: +... + # If it's a training phase or self.draw is False, then skip it + if self.draw is False or mode == 'train': + return +... + if self.every_n_inner_iters(batch_idx, self.interval): + for output in outputs: + img_path = output.img_path + img_bytes = self.file_client.get(img_path) + img = mmcv.imfrombytes(img_bytes, channel_order='rgb') + window_name = f'{mode}_{osp.basename(img_path)}' + + self._visualizer.add_datasample( + window_name, + img, + data_sample=output, + show=self.show, + wait_time=self.wait_time, + step=runner.iter) + +``` + +For more details about visualization, you can check [here](../user_guides/visualization.md). + +## Optimizer + +In the previous configuration and runtime settings, we provided a simple example of configuring the training optimizer. This section will further detailly introduce how to configure optimizers in MMSegmentation. + +## Optimizer Wrapper + +OpenMMLab 2.0 introduces an optimizer wrapper that supports different training strategies, including mixed-precision training, gradient accumulation, and gradient clipping. Users can choose the appropriate training strategy according to their needs. The optimizer wrapper also defines a standard parameter update process, allowing users to switch between different training strategies within the same code. For more information, please refer to the [MMEngine optimizer wrapper documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/optim_wrapper.md). + +Here are some common usage methods in MMSegmentation: + +#### Configuring PyTorch Supported Optimizers + +OpenMMLab 2.0 supports all native PyTorch optimizers, as referenced [here](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/optim_wrapper.md). + +To set the optimizer used by the `Runner` during training in the configuration file, you need to define `optim_wrapper` instead of `optimizer`. Below is an example of configuring an optimizer during training: + +```python +optim_wrapper = dict( + type='OptimWrapper', + optimizer=dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005), + clip_grad=None) +``` + +#### Configuring Gradient Clipping + +When the model training requires gradient clipping, you can configure it as shown in the following example: + +```python +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, + clip_grad=dict(max_norm=0.01, norm_type=2)) +``` + +Here, `max_norm` refers to the maximum value of the gradient after clipping, and `norm_type` refers to the norm used when clipping the gradient. Related methods can be found in [torch.nn.utils.clip_grad_norm\_](https://pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_norm_.html). + +#### Configuring Mixed Precision Training + +When mixed precision training is needed to reduce memory usage, you can use `AmpOptimWrapper`. The specific configuration is as follows: + +```python +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001) +optim_wrapper = dict(type='AmpOptimWrapper', optimizer=optimizer) +``` + +The default setting for `loss_scale` in [`AmpOptimWrapper`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/amp_optimizer_wrapper.py#L20) is `dynamic`. + +#### Configuring Hyperparameters for Different Layers of the Model Network + +In model training, if you want to set different optimization strategies for different parameters in the optimizer, such as setting different learning rates, weight decay, and other hyperparameters, you can achieve this by setting `paramwise_cfg` in the `optim_wrapper` of the configuration file. + +The following config file uses the [ViT `optim_wrapper`](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_vit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py#L15-L27) as an example to introduce the use of `paramwise_cfg` parameters. During training, the weight decay parameter coefficients for the `pos_embed`, `mask_token`, and `norm` modules are set to 0. That is, during training, the weight decay for these modules will be changed to `weight_decay * decay_mult`=0. + +```python +optimizer = dict( + type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01) +optim_wrapper = dict( + type='OptimWrapper', + optimizer=optimizer, + paramwise_cfg=dict( + custom_keys={ + 'pos_embed': dict(decay_mult=0.), + 'cls_token': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + })) +``` + +Here, `decay_mult` refers to the weight decay coefficient for the corresponding parameters. For more information on the usage of `paramwise_cfg`, please refer to the [MMEngine optimizer wrapper documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/optim_wrapper.md). + +### Optimizer Wrapper Constructor + +The default optimizer wrapper constructor [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/default_constructor.py#L19) builds the optimizer used in training based on the input `optim_wrapper` and `paramwise_cfg` defined in the `optim_wrapper`. When the functionality of [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/default_constructor.py#L19) does not meet the requirements, you can customize the optimizer wrapper constructor to implement the configuration of hyperparameters. + +MMSegmentation has implemented the [`LearningRateDecayOptimizerConstructor`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/engine/optimizers/layer_decay_optimizer_constructor.py#L104), which can decay the learning rate of model parameters in the backbone networks of ConvNeXt, BEiT, and MAE models during training according to the defined decay ratio (`decay_rate`). The configuration in the configuration file is as follows: + +```python +optim_wrapper = dict( + _delete_=True, + type='AmpOptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0001, betas=(0.9, 0.999), weight_decay=0.05), + paramwise_cfg={ + 'decay_rate': 0.9, + 'decay_type': 'stage_wise', + 'num_layers': 12 + }, + constructor='LearningRateDecayOptimizerConstructor', + loss_scale='dynamic') +``` + +The purpose of `_delete_=True` is to ignore the inherited configuration in the OpenMMLab Config. In this code snippet, the inherited `optim_wrapper` configuration is ignored. For more information on `_delete_` fields, please refer to the [MMEngine documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/advanced_tutorials/config.md#delete-key-in-dict). diff --git a/docs/en/advanced_guides/evaluation.md b/docs/en/advanced_guides/evaluation.md index 1e42db2a105..ca0beeeccf2 100644 --- a/docs/en/advanced_guides/evaluation.md +++ b/docs/en/advanced_guides/evaluation.md @@ -2,10 +2,7 @@ The evaluation procedure would be executed at [ValLoop](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py#L300) and [TestLoop](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py#L373), users can evaluate model performance during training or using the test script with simple settings in the configuration file. The `ValLoop` and `TestLoop` are properties of [Runner](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/runner.py#L59), they will be built the first time they are called. To build the `ValLoop` successfully, the `val_dataloader` and `val_evaluator` must be set when building `Runner` since `dataloader` and `evaluator` are required parameters, and the same goes for `TestLoop`. For more information about the Runner's design, please refer to the [documentation](https://github.com/open-mmlab/mmengine/blob/main/docs/en/design/runner.md) of [MMEngine](https://github.com/open-mmlab/mmengine). -
- -
test_step/val_step dataflow
-
+![test_step/val_step dataflow](https://user-images.githubusercontent.com/15952744/228828179-3269baa3-bebd-4c9a-9787-59e7d785fbcf.png) In MMSegmentation, we write the settings of dataloader and metrics in the config files of datasets and the configuration of the evaluation loop in the `schedule_x` config files by default. diff --git a/docs/en/advanced_guides/models.md b/docs/en/advanced_guides/models.md index 84e6cb6a9e5..b0089869d96 100644 --- a/docs/en/advanced_guides/models.md +++ b/docs/en/advanced_guides/models.md @@ -34,15 +34,8 @@ MMSegmentation wraps `BaseModel` and implements the [BaseSegmentor](https://gith ### forward -
- -
EncoderDecoder dataflow
-
- -
-
-
CascadeEncoderDecoder dataflow
-
+![EncoderDecoder dataflow](https://user-images.githubusercontent.com/15952744/228827860-c0e34875-d370-4736-84f0-9560c26c9576.png) +![CascadeEncoderDecoder dataflow](https://user-images.githubusercontent.com/15952744/228827987-aa214507-0c6d-4a08-8ce4-679b2b200b79.png) The `forward` method returns losses or predictions of training, validation, testing, and a simple inference process. @@ -114,10 +107,7 @@ Returns: - Dict\[str, `torch.Tensor`\]: A `dict` of tensor for logging. -
- -
train_step dataflow
-
+![train_step dataflow](https://user-images.githubusercontent.com/15952744/228828089-a9ae1225-958d-4cf7-99af-9af8576f7ef7.png) ### val_step @@ -131,10 +121,7 @@ Returns: - `list` - The predictions of given data. -
- -
test_step/val_step dataflow
-
+![test_step/val_step dataflow](https://user-images.githubusercontent.com/15952744/228828179-3269baa3-bebd-4c9a-9787-59e7d785fbcf.png) ### test_step diff --git a/docs/en/advanced_guides/training_tricks.md b/docs/en/advanced_guides/training_tricks.md index 8fa89131d53..bc4f72257d6 100644 --- a/docs/en/advanced_guides/training_tricks.md +++ b/docs/en/advanced_guides/training_tricks.md @@ -1,4 +1,4 @@ -# \[WIP\] Training Tricks +# Training Tricks MMSegmentation support following training tricks out of box. @@ -9,18 +9,19 @@ In semantic segmentation, some methods make the LR of heads larger than backbone In MMSegmentation, you may add following lines to config to make the LR of heads 10 times of backbone. ```python -optimizer=dict( +optim_wrapper=dict( paramwise_cfg = dict( custom_keys={ 'head': dict(lr_mult=10.)})) ``` With this modification, the LR of any parameter group with `'head'` in name will be multiplied by 10. -You may refer to [MMCV doc](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.DefaultOptimizerConstructor) for further details. +You may refer to [MMEngine documentation](https://mmengine.readthedocs.io/en/latest/tutorials/optim_wrapper.html#advanced-usages) for further details. ## Online Hard Example Mining (OHEM) -We implement pixel sampler [here](https://github.com/open-mmlab/mmsegmentation/tree/master/mmseg/core/seg/sampler) for training sampling. +We implement pixel sampler for training sampling, like OHEM (Online Hard Example Mining), +which is used for remove the "easy" examples for model training. Here is an example config of training PSPNet with OHEM enabled. ```python @@ -58,33 +59,17 @@ For loss calculation, we support multiple losses training concurrently. Here is ```python _base_ = './fcn_unet_s5-d16_64x64_40k_drive.py' model = dict( - decode_head=dict(loss_decode=[dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), - dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0)]), - auxiliary_head=dict(loss_decode=[dict(type='CrossEntropyLoss', loss_name='loss_ce',loss_weight=1.0), - dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0)]), - ) + decode_head=dict(loss_decode=[ + dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), + dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0) + ]), + auxiliary_head=dict(loss_decode=[ + dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), + dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0) + ]), +) ``` In this way, `loss_weight` and `loss_name` will be weight and name in training log of corresponding loss, respectively. Note: If you want this loss item to be included into the backward graph, `loss_` must be the prefix of the name. - -## Ignore specified label index in loss calculation - -In default setting, `avg_non_ignore=False` which means each pixel counts for loss calculation although some of them belong to ignore-index labels. - -For loss calculation, we support ignore index of certain label by `avg_non_ignore` and `ignore_index`. In this way, the average loss would only be calculated in non-ignored labels which may achieve better performance, and here is the [reference](https://github.com/open-mmlab/mmsegmentation/pull/1409). Here is an example config of training `unet` on `Cityscapes` dataset: in loss calculation it would ignore label 0 which is background and loss average is only calculated on non-ignore labels: - -```python -_base_ = './unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py' -model = dict( - decode_head=dict( - ignore_index=0, - loss_decode=dict( - type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0, avg_non_ignore=True), - auxiliary_head=dict( - ignore_index=0, - loss_decode=dict( - type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0, avg_non_ignore=True)), - )) -``` diff --git a/docs/en/get_started.md b/docs/en/get_started.md index b082508693c..3f957eb4e1b 100644 --- a/docs/en/get_started.md +++ b/docs/en/get_started.md @@ -4,7 +4,7 @@ In this section we demonstrate how to prepare an environment with PyTorch. -MMSegmentation works on Linux, Windows and macOS. It requires Python 3.6+, CUDA 9.2+ and PyTorch 1.5+. +MMSegmentation works on Linux, Windows and macOS. It requires Python 3.7+, CUDA 10.2+ and PyTorch 1.8+. **Note:** If you are experienced with PyTorch and have already installed it, just skip this part and jump to the [next section](##installation). Otherwise, you can follow these steps for the preparation. @@ -43,7 +43,7 @@ We recommend that users follow our best practices to install MMSegmentation. How ```shell pip install -U openmim mim install mmengine -mim install "mmcv>=2.0.0rc1" +mim install "mmcv>=2.0.0" ``` **Step 1.** Install MMSegmentation. @@ -51,7 +51,7 @@ mim install "mmcv>=2.0.0rc1" Case a: If you develop and run mmseg directly, install it from source: ```shell -git clone -b dev-1.x https://github.com/open-mmlab/mmsegmentation.git +git clone -b main https://github.com/open-mmlab/mmsegmentation.git cd mmsegmentation pip install -v -e . # '-v' means verbose, or more output @@ -62,7 +62,7 @@ pip install -v -e . Case b: If you use mmsegmentation as a dependency or third-party package, install it with pip: ```shell -pip install "mmsegmentation>=1.0.0rc0" +pip install "mmsegmentation>=1.0.0" ``` ### Verify the installation @@ -110,8 +110,8 @@ show_result_pyplot(model, img, result, show=True, out_file='result.jpg', opacity # test a video and show the results video = mmcv.VideoReader('video.mp4') for frame in video: - result = inference_segmentor(model, frame) - show_result_pyplot(model, result, wait_time=1) + result = inference_model(model, frame) + show_result_pyplot(model, frame, result, wait_time=1) ``` You can modify the code above to test a single image or a video, both of these options can verify that the installation was successful. @@ -136,15 +136,15 @@ MMCV contains C++ and CUDA extensions, thus depending on PyTorch in a complex wa To install MMCV with pip instead of MIM, please follow [MMCV installation guides](https://mmcv.readthedocs.io/en/latest/get_started/installation.html). This requires manually specifying a find-url based on PyTorch version and its CUDA version. -For example, the following command install mmcv==2.0.0rc1 built for PyTorch 1.10.x and CUDA 11.3. +For example, the following command install mmcv==2.0.0 built for PyTorch 1.10.x and CUDA 11.3. ```shell -pip install mmcv==2.0.0rc1 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html +pip install mmcv==2.0.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html ``` #### Install on CPU-only platforms -MMSegmentation can be built for CPU only environment. In CPU mode you can train (requires MMCV-Lite version >= 2.0.0rc0), test or inference a model. +MMSegmentation can be built for CPU only environment. In CPU mode you can train (requires MMCV version >= 2.0.0), test or inference a model. #### Install on Google Colab @@ -156,7 +156,7 @@ thus we only need to install MMCV and MMSegmentation with the following commands ```shell !pip3 install openmim !mim install mmengine -!mim install "mmcv>=2.0.0rc1" +!mim install "mmcv>=2.0.0" ``` **Step 2.** Install MMSegmentation from the source. @@ -164,7 +164,7 @@ thus we only need to install MMCV and MMSegmentation with the following commands ```shell !git clone https://github.com/open-mmlab/mmsegmentation.git %cd mmsegmentation -!git checkout dev-1.x +!git checkout main !pip install -e . ``` @@ -173,7 +173,7 @@ thus we only need to install MMCV and MMSegmentation with the following commands ```python import mmseg print(mmseg.__version__) -# Example output: 1.0.0rc0 +# Example output: 1.0.0 ``` **Note:** @@ -181,7 +181,7 @@ Within Jupyter, the exclamation mark `!` is used to call external executables an ### Using MMSegmentation with Docker -We provide a [Dockerfile](https://github.com/open-mmlab/mmsegmentation/blob/master/docker/Dockerfile) to build an image. Ensure that your [docker version](https://docs.docker.com/engine/install/) >=19.03. +We provide a [Dockerfile](https://github.com/open-mmlab/mmsegmentation/blob/main/docker/Dockerfile) to build an image. Ensure that your [docker version](https://docs.docker.com/engine/install/) >=19.03. ```shell # build an image with PyTorch 1.11, CUDA 11.3 @@ -195,6 +195,16 @@ Run it with docker run --gpus all --shm-size=8g -it -v {DATA_DIR}:/mmsegmentation/data mmsegmentation ``` +### Optional Dependencies + +#### Install GDAL + +[GDAL](https://gdal.org/) is a translator library for raster and vector geospatial data formats. Install GDAL to read complex formats and extremely large remote sensing images. + +```shell +conda install GDAL +``` + ## Trouble shooting If you have some issues during the installation, please first view the [FAQ](notes/faq.md) page. diff --git a/docs/en/migration/interface.md b/docs/en/migration/interface.md index 46040d911fc..b83eeb9e4d0 100644 --- a/docs/en/migration/interface.md +++ b/docs/en/migration/interface.md @@ -12,11 +12,11 @@ Or install the below packages manually. 1. [MMEngine](https://github.com/open-mmlab/mmengine): MMEngine is the core the OpenMMLab 2.0 architecture, and we splited many compentents unrelated to computer vision from MMCV to MMEngine. -2. [MMCV](https://github.com/open-mmlab/mmcv): The computer vision package of OpenMMLab. This is not a new dependency, but you need to upgrade it to above **2.0.0rc1** version. +2. [MMCV](https://github.com/open-mmlab/mmcv): The computer vision package of OpenMMLab. This is not a new dependency, but you need to upgrade it to **2.0.0** version or above. -3. [MMClassification](https://github.com/open-mmlab/mmclassification)(Optional): The image classification toolbox and benchmark of OpenMMLab. This is not a new dependency, but you need to upgrade it to above **1.0.0rc0** version. +3. [MMClassification](https://github.com/open-mmlab/mmclassification)(Optional): The image classification toolbox and benchmark of OpenMMLab. This is not a new dependency, but you need to upgrade it to **1.0.0rc6** version. -4. [MMDetection](https://github.com/open-mmlab/mmdetection)(Optional): The object detection toolbox and benchmark of OpenMMLab. This is not a new dependency, but you need to upgrade it to above **3.0.0rc0** version. +4. [MMDetection](https://github.com/open-mmlab/mmdetection)(Optional): The object detection toolbox and benchmark of OpenMMLab. This is not a new dependency, but you need to upgrade it to **3.0.0** version or above. ## Train launch @@ -102,11 +102,11 @@ No changes in `model.backbone`, `model.neck`, `model.decode_head` and `model.los Add `model.data_preprocessor` field to configure the `DataPreProcessor`, including: -- `mean`(Sequence, optional): The pixel mean of R, G, B channels. Defaults to None. +- `mean` (Sequence, optional): The pixel mean of R, G, B channels. Defaults to None. -- `std`(Sequence, optional): The pixel standard deviation of R, G, B channels. Defaults to None. +- `std` (Sequence, optional): The pixel standard deviation of R, G, B channels. Defaults to None. -- `size`(Sequence, optional): Fixed padding size. +- `size` (Sequence, optional): Fixed padding size. - `size_divisor` (int, optional): The divisor of padded size. diff --git a/docs/en/model_zoo.md b/docs/en/model_zoo.md index 782a47002f3..6717df6cc76 100644 --- a/docs/en/model_zoo.md +++ b/docs/en/model_zoo.md @@ -34,123 +34,123 @@ ### FCN -Please refer to [FCN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/fcn) for details. +Please refer to [FCN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn) for details. ### PSPNet -Please refer to [PSPNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/pspnet) for details. +Please refer to [PSPNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet) for details. ### DeepLabV3 -Please refer to [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/deeplabv3) for details. +Please refer to [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3) for details. ### PSANet -Please refer to [PSANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/psanet) for details. +Please refer to [PSANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet) for details. ### DeepLabV3+ -Please refer to [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/deeplabv3plus) for details. +Please refer to [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus) for details. ### UPerNet -Please refer to [UPerNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/upernet) for details. +Please refer to [UPerNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet) for details. ### NonLocal Net -Please refer to [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/nonlocal_net) for details. +Please refer to [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net) for details. ### EncNet -Please refer to [EncNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/encnet) for details. +Please refer to [EncNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet) for details. ### CCNet -Please refer to [CCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ccnet) for details. +Please refer to [CCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet) for details. ### DANet -Please refer to [DANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/danet) for details. +Please refer to [DANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet) for details. ### APCNet -Please refer to [APCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/apcnet) for details. +Please refer to [APCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet) for details. ### HRNet -Please refer to [HRNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/hrnet) for details. +Please refer to [HRNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet) for details. ### GCNet -Please refer to [GCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/gcnet) for details. +Please refer to [GCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet) for details. ### DMNet -Please refer to [DMNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/dmnet) for details. +Please refer to [DMNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet) for details. ### ANN -Please refer to [ANN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ann) for details. +Please refer to [ANN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann) for details. ### OCRNet -Please refer to [OCRNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ocrnet) for details. +Please refer to [OCRNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet) for details. ### Fast-SCNN -Please refer to [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/fastscnn) for details. +Please refer to [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastscnn) for details. ### ResNeSt -Please refer to [ResNeSt](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/resnest) for details. +Please refer to [ResNeSt](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest) for details. ### Semantic FPN -Please refer to [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/sem_fpn) for details. +Please refer to [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn) for details. ### PointRend -Please refer to [PointRend](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/point_rend) for details. +Please refer to [PointRend](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend) for details. ### MobileNetV2 -Please refer to [MobileNetV2](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mobilenet_v2) for details. +Please refer to [MobileNetV2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2) for details. ### MobileNetV3 -Please refer to [MobileNetV3](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mobilenet_v3) for details. +Please refer to [MobileNetV3](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3) for details. ### EMANet -Please refer to [EMANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/emanet) for details. +Please refer to [EMANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/emanet) for details. ### DNLNet -Please refer to [DNLNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/dnlnet) for details. +Please refer to [DNLNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet) for details. ### CGNet -Please refer to [CGNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/cgnet) for details. +Please refer to [CGNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/cgnet) for details. ### Mixed Precision (FP16) Training -Please refer [Mixed Precision (FP16) Training on BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/bisenetv2/bisenetv2_fcn_fp16_4x4_1024x1024_160k_cityscapes.py) for details. +Please refer [Mixed Precision (FP16) Training on BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2/bisenetv2_fcn_4xb4-160k_cityscapes-1024x1024.py) for details. ### U-Net -Please refer to [U-Net](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/unet/README.md) for details. +Please refer to [U-Net](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet/README.md) for details. ### ViT -Please refer to [ViT](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/vit/README.md) for details. +Please refer to [ViT](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/README.md) for details. ### Swin -Please refer to [Swin](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/swin/README.md) for details. +Please refer to [Swin](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/swin/README.md) for details. ### SETR -Please refer to [SETR](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/setr/README.md) for details. +Please refer to [SETR](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr/README.md) for details. ## Speed benchmark diff --git a/docs/en/modelzoo_statistics.md b/docs/en/modelzoo_statistics.md index c8fa46d0139..e5e21a14741 100644 --- a/docs/en/modelzoo_statistics.md +++ b/docs/en/modelzoo_statistics.md @@ -7,96 +7,96 @@ - Number of checkpoints: 612 - - \[ALGORITHM\] [ANN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ann) (16 ckpts) + - \[ALGORITHM\] [ANN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ann) (16 ckpts) - - \[ALGORITHM\] [APCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/apcnet) (12 ckpts) + - \[ALGORITHM\] [APCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/apcnet) (12 ckpts) - - \[BACKBONE\] [BEiT](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/beit) (2 ckpts) + - \[BACKBONE\] [BEiT](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/beit) (2 ckpts) - - \[ALGORITHM\] [BiSeNetV1](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/bisenetv1) (11 ckpts) + - \[ALGORITHM\] [BiSeNetV1](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv1) (11 ckpts) - - \[ALGORITHM\] [BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/bisenetv2) (4 ckpts) + - \[ALGORITHM\] [BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/bisenetv2) (4 ckpts) - - \[ALGORITHM\] [CCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ccnet) (16 ckpts) + - \[ALGORITHM\] [CCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ccnet) (16 ckpts) - - \[ALGORITHM\] [CGNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/cgnet) (2 ckpts) + - \[ALGORITHM\] [CGNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/cgnet) (2 ckpts) - - \[BACKBONE\] [ConvNeXt](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/convnext) (6 ckpts) + - \[BACKBONE\] [ConvNeXt](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/convnext) (6 ckpts) - - \[ALGORITHM\] [DANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/danet) (16 ckpts) + - \[ALGORITHM\] [DANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/danet) (16 ckpts) - - \[ALGORITHM\] [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/deeplabv3) (41 ckpts) + - \[ALGORITHM\] [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3) (41 ckpts) - - \[ALGORITHM\] [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/deeplabv3plus) (42 ckpts) + - \[ALGORITHM\] [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/deeplabv3plus) (42 ckpts) - - \[ALGORITHM\] [DMNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/dmnet) (12 ckpts) + - \[ALGORITHM\] [DMNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dmnet) (12 ckpts) - - \[ALGORITHM\] [DNLNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/dnlnet) (12 ckpts) + - \[ALGORITHM\] [DNLNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dnlnet) (12 ckpts) - - \[ALGORITHM\] [DPT](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/dpt) (1 ckpts) + - \[ALGORITHM\] [DPT](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/dpt) (1 ckpts) - - \[ALGORITHM\] [EMANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/emanet) (4 ckpts) + - \[ALGORITHM\] [EMANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/emanet) (4 ckpts) - - \[ALGORITHM\] [EncNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/encnet) (12 ckpts) + - \[ALGORITHM\] [EncNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/encnet) (12 ckpts) - - \[ALGORITHM\] [ERFNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/erfnet) (1 ckpts) + - \[ALGORITHM\] [ERFNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/erfnet) (1 ckpts) - - \[ALGORITHM\] [FastFCN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/fastfcn) (12 ckpts) + - \[ALGORITHM\] [FastFCN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastfcn) (12 ckpts) - - \[ALGORITHM\] [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/fastscnn) (1 ckpts) + - \[ALGORITHM\] [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fastscnn) (1 ckpts) - - \[ALGORITHM\] [FCN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/fcn) (41 ckpts) + - \[ALGORITHM\] [FCN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn) (41 ckpts) - - \[ALGORITHM\] [GCNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/gcnet) (16 ckpts) + - \[ALGORITHM\] [GCNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/gcnet) (16 ckpts) - - \[BACKBONE\] [HRNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/hrnet) (37 ckpts) + - \[BACKBONE\] [HRNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/hrnet) (37 ckpts) - - \[ALGORITHM\] [ICNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/icnet) (12 ckpts) + - \[ALGORITHM\] [ICNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/icnet) (12 ckpts) - - \[ALGORITHM\] [ISANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/isanet) (16 ckpts) + - \[ALGORITHM\] [ISANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/isanet) (16 ckpts) - - \[ALGORITHM\] [K-Net](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/knet) (7 ckpts) + - \[ALGORITHM\] [K-Net](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/knet) (7 ckpts) - - \[BACKBONE\] [MAE](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mae) (1 ckpts) + - \[BACKBONE\] [MAE](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mae) (1 ckpts) - - \[ALGORITHM\] [Mask2Former](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mask2former) (13 ckpts) + - \[ALGORITHM\] [Mask2Former](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mask2former) (13 ckpts) - - \[ALGORITHM\] [MaskFormer](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/maskformer) (4 ckpts) + - \[ALGORITHM\] [MaskFormer](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/maskformer) (4 ckpts) - - \[BACKBONE\] [MobileNetV2](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mobilenet_v2) (8 ckpts) + - \[BACKBONE\] [MobileNetV2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v2) (8 ckpts) - - \[BACKBONE\] [MobileNetV3](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/mobilenet_v3) (4 ckpts) + - \[BACKBONE\] [MobileNetV3](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/mobilenet_v3) (4 ckpts) - - \[ALGORITHM\] [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/nonlocal_net) (16 ckpts) + - \[ALGORITHM\] [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/nonlocal_net) (16 ckpts) - - \[ALGORITHM\] [OCRNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/ocrnet) (24 ckpts) + - \[ALGORITHM\] [OCRNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/ocrnet) (24 ckpts) - - \[ALGORITHM\] [PointRend](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/point_rend) (4 ckpts) + - \[ALGORITHM\] [PointRend](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/point_rend) (4 ckpts) - - \[BACKBONE\] [PoolFormer](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/poolformer) (5 ckpts) + - \[BACKBONE\] [PoolFormer](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/poolformer) (5 ckpts) - - \[ALGORITHM\] [PSANet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/psanet) (16 ckpts) + - \[ALGORITHM\] [PSANet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/psanet) (16 ckpts) - - \[ALGORITHM\] [PSPNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/pspnet) (54 ckpts) + - \[ALGORITHM\] [PSPNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/pspnet) (54 ckpts) - - \[BACKBONE\] [ResNeSt](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/resnest) (8 ckpts) + - \[BACKBONE\] [ResNeSt](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/resnest) (8 ckpts) - - \[ALGORITHM\] [SegFormer](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/segformer) (13 ckpts) + - \[ALGORITHM\] [SegFormer](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segformer) (13 ckpts) - - \[ALGORITHM\] [Segmenter](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/segmenter) (5 ckpts) + - \[ALGORITHM\] [Segmenter](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/segmenter) (5 ckpts) - - \[ALGORITHM\] [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/sem_fpn) (4 ckpts) + - \[ALGORITHM\] [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/sem_fpn) (4 ckpts) - - \[ALGORITHM\] [SETR](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/setr) (7 ckpts) + - \[ALGORITHM\] [SETR](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/setr) (7 ckpts) - - \[ALGORITHM\] [STDC](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/stdc) (4 ckpts) + - \[ALGORITHM\] [STDC](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/stdc) (4 ckpts) - - \[BACKBONE\] [Swin Transformer](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/swin) (6 ckpts) + - \[BACKBONE\] [Swin Transformer](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/swin) (6 ckpts) - - \[BACKBONE\] [Twins](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/twins) (12 ckpts) + - \[BACKBONE\] [Twins](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/twins) (12 ckpts) - - \[ALGORITHM\] [UNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/unet) (25 ckpts) + - \[ALGORITHM\] [UNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/unet) (25 ckpts) - - \[ALGORITHM\] [UPerNet](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/upernet) (16 ckpts) + - \[ALGORITHM\] [UPerNet](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/upernet) (16 ckpts) - - \[BACKBONE\] [Vision Transformer](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/vit) (11 ckpts) + - \[BACKBONE\] [Vision Transformer](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit) (11 ckpts) diff --git a/docs/en/notes/changelog.md b/docs/en/notes/changelog.md index 518bfb314e6..c26e4c2f5ec 100644 --- a/docs/en/notes/changelog.md +++ b/docs/en/notes/changelog.md @@ -1,5 +1,193 @@ # Changelog of v1.x +## v1.1.2(09/20/2023) + +### Features + +- Add semantic label to the segmentation visualization results ([#3229](https://github.com/open-mmlab/mmsegmentation/pull/3229)) +- Support NYU depth estimation dataset ([#3269](https://github.com/open-mmlab/mmsegmentation/pull/3269)) +- Support Kullback-Leibler divergence Loss ([#3242](https://github.com/open-mmlab/mmsegmentation/pull/3242)) +- Support depth metrics ([#3297](https://github.com/open-mmlab/mmsegmentation/pull/3297)) +- Support Remote sensing inferencer ([#3131](https://github.com/open-mmlab/mmsegmentation/pull/3131)) +- Support VPD Depth Estimator ((#3321)(https://github.com/open-mmlab/mmsegmentation/pull/3321)) +- Support inference and visualization of VPD ([#3331](https://github.com/open-mmlab/mmsegmentation/pull/3331)) +- Support using the pytorch-grad-cam tool to visualize Class Activation Maps (CAM) ([#3324](https://github.com/open-mmlab/mmsegmentation/pull/3324)) + +### New projects + +- Support PP-Mobileseg ([#3239](https://github.com/open-mmlab/mmsegmentation/pull/3239)) +- Support CAT-Seg (CVPR'2023) ([#3098](https://github.com/open-mmlab/mmsegmentation/pull/3098)) +- Support Adabins ([#3257](https://github.com/open-mmlab/mmsegmentation/pull/3257)) +- Add pp_mobileseg onnx inference script ([#3268](https://github.com/open-mmlab/mmsegmentation/pull/3268)) + +### Bug Fixes + +- Fix module PascalContextDataset ([#3235](https://github.com/open-mmlab/mmsegmentation/pull/3235)) +- Fix one hot encoding for dice loss ([#3237](https://github.com/open-mmlab/mmsegmentation/pull/3237)) +- Fix confusion_matrix.py ([#3291](https://github.com/open-mmlab/mmsegmentation/pull/3291)) +- Fix inferencer visualization ([#3333](https://github.com/open-mmlab/mmsegmentation/pull/3333)) + +### Documentation + +- Translate doc for docs/zh_cn/user_guides/5_deployment.md ([#3281](https://github.com/open-mmlab/mmsegmentation/pull/3281)) + +## New Contributors + +- @angiecao made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3235 +- @yeedrag made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3237 +- @Yang-Changhui made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3239 +- @ooooo-create made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3261 +- @Ben-Louis made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3269 +- @crazysteeaam made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3284 +- @zen0no made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3242 +- @XiandongWang made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3291 +- @ZhaoQiiii made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3332 +- @zhen6618 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3324 + +## v1.1.1(07/24/2023) + +### Features + +- Add bdd100K datasets ([#3158](https://github.com/open-mmlab/mmsegmentation/pull/3158)) +- Remove batch inference assertion ([#3210](https://github.com/open-mmlab/mmsegmentation/pull/3210)) + +### Bug Fixes + +- Fix train map path for coco-stuff164k.py ([#3187](https://github.com/open-mmlab/mmsegmentation/pull/3187)) +- Fix mim search error ([#3194](https://github.com/open-mmlab/mmsegmentation/pull/3194)) +- Fix SegTTAModel with no attribute '\_gt_sem_seg' error ([#3152](https://github.com/open-mmlab/mmsegmentation/pull/3152)) +- Fix Albumentations default key mapping mismatch ([#3195](https://github.com/open-mmlab/mmsegmentation/pull/3195)) + +### New Contributors + +- @OliverGrace made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3187 +- @ZiAn-Su made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3152 +- @CastleDream made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3158 +- @coding-famer made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3174 +- @Alias-z made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3195 + +## v1.1.0(06/28/2023) + +## What's Changed + +### Features + +- Support albu transform ([#2943](https://github.com/open-mmlab/mmsegmentation/pull/2943)) +- Support DDRNet ([#2855](https://github.com/open-mmlab/mmsegmentation/pull/2855)) +- Add GDAL backend and Support LEVIR-CD Dataset ([#2903](https://github.com/open-mmlab/mmsegmentation/pull/2903)) +- Support DSDL Dataset ([#2925](https://github.com/open-mmlab/mmsegmentation/pull/2925)) +- huasdorff distance loss ([#2820](https://github.com/open-mmlab/mmsegmentation/pull/2820)) + +### New Projects + +- Support SAM inferencer ([#2897](https://github.com/open-mmlab/mmsegmentation/pull/2897)) +- Added a supported for Visual Attention Network (VAN) ([#2987](https://github.com/open-mmlab/mmsegmentation/pull/2987)) +- add GID dataset ([#3038](https://github.com/open-mmlab/mmsegmentation/pull/3038)) +- add Medical semantic seg dataset: Bactteria ([#2568](https://github.com/open-mmlab/mmsegmentation/pull/2568)) +- add Medical semantic seg dataset: Vampire ([#2633](https://github.com/open-mmlab/mmsegmentation/pull/2633)) +- add Medical semantic seg dataset: Ravir ([#2635](https://github.com/open-mmlab/mmsegmentation/pull/2635)) +- add Medical semantic seg dataset: Cranium ([#2675](https://github.com/open-mmlab/mmsegmentation/pull/2675)) +- add Medical semantic seg dataset: bccs ([#2861](https://github.com/open-mmlab/mmsegmentation/pull/2861)) +- add Medical semantic seg dataset: Gamma Task3 dataset ([#2695](https://github.com/open-mmlab/mmsegmentation/pull/2695)) +- add Medical semantic seg dataset: consep ([#2724](https://github.com/open-mmlab/mmsegmentation/pull/2724)) +- add Medical semantic seg dataset: breast_cancer_cell_seg dataset ([#2726](https://github.com/open-mmlab/mmsegmentation/pull/2726)) +- add Medical semantic seg dataset: chest_image_pneum dataset ([#2727](https://github.com/open-mmlab/mmsegmentation/pull/2727)) +- add Medical semantic seg dataset: conic2022 ([#2725](https://github.com/open-mmlab/mmsegmentation/pull/2725)) +- add Medical semantic seg dataset: dr_hagis ([#2729](https://github.com/open-mmlab/mmsegmentation/pull/2729)) +- add Medical semantic seg dataset: orvs ([#2728](https://github.com/open-mmlab/mmsegmentation/pull/2728)) +- add Medical semantic seg dataset: ISIC-2016 Task1 ([#2708](https://github.com/open-mmlab/mmsegmentation/pull/2708)) +- add Medical semantic seg dataset: ISIC-2017 Task1 ([#2709](https://github.com/open-mmlab/mmsegmentation/pull/2709)) +- add Medical semantic seg dataset: Kvasir seg ([#2677](https://github.com/open-mmlab/mmsegmentation/pull/2677)) +- add Medical semantic seg dataset: Kvasir seg aliyun ([#2678](https://github.com/open-mmlab/mmsegmentation/pull/2678)) +- add Medical semantic seg dataset: Rite ([#2680](https://github.com/open-mmlab/mmsegmentation/pull/2680)) +- add Medical semantic seg dataset: Fusc2021 ([#2682](https://github.com/open-mmlab/mmsegmentation/pull/2682)) +- add Medical semantic seg dataset: 2pm vessel ([#2685](https://github.com/open-mmlab/mmsegmentation/pull/2685)) +- add Medical semantic seg dataset: Pcam ([#2684](https://github.com/open-mmlab/mmsegmentation/pull/2684)) +- add Medical semantic seg dataset: Pannuke ([#2683](https://github.com/open-mmlab/mmsegmentation/pull/2683)) +- add Medical semantic seg dataset: Covid 19 ct cxr ([#2688](https://github.com/open-mmlab/mmsegmentation/pull/2688)) +- add Medical semantic seg dataset: Crass ([#2690](https://github.com/open-mmlab/mmsegmentation/pull/2690)) +- add Medical semantic seg dataset: Chest x ray images with pneumothorax masks ([#2687](https://github.com/open-mmlab/mmsegmentation/pull/2687)) + +### Enhancement + +- Robust mapping from image path to seg map path ([#3091](https://github.com/open-mmlab/mmsegmentation/pull/3091)) +- Change assertion logic inference cfg.model.test_cfg ([#3012](https://github.com/open-mmlab/mmsegmentation/pull/3012)) +- Refactor dice loss ([#3002](https://github.com/open-mmlab/mmsegmentation/pull/3002)) +- Update Dockerfile libgl1-mesa-dev ([#3095](https://github.com/open-mmlab/mmsegmentation/pull/3095)) +- Prevent passed `ann_file` from silently failing to load ([#2966](https://github.com/open-mmlab/mmsegmentation/pull/2966)) +- Update the translation of models documentation ([#2833](https://github.com/open-mmlab/mmsegmentation/pull/2833)) +- Add docs contents at README.md ([#3083](https://github.com/open-mmlab/mmsegmentation/pull/3083)) +- Enhance swin pretrained model loading ([#3097](https://github.com/open-mmlab/mmsegmentation/pull/3097)) + +### Bug Fixes + +- Handle case where device is neither CPU nor CUDA in HamHead ([#2868](https://github.com/open-mmlab/mmsegmentation/pull/2868)) +- Fix bugs when out_channels==1 ([#2911](https://github.com/open-mmlab/mmsegmentation/pull/2911)) +- Fix binary C=1 focal loss & dataset fileio ([#2935](https://github.com/open-mmlab/mmsegmentation/pull/2935)) +- Fix isaid dataset pre-processing tool ([#3010](https://github.com/open-mmlab/mmsegmentation/pull/3010)) +- Fix bug cannot use both '--tta' and '--out' while testing ([#3067](https://github.com/open-mmlab/mmsegmentation/pull/3067)) +- Fix inferencer ut ([#3117](https://github.com/open-mmlab/mmsegmentation/pull/3117)) +- Fix document ([#2863](https://github.com/open-mmlab/mmsegmentation/pull/2863), [#2896](https://github.com/open-mmlab/mmsegmentation/pull/2896), [#2919](https://github.com/open-mmlab/mmsegmentation/pull/2919), [#2951](https://github.com/open-mmlab/mmsegmentation/pull/2951), [#2970](https://github.com/open-mmlab/mmsegmentation/pull/2970), [#2961](https://github.com/open-mmlab/mmsegmentation/pull/2961), [#3042](https://github.com/open-mmlab/mmsegmentation/pull/3042), ) +- Fix squeeze error when N=1 and C=1 ([#2933](https://github.com/open-mmlab/mmsegmentation/pull/2933)) + +### New Contributors + +- @liu-mengyang made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2896 +- @likyoo made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2911 +- @1qh made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2902 +- @JoshuaChou2018 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2951 +- @jts250 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2833 +- @MGAMZ made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2970 +- @tianbinli made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2568 +- @Provable0816 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2633 +- @Zoulinx made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2903 +- @wufan-tb made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2925 +- @haruishi43 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2966 +- @Masaaki-75 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2675 +- @tang576225574 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2987 +- @Kedreamix made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3010 +- @nightrain01 made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3067 +- @shigengtian made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3095 +- @SheffieldCao made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3097 +- @wangruohui made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3091 +- @LHamnett made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/3012 + +## v1.0.0(04/06/2023) + +### Highlights + +- Add Mapillary Vistas Datasets support to MMSegmentation Core Package ([#2576](https://github.com/open-mmlab/mmsegmentation/pull/2576)) +- Support PIDNet ([#2609](https://github.com/open-mmlab/mmsegmentation/pull/2609)) +- Support SegNeXt ([#2654](https://github.com/open-mmlab/mmsegmentation/pull/2654)) + +### Features + +- Support calculating FLOPs of segmentors ([#2706](https://github.com/open-mmlab/mmsegmentation/pull/2706)) +- Support multi-band image for Mosaic ([#2748](https://github.com/open-mmlab/mmsegmentation/pull/2748)) +- Support dump segment prediction ([#2712](https://github.com/open-mmlab/mmsegmentation/pull/2712)) + +### Bug fix + +- Fix format_result and fix prefix param in cityscape metric, and rename CitysMetric to CityscapesMetric ([#2660](https://github.com/open-mmlab/mmsegmentation/pull/2660)) +- Support input gt seg map is not 2D ([#2739](https://github.com/open-mmlab/mmsegmentation/pull/2739)) +- Fix accepting an unexpected argument `local-rank` in PyTorch 2.0 ([#2812](https://github.com/open-mmlab/mmsegmentation/pull/2812)) + +### Documentation + +- Add Chinese version of various documentation ([#2673](https://github.com/open-mmlab/mmsegmentation/pull/2673), [#2702](https://github.com/open-mmlab/mmsegmentation/pull/2702), [#2703](https://github.com/open-mmlab/mmsegmentation/pull/2703), [#2701](https://github.com/open-mmlab/mmsegmentation/pull/2701), [#2722](https://github.com/open-mmlab/mmsegmentation/pull/2722), [#2733](https://github.com/open-mmlab/mmsegmentation/pull/2733), [#2769](https://github.com/open-mmlab/mmsegmentation/pull/2769), [#2790](https://github.com/open-mmlab/mmsegmentation/pull/2790), [#2798](https://github.com/open-mmlab/mmsegmentation/pull/2798)) +- Update and refine various English documentation ([#2715](https://github.com/open-mmlab/mmsegmentation/pull/2715), [#2755](https://github.com/open-mmlab/mmsegmentation/pull/2755), [#2745](https://github.com/open-mmlab/mmsegmentation/pull/2745), [#2797](https://github.com/open-mmlab/mmsegmentation/pull/2797), [#2799](https://github.com/open-mmlab/mmsegmentation/pull/2799), [#2821](https://github.com/open-mmlab/mmsegmentation/pull/2821), [#2827](https://github.com/open-mmlab/mmsegmentation/pull/2827), [#2831](https://github.com/open-mmlab/mmsegmentation/pull/2831)) +- Add deeplabv3 model structure documentation ([#2426](https://github.com/open-mmlab/mmsegmentation/pull/2426)) +- Add custom metrics documentation ([#2799](https://github.com/open-mmlab/mmsegmentation/pull/2799)) +- Add faq in dev-1.x branch ([#2765](https://github.com/open-mmlab/mmsegmentation/pull/2765)) + +### New Contributors + +- @liuruiqiang made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2554 +- @wangjiangben-hw made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2569 +- @jinxianwei made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2557 +- @KKIEEK made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2747 +- @Renzhihan made their first contribution in https://github.com/open-mmlab/mmsegmentation/pull/2765 + ## v1.0.0rc6(03/03/2023) ### Highlights diff --git a/docs/en/notes/faq.md b/docs/en/notes/faq.md index fe5cac3834a..426b70a8d54 100644 --- a/docs/en/notes/faq.md +++ b/docs/en/notes/faq.md @@ -1,6 +1,6 @@ -# \[WIP\] Frequently Asked Questions (FAQ) +# Frequently Asked Questions (FAQ) -We list some common troubles faced by many users and their corresponding solutions here. Feel free to enrich the list if you find any frequent issues and have ways to help others to solve them. If the contents here do not cover your issue, please create an issue using the [provided templates](https://github.com/open-mmlab/mmsegmentation/blob/master/.github/ISSUE_TEMPLATE/error-report.md/) and make sure you fill in all required information in the template. +We list some common troubles faced by many users and their corresponding solutions here. Feel free to enrich the list if you find any frequent issues and have ways to help others to solve them. If the contents here do not cover your issue, please create an issue using the [provided templates](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/.github/ISSUE_TEMPLATE/error-report.md/) and make sure you fill in all required information in the template. ## Installation @@ -8,13 +8,17 @@ The compatible MMSegmentation, MMCV and MMEngine versions are as below. Please i | MMSegmentation version | MMCV version | MMEngine version | MMClassification (optional) version | MMDetection (optional) version | | :--------------------: | :----------------------------: | :---------------: | :---------------------------------: | :----------------------------: | -| dev-1.x branch | mmcv >= 2.0.0rc4 | MMEngine >= 0.5.0 | mmcls>=1.0.0rc0 | mmdet >= 3.0.0rc6 | -| 1.x branch | mmcv >= 2.0.0rc4 | MMEngine >= 0.5.0 | mmcls>=1.0.0rc0 | mmdet >= 3.0.0rc6 | +| dev-1.x branch | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| main branch | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.2 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.1 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.0 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.0.0 | mmcv >= 2.0.0rc4 | MMEngine >= 0.7.1 | mmcls==1.0.0rc6 | mmdet >= 3.0.0 | | 1.0.0rc6 | mmcv >= 2.0.0rc4 | MMEngine >= 0.5.0 | mmcls>=1.0.0rc0 | mmdet >= 3.0.0rc6 | | 1.0.0rc5 | mmcv >= 2.0.0rc4 | MMEngine >= 0.2.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc6 | | 1.0.0rc4 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | -| 1.0.0rc3 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4 \<=3.0.0rc5 | -| 1.0.0rc2 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4 \<=3.0.0rc5 | +| 1.0.0rc3 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | +| 1.0.0rc2 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | | 1.0.0rc1 | mmcv >= 2.0.0rc1, \<=2.0.0rc3> | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | Not required | | 1.0.0rc0 | mmcv >= 2.0.0rc1, \<=2.0.0rc3> | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | Not required | @@ -24,7 +28,102 @@ Notes: - To install MMSegmentation 0.x and master branch, please refer to [the faq 0.x document](https://mmsegmentation.readthedocs.io/en/latest/faq.html#installation) to check compatible versions of MMCV. +- If you have installed an incompatible version of mmcv, please run `pip uninstall mmcv` to uninstall the installed mmcv first. If you have previously installed mmcv-full (which exists in OpenMMLab 1.x), please run `pip uninstall mmcv-full` to uninstall it. + +- If "No module named 'mmcv'" appears, please follow the steps below; + + 1. Use `pip uninstall mmcv` to uninstall the existing mmcv in the environment. + 2. Install the corresponding mmcv according to the [installation instructions](https://mmsegmentation.readthedocs.io/en/dev-1.x/get_started.html#best-practices). + ## How to know the number of GPUs needed to train the model -- Infer from the name of the config file of the model. You can refer to the `Config Name Style` part of [Learn about Configs](https://github.com/open-mmlab/mmsegmentation/blob/master/docs/en/tutorials/config.md). For example, for config file with name `segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py`, `8xb1` means training the model corresponding to it needs 8 GPUs, and the batch size of each GPU is 1. +- Infer from the name of the config file of the model. You can refer to the `Config Name Style` part of [Learn about Configs](../user_guides/1_config.md). For example, for config file with name `segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py`, `8xb1` means training the model corresponding to it needs 8 GPUs, and the batch size of each GPU is 1. - Infer from the log file. Open the log file of the model and search `nGPU` in the file. The number of figures following `nGPU` is the number of GPUs needed to train the model. For instance, searching for `nGPU` in the log file yields the record `nGPU 0,1,2,3,4,5,6,7`, which indicates that eight GPUs are needed to train the model. + +## What does the auxiliary head mean + +Briefly, it is a deep supervision trick to improve the accuracy. In the training phase, `decode_head` is for decoding semantic segmentation output, `auxiliary_head` is just adding an auxiliary loss, the segmentation result produced by it has no impact to your model's result, it just works in training. You may read this [paper](https://arxiv.org/pdf/1612.01105.pdf) for more information. + +## How to output the segmentation mask image when running the test script + +In the test script, we provide `--out` argument to control whether output the painted images. Users might run the following command: + +```shell +python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} --out ${OUTPUT_DIR} +``` + +## How to handle binary segmentation task + +MMSegmentation uses `num_classes` and `out_channels` to control output of last layer `self.conv_seg`. More details could be found [here](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py). + +`num_classes` should be the same as number of types of labels, in binary segmentation task, dataset only has two types of labels: foreground and background, so `num_classes=2`. `out_channels` controls the output channel of last layer of model, it usually equals to `num_classes`. +But in binary segmentation task, there are two solutions: + +- Set `out_channels=2`, using Cross Entropy Loss in training, using `F.softmax()` and `argmax()` to get prediction of each pixel in inference. + +- Set `out_channels=1`, using Binary Cross Entropy Loss in training, using `F.sigmoid()` and `threshold` to get prediction of each pixel in inference. `threshold` is set 0.3 as default. + +In summary, to implement binary segmentation methods users should modify below parameters in the `decode_head` and `auxiliary_head` configs. Here is a modification example of [pspnet_unet_s5-d16.py](https://github.com/open-mmlab/mmsegmentation/blob/master/configs/_base_/models/pspnet_unet_s5-d16.py): + +- (1) `num_classes=2`, `out_channels=2` and `use_sigmoid=False` in `CrossEntropyLoss`. + +```python +decode_head=dict( + type='PSPHead', + in_channels=64, + in_index=4, + num_classes=2, + out_channels=2, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), +auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + num_classes=2, + out_channels=2, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), +``` + +- (2) `num_classes=2`, `out_channels=1` and `use_sigmoid=True` in `CrossEntropyLoss`. + +```python +decode_head=dict( + type='PSPHead', + in_channels=64, + in_index=4, + num_classes=2, + out_channels=1, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)), +auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + num_classes=2, + out_channels=1, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)), +``` + +## Functionality of `reduce_zero_label` + +The parameter type of `reduce_zero_label` in dataset is Boolean, which is default to False. It is used to ignore the dataset label 0. The specific method is to change label 0 to 255, and subtract 1 from the corresponding number of all the remaining labels. At the same time, set 255 as ignore index in the decode head, which means that it will not participate in the loss calculation. + +Following is the specific implementation logic of `reduce_zero_label`: + +```python +if self.reduce_zero_label: + # avoid using underflow conversion + gt_semantic_seg[gt_semantic_seg == 0] = 255 + gt_semantic_seg = gt_semantic_seg - 1 + gt_semantic_seg[gt_semantic_seg == 254] = 255 +``` + +Whether your dataset needs to use `reduce_zero_label`, there are two types of situations: + +- On [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#isprs-potsdam) dataset, there are six classes: 0-Impervious surfaces, 1-Building, 2-Low vegetation, 3-Tree, 4-Car, 5-Clutter/background. However, this dataset provides two types of RGB labels, one with black pixels at the edges of the images, and the other without. For labels with black edges, in [dataset_converters.py](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/tools/dataset_converters/potsdam.py), it converts the black edges to label 0, and the other labels are 1-Impervious surfaces, 2-Building, 3-Low vegetation, 4-Tree, 5-Car, 6-Clutter/background. Therefore, in the dataset config [potsdam.py](https://github.com/open-mmlab/mmsegmentation/blob/ff95416c3b5ce8d62b9289f743531398efce534f/mmseg/datasets/potsdam.py#L23) `reduce_zero_label=True`。 If you are using labels without black edges, then there are only class 0-5 in the mask label. At this point, you should use `reduce_zero_label=False`. `reduce_zero_label` usage needs to be considered with your actual situation. +- On a dataset with class 0 as the background class, if you need to separate the background from the rest of your classes ultimately then you do not need to use `reduce_zero_label`, which in the dataset config settings should be `reduce_zero_label=False` + +**Note:** Please confirm the number of original classes in the dataset. If there are only two classes, you should not use `reduce_zero_label` which is `reduce_zero_label=False`. diff --git a/docs/en/overview.md b/docs/en/overview.md index 399f343fd4f..bbc0b8e32c3 100644 --- a/docs/en/overview.md +++ b/docs/en/overview.md @@ -72,8 +72,8 @@ Here is a detailed step-by-step guide to learn more about MMSegmentation: please refer to the below guides to build your own segmentation project: - [Add new models](advanced_guides/add_models.md) - - [Add new datasets](advanced_guides/add_dataset.md) - - [Add new transforms](advanced_guides/add_transform.md) + - [Add new datasets](advanced_guides/add_datasets.md) + - [Add new transforms](advanced_guides/add_transforms.md) - [Customize runtime](advanced_guides/customize_runtime.md) 5. If you are more familiar with MMSegmentation v0.x, there is documentation about migration from MMSegmentation v0.x to v1.x @@ -82,4 +82,4 @@ Here is a detailed step-by-step guide to learn more about MMSegmentation: ## References -- https://paperswithcode.com/task/semantic-segmentation/codeless#task-home +- [Paper with code](https://paperswithcode.com/task/semantic-segmentation/codeless#task-home) diff --git a/docs/en/switch_language.md b/docs/en/switch_language.md index 80e30dc3ae4..f58efc42be0 100644 --- a/docs/en/switch_language.md +++ b/docs/en/switch_language.md @@ -1,3 +1,3 @@ -## English +## English -## 简体中文 +## 简体中文 diff --git a/docs/en/user_guides/1_config.md b/docs/en/user_guides/1_config.md index 54c1f36363b..291c488e8e1 100644 --- a/docs/en/user_guides/1_config.md +++ b/docs/en/user_guides/1_config.md @@ -521,7 +521,7 @@ if __name__ == '__main__': main() ``` -A example config file `demo_config.py` as follows: +An example config file `demo_config.py` as follows: ```python backbone = dict( diff --git a/docs/en/user_guides/2_dataset_prepare.md b/docs/en/user_guides/2_dataset_prepare.md index 6c81d60f41c..2816a51f0db 100644 --- a/docs/en/user_guides/2_dataset_prepare.md +++ b/docs/en/user_guides/2_dataset_prepare.md @@ -1,7 +1,8 @@ -## Prepare datasets +# Tutorial 2: Prepare datasets It is recommended to symlink the dataset root to `$MMSEGMENTATION/data`. If your folder structure is different, you may need to change the corresponding paths in config files. +For users in China, we also recommend you get the dsdl dataset from our opensource platform [OpenDataLab](https://opendatalab.com/), for better download and use experience,here is an example: [DSDLReadme](../../../configs/dsdl/README.md), welcome to try. ```none mmsegmentation @@ -177,22 +178,67 @@ mmsegmentation | │ │ │ ├── labels | │ │ │ ├── panoptic | │   │   │ └── polygons +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +│ ├── nyu +│ │ ├── images +│ │ │ ├── train +│ │ │ ├── test +│ │ ├── annotations +│ │ │ ├── train +│ │ │ ├── test ``` -### Cityscapes +## Download dataset via MIM + +By using [OpenXLab](https://openxlab.org.cn/datasets), you can obtain free formatted datasets in various fields. Through the search function of the platform, you may address the dataset they look for quickly and easily. Using the formatted datasets from the platform, you can efficiently conduct tasks across datasets. + +If you use MIM to download, make sure that the version is greater than v0.3.8. You can use the following command to update, install, login and download the dataset: + +```shell +# upgrade your MIM +pip install -U openmim + +# install OpenXLab CLI tools +pip install -U openxlab +# log in OpenXLab +openxlab login + +# download ADE20K by MIM +mim download mmsegmentation --dataset ade20k +``` + +## Cityscapes The data could be found [here](https://www.cityscapes-dataset.com/downloads/) after registration. By convention, `**labelTrainIds.png` are used for cityscapes training. -We provided a [scripts](https://github.com/open-mmlab/mmsegmentation/blob/1.x/tools/dataset_converters/cityscapes.py) based on [cityscapesscripts](https://github.com/mcordts/cityscapesScripts) -to generate `**labelTrainIds.png`. +We provided a [script](https://github.com/open-mmlab/mmsegmentation/blob/1.x/tools/dataset_converters/cityscapes.py) based on [cityscapesscripts](https://github.com/mcordts/cityscapesScripts)to generate `**labelTrainIds.png`. ```shell # --nproc means 8 process for conversion, which could be omitted as well. python tools/dataset_converters/cityscapes.py data/cityscapes --nproc 8 ``` -### Pascal VOC +## Pascal VOC Pascal VOC 2012 could be downloaded from [here](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar). Beside, most recent works on Pascal VOC dataset usually exploit extra augmentation data, which could be found [here](http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/semantic_contours/benchmark.tgz). @@ -204,14 +250,14 @@ If you would like to use augmented VOC dataset, please run following command to python tools/dataset_converters/voc_aug.py data/VOCdevkit data/VOCdevkit/VOCaug --nproc 8 ``` -Please refer to [concat dataset](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/datasets.md) for details about how to concatenate them and train them together. +Please refer to [concat dataset](../advanced_guides/add_datasets.md#concatenate-dataset) and [voc_aug config example](../../../configs/_base_/datasets/pascal_voc12_aug.py) for details about how to concatenate them and train them together. -### ADE20K +## ADE20K The training and validation set of ADE20K could be download from this [link](http://data.csail.mit.edu/places/ADEchallenge/ADEChallengeData2016.zip). We may also download test set from [here](http://data.csail.mit.edu/places/ADEchallenge/release_test.zip). -### Pascal Context +## Pascal Context The training and validation set of Pascal Context could be download from [here](http://host.robots.ox.ac.uk/pascal/VOC/voc2010/VOCtrainval_03-May-2010.tar). You may also download test set from [here](http://host.robots.ox.ac.uk:8080/eval/downloads/VOC2010test.tar) after registration. @@ -223,7 +269,7 @@ If you would like to use Pascal Context dataset, please install [Detail](https:/ python tools/dataset_converters/pascal_context.py data/VOCdevkit data/VOCdevkit/VOC2010/trainval_merged.json ``` -### COCO Stuff 10k +## COCO Stuff 10k The data could be downloaded [here](http://calvin.inf.ed.ac.uk/wp-content/uploads/data/cocostuffdataset/cocostuff-10k-v1.1.zip) by wget. @@ -243,7 +289,7 @@ python tools/dataset_converters/coco_stuff10k.py /path/to/coco_stuff10k --nproc By convention, mask labels in `/path/to/coco_stuff164k/annotations/*2014/*_labelTrainIds.png` are used for COCO Stuff 10k training and testing. -### COCO Stuff 164k +## COCO Stuff 164k For COCO Stuff 164k dataset, please run the following commands to download and convert the augmented dataset. @@ -267,7 +313,7 @@ By convention, mask labels in `/path/to/coco_stuff164k/annotations/*2017/*_label The details of this dataset could be found at [here](https://github.com/nightrome/cocostuff#downloads). -### CHASE DB1 +## CHASE DB1 The training and validation set of CHASE DB1 could be download from [here](https://staffnet.kingston.ac.uk/~ku15565/CHASE_DB1/assets/CHASEDB1.zip). @@ -279,7 +325,7 @@ python tools/dataset_converters/chase_db1.py /path/to/CHASEDB1.zip The script will make directory structure automatically. -### DRIVE +## DRIVE The training and validation set of DRIVE could be download from [here](https://drive.grand-challenge.org/). Before that, you should register an account. Currently '1st_manual' is not provided officially. @@ -291,7 +337,7 @@ python tools/dataset_converters/drive.py /path/to/training.zip /path/to/test.zip The script will make directory structure automatically. -### HRF +## HRF First, download [healthy.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/healthy.zip), [glaucoma.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/glaucoma.zip), [diabetic_retinopathy.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/diabetic_retinopathy.zip), [healthy_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/healthy_manualsegm.zip), [glaucoma_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/glaucoma_manualsegm.zip) and [diabetic_retinopathy_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/diabetic_retinopathy_manualsegm.zip). @@ -303,7 +349,7 @@ python tools/dataset_converters/hrf.py /path/to/healthy.zip /path/to/healthy_man The script will make directory structure automatically. -### STARE +## STARE First, download [stare-images.tar](http://cecas.clemson.edu/~ahoover/stare/probing/stare-images.tar), [labels-ah.tar](http://cecas.clemson.edu/~ahoover/stare/probing/labels-ah.tar) and [labels-vk.tar](http://cecas.clemson.edu/~ahoover/stare/probing/labels-vk.tar). @@ -315,15 +361,15 @@ python tools/dataset_converters/stare.py /path/to/stare-images.tar /path/to/labe The script will make directory structure automatically. -### Dark Zurich +## Dark Zurich Since we only support test models on this dataset, you may only download [the validation set](https://data.vision.ee.ethz.ch/csakarid/shared/GCMA_UIoU/Dark_Zurich_val_anon.zip). -### Nighttime Driving +## Nighttime Driving Since we only support test models on this dataset, you may only download [the test set](http://data.vision.ee.ethz.ch/daid/NighttimeDriving/NighttimeDrivingTest.zip). -### LoveDA +## LoveDA The data could be downloaded from Google Drive [here](https://drive.google.com/drive/folders/1ibYV0qwn4yuuh068Rnc-w4tPi0U0c-ti?usp=sharing). @@ -338,25 +384,25 @@ wget https://zenodo.org/record/5706578/files/Val.zip wget https://zenodo.org/record/5706578/files/Test.zip ``` -For LoveDA dataset, please run the following command to download and re-organize the dataset. +For LoveDA dataset, please run the following command to re-organize the dataset. ```shell python tools/dataset_converters/loveda.py /path/to/loveDA ``` -Using trained model to predict test set of LoveDA and submit it to server can be found [here](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/3_inference.md). +Using trained model to predict test set of LoveDA and submit it to server can be found [here](https://codalab.lisn.upsaclay.fr/competitions/421). More details about LoveDA can be found [here](https://github.com/Junjue-Wang/LoveDA). -### ISPRS Potsdam +## ISPRS Potsdam -The [Potsdam](https://www2.isprs.org/commissions/comm2/wg4/benchmark/2d-sem-label-potsdam/) -dataset is for urban semantic segmentation used in the 2D Semantic Labeling Contest - Potsdam. +The [Potsdam](https://www.isprs.org/education/benchmarks/UrbanSemLab/2d-sem-label-potsdam.aspx) dataset is for urban semantic segmentation used in the 2D Semantic Labeling Contest - Potsdam. -The dataset can be requested at the challenge [homepage](https://www2.isprs.org/commissions/comm2/wg4/benchmark/data-request-form/). +The dataset can be requested at the challenge [homepage](https://www.isprs.org/education/benchmarks/UrbanSemLab/default.aspx). +Or download on [BaiduNetdisk](https://pan.baidu.com/s/1K-cLVZnd1X7d8c26FQ-nGg?pwd=mseg),password:mseg, [Google Drive](https://drive.google.com/drive/folders/1w3EJuyUGet6_qmLwGAWZ9vw5ogeG0zLz?usp=sharing) and [OpenDataLab](https://opendatalab.com/ISPRS_Potsdam/download). The '2_Ortho_RGB.zip' and '5_Labels_all_noBoundary.zip' are required. -For Potsdam dataset, please run the following command to download and re-organize the dataset. +For Potsdam dataset, please run the following command to re-organize the dataset. ```shell python tools/dataset_converters/potsdam.py /path/to/potsdam @@ -364,29 +410,29 @@ python tools/dataset_converters/potsdam.py /path/to/potsdam In our default setting, it will generate 3456 images for training and 2016 images for validation. -### ISPRS Vaihingen +## ISPRS Vaihingen -The [Vaihingen](https://www2.isprs.org/commissions/comm2/wg4/benchmark/2d-sem-label-vaihingen/) -dataset is for urban semantic segmentation used in the 2D Semantic Labeling Contest - Vaihingen. +The [Vaihingen](https://www2.isprs.org/commissions/comm2/wg4/benchmark/2d-sem-label-vaihingen/) dataset is for urban semantic segmentation used in the 2D Semantic Labeling Contest - Vaihingen. The dataset can be requested at the challenge [homepage](https://www2.isprs.org/commissions/comm2/wg4/benchmark/data-request-form/). +Or [BaiduNetdisk](https://pan.baidu.com/s/109D3WLrLafsuYtLeerLiiA?pwd=mseg),password:mseg, [Google Drive](https://drive.google.com/drive/folders/1w3NhvLVA2myVZqOn2pbiDXngNC7NTP_t?usp=sharing). The 'ISPRS_semantic_labeling_Vaihingen.zip' and 'ISPRS_semantic_labeling_Vaihingen_ground_truth_eroded_COMPLETE.zip' are required. -For Vaihingen dataset, please run the following command to download and re-organize the dataset. +For Vaihingen dataset, please run the following command to re-organize the dataset. ```shell python tools/dataset_converters/vaihingen.py /path/to/vaihingen ``` -In our default setting (`clip_size` =512, `stride_size`=256), it will generate 344 images for training and 398 images for validation. +In our default setting (`clip_size`=512, `stride_size`=256), it will generate 344 images for training and 398 images for validation. -### iSAID +## iSAID The data images could be download from [DOTA-v1.0](https://captain-whu.github.io/DOTA/dataset.html) (train/val/test) The data annotations could be download from [iSAID](https://captain-whu.github.io/iSAID/dataset.html) (train/val) -The dataset is a Large-scale Dataset for Instance Segmentation (also have segmantic segmentation) in Aerial Images. +The dataset is a Large-scale Dataset for Instance Segmentation (also have semantic segmentation) in Aerial Images. You may need to follow the following structure for dataset preparation after downloading iSAID dataset. @@ -415,7 +461,7 @@ You may need to follow the following structure for dataset preparation after dow python tools/dataset_converters/isaid.py /path/to/iSAID ``` -In our default setting (`patch_width`=896, `patch_height`=896, `overlap_area`=384), it will generate 33978 images for training and 11644 images for validation. +In our default setting (`patch_width`=896, `patch_height`=896, `overlap_area`=384), it will generate 33978 images for training and 11644 images for validation. ## LIP(Look Into Person) dataset @@ -435,7 +481,7 @@ mv val_segmentations ../ cd .. ``` -The contents of LIP datasets include: +The contents of LIP datasets include: ```none ├── data @@ -456,10 +502,9 @@ The contents of LIP datasets include: ## Synapse dataset -This dataset could be download from [this page](https://www.synapse.org/#!Synapse:syn3193805/wiki/) +This dataset could be download from [this page](https://www.synapse.org/#!Synapse:syn3193805/wiki/). -To follow the data preparation setting of [TransUNet](https://arxiv.org/abs/2102.04306), which splits original training set (30 scans) -into new training (18 scans) and validation set (12 scans). Please run the following command to prepare the dataset. +To follow the data preparation setting of [TransUNet](https://arxiv.org/abs/2102.04306), which splits original training set (30 scans) into new training (18 scans) and validation set (12 scans). Please run the following command to prepare the dataset. ```shell unzip RawData.zip @@ -532,10 +577,9 @@ Then, use this command to convert synapse dataset. python tools/dataset_converters/synapse.py --dataset-path /path/to/synapse ``` -Noted that MMSegmentation default evaluation metric (such as mean dice value) is calculated on 2D slice image, -which is not comparable to results of 3D scan in some paper such as [TransUNet](https://arxiv.org/abs/2102.04306). +Noted that MMSegmentation default evaluation metric (such as mean dice value) is calculated on 2D slice image, which is not comparable to results of 3D scan in some paper such as [TransUNet](https://arxiv.org/abs/2102.04306). -### REFUGE +## REFUGE Register in [REFUGE Challenge](https://refuge.grand-challenge.org) and download [REFUGE dataset](https://refuge.grand-challenge.org/REFUGE2Download). @@ -624,4 +668,87 @@ It includes 400 images for training, 400 images for validation and 400 images fo ``` - You could set Datasets version with `MapillaryDataset_v1` and `MapillaryDataset_v2` in your configs. - View the Mapillary Vistas Datasets config file here [V1.2](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/datasets/mapillary_v1.py) and [V2.0](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/datasets/mapillary_v2.py) + View the Mapillary Vistas Datasets config file here [V1.2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v1.py) and [V2.0](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v2.py) + +## LEVIR-CD + +[LEVIR-CD](https://justchenhao.github.io/LEVIR/) Large-scale Remote Sensing Change Detection Dataset for Building. + +Download the dataset from [here](https://justchenhao.github.io/LEVIR/). + +The supplement version of the dataset can be requested on the [homepage](https://github.com/S2Looking/Dataset) + +Please download the supplement version of the dataset, then unzip `LEVIR-CD+.zip`, the contents of original datasets include: + +```none +│ ├── LEVIR-CD+ +│ │ ├── train +│ │ │ ├── A +│ │ │ ├── B +│ │ │ ├── label +│ │ ├── test +│ │ │ ├── A +│ │ │ ├── B +│ │ │ ├── label +``` + +For LEVIR-CD dataset, please run the following command to crop images without overlap: + +```shell +python tools/dataset_converters/levircd.py --dataset-path /path/to/LEVIR-CD+ --out_dir /path/to/LEVIR-CD +``` + +The size of cropped image is 256x256, which is consistent with the original paper. + +## BDD100K + +- You could download BDD100k datasets from [here](https://bdd-data.berkeley.edu/) after registration. + +- You can download images and masks by clicking `10K Images` button and `Segmentation` button. + +- After download, unzip by the following instructions: + + ```bash + unzip ~/bdd100k_images_10k.zip -d ~/mmsegmentation/data/ + unzip ~/bdd100k_sem_seg_labels_trainval.zip -d ~/mmsegmentation/data/ + ``` + +- And get + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +``` + +## NYU + +- To access the NYU dataset, you can download it from [this link](https://drive.google.com/file/d/1wC-io-14RCIL4XTUrQLk6lBqU2AexLVp/view?usp=share_link) + +- Once the download is complete, you can utilize the [tools/dataset_converters/nyu.py](/tools/dataset_converters/nyu.py) script to extract and organize the data into the required format. Run the following command in your terminal: + + ```bash + python tools/dataset_converters/nyu.py nyu.zip + ``` diff --git a/docs/en/user_guides/3_inference.md b/docs/en/user_guides/3_inference.md index c9f4e62f10d..cacebd2f603 100644 --- a/docs/en/user_guides/3_inference.md +++ b/docs/en/user_guides/3_inference.md @@ -19,7 +19,7 @@ MMSegmentation provides several interfaces for users to easily use pre-trained m ## Inferencer -We provides the most **convenient** way to use the model in MMSegmentation `MMSegInferencer`. You can get segmentation mask for an image with only 3 lines of code. +We provide the most **convenient** way to use the model in MMSegmentation `MMSegInferencer`. You can get segmentation mask for an image with only 3 lines of code. ### Basic Usage @@ -36,7 +36,7 @@ The following example shows how to use `MMSegInferencer` to perform inference on The visualization result should look like:
-https://user-images.githubusercontent.com/76149310/221507927-ae01e3a7-016f-4425-b966-7b19cbbe494e.png +
Moreover, you can use `MMSegInferencer` to process a list of images: @@ -44,7 +44,7 @@ Moreover, you can use `MMSegInferencer` to process a list of images: ``` # Input a list of images >>> images = [image1, image2, ...] # image1 can be a file path or a np.ndarray ->>> inferencer(images, show=True, wait_time=0.5) # wait_time is delay time, and 0 means forever. +>>> inferencer(images, show=True, wait_time=0.5) # wait_time is delay time, and 0 means forever # Or input image directory >>> images = $IMAGESDIR @@ -56,13 +56,12 @@ Moreover, you can use `MMSegInferencer` to process a list of images: >>> inferencer(images, out_dir='outputs', img_out_dir='vis', pred_out_dir='pred') ``` -There is a optional parameter of inferencer, `return_datasamples`, whose default value is False, and -return value of inferencer is a `dict` type by default, including 2 keys 'visualization' and 'predictions'. +There is a optional parameter of inferencer, `return_datasamples`, whose default value is False, and return value of inferencer is a `dict` type by default, including 2 keys 'visualization' and 'predictions'. If `return_datasamples=True` inferencer will return [`SegDataSample`](../advanced_guides/structures.md), or list of it. ``` result = inferencer('demo/demo.png') -# result is a `dict` including 2 keys 'visualization' and 'predictions'. +# result is a `dict` including 2 keys 'visualization' and 'predictions' # 'visualization' includes color segmentation map print(result['visualization'].shape) # (512, 683, 3) @@ -92,18 +91,12 @@ print(type(results[0])) ### Initialization `MMSegInferencer` must be initialized from a `model`, which can be a model name or a `Config` even a path of config file. -The model names can be found in models' metafile, like one model name of maskformer is `maskformer_r50-d32_8xb2-160k_ade20k-512x512`, and if input model name and the weights of the model will be download automatically. Below are other input parameters: - -- weights (str, optional) - Path to the checkpoint. If it is not specified and model is a model name of metafile, the weights will be loaded - from metafile. Defaults to None. -- classes (list, optional) - Input classes for result rendering, as the prediction of segmentation - model is a segment map with label indices, `classes` is a list which includes - items responding to the label indices. If classes is not defined, visualizer will take `cityscapes` classes by default. Defaults to None. -- palette (list, optional) - Input palette for result rendering, which is a list of color palette - responding to the classes. If palette is not defined, visualizer will take `cityscapes` palette by default. Defaults to None. -- dataset_name (str, optional)[Dataset name or alias](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/utils/class_names.py#L302-L317) - visulizer will use the meta information of the dataset i.e. classes and palette, - but the `classes` and `palette` have higher priority. Defaults to None. +The model names can be found in models' metafile (configs/xxx/metafile.yaml), like one model name of maskformer is `maskformer_r50-d32_8xb2-160k_ade20k-512x512`, and if input model name and the weights of the model will be download automatically. Below are other input parameters: + +- weights (str, optional) - Path to the checkpoint. If it is not specified and model is a model name of metafile, the weights will be loaded from metafile. Defaults to None. +- classes (list, optional) - Input classes for result rendering, as the prediction of segmentation model is a segment map with label indices, `classes` is a list which includes items responding to the label indices. If classes is not defined, visualizer will take `cityscapes` classes by default. Defaults to None. +- palette (list, optional) - Input palette for result rendering, which is a list of colors responding to the classes. If the palette is not defined, the visualizer will take the palette of `cityscapes` by default. Defaults to None. +- dataset_name (str, optional) - [Dataset name or alias](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/utils/class_names.py#L302-L317), visualizer will use the meta information of the dataset i.e. classes and palette, but the `classes` and `palette` have higher priority. Defaults to None. - device (str, optional) - Device to run inference. If None, the available device will be automatically used. Defaults to None. - scope (str, optional) - The scope of the model. Defaults to 'mmseg'. @@ -113,8 +106,7 @@ The model names can be found in models' metafile, like one model name of maskfor - show (bool) - Whether to display the image in a popup window. Defaults to False. - wait_time (float) - The interval of show (s). Defaults to 0. -- img_out_dir (str) - Subdirectory of `out_dir`, used to save rendering color segmentation mask, so `out_dir` must be defined - if you would like to save predicted mask. Defaults to 'vis'. +- img_out_dir (str) - Subdirectory of `out_dir`, used to save rendering color segmentation mask, so `out_dir` must be defined if you would like to save predicted mask. Defaults to 'vis'. - opacity (int, float) - The transparency of segmentation mask. Defaults to 0.8. The examples of these parameters is in [Basic Usage](#basic-usage) @@ -245,7 +237,7 @@ vis_image = show_result_pyplot(model, img_path, result) # save the visualization result, the output image would be found at the path `work_dirs/result.png` vis_iamge = show_result_pyplot(model, img_path, result, out_file='work_dirs/result.png') -# Modify the time of displaying images, note that 0 is the special value that means "forever". +# Modify the time of displaying images, note that 0 is the special value that means "forever" vis_image = show_result_pyplot(model, img_path, result, wait_time=5) ``` diff --git a/docs/en/user_guides/5_deployment.md b/docs/en/user_guides/5_deployment.md new file mode 100644 index 00000000000..b3b8f571d01 --- /dev/null +++ b/docs/en/user_guides/5_deployment.md @@ -0,0 +1,255 @@ +# Tutorial 5: Model Deployment + +# MMSegmentation Model Deployment + +- [Tutorial 5: Model Deployment](#tutorial-5-model-deployment) +- [MMSegmentation Model Deployment](#mmsegmentation-model-deployment) + - [Installation](#installation) + - [Install mmseg](#install-mmseg) + - [Install mmdeploy](#install-mmdeploy) + - [Convert model](#convert-model) + - [Model specification](#model-specification) + - [Model inference](#model-inference) + - [Backend model inference](#backend-model-inference) + - [SDK model inference](#sdk-model-inference) + - [Supported models](#supported-models) + - [Note](#note) + +______________________________________________________________________ + +[MMSegmentation](https://github.com/open-mmlab/mmsegmentation/tree/main), also known as `mmseg`, is an open source semantic segmentation toolbox based on Pytorch. It's a part of the [OpenMMLab](<(https://openmmlab.com/)>) object. + +## Installation + +### Install mmseg + +Please follow the [Installation Guide](https://mmsegmentation.readthedocs.io/en/latest/get_started.html). + +### Install mmdeploy + +`mmdeploy` can be installed as follows: + +**Option 1:** Install precompiled package + +Please follow the [Installation overview](https://mmdeploy.readthedocs.io/zh_CN/latest/get_started.html#mmdeploy) + +**Option 2:** Automatic Installation script + +If the deployment platform is **Ubuntu 18.04 +**, please follow the [scription installation](../01-how-to-build/build_from_script.md) to install. +For example, the following commands describe how to install mmdeploy and inference engine-`ONNX Runtime`. + +```shell +git clone --recursive -b main https://github.com/open-mmlab/mmdeploy.git +cd mmdeploy +python3 tools/scripts/build_ubuntu_x64_ort.py $(nproc) +export PYTHONPATH=$(pwd)/build/lib:$PYTHONPATH +export LD_LIBRARY_PATH=$(pwd)/../mmdeploy-dep/onnxruntime-linux-x64-1.8.1/lib/:$LD_LIBRARY_PATH +``` + +**NOTE**: + +- Add `$(pwd)/build/lib` to `PYTHONPATH`, can loading mmdeploy SDK python package `mmdeploy_runtime`. See [SDK model inference](#SDK-model-inference) for more information. +- With [ONNX Runtime model inference](#Backend-model-inference), need to load custom operator library and add ONNX Runtime Library's PATH to `LD_LIBRARY_PATH`. + +**Option 3:** Install with mim + +1. Use mim to install mmcv + +```shell +pip install -U openmim +mim install "mmcv>=2.0.0rc2" +``` + +2. Install mmdeploy + +```shell +git clone https://github.com/open-mmlab/mmdeploy.git +cd mmdeploy +mim install -e . +``` + +**Option 4:** Build MMDeploy from source + +If the first three methods aren't suitable, please [Build MMDeploy from source](<(../01-how-to-build/build_from_source.md)>) + +## Convert model + +[tools/deploy.py](https://github.com/open-mmlab/mmdeploy/tree/main/tools/deploy.py) can convert mmseg Model to backend model conveniently. See [this](https://github.com/open-mmlab/mmdeploy/tree/main/docs/en/02-how-to-run/convert_model.md#usage) for detailed information. + +Then convert `unet` to onnx model as follows: + +```shell +cd mmdeploy + +# download unet model from mmseg model zoo +mim download mmsegmentation --config unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024 --dest . + +# convert mmseg model to onnxruntime model with dynamic shape +python tools/deploy.py \ + configs/mmseg/segmentation_onnxruntime_dynamic.py \ + unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py \ + fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204-6860854e.pth \ + demo/resources/cityscapes.png \ + --work-dir mmdeploy_models/mmseg/ort \ + --device cpu \ + --show \ + --dump-info +``` + +It is crucial to specify the correct deployment config during model conversion. MMDeploy has already provided builtin deployment config [files](https://github.com/open-mmlab/mmdeploy/tree/main/configs/mmseg) of all supported backends for mmsegmentation, under which the config file path follows the pattern: + +``` +segmentation_{backend}-{precision}_{static | dynamic}_{shape}.py +``` + +- **{backend}:** inference backend, such as onnxruntime, tensorrt, pplnn, ncnn, openvino, coreml etc. +- **{precision}:** fp16, int8. When it's empty, it means fp32 +- **{static | dynamic}:** static shape or dynamic shape +- **{shape}:** input shape or shape range of a model + +Therefore, in the above example, you can also convert `unet` to tensorrt-fp16 model by `segmentation_tensorrt-fp16_dynamic-512x1024-2048x2048.py`. + +```{tip} +When converting mmsegmentation models to tensorrt models, --device should be set to "cuda" +``` + +## Model specification + +Before moving on to model inference chapter, let's know more about the converted model structure which is very important for model inference. + +The converted model locates in the working directory like `mmdeploy_models/mmseg/ort` in the previous example. It includes: + +``` +mmdeploy_models/mmseg/ort +├── deploy.json +├── detail.json +├── end2end.onnx +└── pipeline.json +``` + +in which, + +- **end2end.onnx**: backend model which can be inferred by ONNX Runtime +- ***xxx*.json**: the necessary information for mmdeploy SDK + +The whole package **mmdeploy_models/mmseg/ort** is defined as **mmdeploy SDK model**, i.e., **mmdeploy SDK model** includes both backend model and inference meta information. + +## Model inference + +### Backend model inference + +Take the previous converted `end2end.onnx` model as an example, you can use the following code to inference the model and visualize the results: + +```python +from mmdeploy.apis.utils import build_task_processor +from mmdeploy.utils import get_input_shape, load_config +import torch + +deploy_cfg = 'configs/mmseg/segmentation_onnxruntime_dynamic.py' +model_cfg = './unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py' +device = 'cpu' +backend_model = ['./mmdeploy_models/mmseg/ort/end2end.onnx'] +image = './demo/resources/cityscapes.png' + +# read deploy_cfg and model_cfg +deploy_cfg, model_cfg = load_config(deploy_cfg, model_cfg) + +# build task and backend model +task_processor = build_task_processor(model_cfg, deploy_cfg, device) +model = task_processor.build_backend_model(backend_model) + +# process input image +input_shape = get_input_shape(deploy_cfg) +model_inputs, _ = task_processor.create_input(image, input_shape) + +# do model inference +with torch.no_grad(): + result = model.test_step(model_inputs) + +# visualize results +task_processor.visualize( + image=image, + model=model, + result=result[0], + window_name='visualize', + output_file='./output_segmentation.png') +``` + +### SDK model inference + +You can also perform SDK model inference like following: + +```python +from mmdeploy_runtime import Segmentor +import cv2 +import numpy as np + +img = cv2.imread('./demo/resources/cityscapes.png') + +# create a classifier +segmentor = Segmentor(model_path='./mmdeploy_models/mmseg/ort', device_name='cpu', device_id=0) +# perform inference +seg = segmentor(img) + +# visualize inference result +## random a palette with size 256x3 +palette = np.random.randint(0, 256, size=(256, 3)) +color_seg = np.zeros((seg.shape[0], seg.shape[1], 3), dtype=np.uint8) +for label, color in enumerate(palette): + color_seg[seg == label, :] = color +# convert to BGR +color_seg = color_seg[..., ::-1] +img = img * 0.5 + color_seg * 0.5 +img = img.astype(np.uint8) +cv2.imwrite('output_segmentation.png', img) +``` + +Besides python API, mmdeploy SDK also provides other FFI (Foreign Function Interface), such as C, C++, C#, Java and so on. You can learn their usage from [demo](https://github.com/open-mmlab/mmdeploy/tree/main/demo) + +## Supported models + +| Model | TorchScript | OnnxRuntime | TensorRT | ncnn | PPLNN | OpenVino | +| :-------------------------------------------------------------------------------------------------------- | :---------: | :---------: | :------: | :--: | :---: | :------: | +| [FCN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fcn) | Y | Y | Y | Y | Y | Y | +| [PSPNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/pspnet)[\*](#static_shape) | Y | Y | Y | Y | Y | Y | +| [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/deeplabv3) | Y | Y | Y | Y | Y | Y | +| [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/deeplabv3plus) | Y | Y | Y | Y | Y | Y | +| [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fastscnn)[\*](#static_shape) | Y | Y | Y | N | Y | Y | +| [UNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/unet) | Y | Y | Y | Y | Y | Y | +| [ANN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ann)[\*](#static_shape) | Y | Y | Y | N | N | N | +| [APCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/apcnet) | Y | Y | Y | Y | N | N | +| [BiSeNetV1](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/bisenetv1) | Y | Y | Y | Y | N | Y | +| [BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/bisenetv2) | Y | Y | Y | Y | N | Y | +| [CGNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/cgnet) | Y | Y | Y | Y | N | Y | +| [DMNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dmnet) | ? | Y | N | N | N | N | +| [DNLNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dnlnet) | ? | Y | Y | Y | N | Y | +| [EMANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/emanet) | Y | Y | Y | N | N | Y | +| [EncNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/encnet) | Y | Y | Y | N | N | Y | +| [ERFNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/erfnet) | Y | Y | Y | Y | N | Y | +| [FastFCN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fastfcn) | Y | Y | Y | Y | N | Y | +| [GCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/gcnet) | Y | Y | Y | N | N | N | +| [ICNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/icnet)[\*](#static_shape) | Y | Y | Y | N | N | Y | +| [ISANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/isanet)[\*](#static_shape) | N | Y | Y | N | N | Y | +| [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/nonlocal_net) | ? | Y | Y | Y | N | Y | +| [OCRNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ocrnet) | Y | Y | Y | Y | N | Y | +| [PointRend](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/point_rend)[\*](#static_shape) | Y | Y | Y | N | N | N | +| [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/sem_fpn) | Y | Y | Y | Y | N | Y | +| [STDC](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/stdc) | Y | Y | Y | Y | N | Y | +| [UPerNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/upernet)[\*](#static_shape) | N | Y | Y | N | N | N | +| [DANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/danet) | ? | Y | Y | N | N | Y | +| [Segmenter](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/segmenter)[\*](#static_shape) | N | Y | Y | Y | N | Y | +| [SegFormer](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/segformer)[\*](#static_shape) | ? | Y | Y | N | N | Y | +| [SETR](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/setr) | ? | Y | N | N | N | Y | +| [CCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ccnet) | ? | N | N | N | N | N | +| [PSANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/psanet) | ? | N | N | N | N | N | +| [DPT](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dpt) | ? | N | N | N | N | N | + +## Note + +- All mmseg models only support the 'whole' inference mode. + +- PSPNet,Fast-SCNN only supports static input, because most inference framework's [nn.AdaptiveAvgPool2d](https://github.com/open-mmlab/mmsegmentation/blob/0c87f7a0c9099844eff8e90fa3db5b0d0ca02fee/mmseg/models/decode_heads/psp_head.py#L38) don't support dynamic input。 + +- For models that only support static shapes, should use the static shape deployment config file, such as `configs/mmseg/segmentation_tensorrt_static-1024x2048.py` + +- To deploy models to generate probabilistic feature maps, please add `codebase_config = dict(with_argmax=False)` to deployment config file. diff --git a/docs/en/user_guides/deployment.md b/docs/en/user_guides/deployment.md deleted file mode 100644 index a23f4b404bc..00000000000 --- a/docs/en/user_guides/deployment.md +++ /dev/null @@ -1,184 +0,0 @@ -# \[WIP\] Deployment - -> ## [Try the new MMDeploy to deploy your model](https://mmdeploy.readthedocs.io/) - -## Convert to ONNX (experimental) - -We provide a script to convert model to [ONNX](https://github.com/onnx/onnx) format. The converted model could be visualized by tools like [Netron](https://github.com/lutzroeder/netron). Besides, we also support comparing the output results between PyTorch and ONNX model. - -```bash -python tools/pytorch2onnx.py \ - ${CONFIG_FILE} \ - --checkpoint ${CHECKPOINT_FILE} \ - --output-file ${ONNX_FILE} \ - --input-img ${INPUT_IMG} \ - --shape ${INPUT_SHAPE} \ - --rescale-shape ${RESCALE_SHAPE} \ - --show \ - --verify \ - --dynamic-export \ - --cfg-options \ - model.test_cfg.mode="whole" -``` - -Description of arguments: - -- `config` : The path of a model config file. -- `--checkpoint` : The path of a model checkpoint file. -- `--output-file`: The path of output ONNX model. If not specified, it will be set to `tmp.onnx`. -- `--input-img` : The path of an input image for conversion and visualize. -- `--shape`: The height and width of input tensor to the model. If not specified, it will be set to img_scale of test_pipeline. -- `--rescale-shape`: rescale shape of output, set this value to avoid OOM, only work on `slide` mode. -- `--show`: Determines whether to print the architecture of the exported model. If not specified, it will be set to `False`. -- `--verify`: Determines whether to verify the correctness of an exported model. If not specified, it will be set to `False`. -- `--dynamic-export`: Determines whether to export ONNX model with dynamic input and output shapes. If not specified, it will be set to `False`. -- `--cfg-options`:Update config options. - -:::{note} -This tool is still experimental. Some customized operators are not supported for now. -::: - -### Evaluate ONNX model - -We provide `tools/deploy_test.py` to evaluate ONNX model with different backend. - -### Prerequisite - -- Install onnx and onnxruntime-gpu - - ```shell - pip install onnx onnxruntime-gpu - ``` - -- Install TensorRT following [how-to-build-tensorrt-plugins-in-mmcv](https://mmcv.readthedocs.io/en/latest/tensorrt_plugin.html#how-to-build-tensorrt-plugins-in-mmcv)(optional) - -### Usage - -```bash -python tools/deploy_test.py \ - ${CONFIG_FILE} \ - ${MODEL_FILE} \ - ${BACKEND} \ - --out ${OUTPUT_FILE} \ - --eval ${EVALUATION_METRICS} \ - --show \ - --show-dir ${SHOW_DIRECTORY} \ - --cfg-options ${CFG_OPTIONS} \ - --eval-options ${EVALUATION_OPTIONS} \ - --opacity ${OPACITY} \ -``` - -Description of all arguments - -- `config`: The path of a model config file. -- `model`: The path of a converted model file. -- `backend`: Backend of the inference, options: `onnxruntime`, `tensorrt`. -- `--out`: The path of output result file in pickle format. -- `--format-only` : Format the output results without perform evaluation. It is useful when you want to format the result to a specific format and submit it to the test server. If not specified, it will be set to `False`. Note that this argument is **mutually exclusive** with `--eval`. -- `--eval`: Evaluation metrics, which depends on the dataset, e.g., "mIoU" for generic datasets, and "cityscapes" for Cityscapes. Note that this argument is **mutually exclusive** with `--format-only`. -- `--show`: Show results flag. -- `--show-dir`: Directory where painted images will be saved -- `--cfg-options`: Override some settings in the used config file, the key-value pair in `xxx=yyy` format will be merged into config file. -- `--eval-options`: Custom options for evaluation, the key-value pair in `xxx=yyy` format will be kwargs for `dataset.evaluate()` function -- `--opacity`: Opacity of painted segmentation map. In (0, 1\] range. - -### Results and Models - -| Model | Config | Dataset | Metric | PyTorch | ONNXRuntime | TensorRT-fp32 | TensorRT-fp16 | -| :--------: | :---------------------------------------------: | :--------: | :----: | :-----: | :---------: | :-----------: | :-----------: | -| FCN | fcn_r50-d8_512x1024_40k_cityscapes.py | cityscapes | mIoU | 72.2 | 72.2 | 72.2 | 72.2 | -| PSPNet | pspnet_r50-d8_512x1024_40k_cityscapes.py | cityscapes | mIoU | 77.8 | 77.8 | 77.8 | 77.8 | -| deeplabv3 | deeplabv3_r50-d8_512x1024_40k_cityscapes.py | cityscapes | mIoU | 79.0 | 79.0 | 79.0 | 79.0 | -| deeplabv3+ | deeplabv3plus_r50-d8_512x1024_40k_cityscapes.py | cityscapes | mIoU | 79.6 | 79.5 | 79.5 | 79.5 | -| PSPNet | pspnet_r50-d8_769x769_40k_cityscapes.py | cityscapes | mIoU | 78.2 | 78.1 | | | -| deeplabv3 | deeplabv3_r50-d8_769x769_40k_cityscapes.py | cityscapes | mIoU | 78.5 | 78.3 | | | -| deeplabv3+ | deeplabv3plus_r50-d8_769x769_40k_cityscapes.py | cityscapes | mIoU | 78.9 | 78.7 | | | - -:::{note} -TensorRT is only available on configs with `whole mode`. -::: - -## Convert to TorchScript (experimental) - -We also provide a script to convert model to [TorchScript](https://pytorch.org/docs/stable/jit.html) format. You can use the pytorch C++ API [LibTorch](https://pytorch.org/docs/stable/cpp_index.html) inference the trained model. The converted model could be visualized by tools like [Netron](https://github.com/lutzroeder/netron). Besides, we also support comparing the output results between PyTorch and TorchScript model. - -```shell -python tools/pytorch2torchscript.py \ - ${CONFIG_FILE} \ - --checkpoint ${CHECKPOINT_FILE} \ - --output-file ${ONNX_FILE} - --shape ${INPUT_SHAPE} - --verify \ - --show -``` - -Description of arguments: - -- `config` : The path of a pytorch model config file. -- `--checkpoint` : The path of a pytorch model checkpoint file. -- `--output-file`: The path of output TorchScript model. If not specified, it will be set to `tmp.pt`. -- `--input-img` : The path of an input image for conversion and visualize. -- `--shape`: The height and width of input tensor to the model. If not specified, it will be set to `512 512`. -- `--show`: Determines whether to print the traced graph of the exported model. If not specified, it will be set to `False`. -- `--verify`: Determines whether to verify the correctness of an exported model. If not specified, it will be set to `False`. - -:::{note} -It's only support PyTorch>=1.8.0 for now. -::: - -:::{note} -This tool is still experimental. Some customized operators are not supported for now. -::: - -Examples: - -- Convert the cityscapes PSPNet pytorch model. - - ```shell - python tools/pytorch2torchscript.py configs/pspnet/pspnet_r50-d8_512x1024_40k_cityscapes.py \ - --checkpoint checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth \ - --output-file checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pt \ - --shape 512 1024 - ``` - -## Convert to TensorRT (experimental) - -A script to convert [ONNX](https://github.com/onnx/onnx) model to [TensorRT](https://developer.nvidia.com/tensorrt) format. - -Prerequisite - -- install `mmcv-full` with ONNXRuntime custom ops and TensorRT plugins follow [ONNXRuntime in mmcv](https://mmcv.readthedocs.io/en/latest/deployment/onnxruntime_op.html) and [TensorRT plugin in mmcv](https://github.com/open-mmlab/mmcv/blob/master/docs/en/deployment/tensorrt_plugin.md). -- Use [pytorch2onnx](#convert-to-onnx-experimental) to convert the model from PyTorch to ONNX. - -Usage - -```bash -python ${MMSEG_PATH}/tools/onnx2tensorrt.py \ - ${CFG_PATH} \ - ${ONNX_PATH} \ - --trt-file ${OUTPUT_TRT_PATH} \ - --min-shape ${MIN_SHAPE} \ - --max-shape ${MAX_SHAPE} \ - --input-img ${INPUT_IMG} \ - --show \ - --verify -``` - -Description of all arguments - -- `config` : Config file of the model. -- `model` : Path to the input ONNX model. -- `--trt-file` : Path to the output TensorRT engine. -- `--max-shape` : Maximum shape of model input. -- `--min-shape` : Minimum shape of model input. -- `--fp16` : Enable fp16 model conversion. -- `--workspace-size` : Max workspace size in GiB. -- `--input-img` : Image for visualize. -- `--show` : Enable result visualize. -- `--dataset` : Palette provider, `CityscapesDataset` as default. -- `--verify` : Verify the outputs of ONNXRuntime and TensorRT. -- `--verbose` : Whether to verbose logging messages while creating TensorRT engine. Defaults to False. - -:::{note} -Only tested on whole mode. -::: diff --git a/docs/en/user_guides/visualization_feature_map.md b/docs/en/user_guides/visualization_feature_map.md index d61226f055c..08398e514a0 100644 --- a/docs/en/user_guides/visualization_feature_map.md +++ b/docs/en/user_guides/visualization_feature_map.md @@ -194,7 +194,7 @@ ann_r50-d8_512x1024_40k_cityscapes_20200605_095211-049fc292.pth \ --gt_mask aachen_000000_000019_gtFine_labelTrainIds.png ``` -The visualized image result and its corresponding reature map will appear in the wandb account. +The visualized image result and its corresponding feature map will appear in the wandb account.
diff --git a/docs/zh_cn/advanced_guides/add_datasets.md b/docs/zh_cn/advanced_guides/add_datasets.md index 4ea14934ed2..22fbf3462fc 100644 --- a/docs/zh_cn/advanced_guides/add_datasets.md +++ b/docs/zh_cn/advanced_guides/add_datasets.md @@ -1,4 +1,62 @@ -# 新增自定义数据集(待更新) +# 新增自定义数据集 + +## 新增自定义数据集 + +在这里,我们展示如何构建一个新的数据集。 + +1. 创建一个新文件 `mmseg/datasets/example.py` + + ```python + from mmseg.registry import DATASETS + from .basesegdataset import BaseSegDataset + + + @DATASETS.register_module() + class ExampleDataset(BaseSegDataset): + + METAINFO = dict( + classes=('xxx', 'xxx', ...), + palette=[[x, x, x], [x, x, x], ...]) + + def __init__(self, aeg1, arg2): + pass + ``` + +2. 在 `mmseg/datasets/__init__.py` 中导入模块 + + ```python + from .example import ExampleDataset + ``` + +3. 通过创建一个新的数据集配置文件 `configs/_base_/datasets/example_dataset.py` 来使用它 + + ```python + dataset_type = 'ExampleDataset' + data_root = 'data/example/' + ... + ``` + +4. 在 `mmseg/utils/class_names.py` 中补充数据集元信息 + + ```python + def example_classes(): + return [ + 'xxx', 'xxx', + ... + ] + + def example_palette(): + return [ + [x, x, x], [x, x, x], + ... + ] + dataset_aliases ={ + 'example': ['example', ...], + ... + } + ``` + +**注意:** 如果新数据集不满足 mmseg 的要求,则需要在 `tools/dataset_converters/` 中准备一个数据集预处理脚本 ## 通过重新组织数据来定制数据集 @@ -26,30 +84,17 @@ 一个训练对将由 img_dir/ann_dir 里同样首缀的文件组成。 -如果给定 `split` 参数,只有部分在 img_dir/ann_dir 里的文件会被加载。 -我们可以对被包括在 split 文本里的文件指定前缀。 +有些数据集不会发布测试集或测试集的标注,如果没有测试集的标注,我们就无法在本地进行评估模型,因此我们在配置文件中将验证集设置为默认测试集。 -除此以外,一个 split 文本如下所示: - -```none -xxx -zzz -``` +关于如何构建自己的数据集或实现新的数据集类,请参阅[数据集指南](./datasets.md)以获取更多详细信息。 -只有 - -`data/my_dataset/img_dir/train/xxx{img_suffix}`, -`data/my_dataset/img_dir/train/zzz{img_suffix}`, -`data/my_dataset/ann_dir/train/xxx{seg_map_suffix}`, -`data/my_dataset/ann_dir/train/zzz{seg_map_suffix}` 将被加载。 - -注意:标注是跟图像同样的形状 (H, W),其中的像素值的范围是 `[0, num_classes - 1]`。 +**注意:** 标注是跟图像同样的形状 (H, W),其中的像素值的范围是 `[0, num_classes - 1]`。 您也可以使用 [pillow](https://pillow.readthedocs.io/en/stable/handbook/concepts.html#palette) 的 `'P'` 模式去创建包含颜色的标注。 ## 通过混合数据去定制数据集 MMSegmentation 同样支持混合数据集去训练。 -当前它支持拼接 (concat), 重复 (repeat) 和多图混合 (multi-image mix)数据集。 +当前它支持拼接 (concat), 重复 (repeat) 和多图混合 (multi-image mix) 数据集。 ### 重复数据集 @@ -58,79 +103,29 @@ MMSegmentation 同样支持混合数据集去训练。 ```python dataset_A_train = dict( - type='RepeatDataset', - times=N, - dataset=dict( # 这是 Dataset_A 数据集的原始配置 - type='Dataset_A', - ... - pipeline=train_pipeline - ) + type='RepeatDataset', + times=N, + dataset=dict( # 这是 Dataset_A 数据集的原始配置 + type='Dataset_A', + ... + pipeline=train_pipeline ) +) ``` ### 拼接数据集 -有2种方式去拼接数据集。 - -1. 如果您想拼接的数据集是同样的类型,但有不同的标注文件, - 您可以按如下操作去拼接数据集的配置文件: - - 1. 您也许可以拼接两个标注文件夹 `ann_dir` - - ```python - dataset_A_train = dict( - type='Dataset_A', - img_dir = 'img_dir', - ann_dir = ['anno_dir_1', 'anno_dir_2'], - pipeline=train_pipeline - ) - ``` - - 2. 您也可以去拼接两个 `split` 文件列表 - - ```python - dataset_A_train = dict( - type='Dataset_A', - img_dir = 'img_dir', - ann_dir = 'anno_dir', - split = ['split_1.txt', 'split_2.txt'], - pipeline=train_pipeline - ) - ``` +如果要拼接不同的数据集,可以按如下方式连接数据集配置。 - 3. 您也可以同时拼接 `ann_dir` 文件夹和 `split` 文件列表 - - ```python - dataset_A_train = dict( - type='Dataset_A', - img_dir = 'img_dir', - ann_dir = ['anno_dir_1', 'anno_dir_2'], - split = ['split_1.txt', 'split_2.txt'], - pipeline=train_pipeline - ) - ``` - - 在这样的情况下, `ann_dir_1` 和 `ann_dir_2` 分别对应于 `split_1.txt` 和 `split_2.txt` - -2. 如果您想拼接不同的数据集,您可以如下去拼接数据集的配置文件: - - ```python - dataset_A_train = dict() - dataset_B_train = dict() - - data = dict( - imgs_per_gpu=2, - workers_per_gpu=2, - train = [ - dataset_A_train, - dataset_B_train - ], - val = dataset_A_val, - test = dataset_A_test - ) - ``` +```python +dataset_A_train = dict() +dataset_B_train = dict() +concatenate_dataset = dict( + type='ConcatDataset', + datasets=[dataset_A_train, dataset_B_train]) +``` -一个更复杂的例子如下:分别重复 `Dataset_A` 和 `Dataset_B` N 次和 M 次,然后再去拼接重复后的数据集 +下面是一个更复杂的示例,它分别重复 `Dataset_A` 和 `Dataset_B` N 次和 M 次,然后连接重复的数据集。 ```python dataset_A_train = dict( @@ -159,41 +154,36 @@ dataset_B_train = dict( pipeline=train_pipeline ) ) -data = dict( - imgs_per_gpu=2, - workers_per_gpu=2, - train = [ - dataset_A_train, - dataset_B_train - ], - val = dataset_A_val, - test = dataset_A_test -) +train_dataloader = dict( + dataset=dict( + type='ConcatDataset', + datasets=[dataset_A_train, dataset_B_train])) + +val_dataloader = dict(dataset=dataset_A_val) +test_dataloader = dict(dataset=dataset_A_test) ``` +您可以参考 mmengine 的基础数据集[教程](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/basedataset.html)以了解更多详细信息 + ### 多图混合集 -我们使用 `MultiImageMixDataset` 作为包装(wrapper)去混合多个数据集的图片。 -`MultiImageMixDataset`可以被类似mosaic和mixup的多图混合数据増广使用。 +我们使用 `MultiImageMixDataset` 作为包装(wrapper)去混合多个数据集的图片。 +`MultiImageMixDataset`可以被类似 mosaic 和 mixup 的多图混合数据増广使用。 -`MultiImageMixDataset`与`Mosaic`数据増广一起使用的例子: +`MultiImageMixDataset` 与 `Mosaic` 数据増广一起使用的例子: ```python train_pipeline = [ dict(type='RandomMosaic', prob=1), dict(type='Resize', img_scale=(1024, 512), keep_ratio=True), dict(type='RandomFlip', prob=0.5), - dict(type='Normalize', **img_norm_cfg), - dict(type='DefaultFormatBundle'), - dict(type='Collect', keys=['img', 'gt_semantic_seg']), + dict(type='PackSegInputs') ] train_dataset = dict( type='MultiImageMixDataset', dataset=dict( - classes=classes, - palette=palette, type=dataset_type, reduce_zero_label=False, img_dir=data_root + "images/train", diff --git a/docs/zh_cn/advanced_guides/add_metrics.md b/docs/zh_cn/advanced_guides/add_metrics.md index 3a371e357e8..0637b447284 100644 --- a/docs/zh_cn/advanced_guides/add_metrics.md +++ b/docs/zh_cn/advanced_guides/add_metrics.md @@ -1 +1,81 @@ -# 新增评测指标 (待更新) +# 新增评测指标 + +## 使用 MMSegmentation 的源代码进行开发 + +在这里,我们用 `CustomMetric` 作为例子来展示如何开发一个新的评测指标。 + +1. 创建一个新文件 `mmseg/evaluation/metrics/custom_metric.py`。 + + ```python + from typing import List, Sequence + + from mmengine.evaluator import BaseMetric + + from mmseg.registry import METRICS + + + @METRICS.register_module() + class CustomMetric(BaseMetric): + + def __init__(self, arg1, arg2): + """ + The metric first processes each batch of data_samples and predictions, + and appends the processed results to the results list. Then it + collects all results together from all ranks if distributed training + is used. Finally, it computes the metrics of the entire dataset. + """ + + def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: + pass + + def compute_metrics(self, results: list) -> dict: + pass + + def evaluate(self, size: int) -> dict: + pass + ``` + + 在上面的示例中,`CustomMetric` 是 `BaseMetric` 的子类。它有三个方法:`process`,`compute_metrics` 和 `evaluate`。 + + - `process()` 处理一批数据样本和预测。处理后的结果需要显示地传给 `self.results` ,将在处理所有数据样本后用于计算指标。更多细节请参考 [MMEngine 文档](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/design/evaluation.md) + + - `compute_metrics()` 用于从处理后的结果中计算指标。 + + - `evaluate()` 是一个接口,用于计算指标并返回结果。它将由 `ValLoop` 或 `TestLoop` 在 `Runner` 中调用。在大多数情况下,您不需要重写此方法,但如果您想做一些额外的工作,可以重写它。 + + **注意:** 您可以在[这里](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py#L366) 找到 `Runner` 调用 `evaluate()` 方法的过程。`Runner` 是训练和测试过程的执行器,您可以在[训练引擎文档](./engine.md)中找到有关它的详细信息。 + +2. 在 `mmseg/evaluation/metrics/__init__.py` 中导入新的指标。 + + ```python + from .custom_metric import CustomMetric + __all__ = ['CustomMetric', ...] + ``` + +3. 在配置文件中设置新的评测指标 + + ```python + val_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + test_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + ``` + +## 使用发布版本的 MMSegmentation 进行开发 + +上面的示例展示了如何使用 MMSegmentation 的源代码开发新指标。如果您想使用 MMSegmentation 的发布版本开发新指标,可以按照以下步骤操作。 + +1. 创建一个新文件 `/Path/to/metrics/custom_metric.py`,实现 `process`,`compute_metrics` 和 `evaluate` 方法,`evaluate` 方法是可选的。 + +2. 在代码或配置文件中导入新的指标。 + + ```python + from path.to.metrics import CustomMetric + ``` + + 或者 + + ```python + custom_imports = dict(imports=['/Path/to/metrics'], allow_failed_imports=False) + + val_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + test_evaluator = dict(type='CustomMetric', arg1=xxx, arg2=xxx) + ``` diff --git a/docs/zh_cn/advanced_guides/add_models.md b/docs/zh_cn/advanced_guides/add_models.md index 2f0a5af0d18..e05c07c8bac 100644 --- a/docs/zh_cn/advanced_guides/add_models.md +++ b/docs/zh_cn/advanced_guides/add_models.md @@ -166,7 +166,7 @@ loss_decode=dict(type='MyLoss', loss_weight=1.0)) ### 添加新的数据预处理器(data preprocessor) -在 MMSegmentation 1.x 版本中,我们使用 [SegDataPreProcessor](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/data_preprocessor.py#L13) 将数据复制到目标设备,并将数据预处理为默认的模型输入格式。这里我们将展示如何开发一个新的数据预处理器。 +在 MMSegmentation 1.x 版本中,我们使用 [SegDataPreProcessor](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/data_preprocessor.py#L13) 将数据复制到目标设备,并将数据预处理为默认的模型输入格式。这里我们将展示如何开发一个新的数据预处理器。 1. 创建一个新文件 `mmseg/models/my_datapreprocessor.py`。 diff --git a/docs/zh_cn/advanced_guides/contribute_dataset.md b/docs/zh_cn/advanced_guides/contribute_dataset.md new file mode 100644 index 00000000000..4222de32a6c --- /dev/null +++ b/docs/zh_cn/advanced_guides/contribute_dataset.md @@ -0,0 +1,461 @@ +# 在 mmsegmentation projects 中贡献一个标准格式的数据集 + +- 在开始您的贡献流程前,请先阅读[《OpenMMLab 贡献代码指南》](https://mmcv.readthedocs.io/zh_CN/latest/community/contributing.html),以详细的了解 OpenMMLab 代码库的代码贡献流程。 +- 该教程以 [Gaofen Image Dataset (GID)](https://www.sciencedirect.com/science/article/pii/S0034425719303414) 高分 2 号卫星所拍摄的遥感图像语义分割数据集作为样例,来演示在 mmsegmentation 中的数据集贡献流程。 + +## 步骤 1: 配置 mmsegmentation 开发所需必要环境 + +- 开发所必需的环境安装请参考[中文快速入门指南](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/zh_cn/get_started.md)或[英文 get_started](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/get_started.md)。 + +- 如果您已安装了最新版的 pytorch、mmcv、mmengine,那么您可以跳过步骤 1 至[步骤 2](<#[步骤-2](#%E6%AD%A5%E9%AA%A4-2%E4%BB%A3%E7%A0%81%E8%B4%A1%E7%8C%AE%E5%89%8D%E7%9A%84%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C)>)。 + +- **注:** 在此处无需安装 mmsegmentation,只需安装开发 mmsegmentation 所必需的 pytorch、mmcv、mmengine 等即可。 + +**新建虚拟环境(如已有合适的开发环境,可跳过)** + +- 从[官方网站](https://docs.conda.io/en/latest/miniconda.html)下载并安装 Miniconda +- 创建一个 conda 环境,并激活 + +```shell +conda create --name openmmlab python=3.8 -y +conda activate openmmlab +``` + +**安装 pytorch (如环境下已安装 pytorch,可跳过)** + +- 参考 [official instructions](https://pytorch.org/get-started/locally/) 安装 **PyTorch** + +**使用 mim 安装 mmcv、mmengine** + +- 使用 [MIM](https://github.com/open-mmlab/mim) 安装 [MMCV](https://github.com/open-mmlab/mmcv) + +```shell +pip install -U openmim +mim install mmengine +mim install "mmcv>=2.0.0" +``` + +## 步骤 2:代码贡献前的准备工作 + +### 2.1 Fork mmsegmentation 仓库 + +- 通过浏览器打开[mmsegmentation 官方仓库](https://github.com/open-mmlab/mmsegmentation/tree/main)。 +- 登录您的 GitHub 账户,以下步骤均需在 GitHub 登录的情况下进行。 +- Fork mmsegmentation 仓库 + ![image](https://user-images.githubusercontent.com/50650583/233825567-b8bf273c-38f5-4487-b4c6-75ede1e283ee.png) +- Fork 之后,mmsegmentation 仓库将会出现在您的个人仓库中。 + +### 2.2 在您的代码编写软件中 git clone mmsegmentation + +这里以 VSCODE 为例 + +- 打开 VSCODE,新建终端窗口并激活您在[步骤 1 ](#%E6%AD%A5%E9%AA%A4-1-%E9%85%8D%E7%BD%AE-mmsegmentation-%E5%BC%80%E5%8F%91%E6%89%80%E9%9C%80%E5%BF%85%E8%A6%81%E7%8E%AF%E5%A2%83)中所安装的虚拟环境。 +- 在您 GitHub 的个人仓库中找到您 Fork 的 mmsegmentation 仓库,复制其链接。 + ![image](https://github.com/AI-Tianlong/OpenMMLabCamp/assets/50650583/92ad555b-c5b2-4a7f-a800-ebee1e405ab6) +- 在终端中执行命令 + ```bash + git clone {您所复制的个人仓库的链接} + ``` + ![image](https://github.com/AI-Tianlong/OpenMMLabCamp/assets/50650583/23ba2636-e66f-4ea5-9077-9dd6b69deb1d) + **注:** 如提示以下信息,请在 GitHub 中添加 [SSH 秘钥](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) + ![image](https://github.com/AI-Tianlong/OpenMMLabCamp/assets/50650583/6fcab213-0739-483c-b345-c59656027377) +- 进入 mmsegmentation 目录(之后的操作均在 mmsegmentation 目录下)。 + ```bash + cd mmsegmentation + ``` +- 在终端中执行以下命令,添加官方仓库为上游仓库。 + ```bash + git remote add upstream git@github.com:open-mmlab/mmsegmentation.git + ``` +- 使用以下命令检查 remote 是否添加成功。 + ```bash + git remote -v + ``` + ![image](https://github.com/AI-Tianlong/OpenMMLabCamp/assets/50650583/beec7e5e-2b00-4e49-ab38-f0c79e346594) + +### 2.3 切换目录至 mmsegmentation 并从源码安装mmsegmentation + +在`mmsegmentation`目录下执行`pip install -v -e .`,通过源码构建方式安装 mmsegmentaion 库。 +安装完成后,您将能看到如下图所示的文件树。 +image + +### 2.4 切换分支为 dev-1.x + +正如您在[ mmsegmentation 官网](https://github.com/open-mmlab/mmsegmentation/tree/main)所见,该仓库有许多分支,默认分支`main`为稳定的发行版本,以及用于贡献者进行开发的`dev-1.x`分支。`dev-1.x`分支是贡献者们用来提交创意和 PR 的分支,`dev-1.x`分支的内容会被周期性的合入到`main`分支。 +![image](https://user-images.githubusercontent.com/50650583/233826225-f4b7299d-de23-47db-900d-dfb01ba0efc3.png) + +回到 VSCODE 中,在终端执行命令 + +```bash +git checkout dev-1.x +``` + +### 2.5 创新属于自己的新分支 + +在基于`dev-1.x`分支下,使用如下命令,创建属于您自己的分支。 + +```bash +# git checkout -b 您的GitHubID/您的分支想要实现的功能的名字 +# git checkout -b AI-Tianlong/support_GID_dataset +git checkout -b {您的GitHubID/您的分支想要实现的功能的名字} +``` + +### 2.6 配置 pre-commit + +OpenMMLab 仓库对代码质量有着较高的要求,所有提交的 PR 必须要通过代码格式检查。pre-commit 详细配置参阅[配置 pre-commit](https://mmcv.readthedocs.io/zh_CN/latest/community/contributing.html#pre-commit)。 + +## 步骤 3:在`mmsegmentation/projects`下贡献您的代码 + +**先对 GID 数据集进行分析** + +这里以贡献高分 2 号遥感图像语义分割数据集 GID 为例,GID 数据集是由我国自主研发的高分 2 号卫星所拍摄的光学遥感图像所创建,经图像预处理后共提供了 150 张 6800x7200 像素的 RGB 三通道遥感图像。并提供了两种不同类别数的数据标注,一种是包含 5 类有效物体的 RGB 标签,另一种是包含 15 类有效物体的 RGB 标签。本教程将针对 5 类标签进行数据集贡献流程讲解。 + +GID 的 5 类有效标签分别为:0-背景-\[0,0,0\](mask 标签值-标签名称-RGB 标签值)、1-建筑-\[255,0,0\]、2-农田-\[0,255,0\]、3-森林-\[0,0,255\]、4-草地-\[255,255,0\]、5-水-\[0,0,255\]。在语义分割任务中,标签是与原图尺寸一致的单通道图像,标签图像中的像素值为真实样本图像中对应像素所包含的物体的类别。GID 数据集提供的是具有 RGB 三通道的彩色标签,为了模型的训练需要将 RGB 标签转换为 mask 标签。并且由于图像尺寸为 6800x7200 像素,对于神经网络的训练来有些过大,所以将每张图像裁切成了没有重叠的 512x512 的图像以便进行训练。 +image + +### 3.1 在`mmsegmentation/projects`下创建新的项目文件夹 + +在`mmsegmentation/projects`下创建文件夹`gid_dataset` +![image](https://user-images.githubusercontent.com/50650583/233829687-8f2b6600-bc9d-48ff-a865-d462af54d55a.png) + +### 3.2 贡献您的数据集代码 + +为了最终能将您在 projects 中贡献的代码更加顺畅的移入核心库中(对代码要求质量更高),非常建议按照核心库的目录来编辑您的数据集文件。 +关于数据集有 4 个必要的文件: + +- **1** `mmseg/datasets/gid.py` 定义了数据集的尾缀、CLASSES、PALETTE、reduce_zero_label等 +- **2** `configs/_base_/gid.py` GID 数据集的配置文件,定义了数据集的`dataset_type`(数据集类型,`mmseg/datasets/gid.py`中注册的数据集的类名)、`data_root`(数据集所在的根目录,建议将数据集通过软连接的方式将数据集放至`mmsegmentation/data`)、`train_pipline`(训练的数据流)、`test_pipline`(测试和验证时的数据流)、`img_rations`(多尺度预测时的多尺度配置)、`tta_pipeline`(多尺度预测)、`train_dataloader`(训练集的数据加载器)、`val_dataloader`(验证集的数据加载器)、`test_dataloader`(测试集的数据加载器)、`val_evaluator`(验证集的评估器)、`test_evaluator`(测试集的评估器)。 +- **3** 使用了 GID 数据集的模型训练配置文件 + 这个是可选的,但是强烈建议您添加。在核心库中,所贡献的数据集需要和参考文献中所提出的结果精度对齐,为了后期将您贡献的代码合并入核心库。如您的算力充足,最好能提供对应的模型配置文件在您贡献的数据集上所验证的结果以及相应的权重文件,并撰写较为详细的README.md文档。[示例参考结果](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/deeplabv3plus#mapillary-vistas-v12) + ![image](https://user-images.githubusercontent.com/50650583/233877682-eabe8723-bce9-40e4-a303-08c8385cb6b5.png) +- **4** 使用如下命令格式: 撰写`docs/zh_cn/user_guides/2_dataset_prepare.md`来添加您的数据集介绍,包括但不限于数据集的下载方式,数据集目录结构、数据集生成等一些必要性的文字性描述和运行命令。以更好地帮助用户能更快的实现数据集的准备工作。 + +### 3.3 贡献`tools/dataset_converters/gid.py` + +由于 GID 数据集是由未经过切分的 6800x7200 图像所构成的数据集,并且没有划分训练集、验证集与测试集。以及其标签为 RGB 彩色标签,需要将标签转换为单通道的 mask label。为了方便训练,首先将 GID 数据集进行裁切和标签转换,并进行数据集划分,构建为 mmsegmentation 所支持的格式。 + +```python +# tools/dataset_converters/gid.py +import argparse +import glob +import math +import os +import os.path as osp +from PIL import Image + +import mmcv +import numpy as np +from mmengine.utils import ProgressBar, mkdir_or_exist + +def parse_args(): + parser = argparse.ArgumentParser( + description='Convert GID dataset to mmsegmentation format') + parser.add_argument('dataset_img_path', help='GID images folder path') + parser.add_argument('dataset_label_path', help='GID labels folder path') + parser.add_argument('--tmp_dir', help='path of the temporary directory') + parser.add_argument('-o', '--out_dir', help='output path', default='data/gid') + parser.add_argument( + '--clip_size', + type=int, + help='clipped size of image after preparation', + default=256) + parser.add_argument( + '--stride_size', + type=int, + help='stride of clipping original images', + default=256) + args = parser.parse_args() + return args + +GID_COLORMAP = dict( + Background=(0, 0, 0), #0-背景-黑色 + Building=(255, 0, 0), #1-建筑-红色 + Farmland=(0, 255, 0), #2-农田-绿色 + Forest=(0, 0, 255), #3-森林-蓝色 + Meadow=(255, 255, 0),#4-草地-黄色 + Water=(0, 0, 255)#5-水-蓝色 +) +palette = list(GID_COLORMAP.values()) +classes = list(GID_COLORMAP.keys()) + +#############用列表来存一个 RGB 和一个类别的对应################ +def colormap2label(palette): + colormap2label_list = np.zeros(256**3, dtype = np.longlong) + for i, colormap in enumerate(palette): + colormap2label_list[(colormap[0] * 256 + colormap[1])*256+colormap[2]] = i + return colormap2label_list + +#############给定那个列表,和vis_png然后生成masks_png################ +def label_indices(RGB_label, colormap2label_list): + RGB_label = RGB_label.astype('int32') + idx = (RGB_label[:, :, 0] * 256 + RGB_label[:, :, 1]) * 256 + RGB_label[:, :, 2] + # print(idx.shape) + return colormap2label_list[idx] + +def RGB2mask(RGB_label, colormap2label_list): + # RGB_label = np.array(Image.open(RGB_label).convert('RGB')) #打开RGB_png + mask_label = label_indices(RGB_label, colormap2label_list) # .numpy() + return mask_label + +colormap2label_list = colormap2label(palette) + +def clip_big_image(image_path, clip_save_dir, args, to_label=False): + """ + Original image of GID dataset is very large, thus pre-processing + of them is adopted. Given fixed clip size and stride size to generate + clipped image, the intersection of width and height is determined. + For example, given one 6800 x 7200 original image, the clip size is + 256 and stride size is 256, thus it would generate 29 x 27 = 783 images + whose size are all 256 x 256. + + """ + + image = mmcv.imread(image_path, channel_order='rgb') + # image = mmcv.bgr2gray(image) + + h, w, c = image.shape + clip_size = args.clip_size + stride_size = args.stride_size + + num_rows = math.ceil((h - clip_size) / stride_size) if math.ceil( + (h - clip_size) / + stride_size) * stride_size + clip_size >= h else math.ceil( + (h - clip_size) / stride_size) + 1 + num_cols = math.ceil((w - clip_size) / stride_size) if math.ceil( + (w - clip_size) / + stride_size) * stride_size + clip_size >= w else math.ceil( + (w - clip_size) / stride_size) + 1 + + x, y = np.meshgrid(np.arange(num_cols + 1), np.arange(num_rows + 1)) + xmin = x * clip_size + ymin = y * clip_size + + xmin = xmin.ravel() + ymin = ymin.ravel() + xmin_offset = np.where(xmin + clip_size > w, w - xmin - clip_size, + np.zeros_like(xmin)) + ymin_offset = np.where(ymin + clip_size > h, h - ymin - clip_size, + np.zeros_like(ymin)) + boxes = np.stack([ + xmin + xmin_offset, ymin + ymin_offset, + np.minimum(xmin + clip_size, w), + np.minimum(ymin + clip_size, h) + ], axis=1) + + if to_label: + image = RGB2mask(image, colormap2label_list) #这里得改一下 + + for count, box in enumerate(boxes): + start_x, start_y, end_x, end_y = box + clipped_image = image[start_y:end_y, + start_x:end_x] if to_label else image[ + start_y:end_y, start_x:end_x, :] + img_name = osp.basename(image_path).replace('.tif', '') + img_name = img_name.replace('_label', '') + if count % 3 == 0: + mmcv.imwrite( + clipped_image.astype(np.uint8), + osp.join( + clip_save_dir.replace('train', 'val'), + f'{img_name}_{start_x}_{start_y}_{end_x}_{end_y}.png')) + else: + mmcv.imwrite( + clipped_image.astype(np.uint8), + osp.join( + clip_save_dir, + f'{img_name}_{start_x}_{start_y}_{end_x}_{end_y}.png')) + count += 1 + +def main(): + args = parse_args() + + """ + According to this paper: https://ieeexplore.ieee.org/document/9343296/ + select 15 images contained in GID, , which cover the whole six + categories, to generate train set and validation set. + + According to Paper: https://ieeexplore.ieee.org/document/9343296/ + + """ + + if args.out_dir is None: + out_dir = osp.join('data', 'gid') + else: + out_dir = args.out_dir + + print('Making directories...') + mkdir_or_exist(osp.join(out_dir, 'img_dir', 'train')) + mkdir_or_exist(osp.join(out_dir, 'img_dir', 'val')) + mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'train')) + mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'val')) + + src_path_list = glob.glob(os.path.join(args.dataset_img_path, '*.tif')) + print(f'Find {len(src_path_list)} pictures') + + prog_bar = ProgressBar(len(src_path_list)) + + dst_img_dir = osp.join(out_dir, 'img_dir', 'train') + dst_label_dir = osp.join(out_dir, 'ann_dir', 'train') + + for i, img_path in enumerate(src_path_list): + label_path = osp.join(args.dataset_label_path, osp.basename(img_path.replace('.tif', '_label.tif'))) + + clip_big_image(img_path, dst_img_dir, args, to_label=False) + clip_big_image(label_path, dst_label_dir, args, to_label=True) + prog_bar.update() + + print('Done!') + +if __name__ == '__main__': + main() +``` + +### 3.4 贡献`mmseg/datasets/gid.py` + +可参考[`projects/mapillary_dataset/mmseg/datasets/mapillary.py`](https://github.com/open-mmlab/mmsegmentation/blob/main/projects/mapillary_dataset/mmseg/datasets/mapillary.py)并在此基础上修改相应变量以适配您的数据集。 + +```python +# mmseg/datasets/gid.py +# Copyright (c) OpenMMLab. All rights reserved. +from mmseg.datasets.basesegdataset import BaseSegDataset +from mmseg.registry import DATASETS + +# 注册数据集类 +@DATASETS.register_module() +class GID_Dataset(BaseSegDataset): + """Gaofen Image Dataset (GID) + + Dataset paper link: + https://www.sciencedirect.com/science/article/pii/S0034425719303414 + https://x-ytong.github.io/project/GID.html + + GID 6 classes: background(others), built-up, farmland, forest, meadow, water + + In This example, select 10 images from GID dataset as training set, + and select 5 images as validation set. + The selected images are listed as follows: + + GF2_PMS1__L1A0000647767-MSS1 + GF2_PMS1__L1A0001064454-MSS1 + GF2_PMS1__L1A0001348919-MSS1 + GF2_PMS1__L1A0001680851-MSS1 + GF2_PMS1__L1A0001680853-MSS1 + GF2_PMS1__L1A0001680857-MSS1 + GF2_PMS1__L1A0001757429-MSS1 + GF2_PMS2__L1A0000607681-MSS2 + GF2_PMS2__L1A0000635115-MSS2 + GF2_PMS2__L1A0000658637-MSS2 + GF2_PMS2__L1A0001206072-MSS2 + GF2_PMS2__L1A0001471436-MSS2 + GF2_PMS2__L1A0001642620-MSS2 + GF2_PMS2__L1A0001787089-MSS2 + GF2_PMS2__L1A0001838560-MSS2 + + The ``img_suffix`` is fixed to '.tif' and ``seg_map_suffix`` is + fixed to '.tif' for GID. + """ + METAINFO = dict( + classes=('Others', 'Built-up', 'Farmland', 'Forest', + 'Meadow', 'Water'), + + palette=[[0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 255, 255], + [255, 255, 0], [0, 0, 255]]) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=None, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) +``` + +### 3.5 贡献使用 GID 的训练 config file + +```python +_base_ = [ + '../../../configs/_base_/models/deeplabv3plus_r50-d8.py', + './_base_/datasets/gid.py', + '../../../configs/_base_/default_runtime.py', + '../../../configs/_base_/schedules/schedule_240k.py' +] +custom_imports = dict( + imports=['projects.gid_dataset.mmseg.datasets.gid']) + +crop_size = (256, 256) +data_preprocessor = dict(size=crop_size) +model = dict( + data_preprocessor=data_preprocessor, + pretrained='open-mmlab://resnet101_v1c', + backbone=dict(depth=101), + decode_head=dict(num_classes=6), + auxiliary_head=dict(num_classes=6)) + +``` + +### 3.6 撰写`docs/zh_cn/user_guides/2_dataset_prepare.md` + +**Gaofen Image Dataset (GID)** + +- GID 数据集可在[此处](https://x-ytong.github.io/project/Five-Billion-Pixels.html)进行下载。 +- GID 数据集包含 150 张 6800x7200 的大尺寸图像,标签为 RGB 标签。 +- 此处选择 15 张图像生成训练集和验证集,该 15 张图像包含了所有六类信息。所选的图像名称如下: + +```None + GF2_PMS1__L1A0000647767-MSS1 + GF2_PMS1__L1A0001064454-MSS1 + GF2_PMS1__L1A0001348919-MSS1 + GF2_PMS1__L1A0001680851-MSS1 + GF2_PMS1__L1A0001680853-MSS1 + GF2_PMS1__L1A0001680857-MSS1 + GF2_PMS1__L1A0001757429-MSS1 + GF2_PMS2__L1A0000607681-MSS2 + GF2_PMS2__L1A0000635115-MSS2 + GF2_PMS2__L1A0000658637-MSS2 + GF2_PMS2__L1A0001206072-MSS2 + GF2_PMS2__L1A0001471436-MSS2 + GF2_PMS2__L1A0001642620-MSS2 + GF2_PMS2__L1A0001787089-MSS2 + GF2_PMS2__L1A0001838560-MSS2 +``` + +执行以下命令进行裁切及标签的转换,需要修改为您所存储 15 张图像及标签的路径。 + +``` +python projects/gid_dataset/tools/dataset_converters/gid.py [15 张图像的路径] [15 张标签的路径] +``` + +完成裁切后的 GID 数据结构如下: + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── gid +│ │ ├── ann_dir +| │ │ │ ├── train +| │ │ │ ├── val +│ │ ├── img_dir +| │ │ │ ├── train +| │ │ │ ├── val + +``` + +### 3.7 贡献的代码及文档通过`pre-commit`检查 + +使用命令 + +```bash +git add . +git commit -m "添加描述" +git push +``` + +### 3.8 在 GitHub 中向 mmsegmentation 提交 PR + +具体步骤可见[《OpenMMLab 贡献代码指南》](https://mmcv.readthedocs.io/zh_CN/latest/community/contributing.html) diff --git a/docs/zh_cn/advanced_guides/data_flow.md b/docs/zh_cn/advanced_guides/data_flow.md index 0716d36d1b4..20dbe07e75d 100644 --- a/docs/zh_cn/advanced_guides/data_flow.md +++ b/docs/zh_cn/advanced_guides/data_flow.md @@ -16,7 +16,7 @@ val_cfg = dict(type='ValLoop') test_cfg = dict(type='TestLoop') ``` -在上图中,红色线表示 [train_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#train_step) ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/models.md#train_step))*** ,在每次训练迭代中,数据加载器(dataloader)从存储中加载图像并传输到数据预处理器(data preprocessor),数据预处理器会将图像放到特定的设备上,并将数据堆叠到批处理中,之后模型接受批处理数据作为输入,最后将模型的输出发送给优化器(optimizer)。蓝色线表示 [val_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#val_step) 和 [test_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#test_step) ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/models.md#test_step))*** 。这两个过程的数据流除了模型输出与 `train_step` 不同外,其余均和 `train_step` 类似。由于在评估时模型参数会被冻结,因此模型的输出将被传递给 [Evaluator](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/evaluation.md#ioumetric) ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/evaluation.md#ioumetric))*** +在上图中,红色线表示 [train_step](./models.md#train_step),在每次训练迭代中,数据加载器(dataloader)从存储中加载图像并传输到数据预处理器(data preprocessor),数据预处理器会将图像放到特定的设备上,并将数据堆叠到批处理中,之后模型接受批处理数据作为输入,最后将模型的输出发送给优化器(optimizer)。蓝色线表示 [val_step](./models.md#val_step) 和 [test_step](./models.md#test_step)。这两个过程的数据流除了模型输出与 `train_step` 不同外,其余均和 `train_step` 类似。由于在评估时模型参数会被冻结,因此模型的输出将被传递给 [Evaluator](./evaluation.md#ioumetric)。 来计算指标。 ## MMSegmentation 中的数据流约定 @@ -28,7 +28,7 @@ test_cfg = dict(type='TestLoop') 数据加载器(DataLoader)是 MMEngine 的训练和测试流程中的一个重要组件。 从概念上讲,它源于 [PyTorch](https://pytorch.org/) 并保持一致。DataLoader 从文件系统加载数据,原始数据通过数据准备流程后被发送给数据预处理器。 -MMSegmentation 在 [PackSegInputs](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/transforms/formatting.py#L12) 中定义了默认数据格式, 它是 `train_pipeline` 和 `test_pipeline` 的最后一个组件。有关数据转换 `pipeline` 的更多信息,请参阅[数据转换文档](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/transforms.html)。 ***([中文链接待更新](https://mmsegmentation.readthedocs.io/zh_CN/dev-1.x/advanced_guides/transforms.html))*** +MMSegmentation 在 [PackSegInputs](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/transforms/formatting.py#L12) 中定义了默认数据格式, 它是 `train_pipeline` 和 `test_pipeline` 的最后一个组件。有关数据转换 `pipeline` 的更多信息,请参阅[数据转换文档](./transforms.md)。 在没有任何修改的情况下,PackSegInputs 的返回值通常是一个包含 `inputs` 和 `data_samples` 的 `dict`。以下伪代码展示了 mmseg 中数据加载器输出的数据类型,它是从数据集中获取的一批数据样本,数据加载器将它们打包成一个字典列表。`inputs` 是输入进模型的张量列表,`data_samples` 包含了输入图像的 meta information 和相应的 ground truth。 @@ -39,11 +39,11 @@ dict( ) ``` -**注意:** [SegDataSample](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/structures/seg_data_sample.py) 是 MMSegmentation 的数据结构接口,用于连接不同组件。`SegDataSample` 实现了抽象数据元素 `mmengine.structures.BaseDataElement`,更多信息请在 [MMEngine](https://github.com/open-mmlab/mmengine) 中参阅 [SegDataSample 文档](https://mmsegmentation.readthedocs.io/zh_CN/1.x/advanced_guides/structures.html)和[数据元素文档](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/data_element.html)。 +**注意:** [SegDataSample](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/structures/seg_data_sample.py) 是 MMSegmentation 的数据结构接口,用于连接不同组件。`SegDataSample` 实现了抽象数据元素 `mmengine.structures.BaseDataElement`,更多信息请在 [MMEngine](https://github.com/open-mmlab/mmengine) 中参阅 [SegDataSample 文档](./structures.md)和[数据元素文档](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/data_element.html)。 ### 数据预处理器到模型 -虽然在[上面的图](##数据流概述)中分开绘制了数据预处理器和模型,但数据预处理器是模型的一部分,因此可以在[模型教程](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/models.html)中找到数据预处理器章节。 ***([中文链接待更新](https://mmsegmentation.readthedocs.io/zh_CN/dev-1.x/advanced_guides/models.html))*** +虽然在[上面的图](##数据流概述)中分开绘制了数据预处理器和模型,但数据预处理器是模型的一部分,因此可以在[模型教程](./models.md)中找到数据预处理器章节。 数据预处理器的返回值是一个包含 `inputs` 和 `data_samples` 的字典,其中 `inputs` 是批处理图像的 4D 张量,`data_samples` 中添加了一些用于数据预处理的额外元信息。当传递给网络时,字典将被解包为两个值。 以下伪代码展示了数据预处理器的返回值和模型的输入值。 @@ -61,22 +61,22 @@ class Network(BaseSegmentor): pass ``` -**注意:** 模型的前向传播有 3 种模式,由输入参数 mode 控制,更多信息请参阅[模型教程](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md)。 ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/models.md))*** +**注意:** 模型的前向传播有 3 种模式,由输入参数 mode 控制,更多信息请参阅[模型教程](./models.md)。 ### 模型输出 -如[模型教程](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#forward) ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/models.md#forward))*** 所提到的 3 种前向传播具有 3 种输出。 +如[模型教程](./models.md#forward) ***([中文链接待更新](./models.md#forward))*** 所提到的 3 种前向传播具有 3 种输出。 `train_step` 和 `test_step`(或 `val_step`)分别对应于 `'loss'` 和 `'predict'`。 -在 `test_step` 或 `val_step` 中,推理结果会被传递给 `Evaluator` 。您可以参阅[评估文档](https://mmsegmentation.readthedocs.io/en/dev-1.x/advanced_guides/evaluation.html) ***([中文链接待更新](https://mmsegmentation.readthedocs.io/zh_CN/dev-1.x/advanced_guides/evaluation.html))*** 来获取更多关于 `Evaluator` 的信息。 +在 `test_step` 或 `val_step` 中,推理结果会被传递给 `Evaluator` 。您可以参阅[评估文档](./evaluation.md)来获取更多关于 `Evaluator` 的信息。 -在推理后,MMSegmentation 中的 [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/segmentors/base.py#L15) 会对推理结果进行简单的后处理以打包推理结果。神经网络生成的分割 logits,经过 `argmax` 操作后的分割 mask 和 ground truth(如果存在)将被打包到类似 `SegDataSample` 的实例。 [postprocess_result](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/segmentors/base.py#L132) 的返回值是一个 **`SegDataSample`的`List`**。下图显示了这些 `SegDataSample` 实例的关键属性。 +在推理后,MMSegmentation 中的 [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/segmentors/base.py#L15) 会对推理结果进行简单的后处理以打包推理结果。神经网络生成的分割 logits,经过 `argmax` 操作后的分割 mask 和 ground truth(如果存在)将被打包到类似 `SegDataSample` 的实例。 [postprocess_result](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/segmentors/base.py#L132) 的返回值是一个 **`SegDataSample`的`List`**。下图显示了这些 `SegDataSample` 实例的关键属性。 ![SegDataSample](https://user-images.githubusercontent.com/15952744/209912225-ab46a8d9-904a-43cb-8bf1-8bec4938ed29.png) -与数据预处理器一致,损失函数也是模型的一部分,它是[解码头](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py#L142)的属性之一。 +与数据预处理器一致,损失函数也是模型的一部分,它是[解码头](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/decode_heads/decode_head.py#L142)的属性之一。 -在 MMSegmentation 中,`decode_head` 的 [loss_by_feat](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py#L291) 方法是用于计算损失的统一接口。 +在 MMSegmentation 中,`decode_head` 的 [loss_by_feat](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/models/decode_heads/decode_head.py#L291) 方法是用于计算损失的统一接口。 参数: @@ -87,4 +87,4 @@ class Network(BaseSegmentor): - dict\[str, Tensor\]:一个损失组件的字典 -**注意:** `train_step` 将损失传递进 OptimWrapper 以更新模型中的权重,更多信息请参阅 [train_step](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/advanced_guides/models.md#train_step)。 ***([中文链接待更新](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/models.md#train_step))*** +**注意:** `train_step` 将损失传递进 OptimWrapper 以更新模型中的权重,更多信息请参阅 [train_step](./models.md#train_step)。 diff --git a/docs/zh_cn/advanced_guides/datasets.md b/docs/zh_cn/advanced_guides/datasets.md index 546e97f70d6..b45f2d22bb6 100644 --- a/docs/zh_cn/advanced_guides/datasets.md +++ b/docs/zh_cn/advanced_guides/datasets.md @@ -1,10 +1,10 @@ # 数据集 -在 MMSegmentation 算法库中, 所有 Dataset 类的功能有两个: 加载[预处理](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/2_dataset_prepare.md) 之后的数据集的信息, 和将数据送入[数据集变换流水线](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/basesegdataset.py#L141) 中, 进行[数据变换操作](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/transforms.md). 加载的数据集信息包括两类: 元信息 (meta information), 数据集本身的信息, 例如数据集总共的类别, 和它们对应调色盘信息: 数据信息 (data information) 是指每组数据中图片和对应标签的路径. 下文中介绍了 MMSegmentation 1.x 中数据集的常用接口, 和 mmseg 数据集基类中数据信息加载与修改数据集类别的逻辑, 以及数据集与数据变换流水线 (pipeline) 的关系. +在 MMSegmentation 算法库中, 所有 Dataset 类的功能有两个: 加载[预处理](../user_guides/2_dataset_prepare.md) 之后的数据集的信息, 和将数据送入[数据集变换流水线](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L141) 中, 进行[数据变换操作](./transforms.md). 加载的数据集信息包括两类: 元信息 (meta information), 数据集本身的信息, 例如数据集总共的类别, 和它们对应调色盘信息: 数据信息 (data information) 是指每组数据中图片和对应标签的路径. 下文中介绍了 MMSegmentation 1.x 中数据集的常用接口, 和 mmseg 数据集基类中数据信息加载与修改数据集类别的逻辑, 以及数据集与数据变换流水线 (pipeline) 的关系. ## 常用接口 -以 Cityscapes 为例, 介绍数据集常用接口. 如需运行以下示例, 请在当前工作目录下的 `data` 目录下载并[预处理](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/2_dataset_prepare.md#cityscapes) Cityscapes 数据集. +以 Cityscapes 为例, 介绍数据集常用接口. 如需运行以下示例, 请在当前工作目录下的 `data` 目录下载并[预处理](../user_guides/2_dataset_prepare.md#cityscapes) Cityscapes 数据集. 实例化 Cityscapes 训练数据集: @@ -96,7 +96,7 @@ print(dataset.metainfo) 'reduce_zero_label': False} ``` -数据集 `__getitem__` 方法的返回值, 是经过数据增强的样本数据的输出, 同样也是一个字典, 包括两个字段, `'inputs'` 字段是当前样本经过数据增强操作的图像, 类型为 torch.Tensor, `'data_samples'` 字段存放的数据类型是 MMSegmentation 1.x 新添加的数据结构 [`Segdatasample`](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/advanced_guides/structures.md), 其中`gt_sem_seg` 字段是经过数据增强的标签数据. +数据集 `__getitem__` 方法的返回值, 是经过数据增强的样本数据的输出, 同样也是一个字典, 包括两个字段, `'inputs'` 字段是当前样本经过数据增强操作的图像, 类型为 torch.Tensor, `'data_samples'` 字段存放的数据类型是 MMSegmentation 1.x 新添加的数据结构 [`Segdatasample`](./structures.md), 其中`gt_sem_seg` 字段是经过数据增强的标签数据. ```python print(dataset[0]) @@ -166,13 +166,13 @@ print(dataset[0]) ## BaseSegDataset -由于 MMSegmentation 中的所有数据集的基本功能均包括(1) 加载[数据集预处理](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/user_guides/2_dataset_prepare.md) 之后的数据信息和 (2) 将数据送入数据变换流水线中进行数据变换, 因此在 MMSegmentation 中将其中的共同接口抽象成 [`BaseSegDataset`](https://mmsegmentation.readthedocs.io/en/dev-1.x/api.html?highlight=BaseSegDataset#mmseg.datasets.BaseSegDataset),它继承自 [MMEngine 的 `BaseDataset`](https://github.com/open-mmlab/mmengine/blob/main/docs/en/advanced_tutorials/basedataset.md), 遵循 OpenMMLab 数据集初始化统一流程, 支持高效的内部数据存储格式, 支持数据集拼接、数据集重复采样等功能. +由于 MMSegmentation 中的所有数据集的基本功能均包括(1) 加载[数据集预处理](../user_guides/2_dataset_prepare.md) 之后的数据信息和 (2) 将数据送入数据变换流水线中进行数据变换, 因此在 MMSegmentation 中将其中的共同接口抽象成 [`BaseSegDataset`](https://mmsegmentation.readthedocs.io/zh_CN/latest/api.html?highlight=BaseSegDataset#mmseg.datasets.BaseSegDataset),它继承自 [MMEngine 的 `BaseDataset`](https://github.com/open-mmlab/mmengine/blob/main/docs/en/advanced_tutorials/basedataset.md), 遵循 OpenMMLab 数据集初始化统一流程, 支持高效的内部数据存储格式, 支持数据集拼接、数据集重复采样等功能. 在 MMSegmentation BaseSegDataset 中重新定义了**数据信息加载方法**(`load_data_list`)和并新增了 `get_label_map` 方法用来**修改数据集的类别信息**. ### 数据信息加载 -数据信息加载的内容是样本数据的图片路径和标签路径, 具体实现在 MMSegmentation 的 BaseSegDataset 的 [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/163277bfe0fa8fefb63ee5137917fafada1b301c/mmseg/datasets/basesegdataset.py#L231) 中. -主要有两种获取图片和标签的路径方法, 如果当数据集目录按以下目录结构组织, [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/163277bfe0fa8fefb63ee5137917fafada1b301c/mmseg/datasets/basesegdataset.py#L231)) 会根据数据路径和后缀来解析. +数据信息加载的内容是样本数据的图片路径和标签路径, 具体实现在 MMSegmentation 的 BaseSegDataset 的 [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L231) 中. +主要有两种获取图片和标签的路径方法, 如果当数据集目录按以下目录结构组织, [`load_data_list`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L231)) 会根据数据路径和后缀来解析. ``` ├── data @@ -322,7 +322,7 @@ print(dataset.metainfo) 'reduce_zero_label': False} ``` -可以看到, 数据集元信息的类别和默认 Cityscapes 不同. 并且, 定义了标签重映射的字段 `label_map` 用来修改每个分割掩膜上的像素的类别索引, 分割标签类别会根据 `label_map`, 将类别重映射, [具体实现](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/datasets/basesegdataset.py#L151): +可以看到, 数据集元信息的类别和默认 Cityscapes 不同. 并且, 定义了标签重映射的字段 `label_map` 用来修改每个分割掩膜上的像素的类别索引, 分割标签类别会根据 `label_map`, 将类别重映射, [具体实现](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/datasets/basesegdataset.py#L151): ```python gt_semantic_seg_copy = gt_semantic_seg.copy() diff --git a/docs/zh_cn/advanced_guides/engine.md b/docs/zh_cn/advanced_guides/engine.md index a5746fcec89..79b4c8d2296 100644 --- a/docs/zh_cn/advanced_guides/engine.md +++ b/docs/zh_cn/advanced_guides/engine.md @@ -61,21 +61,21 @@ OpenMMLab 将模型训练和测试过程抽象为 `Runner`, 插入钩子可以 - 默认钩子 (default hooks) -它们实现了训练时所必需的功能, 在配置文件中用 `default_hooks` 定义传给 `Runner`, `Runner` 通过 [`register_default_hooks`](https://github.com/open-mmlab/mmengine/blob/090104df21acd05a8aadae5a0d743a7da3314f6f/mmengine/runner/runner.py#L1780) 方法注册. +它们实现了训练时所必需的功能, 在配置文件中用 `default_hooks` 定义传给 `Runner`, `Runner` 通过 [`register_default_hooks`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/runner.py#L1780) 方法注册. 钩子有对应的优先级, 优先级越高, 越早被执行器调用. 如果优先级一样, 被调用的顺序和钩子注册的顺序一致. 不建议用户修改默认钩子的优先级, 可以参考 [mmengine hooks 文档](https://github.com/open-mmlab/mmengine/blob/main/docs/zh_cn/tutorials/hook.md) 了解钩子优先级的定义. 下面是 MMSegmentation 中所用到的默认钩子: -| 钩子 | 功能 | 优先级 | -| :-----------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------: | :---------------: | -| [IterTimerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/iter_timer_hook.py) | 记录 iteration 花费的时间. | NORMAL (50) | -| [LoggerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/logger_hook.py) | 从 `Runner` 里不同的组件中收集日志记录, 并将其输出到终端, JSON 文件, tensorboard, wandb 等下游. | BELOW_NORMAL (60) | -| [ParamSchedulerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/param_scheduler_hook.py) | 更新优化器里面的一些超参数, 例如学习率的动量. | LOW (70) | -| [CheckpointHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/checkpoint_hook.py) | 规律性地保存 checkpoint 文件. | VERY_LOW (90) | -| [DistSamplerSeedHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/sampler_seed_hook.py) | 确保分布式采样器 shuffle 是打开的. | NORMAL (50) | -| [SegVisualizationHook](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/visualization/local_visualizer.py) | 可视化验证和测试过程里的预测结果. | NORMAL (50) | +| 钩子 | 功能 | 优先级 | +| :--------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------: | :---------------: | +| [IterTimerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/iter_timer_hook.py) | 记录 iteration 花费的时间. | NORMAL (50) | +| [LoggerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/logger_hook.py) | 从 `Runner` 里不同的组件中收集日志记录, 并将其输出到终端, JSON 文件, tensorboard, wandb 等下游. | BELOW_NORMAL (60) | +| [ParamSchedulerHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/param_scheduler_hook.py) | 更新优化器里面的一些超参数, 例如学习率的动量. | LOW (70) | +| [CheckpointHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/checkpoint_hook.py) | 规律性地保存 checkpoint 文件. | VERY_LOW (90) | +| [DistSamplerSeedHook](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/sampler_seed_hook.py) | 确保分布式采样器 shuffle 是打开的. | NORMAL (50) | +| [SegVisualizationHook](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/visualization/local_visualizer.py) | 可视化验证和测试过程里的预测结果. | NORMAL (50) | -MMSegmentation 会在 [`defualt_hooks`](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/schedules/schedule_160k.py#L19-L25) 里面注册一些训练所必需功能的钩子:: +MMSegmentation 会在 [`defualt_hooks`](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/schedules/schedule_160k.py#L19-L25) 里面注册一些训练所必需功能的钩子:: ```python default_hooks = dict( @@ -94,6 +94,7 @@ default_hooks = dict( 以 `default_hooks` 里面的 `logger` 和 `checkpoint` 为例, 我们来介绍如何修改 `default_hooks` 中默认的钩子. (1) 模型保存配置 + `default_hooks` 使用 `checkpoint` 字段来初始化[模型保存钩子 (CheckpointHook)](https://github.com/open-mmlab/mmengine/blob/main/mmengine/hooks/checkpoint_hook.py#L19). ```python @@ -104,6 +105,7 @@ checkpoint = dict(type='CheckpointHook', interval=1) 更多相关参数的细节可以参考[这里](https://mmengine.readthedocs.io/zh_CN/latest/api/generated/mmengine.hooks.CheckpointHook.html#checkpointhook). (2) 日志配置 + `日志钩子 (LoggerHook)` 被用来收集 `执行器 (Runner)` 里面不同组件的日志信息然后写入终端, JSON 文件, tensorboard 和 wandb 等地方. ```python @@ -126,7 +128,7 @@ visualizer = dict( - 自定义钩子 (custom hooks) -自定义钩子在配置通过 `custom_hooks` 定义, `Runner` 通过 [`register_custom_hooks`](https://github.com/open-mmlab/mmengine/blob/090104df21acd05a8aadae5a0d743a7da3314f6f/mmengine/runner/runner.py#L1852) 方法注册. +自定义钩子在配置通过 `custom_hooks` 定义, `Runner` 通过 [`register_custom_hooks`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/runner.py#L1820) 方法注册. 自定义钩子优先级需要在配置文件里设置, 如果没有设置, 则会被默认设置为 `NORMAL`. 下面是部分 MMEngine 中实现的自定义钩子: | 钩子 | 用法 | @@ -145,7 +147,7 @@ custom_hooks = [ ### SegVisualizationHook -MMSegmentation 实现了 [`SegVisualizationHook`](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/engine/hooks/visualization_hook.py#L17), 用来在验证和测试时可视化预测结果. +MMSegmentation 实现了 [`SegVisualizationHook`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/engine/hooks/visualization_hook.py#L17), 用来在验证和测试时可视化预测结果. `SegVisualizationHook` 重写了基类 `Hook` 中的 `_after_iter` 方法, 在验证或测试时, 根据指定的迭代次数间隔调用 `visualizer` 的 `add_datasample` 方法绘制语义分割结果, 具体实现如下: ```python @@ -181,7 +183,7 @@ class SegVisualizationHook(Hook): ``` -关于可视化更多的细节可以查看[这里](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/en/user_guides/visualization.md). +关于可视化更多的细节可以查看[这里](../user_guides/visualization.md). ## 优化器 @@ -234,7 +236,7 @@ optim_wrapper = dict(type='AmpOptimWrapper', optimizer=optimizer) 在模型训练中, 如果想在优化器里为不同参数分别设置优化策略, 例如设置不同的学习率、权重衰减等超参数, 可以通过设置配置文件里 `optim_wrapper` 中的 `paramwise_cfg` 来实现. -下面的配置文件以 [ViT `optim_wrapper`](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/vit/vit_vit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py#L15-L27) 为例介绍 `paramwise_cfg` 参数使用. +下面的配置文件以 [ViT `optim_wrapper`](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/vit/vit_vit-b16-ln_mln_upernet_8xb2-160k_ade20k-512x512.py#L15-L27) 为例介绍 `paramwise_cfg` 参数使用. 训练时将 `pos_embed`, `mask_token`, `norm` 模块的 weight decay 参数的系数设置成 0. 即: 在训练时, 这些模块的 weight decay 将被变为 `weight_decay * decay_mult`=0. @@ -257,9 +259,9 @@ optim_wrapper = dict( ### 优化器封装构造器 -默认的优化器封装构造器 [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/376251961da47ea8254ab808ae5c51e1430f18dc/mmengine/optim/optimizer/default_constructor.py#L19) 根据输入的 `optim_wrapper` 和 `optim_wrapper` 中定义的 `paramwise_cfg` 来构建训练中使用的优化器. 当 [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/376251961da47ea8254ab808ae5c51e1430f18dc/mmengine/optim/optimizer/default_constructor.py#L19) 功能不能满足需求时, 可以自定义优化器封装构造器来实现超参数的配置. +默认的优化器封装构造器 [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/default_constructor.py#L19) 根据输入的 `optim_wrapper` 和 `optim_wrapper` 中定义的 `paramwise_cfg` 来构建训练中使用的优化器. 当 [`DefaultOptimWrapperConstructor`](https://github.com/open-mmlab/mmengine/blob/main/mmengine/optim/optimizer/default_constructor.py#L19) 功能不能满足需求时, 可以自定义优化器封装构造器来实现超参数的配置. -MMSegmentation 中的实现了 [`LearningRateDecayOptimizerConstructor`](https://github.com/open-mmlab/mmsegmentation/blob/b21df463d47447f33c28d9a4f46136ad64d34a40/mmseg/engine/optimizers/layer_decay_optimizer_constructor.py#L104), 可以对以 ConvNeXt, BEiT 和 MAE 为骨干网络的模型训练时, 骨干网络的模型参数的学习率按照定义的衰减比例(`decay_rate`)逐层递减, 在配置文件中的配置如下: +MMSegmentation 中的实现了 [`LearningRateDecayOptimizerConstructor`](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/engine/optimizers/layer_decay_optimizer_constructor.py#L104), 可以对以 ConvNeXt, BEiT 和 MAE 为骨干网络的模型训练时, 骨干网络的模型参数的学习率按照定义的衰减比例(`decay_rate`)逐层递减, 在配置文件中的配置如下: ```python optim_wrapper = dict( diff --git a/docs/zh_cn/advanced_guides/models.md b/docs/zh_cn/advanced_guides/models.md index 408a57863c4..6eb22517a46 100644 --- a/docs/zh_cn/advanced_guides/models.md +++ b/docs/zh_cn/advanced_guides/models.md @@ -30,17 +30,17 @@ ## 基本接口 -MMSegmentation 封装 `BaseModel` 并实现了 [BaseSegmenter](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/models/segmentors/base.py#L15) 类,主要提供 `forward`、`train_step`、`val_step` 和 `test_step` 接口。接下来将详细介绍这些接口。 +MMSegmentation 封装 `BaseModel` 并实现了 [BaseSegmentor](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/models/segmentors/base.py#L15) 类,主要提供 `forward`、`train_step`、`val_step` 和 `test_step` 接口。接下来将详细介绍这些接口。 ### forward
- +
编码器解码器数据流
-
+
级联编码器解码器数据流
@@ -115,7 +115,7 @@ MMSegmentation 封装 `BaseModel` 并实现了 [BaseSegmenter](https://github.co -Dict\[str, `torch.Tensor`\]:用于记录日志的张量的`字典`。
- +
train_step 数据流
@@ -132,7 +132,7 @@ MMSegmentation 封装 `BaseModel` 并实现了 [BaseSegmenter](https://github.co - `list` - 给定数据的预测结果。
- +
test_step/val_step 数据流
diff --git a/docs/zh_cn/advanced_guides/training_tricks.md b/docs/zh_cn/advanced_guides/training_tricks.md index a33c0ea9cfd..e5b8e4dae1e 100644 --- a/docs/zh_cn/advanced_guides/training_tricks.md +++ b/docs/zh_cn/advanced_guides/training_tricks.md @@ -1,4 +1,4 @@ -# 训练技巧(待更新) +# 训练技巧 MMSegmentation 支持如下训练技巧: @@ -9,17 +9,17 @@ MMSegmentation 支持如下训练技巧: 在 MMSegmentation 里面,您也可以在配置文件里添加如下行来让解码头组件的学习率是主干组件的10倍。 ```python -optimizer=dict( +optim_wrapper=dict( paramwise_cfg = dict( custom_keys={ 'head': dict(lr_mult=10.)})) ``` -通过这种修改,任何被分组到 `'head'` 的参数的学习率都将乘以10。您也可以参照 [MMCV 文档](https://mmcv.readthedocs.io/en/latest/api.html#mmcv.runner.DefaultOptimizerConstructor) 获取更详细的信息。 +通过这种修改,任何被分组到 `'head'` 的参数的学习率都将乘以10。您也可以参照 [MMEngine 文档](https://mmengine.readthedocs.io/zh_CN/latest/tutorials/optim_wrapper.html#id6) 获取更详细的信息。 ## 在线难样本挖掘 (Online Hard Example Mining, OHEM) -对于训练时采样,我们在 [这里](https://github.com/open-mmlab/mmsegmentation/tree/master/mmseg/core/seg/sampler) 做了像素采样器。 +MMSegmentation 中实现了像素采样器,训练时可以对特定像素进行采样,例如 OHEM(Online Hard Example Mining),可以解决样本不平衡问题, 如下例子是使用 PSPNet 训练并采用 OHEM 策略的配置: ```python @@ -58,38 +58,17 @@ model=dict( ```python _base_ = './fcn_unet_s5-d16_64x64_40k_drive.py' model = dict( - decode_head=dict(loss_decode=[dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), - dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0)]), - auxiliary_head=dict(loss_decode=[dict(type='CrossEntropyLoss', loss_name='loss_ce',loss_weight=1.0), - dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0)]), - ) + decode_head=dict(loss_decode=[ + dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), + dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0) + ]), + auxiliary_head=dict(loss_decode=[ + dict(type='CrossEntropyLoss', loss_name='loss_ce', loss_weight=1.0), + dict(type='DiceLoss', loss_name='loss_dice', loss_weight=3.0) + ]), +) ``` 通过这种方式,确定训练过程中损失函数的权重 `loss_weight` 和在训练日志里的名字 `loss_name`。 -注意: `loss_name` 的名字必须带有 `loss_` 前缀,这样它才能被包括在反传的图里。 - -## 在损失函数中忽略特定的 label 类别 - -默认设置 `avg_non_ignore=False`, 即每个像素都用来计算损失函数。尽管其中的一些像素属于需要被忽略的类别。 - -对于训练时损失函数的计算,我们目前支持使用 `avg_non_ignore` 和 `ignore_index` 来忽略 label 特定的类别。 这样损失函数将只在非忽略类别像素中求平均值,会获得更好的表现。这里是[相关 PR](https://github.com/open-mmlab/mmsegmentation/pull/1409)。以 `unet` 使用 `Cityscapes` 数据集训练为例, -在计算损失函数时,忽略 label 为0的背景,并且仅在不被忽略的像素上计算均值。配置文件写为: - -```python -_base_ = './fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes.py' -model = dict( - decode_head=dict( - ignore_index=0, - loss_decode=dict( - type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0, avg_non_ignore=True), - auxiliary_head=dict( - ignore_index=0, - loss_decode=dict( - type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0, avg_non_ignore=True)), - )) -``` - -通过这种方式,确定训练过程中损失函数的权重 `loss_weight` 和在训练日志里的名字 `loss_name`。 - -注意: `loss_name` 的名字必须带有 `loss_` 前缀,这样它才能被包括在反传的图里。 +注意: `loss_name` 的名字必须带有 `loss_` 前缀,这样它才能被包括在计算图里。 diff --git a/docs/zh_cn/get_started.md b/docs/zh_cn/get_started.md index 38e93e9cb4e..ca375f3d9d6 100644 --- a/docs/zh_cn/get_started.md +++ b/docs/zh_cn/get_started.md @@ -4,7 +4,7 @@ 本教程中,我们将会演示如何使用 PyTorch 准备环境。 -MMSegmentation 可以在 Linux, Windows 和 macOS 系统上运行,并且需要安装 Python 3.6+, CUDA 9.2+ 和 PyTorch 1.5+ +MMSegmentation 可以在 Linux, Windows 和 macOS 系统上运行,并且需要安装 Python 3.7+, CUDA 10.2+ 和 PyTorch 1.8+ **注意:** 如果您已经安装了 PyTorch, 可以跳过该部分,直接到[下一小节](##安装)。否则,您可以按照以下步骤操作。 @@ -43,7 +43,7 @@ conda install pytorch torchvision cpuonly -c pytorch ```shell pip install -U openmim mim install mmengine -mim install "mmcv>=2.0.0rc1" +mim install "mmcv>=2.0.0" ``` **步骤 1.** 安装 MMSegmentation @@ -51,7 +51,7 @@ mim install "mmcv>=2.0.0rc1" 情况 a: 如果您想立刻开发和运行 mmsegmentation,您可通过源码安装: ```shell -git clone -b dev-1.x https://github.com/open-mmlab/mmsegmentation.git +git clone -b main https://github.com/open-mmlab/mmsegmentation.git cd mmsegmentation pip install -v -e . # '-v' 表示详细模式,更多的输出 @@ -62,7 +62,7 @@ pip install -v -e . 情况 b: 如果您把 mmsegmentation 作为依赖库或者第三方库,可以通过 pip 安装: ```shell -pip install "mmsegmentation>=1.0.0rc0" +pip install "mmsegmentation>=1.0.0" ``` ### 验证是否安装成功 @@ -87,8 +87,7 @@ python demo/image_demo.py demo/demo.png configs/pspnet/pspnet_r50-d8_4xb2-40k_ci 您将在当前文件夹中看到一个新图像 `result.jpg`,其中所有目标都覆盖了分割 mask -选项 (b). 如果您通过 pip 安装 mmsegmentation, 打开您的 python -解释器,复制粘贴以下代码: +选项 (b). 如果您通过 pip 安装 mmsegmentation, 打开您的 python 解释器,复制粘贴以下代码: ```python from mmseg.apis import inference_model, init_model, show_result_pyplot @@ -111,8 +110,8 @@ show_result_pyplot(model, img, result, show=True, out_file='result.jpg', opacity # 在一段视频上测试并可视化分割结果 video = mmcv.VideoReader('video.mp4') for frame in video: - result = inference_segmentor(model, frame) - show_result_pyplot(model, result, wait_time=1) + result = inference_model(model, frame) + show_result_pyplot(model, frame, result, wait_time=1) ``` 您可以修改上面的代码来测试单个图像或视频,这两个选项都可以验证安装是否成功。 @@ -137,15 +136,15 @@ MMCV 包含 C++ 和 CUDA 扩展,因此与 PyTorch 的依赖方式比较复杂 为了使用 pip 而不是 MIM 安装 MMCV, 请参考 [MMCV 安装指南](https://mmcv.readthedocs.io/en/latest/get_started/installation.html). 这需要手动指定一个基于 PyTorch 版本及其 CUDA 版本的 find-url. -例如,以下命令可为 PyTorch 1.10.x and CUDA 11.3 安装 mmcv==2.0.0rc1 +例如,以下命令可为 PyTorch 1.10.x and CUDA 11.3 安装 mmcv==2.0.0 ```shell -pip install mmcv==2.0.0rc1 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html +pip install mmcv==2.0.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html ``` #### 在仅有 CPU 的平台安装 -MMSegmentation 可以在仅有 CPU 的版本上运行。在 CPU 模式,您可以训练(需要 MMCV-Lite 版本 >= 2.0.0rc0),测试和推理模型。 +MMSegmentation 可以在仅有 CPU 的版本上运行。在 CPU 模式,您可以训练(需要 MMCV 版本 >= 2.0.0),测试和推理模型。 #### 在 Google Colab 上安装 @@ -156,7 +155,7 @@ MMSegmentation 可以在仅有 CPU 的版本上运行。在 CPU 模式,您可 ```shell !pip3 install openmim !mim install mmengine -!mim install "mmcv>=2.0.0rc1" +!mim install "mmcv>=2.0.0" ``` **Step 2.** 通过源码安装 MMSegmentation @@ -164,7 +163,7 @@ MMSegmentation 可以在仅有 CPU 的版本上运行。在 CPU 模式,您可 ```shell !git clone https://github.com/open-mmlab/mmsegmentation.git %cd mmsegmentation -!git checkout dev-1.x +!git checkout main !pip install -e . ``` @@ -173,7 +172,7 @@ MMSegmentation 可以在仅有 CPU 的版本上运行。在 CPU 模式,您可 ```python import mmseg print(mmseg.__version__) -# 示例输出: 1.0.0rc0 +# 示例输出: 1.0.0 ``` **注意:** @@ -195,6 +194,16 @@ docker build -t mmsegmentation docker/ docker run --gpus all --shm-size=8g -it -v {DATA_DIR}:/mmsegmentation/data mmsegmentation ``` +### 可选依赖 + +#### 安装 GDAL + +[GDAL](https://gdal.org/) 是一个用于栅格和矢量地理空间数据格式的转换库。安装 GDAL 可以读取复杂格式和极大的遥感图像。 + +```shell +conda install GDAL +``` + ## 问题解答 如果您在安装过程中遇到了其他问题,请第一时间查阅 [FAQ](notes/faq.md) 文件。如果没有找到答案,您也可以在 GitHub 上提出 [issue](https://github.com/open-mmlab/mmsegmentation/issues/new/choose) diff --git a/docs/zh_cn/imgs/qq_group_qrcode.jpg b/docs/zh_cn/imgs/qq_group_qrcode.jpg deleted file mode 100644 index 417347449fe..00000000000 Binary files a/docs/zh_cn/imgs/qq_group_qrcode.jpg and /dev/null differ diff --git a/docs/zh_cn/imgs/seggroup_qrcode.jpg b/docs/zh_cn/imgs/seggroup_qrcode.jpg deleted file mode 100644 index 9684582ee1c..00000000000 Binary files a/docs/zh_cn/imgs/seggroup_qrcode.jpg and /dev/null differ diff --git a/docs/zh_cn/index.rst b/docs/zh_cn/index.rst index e66c178689d..ce5e49977dc 100644 --- a/docs/zh_cn/index.rst +++ b/docs/zh_cn/index.rst @@ -23,7 +23,7 @@ :maxdepth: 1 :caption: 迁移指引 - migration.md + migration/index.rst .. toctree:: :caption: 接口文档(英文) diff --git a/docs/zh_cn/migration/interface.md b/docs/zh_cn/migration/interface.md index cd16d2cbc68..42f91bf50ac 100644 --- a/docs/zh_cn/migration/interface.md +++ b/docs/zh_cn/migration/interface.md @@ -2,7 +2,7 @@ ## 引言 -本指南介绍了 MMSegmentation 0.x 和 MMSegmentation1.x 在行为和 API 方面的基本区别,以及这些如何都与您的迁移过程相关。 +本指南介绍了 MMSegmentation 0.x 和 MMSegmentation1.x 在表现和 API 方面的基本区别,以及这些与迁移过程的关系。 ## 新的依赖 @@ -12,11 +12,11 @@ MMSegmentation 1.x 依赖于一些新的软件包,您可以准备一个新的 1. [MMEngine](https://github.com/open-mmlab/mmengine):MMEngine 是 OpenMMLab 2.0 架构的核心,我们将许多与计算机视觉无关的内容从 MMCV 拆分到 MMEngine 中。 -2. [MMCV](https://github.com/open-mmlab/mmcv):OpenMMLab 的计算机视觉包。这不是一个新的依赖,但您需要将其升级到 **2.0.0rc1** 以上的版本。 +2. [MMCV](https://github.com/open-mmlab/mmcv):OpenMMLab 的计算机视觉包。这不是一个新的依赖,但您需要将其升级到 **2.0.0** 或以上的版本。 -3. [MMClassification](https://github.com/open-mmlab/mmclassification)(可选):OpenMMLab 的图像分类工具箱和基准。这不是一个新的依赖,但您需要将其升级到 **1.0.0rc0** 以上的版本。 +3. [MMClassification](https://github.com/open-mmlab/mmclassification)(可选):OpenMMLab 的图像分类工具箱和基准。这不是一个新的依赖,但您需要将其升级到 **1.0.0rc6** 版本。 -4. [MMDetection](https://github.com/open-mmlab/mmdetection)(可选): OpenMMLab 的目标检测工具箱和基准。这不是一个新的依赖,但您需要将其升级到 **3.0.0rc0** 以上的版本。 +4. [MMDetection](https://github.com/open-mmlab/mmdetection)(可选): OpenMMLab 的目标检测工具箱和基准。这不是一个新的依赖,但您需要将其升级到 **3.0.0** 或以上的版本。 ## 启动训练 @@ -46,7 +46,7 @@ OpenMMLab 2.0 的主要改进是发布了 MMEngine,它为启动训练任务的 --resume='auto' -培训练期间是否不评估检查点 +训练期间是否不评估检查点 --no-validate --cfg-options val_cfg=None val_dataloader=None val_evaluator=None @@ -102,11 +102,11 @@ OpenMMLab 2.0 的主要改进是发布了 MMEngine,它为启动训练任务的 - `mean`(Sequence,可选):R、G、B 通道的像素平均值。默认为 None。 -- `std`(Sequence,可选):R、G、B通道的像素标准差。默认为 None。 +- `std`(Sequence,可选):R、G、B 通道的像素标准差。默认为 None。 - `size`(Sequence,可选):固定的填充大小。 -- `size_divisor`(int,可选):填充大小的除法因子。 +- `size_divisor`(int,可选):填充图像可以被当前值整除。 - `seg_pad_val`(float,可选):分割图的填充值。默认值:255。 @@ -154,14 +154,14 @@ train_dataloader = dict( batch_size=4, num_workers=4, dataset=dict(...), - sampler=dict(type='DefaultSampler', shuffle=True) # necessary + sampler=dict(type='DefaultSampler', shuffle=True) # 必须 ) val_dataloader = dict( batch_size=4, num_workers=4, dataset=dict(...), - sampler=dict(type='DefaultSampler', shuffle=False) # necessary + sampler=dict(type='DefaultSampler', shuffle=False) # 必须 ) test_dataloader = val_dataloader @@ -417,10 +417,10 @@ runner = dict(type='IterBasedRunner', max_iters=20000) ```python -# The `val_interval` is the original `evaluation.interval`. +# `val_interval` 是旧版本的 `evaluation.interval`。 train_cfg = dict(type='IterBasedTrainLoop', max_iters=20000, val_interval=2000) -val_cfg = dict(type='ValLoop') # Use the default validation loop. -test_cfg = dict(type='TestLoop') # Use the default test loop. +val_cfg = dict(type='ValLoop') # 使用默认的验证循环。 +test_cfg = dict(type='TestLoop') # 使用默认的测试循环。 ``` @@ -438,22 +438,22 @@ test_cfg = dict(type='TestLoop') # Use the default test loop. ```python default_hooks = dict( - # record the time of every iterations. + # 记录每次迭代的时间。 timer=dict(type='IterTimerHook'), - # print log every 50 iterations. + # 每50次迭代打印一次日志。 logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), - # enable the parameter scheduler. + # 启用参数调度程序。 param_scheduler=dict(type='ParamSchedulerHook'), - # save checkpoint every 2000 iterations. + # 每2000次迭代保存一次检查点。 checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=2000), - # set sampler seed in distributed environment. + # 在分布式环境中设置采样器种子。 sampler_seed=dict(type='DistSamplerSeedHook'), - # validation results visualization. + # 验证结果可视化。 visualization=dict(type='SegVisualizationHook')) ``` @@ -505,13 +505,13 @@ visualizer = dict( ```python env_cfg = dict( - # whether to enable cudnn benchmark + # 是否启用 cudnn_benchmark cudnn_benchmark=False, - # set multi process parameters + # 设置多进程参数 mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), - # set distributed parameters + # 设置分布式参数 dist_cfg=dict(backend='nccl'), ) ``` diff --git a/docs/zh_cn/migration/package.md b/docs/zh_cn/migration/package.md index d8d2245bed0..19e5f18c9c4 100644 --- a/docs/zh_cn/migration/package.md +++ b/docs/zh_cn/migration/package.md @@ -1,6 +1,6 @@ -#包结构更改 +# 包结构更改 -本节包含您对 MMSeg 0.x 和 1.x 之间的变化感到好奇的内容。 +本节包含您对 MMSeg 0.x 和 1.x 之间的变化可能感到好奇的内容。 @@ -49,7 +49,7 @@ ## `mmseg.ops` -`ops` 包包含 `encoding` 和 `wrappers`,它们被移到了 `mmseg.models.utils` 中。 +`ops` 包含 `encoding` 和 `wrappers`,它们被移到了 `mmseg.models.utils` 中。 ## 增加的包 @@ -110,4 +110,4 @@ OpenMMLab 2.0 将 `BaseDataset` 定义为数据集的函数和接口,MMSegment ### `mmseg.models` -`models` 没有太大变化,只是从以前的 `mmseg.ops` 中添加了 `encoding` 和 `wrappers` +`models` 没有太大变化,只是从以前的 `mmseg.ops` 添加了 `encoding` 和 `wrappers` diff --git a/docs/zh_cn/notes/faq.md b/docs/zh_cn/notes/faq.md index 09fde025fde..bf3b3417802 100644 --- a/docs/zh_cn/notes/faq.md +++ b/docs/zh_cn/notes/faq.md @@ -1,8 +1,122 @@ -# 常见问题解答(FAQ)(待更新) +# 常见问题解答(FAQ) -我们在这里列出了使用时的一些常见问题及其相应的解决方案。 如果您发现有一些问题被遗漏,请随时提 PR 丰富这个列表。 如果您无法在此获得帮助,请使用 [issue模板](https://github.com/open-mmlab/mmsegmentation/blob/master/.github/ISSUE_TEMPLATE/error-report.md/)创建问题,但是请在模板中填写所有必填信息,这有助于我们更快定位问题。 +我们在这里列出了使用时的一些常见问题及其相应的解决方案。 如果您发现有一些问题被遗漏,请随时提 PR 丰富这个列表。 如果您无法在此获得帮助,请使用 [issue 模板](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/.github/ISSUE_TEMPLATE/error-report.md/)创建问题,但是请在模板中填写所有必填信息,这有助于我们更快定位问题。 + +## 安装 + +兼容的 MMSegmentation 和 MMCV 版本如下。请安装正确版本的 MMCV 以避免安装问题。 + +| MMSegmentation version | MMCV version | MMEngine version | MMClassification (optional) version | MMDetection (optional) version | +| :--------------------: | :----------------------------: | :---------------: | :---------------------------------: | :----------------------------: | +| dev-1.x branch | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| main branch | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.2 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.1 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.1.0 | mmcv >= 2.0.0 | MMEngine >= 0.7.4 | mmpretrain>=1.0.0rc7 | mmdet >= 3.0.0 | +| 1.0.0 | mmcv >= 2.0.0rc4 | MMEngine >= 0.7.1 | mmcls==1.0.0rc6 | mmdet >= 3.0.0 | +| 1.0.0rc6 | mmcv >= 2.0.0rc4 | MMEngine >= 0.5.0 | mmcls>=1.0.0rc0 | mmdet >= 3.0.0rc6 | +| 1.0.0rc5 | mmcv >= 2.0.0rc4 | MMEngine >= 0.2.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc6 | +| 1.0.0rc4 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | +| 1.0.0rc3 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | +| 1.0.0rc2 | mmcv == 2.0.0rc3 | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | mmdet>=3.0.0rc4, \<=3.0.0rc5 | +| 1.0.0rc1 | mmcv >= 2.0.0rc1, \<=2.0.0rc3> | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | Not required | +| 1.0.0rc0 | mmcv >= 2.0.0rc1, \<=2.0.0rc3> | MMEngine >= 0.1.0 | mmcls>=1.0.0rc0 | Not required | + +如果您已经安装了版本不合适的 mmcv,请先运行`pip uninstall mmcv`卸载已安装的 mmcv,如您先前安装的为 mmcv-full(存在于 OpenMMLab 1.x),请运行`pip uninstall mmcv-full`进行卸载。 + +- 如出现 "No module named 'mmcv'" + 1. 使用`pip uninstall mmcv`卸载环境中现有的 mmcv + 2. 按照[安装说明](../get_started.md)安装对应的 mmcv ## 如何获知模型训练时需要的显卡数量 -- 看模型的config文件的命名。可以参考[学习配置文件](https://github.com/open-mmlab/mmsegmentation/blob/master/docs/zh_cn/tutorials/config.md)中的`配置文件命名风格`部分。比如,对于名字为`segformer_mit-b0_8x1_1024x1024_160k_cityscapes.py`的config文件,`8x1`代表训练其对应的模型需要的卡数为8,每张卡中的batch size为1。 -- 看模型的log文件。点开该模型的log文件,并在其中搜索`nGPU`,在`nGPU`后的数字个数即训练时所需的卡数。比如,在log文件中搜索`nGPU`得到`nGPU 0,1,2,3,4,5,6,7`的记录,则说明训练该模型需要使用八张卡。 +- 看模型的 config 文件命名。可以参考[了解配置文件](../user_guides/1_config.md)中的`配置文件命名风格`部分。比如,对于名字为`segformer_mit-b0_8xb1-160k_cityscapes-1024x1024.py`的 config 文件,`8xb1`代表训练其对应的模型需要的卡数为 8,每张卡中的 batch size 为 1。 +- 看模型的 log 文件。点开该模型的 log 文件,并在其中搜索`nGPU`,在`nGPU`后的数字个数即训练时所需的卡数。比如,在 log 文件中搜索`nGPU`得到`nGPU 0,1,2,3,4,5,6,7`的记录,则说明训练该模型需要使用八张卡。 + +## auxiliary head 是什么 + +简单来说,这是一个提高准确率的深度监督技术。在训练阶段,`decode_head`用于输出语义分割的结果,`auxiliary_head` 只是增加了一个辅助损失,其产生的分割结果对你的模型结果没有影响,仅在在训练中起作用。您可以阅读这篇[论文](https://arxiv.org/pdf/1612.01105.pdf)了解更多信息。 + +## 运行测试脚本时如何输出绘制分割掩膜的图像 + +在测试脚本中,我们提供了`--out`参数来控制是否输出保存预测的分割掩膜图像。您可以运行以下命令输出测试结果: + +```shell +python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} --out ${OUTPUT_DIR} +``` + +更多用例细节可查阅[文档](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/user_guides/4_train_test.md#%E6%B5%8B%E8%AF%95%E5%B9%B6%E4%BF%9D%E5%AD%98%E5%88%86%E5%89%B2%E7%BB%93%E6%9E%9C),[PR #2712](https://github.com/open-mmlab/mmsegmentation/pull/2712) 以及[迁移文档](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/docs/zh_cn/migration/interface.md#%E6%B5%8B%E8%AF%95%E5%90%AF%E5%8A%A8)了解相关说明。 + +## 如何处理二值分割任务? + +MMSegmentation 使用 `num_classes` 和 `out_channels` 来控制模型最后一层 `self.conv_seg` 的输出。更多细节可以参考 [这里](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/models/decode_heads/decode_head.py)。 + +`num_classes` 应该和数据集本身类别个数一致,当是二值分割时,数据集只有前景和背景两类,所以 `num_classes` 为 2. `out_channels` 控制模型最后一层的输出的通道数,通常和 `num_classes` 相等,但当二值分割时候,可以有两种处理方法, 分别是: + +- 设置 `out_channels=2`,在训练时以 Cross Entropy Loss 作为损失函数,在推理时使用 `F.softmax()` 归一化 logits 值,然后通过 `argmax()` 得到每个像素的预测结果。 + +- 设置 `out_channels=1`,在训练时以 Binary Cross Entropy Loss 作为损失函数,在推理时使用 `F.sigmoid()` 和 `threshold` 得到预测结果,`threshold` 默认为 0.3。 + +对于实现上述两种计算二值分割的方法,需要在 `decode_head` 和 `auxiliary_head` 的配置里修改。下面是对样例 [pspnet_unet_s5-d16.py](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/models/pspnet_unet_s5-d16.py) 做出的对应修改。 + +- (1) `num_classes=2`, `out_channels=2` 并在 `CrossEntropyLoss` 里面设置 `use_sigmoid=False`。 + +```python +decode_head=dict( + type='PSPHead', + in_channels=64, + in_index=4, + num_classes=2, + out_channels=2, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), +auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + num_classes=2, + out_channels=2, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), +``` + +- (2) `num_classes=2`, `out_channels=1` 并在 `CrossEntropyLoss` 里面设置 `use_sigmoid=True`. + +```python +decode_head=dict( + type='PSPHead', + in_channels=64, + in_index=4, + num_classes=2, + out_channels=1, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0)), +auxiliary_head=dict( + type='FCNHead', + in_channels=128, + in_index=3, + num_classes=2, + out_channels=1, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=True, loss_weight=0.4)), +``` + +## `reduce_zero_label` 的作用 + +数据集中 `reduce_zero_label` 参数类型为布尔类型,默认为 False,它的功能是为了忽略数据集 label 0。具体做法是将 label 0 改为 255,其余 label 相应编号减 1,同时 decode head 里将 255 设为 ignore index,即不参与 loss 计算。 +以下是 `reduce_zero_label` 具体实现逻辑: + +```python +if self.reduce_zero_label: + # avoid using underflow conversion + gt_semantic_seg[gt_semantic_seg == 0] = 255 + gt_semantic_seg = gt_semantic_seg - 1 + gt_semantic_seg[gt_semantic_seg == 254] = 255 +``` + +关于您的数据集是否需要使用 reduce_zero_label,有以下两类情况: + +- 例如在 [Potsdam](https://github.com/open-mmlab/mmsegmentation/blob/1.x/docs/en/user_guides/2_dataset_prepare.md#isprs-potsdam) 数据集上,有 0-不透水面、1-建筑、2-低矮植被、3-树、4-汽车、5-杂乱,六类。但该数据集提供了两种 RGB 标签,一种为图像边缘处有黑色像素的标签,另一种是没有黑色边缘的标签。对于有黑色边缘的标签,在 [dataset_converters.py](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/tools/dataset_converters/potsdam.py)中,其将黑色边缘转换为 label 0,其余标签分别为 1-不透水面、2-建筑、3-低矮植被、4-树、5-汽车、6-杂乱,那么此时,就应该在数据集 [potsdam.py](https://github.com/open-mmlab/mmsegmentation/blob/ff95416c3b5ce8d62b9289f743531398efce534f/mmseg/datasets/potsdam.py#L23) 中将`reduce_zero_label=True`。如果使用的是没有黑色边缘的标签,那么 mask label 中只有 0-5,此时就应该使`reduce_zero_label=False`。需要结合您的实际情况来使用。 +- 例如在第 0 类为 background 类别的数据集上,如果您最终是需要将背景和您的其余类别分开时,是不需要使用`reduce_zero_label`的,此时在数据集中应该将其设置为`reduce_zero_label=False` + +**注意:** 使用 `reduce_zero_label` 请确认数据集原始类别个数,如果只有两类,需要关闭 `reduce_zero_label` 即设置 `reduce_zero_label=False`。 diff --git a/docs/zh_cn/overview.md b/docs/zh_cn/overview.md index 7dce105a813..ed147956d08 100644 --- a/docs/zh_cn/overview.md +++ b/docs/zh_cn/overview.md @@ -42,7 +42,7 @@ MMSeg 主要包含了 apis, structures, datasets, models, engine, evaluation 和 以下是详细步骤,将带您一步步学习如何使用 MMSegmentation : -1. 有关安装说明,请参阅 [开始你的第一步](getting_started.md)。 +1. 有关安装说明,请参阅 [开始你的第一步](get_started.md)。 2. 对于初学者来说,MMSegmentation 是开始语义分割之旅的最好选择,因为这里实现了许多 SOTA 模型以及经典的模型 [model](model_zoo.md) 。另外,将各类组件和高级 API 結合使用,可以更便捷的执行分割任务。关于 MMSegmentation 的基本用法,请参考下面的教程: @@ -62,8 +62,8 @@ MMSeg 主要包含了 apis, structures, datasets, models, engine, evaluation 和 4. MMSegmentation 也为用户自定义和一些前沿的研究提供了教程,请参考下面的教程来建立你自己的分割项目: - [添加新的模型](advanced_guides/add_models.md) - - [添加新的数据集](advanced_guides/add_dataset.md) - - [添加新的 transform](advanced_guides/add_transform.md) + - [添加新的数据集](advanced_guides/add_datasets.md) + - [添加新的 transform](advanced_guides/add_transforms.md) - [自定义 runtime](advanced_guides/customize_runtime.md) 5. 如果您更熟悉 MMSegmentation v0.x , 以下是 MMSegmentation v0.x 迁移到 v1.x 的文档 diff --git a/docs/zh_cn/user_guides/2_dataset_prepare.md b/docs/zh_cn/user_guides/2_dataset_prepare.md index c9c3606977d..5532624bef4 100644 --- a/docs/zh_cn/user_guides/2_dataset_prepare.md +++ b/docs/zh_cn/user_guides/2_dataset_prepare.md @@ -1,3 +1,750 @@ -## 准备数据集(待更新) +# 教程2:准备数据集 -中文版文档支持中,请先阅读[英文版本](../../en/user_guides/2_dataset_prepare.md) +我们建议将数据集根目录符号链接到 `$MMSEGMENTATION/data`。 +如果您的目录结构不同,您可能需要更改配置文件中相应的路径。 +对于中国境内的用户,我们也推荐通过开源数据平台 [OpenDataLab](https://opendatalab.com/) 来下载dsdl标准数据,以获得更好的下载和使用体验,这里有一个下载dsdl数据集并进行训练的案例[DSDLReadme](../../../configs/dsdl/README.md),欢迎尝试。 + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── cityscapes +│ │ ├── leftImg8bit +│ │ │ ├── train +│ │ │ ├── val +│ │ ├── gtFine +│ │ │ ├── train +│ │ │ ├── val +│ ├── VOCdevkit +│ │ ├── VOC2012 +│ │ │ ├── JPEGImages +│ │ │ ├── SegmentationClass +│ │ │ ├── ImageSets +│ │ │ │ ├── Segmentation +│ │ ├── VOC2010 +│ │ │ ├── JPEGImages +│ │ │ ├── SegmentationClassContext +│ │ │ ├── ImageSets +│ │ │ │ ├── SegmentationContext +│ │ │ │ │ ├── train.txt +│ │ │ │ │ ├── val.txt +│ │ │ ├── trainval_merged.json +│ │ ├── VOCaug +│ │ │ ├── dataset +│ │ │ │ ├── cls +│ ├── ade +│ │ ├── ADEChallengeData2016 +│ │ │ ├── annotations +│ │ │ │ ├── training +│ │ │ │ ├── validation +│ │ │ ├── images +│ │ │ │ ├── training +│ │ │ │ ├── validation +│ ├── coco_stuff10k +│ │ ├── images +│ │ │ ├── train2014 +│ │ │ ├── test2014 +│ │ ├── annotations +│ │ │ ├── train2014 +│ │ │ ├── test2014 +│ │ ├── imagesLists +│ │ │ ├── train.txt +│ │ │ ├── test.txt +│ │ │ ├── all.txt +│ ├── coco_stuff164k +│ │ ├── images +│ │ │ ├── train2017 +│ │ │ ├── val2017 +│ │ ├── annotations +│ │ │ ├── train2017 +│ │ │ ├── val2017 +│ ├── CHASE_DB1 +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +│ ├── DRIVE +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +│ ├── HRF +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +│ ├── STARE +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +| ├── dark_zurich +| │   ├── gps +| │   │   ├── val +| │   │   └── val_ref +| │   ├── gt +| │   │   └── val +| │   ├── LICENSE.txt +| │   ├── lists_file_names +| │   │   ├── val_filenames.txt +| │   │   └── val_ref_filenames.txt +| │   ├── README.md +| │   └── rgb_anon +| │   | ├── val +| │   | └── val_ref +| ├── NighttimeDrivingTest +| | ├── gtCoarse_daytime_trainvaltest +| | │   └── test +| | │   └── night +| | └── leftImg8bit +| | | └── test +| | | └── night +│ ├── loveDA +│ │ ├── img_dir +│ │ │ ├── train +│ │ │ ├── val +│ │ │ ├── test +│ │ ├── ann_dir +│ │ │ ├── train +│ │ │ ├── val +│ ├── potsdam +│ │ ├── img_dir +│ │ │ ├── train +│ │ │ ├── val +│ │ ├── ann_dir +│ │ │ ├── train +│ │ │ ├── val +│ ├── vaihingen +│ │ ├── img_dir +│ │ │ ├── train +│ │ │ ├── val +│ │ ├── ann_dir +│ │ │ ├── train +│ │ │ ├── val +│ ├── iSAID +│ │ ├── img_dir +│ │ │ ├── train +│ │ │ ├── val +│ │ │ ├── test +│ │ ├── ann_dir +│ │ │ ├── train +│ │ │ ├── val +│ ├── synapse +│ │ ├── img_dir +│ │ │ ├── train +│ │ │ ├── val +│ │ ├── ann_dir +│ │ │ ├── train +│ │ │ ├── val +│ ├── REFUGE +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ │ ├── test +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +│ │ │ ├── test +│ ├── mapillary +│ │ ├── training +│ │ │ ├── images +│ │ │ ├── v1.2 +| │ │ │ ├── instances +| │ │ │ ├── labels +| │   │   │ └── panoptic +│ │ │ ├── v2.0 +| │ │ │ ├── instances +| │ │ │ ├── labels +| │ │ │ ├── panoptic +| │   │   │ └── polygons +│ │ ├── validation +│ │ │ ├── images +| │ │ ├── v1.2 +| │ │ │ ├── instances +| │ │ │ ├── labels +| │   │   │ └── panoptic +│ │ │ ├── v2.0 +| │ │ │ ├── instances +| │ │ │ ├── labels +| │ │ │ ├── panoptic +| │   │   │ └── polygons +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +│ ├── nyu +│ │ ├── images +│ │ │ ├── train +│ │ │ ├── test +│ │ ├── annotations +│ │ │ ├── train +│ │ │ ├── test +``` + +## 用 MIM 下载数据集 + +通过使用 [OpenXLab](https://openxlab.org.cn/datasets),您可以直接下载开源数据集。通过平台的搜索功能,您可以快速轻松地找到他们正在寻找的数据集。使用平台上的格式化数据集,您可以高效地跨数据集执行任务。 + +如果您使用 MIM 下载,请确保版本大于 v0.3.8。您可以使用以下命令进行更新、安装、登录和数据集下载: + +```shell +# upgrade your MIM +pip install -U openmim + +# install OpenXLab CLI tools +pip install -U openxlab +# log in OpenXLab +openxlab login + +# download ADE20K by MIM +mim download mmsegmentation --dataset ade20k +``` + +## Cityscapes + +Cityscapes [官方网站](https://www.cityscapes-dataset.com/)可以下载 Cityscapes 数据集,按照官网要求注册并登陆后,数据可以在[这里](https://www.cityscapes-dataset.com/downloads/)找到。 + +按照惯例,`**labelTrainIds.png` 用于 cityscapes 训练。 +我们提供了一个基于 [cityscapesscripts](https://github.com/mcordts/cityscapesScripts) 的[脚本](https://github.com/open-mmlab/mmsegmentation/blob/1.x/tools/dataset_converters/cityscapes.py)用于生成 `**labelTrainIds.png`。 + +```shell +# --nproc 表示 8 个转换进程,也可以省略。 +python tools/dataset_converters/cityscapes.py data/cityscapes --nproc 8 +``` + +## Pascal VOC + +Pascal VOC 2012 可从[此处](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar)下载。 +此外,Pascal VOC 数据集的最新工作通常利用额外的增强数据,可以在[这里](http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/semantic_contours/benchmark.tgz)找到。 + +如果您想使用增强的 VOC 数据集,请运行以下命令将增强数据的标注转换为正确的格式。 + +```shell +# --nproc 表示 8 个转换进程,也可以省略。 +python tools/dataset_converters/voc_aug.py data/VOCdevkit data/VOCdevkit/VOCaug --nproc 8 +``` + +请参考[拼接数据集文档](../advanced_guides/add_datasets.md#拼接数据集)及 [voc_aug 配置示例](../../../configs/_base_/datasets/pascal_voc12_aug.py)以详细了解如何将它们拼接并合并训练。 + +## ADE20K + +ADE20K 的训练和验证集可以从这个[链接](http://data.csail.mit.edu/places/ADEchallenge/ADEChallengeData2016.zip)下载。 +如果需要下载测试数据集,可以在[官网](http://host.robots.ox.ac.uk/)注册后,下载[测试集](http://host.robots.ox.ac.uk:8080/eval/downloads/VOC2010test.tar)。 + +## Pascal Context + +Pascal Context 的训练和验证集可以从[此处](http://host.robots.ox.ac.uk/pascal/VOC/voc2010/VOCtrainval_03-May-2010.tar)下载。注册后,您也可以从[此处](http://host.robots.ox.ac.uk:8080/eval/downloads/VOC2010test.tar)下载测试集。 + +从原始数据集中抽出部分数据作为验证集,您可以从[此处](https://codalabuser.blob.core.windows.net/public/trainval_merged.json)下载 trainval_merged.json 文件。 + +请先安装 [Detail](https://github.com/zhanghang1989/detail-api) 工具然后运行以下命令将标注转换为正确的格式。 + +```shell +python tools/dataset_converters/pascal_context.py data/VOCdevkit data/VOCdevkit/VOC2010/trainval_merged.json +``` + +## COCO Stuff 10k + +数据可以通过 wget 在[这里](http://calvin.inf.ed.ac.uk/wp-content/uploads/data/cocostuffdataset/cocostuff-10k-v1.1.zip)下载。 + +对于 COCO Stuff 10k 数据集,请运行以下命令下载并转换数据集。 + +```shell +# 下载 +mkdir coco_stuff10k && cd coco_stuff10k +wget http://calvin.inf.ed.ac.uk/wp-content/uploads/data/cocostuffdataset/cocostuff-10k-v1.1.zip + +# 解压 +unzip cocostuff-10k-v1.1.zip + +# --nproc 表示 8 个转换进程,也可以省略。 +python tools/dataset_converters/coco_stuff10k.py /path/to/coco_stuff10k --nproc 8 +``` + +按照惯例,`/path/to/coco_stuff164k/annotations/*2014/*_labelTrainIds.png` 中的 mask 标注用于 COCO Stuff 10k 的训练和测试。 + +## COCO Stuff 164k + +对于 COCO Stuff 164k 数据集,请运行以下命令下载并转换增强的数据集。 + +```shell +# 下载 +mkdir coco_stuff164k && cd coco_stuff164k +wget http://images.cocodataset.org/zips/train2017.zip +wget http://images.cocodataset.org/zips/val2017.zip +wget http://calvin.inf.ed.ac.uk/wp-content/uploads/data/cocostuffdataset/stuffthingmaps_trainval2017.zip + +# 解压 +unzip train2017.zip -d images/ +unzip val2017.zip -d images/ +unzip stuffthingmaps_trainval2017.zip -d annotations/ + +# --nproc 表示 8 个转换进程,也可以省略。 +python tools/dataset_converters/coco_stuff164k.py /path/to/coco_stuff164k --nproc 8 +``` + +按照惯例,`/path/to/coco_stuff164k/annotations/*2017/*_labelTrainIds.png` 中的 mask 标注用于 COCO Stuff 164k 的训练和测试。 + +此数据集的详细信息可在[此处](https://github.com/nightrome/cocostuff#downloads)找到。 + +## CHASE DB1 + +CHASE DB1 的训练和验证集可以从[此处](https://staffnet.kingston.ac.uk/~ku15565/CHASE_DB1/assets/CHASEDB1.zip)下载。 + +请运行以下命令,准备 CHASE DB1 数据集: + +```shell +python tools/dataset_converters/chase_db1.py /path/to/CHASEDB1.zip +``` + +该脚本将自动调整数据集目录结构,使其满足 MMSegmentation 数据集加载要求。 + +## DRIVE + +按照[官网](https://drive.grand-challenge.org/)要求,注册并登陆后,便可以下载 DRIVE 的训练和验证数据集。 + +要将 DRIVE 数据集转换为 MMSegmentation 的格式,请运行以下命令: + +```shell +python tools/dataset_converters/drive.py /path/to/training.zip /path/to/test.zip +``` + +该脚本将自动调整数据集目录结构,使其满足 MMSegmentation 数据集加载要求。 + +## HRF + +请下载 [health.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/healthy.zip)、[glaucoma.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/glaucoma.zip)、[diabetic_retinopathy.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/diabetic_retinopathy.zip)、[healthy_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/healthy_manualsegm.zip)、[glaucoma_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/glaucoma_manualsegm.zip) 和 [diabetic_retinopathy_manualsegm.zip](https://www5.cs.fau.de/fileadmin/research/datasets/fundus-images/diabetic_retinopathy_manualsegm.zip),无需解压,可以直接运行以下命令,准备 HRF 数据集: + +```shell +python tools/dataset_converters/hrf.py /path/to/healthy.zip /path/to/healthy_manualsegm.zip /path/to/glaucoma.zip /path/to/glaucoma_manualsegm.zip /path/to/diabetic_retinopathy.zip /path/to/diabetic_retinopathy_manualsegm.zip +``` + +该脚本将自动调整数据集目录结构,使其满足 MMSegmentation 数据集加载要求。 + +## STARE + +请下载 [stare images.tar](http://cecas.clemson.edu/~ahoover/stare/probing/stare-images.tar)、[labels-ah.tar](http://cecas.clemson.edu/~ahoover/stare/probing/labels-ah.tar) 和 [labels-vk.tar](http://cecas.clemson.edu/~ahoover/stare/probing/labels-vk.tar),无需解压,可以直接运行以下命令,准备 STARE 数据集: + +```shell +python tools/dataset_converters/stare.py /path/to/stare-images.tar /path/to/labels-ah.tar /path/to/labels-vk.tar +``` + +该脚本将自动调整数据集目录结构,使其满足 MMSegmentation 数据集加载要求。 + +## Dark Zurich + +由于我们只支持在此数据集上的模型测试,因此您只需要下载并解压[验证数据集](https://data.vision.ee.ethz.ch/csakarid/shared/GCMA_UIoU/Dark_Zurich_val_anon.zip)。 + +## Nighttime Driving + +由于我们只支持在此数据集上的模型测试,因此您只需要下载并解压[验证数据集](http://data.vision.ee.ethz.ch/daid/NighttimeDriving/NighttimeDrivingTest.zip)。 + +## LoveDA + +数据可以从[此处](https://drive.google.com/drive/folders/1ibYV0qwn4yuuh068Rnc-w4tPi0U0c-ti?usp=sharing)下载 LaveDA 数据集。 + +或者可以从 [zenodo](https://zenodo.org/record/5706578#.YZvN7SYRXdF) 下载。下载后,无需解压,直接运行以下命令: + +```shell +# 下载 Train.zip +wget https://zenodo.org/record/5706578/files/Train.zip +# 下载 Val.zip +wget https://zenodo.org/record/5706578/files/Val.zip +# 下载 Test.zip +wget https://zenodo.org/record/5706578/files/Test.zip +``` + +请对于 LoveDA 数据集,请运行以下命令调整数据集目录。 + +```shell +python tools/dataset_converters/loveda.py /path/to/loveDA +``` + +可将模型对 LoveDA 的测试集的预测结果上传至到数据集[测试服务器](https://codalab.lisn.upsaclay.fr/competitions/421),查看评测结果。 + +有关 LoveDA 的更多详细信息,可查看[此处](https://github.com/Junjue-Wang/LoveDA). + +## ISPRS Potsdam + +[Potsdam](https://www.isprs.org/education/benchmarks/UrbanSemLab/2d-sem-label-potsdam.aspx) 城市语义分割数据集用于 2D 语义分割竞赛 —— Potsdam。 + +数据集可以在竞赛[主页](https://www.isprs.org/education/benchmarks/UrbanSemLab/default.aspx)上请求获得。 +这里也提供了[BaiduNetdisk](https://pan.baidu.com/s/1K-cLVZnd1X7d8c26FQ-nGg?pwd=mseg),提取码:mseg、 [Google Drive](https://drive.google.com/drive/folders/1w3EJuyUGet6_qmLwGAWZ9vw5ogeG0zLz?usp=sharing)以及[OpenDataLab](https://opendatalab.com/ISPRS_Potsdam/download)。 +实验中需要下载 '2_Ortho_RGB.zip' 和 '5_Labels_all_noBoundary.zip'。 + +对于 Potsdam 数据集,请运行以下命令调整数据集目录。 + +```shell +python tools/dataset_converters/potsdam.py /path/to/potsdam +``` + +在我们的默认设置中,将生成 3456 张图像用于训练和 2016 张图像用于验证。 + +## ISPRS Vaihingen + +[Vaihingen](https://www.isprs.org/education/benchmarks/UrbanSemLab/2d-sem-label-vaihingen.aspx) 城市语义分割数据集用于 2D 语义分割竞赛 —— Vaihingen。 + +数据集可以在竞赛[主页](https://www.isprs.org/education/benchmarks/UrbanSemLab/default.aspx)上请求获得。 +这里也提供了[BaiduNetdisk](https://pan.baidu.com/s/109D3WLrLafsuYtLeerLiiA?pwd=mseg),提取码:mseg 、 [Google Drive](https://drive.google.com/drive/folders/1w3NhvLVA2myVZqOn2pbiDXngNC7NTP_t?usp=sharing)。 +实验中需要下载 'ISPRS_semantic_labeling_Vaihingen.zip' 和 'ISPRS_semantic_labeling_Vaihingen_ground_truth_eroded_COMPLETE.zip'。 + +对于 Vaihingen 数据集,请运行以下命令调整数据集目录。 + +```shell +python tools/dataset_converters/vaihingen.py /path/to/vaihingen +``` + +在我们的默认设置(`clip_size`=512, `stride_size`=256)中,将生成 344 张图像用于训练和 398 张图像用于验证。 + +## iSAID + +iSAID 数据集可从 [DOTA-v1.0](https://captain-whu.github.io/DOTA/dataset.html) 下载训练/验证/测试数据集的图像数据, + +并从 [iSAID](https://captain-whu.github.io/iSAID/dataset.html)下载训练/验证数据集的标注数据。 + +该数据集是航空图像实例分割和语义分割任务的大规模数据集。 + +下载 iSAID 数据集后,您可能需要按照以下结构进行数据集准备。 + +```none +├── data +│ ├── iSAID +│ │ ├── train +│ │ │ ├── images +│ │ │ │ ├── part1.zip +│ │ │ │ ├── part2.zip +│ │ │ │ ├── part3.zip +│ │ │ ├── Semantic_masks +│ │ │ │ ├── images.zip +│ │ ├── val +│ │ │ ├── images +│ │ │ │ ├── part1.zip +│ │ │ ├── Semantic_masks +│ │ │ │ ├── images.zip +│ │ ├── test +│ │ │ ├── images +│ │ │ │ ├── part1.zip +│ │ │ │ ├── part2.zip +``` + +```shell +python tools/dataset_converters/isaid.py /path/to/iSAID +``` + +在我们的默认设置(`patch_width`=896, `patch_height`=896, `overlap_area`=384)中,将生成 33978 张图像用于训练和 11644 张图像用于验证。 + +## LIP(Look Into Person) dataset + +该数据集可以从[此页面](https://lip.sysuhcp.com/overview.php)下载。 + +请运行以下命令来解压数据集。 + +```shell +unzip LIP.zip +cd LIP +unzip TrainVal_images.zip +unzip TrainVal_parsing_annotations.zip +cd TrainVal_parsing_annotations +unzip TrainVal_parsing_annotations.zip +mv train_segmentations ../ +mv val_segmentations ../ +cd .. +``` + +LIP 数据集的内容包括: + +```none +├── data +│ ├── LIP +│ │ ├── train_images +│   │ │ ├── 1000_1234574.jpg +│   │ │ ├── ... +│ │ ├── train_segmentations +│   │ │ ├── 1000_1234574.png +│   │ │ ├── ... +│ │ ├── val_images +│   │ │ ├── 100034_483681.jpg +│   │ │ ├── ... +│ │ ├── val_segmentations +│   │ │ ├── 100034_483681.png +│   │ │ ├── ... +``` + +## Synapse dataset + +此数据集可以从[此页面](https://www.synapse.org/#!Synapse:syn3193805/wiki/)下载。 + +遵循 [TransUNet](https://arxiv.org/abs/2102.04306) 的数据准备设定,将原始训练集(30 次扫描)拆分为新的训练集(18 次扫描)和验证集(12 次扫描)。请运行以下命令来准备数据集。 + +```shell +unzip RawData.zip +cd ./RawData/Training +``` + +然后创建 `train.txt` 和 `val.txt` 以拆分数据集。 + +根据 TransUnet,以下是数据集的划分。 + +train.txt + +```none +img0005.nii.gz +img0006.nii.gz +img0007.nii.gz +img0009.nii.gz +img0010.nii.gz +img0021.nii.gz +img0023.nii.gz +img0024.nii.gz +img0026.nii.gz +img0027.nii.gz +img0028.nii.gz +img0030.nii.gz +img0031.nii.gz +img0033.nii.gz +img0034.nii.gz +img0037.nii.gz +img0039.nii.gz +img0040.nii.gz +``` + +val.txt + +```none +img0008.nii.gz +img0022.nii.gz +img0038.nii.gz +img0036.nii.gz +img0032.nii.gz +img0002.nii.gz +img0029.nii.gz +img0003.nii.gz +img0001.nii.gz +img0004.nii.gz +img0025.nii.gz +img0035.nii.gz +``` + +synapse 数据集的内容包括: + +```none +├── Training +│ ├── img +│ │ ├── img0001.nii.gz +│ │ ├── img0002.nii.gz +│ │ ├── ... +│ ├── label +│ │ ├── label0001.nii.gz +│ │ ├── label0002.nii.gz +│ │ ├── ... +│ ├── train.txt +│ ├── val.txt +``` + +然后,使用此命令转换 synapse 数据集。 + +```shell +python tools/dataset_converters/synapse.py --dataset-path /path/to/synapse +``` + +注意,MMSegmentation 的默认评估指标(例如 mean dice value)是在 2D 切片图像上计算的,这与 [TransUNet](https://arxiv.org/abs/2102.04306) 等一些论文中的 3D 扫描结果是不同的。 + +## REFUGE + +在 [REFUGE Challenge](https://refuge.grand-challenge.org) 官网上注册并下载 [REFUGE 数据集](https://refuge.grand-challenge.org/REFUGE2Download)。 + +然后,解压 `REFUGE2.zip`,原始数据集的内容包括: + +```none +├── REFUGE2 +│ ├── REFUGE2 +│ │ ├── Annotation-Training400.zip +│ │ ├── REFUGE-Test400.zip +│ │ ├── REFUGE-Test-GT.zip +│ │ ├── REFUGE-Training400.zip +│ │ ├── REFUGE-Validation400.zip +│ │ ├── REFUGE-Validation400-GT.zip +│ ├── __MACOSX +``` + +请运行以下命令转换 REFUGE 数据集: + +```shell +python tools/convert_datasets/refuge.py --raw_data_root=/path/to/refuge/REFUGE2/REFUGE2 +``` + +脚本会将目录结构转换如下: + +```none +│ ├── REFUGE +│ │ ├── images +│ │ │ ├── training +│ │ │ ├── validation +│ │ │ ├── test +│ │ ├── annotations +│ │ │ ├── training +│ │ │ ├── validation +│ │ │ ├── test +``` + +包含 400 张用于训练的图像、400 张用于验证的图像和 400 张用于测试的图像,这与 REFUGE 2018 数据集相同。 + +## Mapillary Vistas Datasets + +- Mapillary Vistas [官方网站](https://www.mapillary.com/dataset/vistas) 可以下载 Mapillary Vistas 数据集,按照官网要求注册并登陆后,数据可以在[这里](https://www.mapillary.com/dataset/vistas)找到。 + +- Mapillary Vistas 数据集使用 8-bit with color-palette 来存储标签。不需要进行转换操作。 + +- 假设您已将数据集 zip 文件放在 `mmsegmentation/data/mapillary` 中 + +- 请运行以下命令来解压数据集。 + + ```bash + cd data/mapillary + unzip An-ZjB1Zm61yAZG0ozTymz8I8NqI4x0MrYrh26dq7kPgfu8vf9ImrdaOAVOFYbJ2pNAgUnVGBmbue9lTgdBOb5BbKXIpFs0fpYWqACbrQDChAA2fdX0zS9PcHu7fY8c-FOvyBVxPNYNFQuM.zip + ``` + +- 解压后,您将获得类似于此结构的 Mapillary Vistas 数据集。语义分割 mask 标签在 `labels` 文件夹中。 + + ```none + mmsegmentation + ├── mmseg + ├── tools + ├── configs + ├── data + │ ├── mapillary + │ │ ├── training + │ │ │ ├── images + │ │ │ ├── v1.2 + | │ │ │ ├── instances + | │ │ │ ├── labels + | │   │   │ └── panoptic + │ │ │ ├── v2.0 + | │ │ │ ├── instances + | │ │ │ ├── labels + | │ │ │ ├── panoptic + | │   │   │ └── polygons + │ │ ├── validation + │ │ │ ├── images + | │ │ ├── v1.2 + | │ │ │ ├── instances + | │ │ │ ├── labels + | │   │   │ └── panoptic + │ │ │ ├── v2.0 + | │ │ │ ├── instances + | │ │ │ ├── labels + | │ │ │ ├── panoptic + | │   │   │ └── polygons + ``` + +- 您可以在配置中使用 `MapillaryDataset_v1` 和 `Mapillary Dataset_v2` 设置数据集版本。 + 在此处 [V1.2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v1.py) 和 [V2.0](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v2.py) 查看 Mapillary Vistas 数据集配置文件 + +## LEVIR-CD + +[LEVIR-CD](https://justchenhao.github.io/LEVIR/) 大规模遥感建筑变化检测数据集。 + +数据集可以在[主页](https://justchenhao.github.io/LEVIR/)上请求获得。 + +数据集的补充版本可以在[主页](https://github.com/S2Looking/Dataset)上请求获得。 + +请下载数据集的补充版本,然后解压 `LEVIR-CD+.zip`,数据集的内容包括: + +```none +│ ├── LEVIR-CD+ +│ │ ├── train +│ │ │ ├── A +│ │ │ ├── B +│ │ │ ├── label +│ │ ├── test +│ │ │ ├── A +│ │ │ ├── B +│ │ │ ├── label +``` + +对于 LEVIR-CD 数据集,请运行以下命令无重叠裁剪影像: + +```shell +python tools/dataset_converters/levircd.py --dataset-path /path/to/LEVIR-CD+ --out_dir /path/to/LEVIR-CD +``` + +裁剪后的影像大小为256x256,与原论文保持一致。 + +## BDD100K + +- 可以从[官方网站](https://bdd-data.berkeley.edu/) 下载 BDD100K数据集(语义分割任务主要是10K数据集),按照官网要求注册并登陆后,数据可以在[这里](https://bdd-data.berkeley.edu/portal.html#download)找到。 + +- 图像数据对应的名称是是`10K Images`, 语义分割标注对应的名称是`Segmentation` + +- 下载后,可以使用以下代码进行解压 + + ```bash + unzip ~/bdd100k_images_10k.zip -d ~/mmsegmentation/data/ + unzip ~/bdd100k_sem_seg_labels_trainval.zip -d ~/mmsegmentation/data/ + ``` + +就可以得到以下文件结构了: + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +``` + +## NYU + +- 您可以从 [这个链接](https://drive.google.com/file/d/1wC-io-14RCIL4XTUrQLk6lBqU2AexLVp/view?usp=share_link) 下载 NYU 数据集 + +- 下载完成后,您可以使用 [tools/dataset_converters/nyu.py](/tools/dataset_converters/nyu.py) 脚本来解压和组织数据到所需的格式 + + ```bash + python tools/dataset_converters/nyu.py nyu.zip + ``` diff --git a/docs/zh_cn/user_guides/3_inference.md b/docs/zh_cn/user_guides/3_inference.md index d2fe60076f8..0afcb4b05d6 100644 --- a/docs/zh_cn/user_guides/3_inference.md +++ b/docs/zh_cn/user_guides/3_inference.md @@ -1,3 +1,244 @@ -## 使用预训练模型推理(待更新) +# 教程3:使用预训练模型推理 -中文版文档支持中,请先阅读[英文版本](../../en/user_guides/3_inference.md) +MMSegmentation 在 [Model Zoo](../Model_Zoo.md) 中为语义分割提供了预训练的模型,并支持多个标准数据集,包括 Cityscapes、ADE20K 等。 +本说明将展示如何使用现有模型对给定图像进行推理。 +关于如何在标准数据集上测试现有模型,请参阅本[指南](./4_train_test.md) + +MMSegmentation 为用户提供了数个接口,以便轻松使用预训练的模型进行推理。 + +- [教程3:使用预训练模型推理](#教程3使用预训练模型推理) + - [推理器](#推理器) + - [基本使用](#基本使用) + - [初始化](#初始化) + - [可视化预测结果](#可视化预测结果) + - [模型列表](#模型列表) + - [推理 API](#推理-api) + - [mmseg.apis.init_model](#mmsegapisinit_model) + - [mmseg.apis.inference_model](#mmsegapisinference_model) + - [mmseg.apis.show_result_pyplot](#mmsegapisshow_result_pyplot) + +## 推理器 + +在 MMSegmentation 中,我们提供了最**方便的**方式 `MMSegInferencer` 来使用模型。您只需 3 行代码就可以获得图像的分割掩膜。 + +### 基本使用 + +以下示例展示了如何使用 `MMSegInferencer` 对单个图像执行推理。 + +``` +>>> from mmseg.apis import MMSegInferencer +>>> # 将模型加载到内存中 +>>> inferencer = MMSegInferencer(model='deeplabv3plus_r18-d8_4xb2-80k_cityscapes-512x1024') +>>> # 推理 +>>> inferencer('demo/demo.png', show=True) +``` + +可视化结果应如下所示: + +
+ +
+ +此外,您可以使用 `MMSegInferencer` 来处理一个包含多张图片的 `list`: + +``` +# 输入一个图片 list +>>> images = [image1, image2, ...] # image1 可以是文件路径或 np.ndarray +>>> inferencer(images, show=True, wait_time=0.5) # wait_time 是延迟时间,0 表示无限 + +# 或输入图像目录 +>>> images = $IMAGESDIR +>>> inferencer(images, show=True, wait_time=0.5) + +# 保存可视化渲染彩色分割图和预测结果 +# out_dir 是保存输出结果的目录,img_out_dir 和 pred_out_dir 为 out_dir 的子目录 +# 以保存可视化渲染彩色分割图和预测结果 +>>> inferencer(images, out_dir='outputs', img_out_dir='vis', pred_out_dir='pred') +``` + +推理器有一个可选参数 `return_datasamples`,其默认值为 False,推理器的返回值默认为 `dict` 类型,包括 'visualization' 和 'predictions' 两个 key。 +如果 `return_datasamples=True` 推理器将返回 [`SegDataSample`](../advanced_guides/structures.md) 或其列表。 + +``` +result = inferencer('demo/demo.png') +# 结果是一个包含 'visualization' 和 'predictions' 两个 key 的 `dict` +# 'visualization' 包含彩色分割图 +print(result['visualization'].shape) +# (512, 683, 3) + +# 'predictions' 包含带有标签索引的分割掩膜 +print(result['predictions'].shape) +# (512, 683) + +result = inferencer('demo/demo.png', return_datasamples=True) +print(type(result)) +# + +# 输入一个图片 list +results = inferencer(images) +# 输出为列表 +print(type(results['visualization']), results['visualization'][0].shape) +# (512, 683, 3) +print(type(results['predictions']), results['predictions'][0].shape) +# (512, 683) + +results = inferencer(images, return_datasamples=True) +# +print(type(results[0])) +# +``` + +### 初始化 + +`MMSegInferencer` 必须使用 `model` 初始化,该 `model` 可以是模型名称或一个 `Config`,甚至可以是配置文件的路径。 +模型名称可以在模型的元文件(configs/xxx/metafile.yaml)中找到,比如 maskformer 的一个模型名称是 `maskformer_r50-d32_8xb2-160k_ade20k-512x512`,如果输入模型名称,模型的权重将自动下载。以下是其他输入参数: + +- weights(str,可选)- 权重的路径。如果未指定,并且模型是元文件中的模型名称,则权重将从元文件加载。默认为 None。 +- classes(list,可选)- 输入类别用于结果渲染,由于分割模型的预测结构是标签索引的分割图,`classes` 是一个相应的标签索引的类别列表。若 classes 没有定义,可视化工具将默认使用 `cityscapes` 的类别。默认为 None。 +- palette(list,可选)- 输入调色盘用于结果渲染,它是对应分类的配色列表。若 palette 没有定义,可视化工具将默认使用 `cityscapes` 的调色盘。默认为 None。 +- dataset_name(str,可选)- [数据集名称或别名](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/utils/class_names.py#L302-L317),可视化工具将使用数据集的元信息,如类别和配色,但 `classes` 和 `palette` 具有更高的优先级。默认为 None。 +- device(str,可选)- 运行推理的设备。如果无,则会自动使用可用的设备。默认为 None。 +- scope(str,可选)- 模型的作用域。默认为 'mmseg'。 + +### 可视化预测结果 + +`MMSegInferencer` 有4个用于可视化预测的参数,您可以在初始化推理器时使用它们: + +- show(bool)- 是否弹出窗口显示图像。默认为 False。 +- wait_time(float)- 显示的间隔。默认值为 0。 +- img_out_dir(str)- `out_dir` 的子目录,用于保存渲染有色分割掩膜,因此如果要保存预测掩膜,则必须定义 `out_dir`。默认为 `vis`。 +- opacity(int,float)- 分割掩膜的透明度。默认值为 0.8。 + +这些参数的示例请参考[基本使用](#基本使用) + +### 模型列表 + +在 MMSegmentation 中有一个非常容易列出所有模型名称的方法 + +``` +>>> from mmseg.apis import MMSegInferencer +# models 是一个模型名称列表,它们将自动打印 +>>> models = MMSegInferencer.list_models('mmseg') +``` + +## 推理 API + +### mmseg.apis.init_model + +从配置文件初始化一个分割器。 + +参数: + +- config(str,`Path` 或 `mmengine.Config`)- 配置文件路径或配置对象。 +- checkpoint(str,可选)- 权重路径。如果为 None,则模型将不会加载任何权重。 +- device(str,可选)- CPU/CUDA 设备选项。默认为 'cuda:0'。 +- cfg_options(dict,可选)- 用于覆盖所用配置中的某些设置的选项。 + +返回值: + +- nn.Module:构建好的分割器。 + +示例: + +```python +from mmseg.apis import init_model + +config_path = 'configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py' +checkpoint_path = 'checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth' + +# 初始化不带权重的模型 +model = init_model(config_path) + +# 初始化模型并加载权重 +model = init_model(config_path, checkpoint_path) + +# 在 CPU 上的初始化模型并加载权重 +model = init_model(config_path, checkpoint_path, 'cpu') +``` + +### mmseg.apis.inference_model + +使用分割器推理图像。 + +参数: + +- model(nn.Module)- 加载的分割器 +- imgs(str,np.ndarray 或 list\[str/np.ndarray\])- 图像文件或加载的图像 + +返回值: + +- `SegDataSample` 或 list\[`SegDataSample`\]:如果 imgs 是列表或元组,则返回相同长度的列表类型结果,否则直接返回分割结果。 + +**注意:** [SegDataSample](https://github.com/open-mmlab/mmsegmentation/blob/1.x/mmseg/structures/seg_data_sample.py) 是 MMSegmentation 的数据结构接口,用作不同组件之间的接口。`SegDataSample` 实现抽象数据元素 `mmengine.structures.BaseDataElement`,请参阅 [MMEngine](https://github.com/open-mmlab/mmengine) 中的数据元素[文档](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/data_element.html)了解更多信息。 + +`SegDataSample` 中的参数分为几个部分: + +- `gt_sem_seg`(`PixelData`)- 语义分割的标注。 +- `pred_sem_seg`(`PixelData`)- 语义分割的预测。 +- `seg_logits`(`PixelData`)- 模型最后一层的输出结果。 + +**注意:** [PixelData](https://github.com/open-mmlab/mmengine/blob/main/mmengine/structures/pixel_data.py) 是像素级标注或预测的数据结构,请参阅 [MMEngine](https://github.com/open-mmlab/mmengine) 中的 PixelData [文档](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/data_element.html)了解更多信息。 + +示例: + +```python +from mmseg.apis import init_model, inference_model + +config_path = 'configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py' +checkpoint_path = 'checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth' +img_path = 'demo/demo.png' + + +model = init_model(config_path, checkpoint_path) +result = inference_model(model, img_path) +``` + +### mmseg.apis.show_result_pyplot + +在图像上可视化分割结果。 + +参数: + +- model(nn.Module)- 加载的分割器。 +- img(str 或 np.ndarray)- 图像文件名或加载的图像。 +- result(`SegDataSample`)- SegDataSample 预测结果。 +- opacity(float)- 绘制分割图的不透明度。默认值为 `0.5`,必须在 `(0,1]` 范围内。 +- title(str)- pyplot 图的标题。默认值为 ''。 +- draw_gt(bool)- 是否绘制 GT SegDataSample。默认为 `True`。 +- draw_pred(draws_pred)- 是否绘制预测 SegDataSample。默认为 `True`。 +- wait_time(float)- 显示的间隔,0 是表示“无限”的特殊值。默认为 `0`。 +- show(bool)- 是否展示绘制的图像。默认为 `True`。 +- save_dir(str,可选)- 为所有存储后端保存的文件路径。如果为 `None`,则后端存储将不会保存任何数据。 +- out_file(str,可选)- 输出文件的路径。默认为 `None`。 + +返回值: + +- np.ndarray:通道为 RGB 的绘制图像。 + +示例: + +```python +from mmseg.apis import init_model, inference_model, show_result_pyplot + +config_path = 'configs/pspnet/pspnet_r50-d8_4xb2-40k_cityscapes-512x1024.py' +checkpoint_path = 'checkpoints/pspnet_r50-d8_512x1024_40k_cityscapes_20200605_003338-2966598c.pth' +img_path = 'demo/demo.png' + + +# 从配置文件和权重文件构建模型 +model = init_model(config_path, checkpoint_path, device='cuda:0') + +# 推理给定图像 +result = inference_model(model, img_path) + +# 展示分割结果 +vis_image = show_result_pyplot(model, img_path, result) + +# 保存可视化结果,输出图像将在 `workdirs/result.png` 路径下找到 +vis_iamge = show_result_pyplot(model, img_path, result, out_file='work_dirs/result.png') + +# 修改展示图像的时间,注意 0 是表示“无限”的特殊值 +vis_image = show_result_pyplot(model, img_path, result, wait_time=5) +``` + +**注意:** 如果当前设备没有图形用户界面,建议将 `show` 设置为 `False`,并指定 `out_file` 或 `save_dir` 来保存结果。如果您想在窗口上显示结果,则不需要特殊设置。 diff --git a/docs/zh_cn/user_guides/5_deployment.md b/docs/zh_cn/user_guides/5_deployment.md new file mode 100644 index 00000000000..b2bec028833 --- /dev/null +++ b/docs/zh_cn/user_guides/5_deployment.md @@ -0,0 +1,243 @@ +# 教程5:模型部署 + +# MMSegmentation 模型部署 + +- [教程5:模型部署](#教程5模型部署) +- [MMSegmentation 模型部署](#mmsegmentation-模型部署) + - [安装](#安装) + - [安装 mmseg](#安装-mmseg) + - [安装 mmdeploy](#安装-mmdeploy) + - [模型转换](#模型转换) + - [模型规范](#模型规范) + - [模型推理](#模型推理) + - [后端模型推理](#后端模型推理) + - [SDK 模型推理](#sdk-模型推理) + - [模型支持列表](#模型支持列表) + - [注意事项](#注意事项) + +______________________________________________________________________ + +[MMSegmentation](https://github.com/open-mmlab/mmsegmentation/tree/main) 又称`mmseg`,是一个基于 PyTorch 的开源对象分割工具箱。它是 [OpenMMLab](https://openmmlab.com/) 项目的一部分。 + +## 安装 + +### 安装 mmseg + +请参考[官网安装指南](https://mmsegmentation.readthedocs.io/en/latest/get_started.html)。 + +### 安装 mmdeploy + +mmdeploy 有以下几种安装方式: + +**方式一:** 安装预编译包 + +请参考[安装概述](https://mmdeploy.readthedocs.io/zh_CN/latest/get_started.html#mmdeploy) + +**方式二:** 一键式脚本安装 + +如果部署平台是 **Ubuntu 18.04 及以上版本**, 请参考[脚本安装说明](../01-how-to-build/build_from_script.md),完成安装过程。 +比如,以下命令可以安装 mmdeploy 以及配套的推理引擎——`ONNX Runtime`. + +```shell +git clone --recursive -b main https://github.com/open-mmlab/mmdeploy.git +cd mmdeploy +python3 tools/scripts/build_ubuntu_x64_ort.py $(nproc) +export PYTHONPATH=$(pwd)/build/lib:$PYTHONPATH +export LD_LIBRARY_PATH=$(pwd)/../mmdeploy-dep/onnxruntime-linux-x64-1.8.1/lib/:$LD_LIBRARY_PATH +``` + +**说明**: + +- 把 `$(pwd)/build/lib` 添加到 `PYTHONPATH`,目的是为了加载 mmdeploy SDK python 包 `mmdeploy_runtime`,在章节 [SDK模型推理](#sdk模型推理)中讲述其用法。 +- 在[使用 ONNX Runtime推理后端模型](#后端模型推理)时,需要加载自定义算子库,需要把 ONNX Runtime 库的路径加入环境变量 `LD_LIBRARY_PATH`中。 + +**方式三:** 源码安装 + +在方式一、二都满足不了的情况下,请参考[源码安装说明](../01-how-to-build/build_from_source.md) 安装 mmdeploy 以及所需推理引擎。 + +## 模型转换 + +你可以使用 [tools/deploy.py](https://github.com/open-mmlab/mmdeploy/tree/main/tools/deploy.py) 把 mmseg 模型一键式转换为推理后端模型。 +该工具的详细使用说明请参考[这里](https://github.com/open-mmlab/mmdeploy/tree/main/docs/en/02-how-to-run/convert_model.md#usage). + +以下,我们将演示如何把 `unet` 转换为 onnx 模型。 + +```shell +cd mmdeploy + +# download unet model from mmseg model zoo +mim download mmsegmentation --config unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024 --dest . + +# convert mmseg model to onnxruntime model with dynamic shape +python tools/deploy.py \ + configs/mmseg/segmentation_onnxruntime_dynamic.py \ + unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py \ + fcn_unet_s5-d16_4x4_512x1024_160k_cityscapes_20211210_145204-6860854e.pth \ + demo/resources/cityscapes.png \ + --work-dir mmdeploy_models/mmseg/ort \ + --device cpu \ + --show \ + --dump-info +``` + +转换的关键之一是使用正确的配置文件。项目中已内置了各后端部署[配置文件](https://github.com/open-mmlab/mmdeploy/tree/main/configs/mmseg)。 +文件的命名模式是: + +``` +segmentation_{backend}-{precision}_{static | dynamic}_{shape}.py +``` + +其中: + +- **{backend}:** 推理后端名称。比如,onnxruntime、tensorrt、pplnn、ncnn、openvino、coreml 等等 +- **{precision}:** 推理精度。比如,fp16、int8。不填表示 fp32 +- **{static | dynamic}:** 动态、静态 shape +- **{shape}:** 模型输入的 shape 或者 shape 范围 + +在上例中,你也可以把 `unet` 转为其他后端模型。比如使用`segmentation_tensorrt-fp16_dynamic-512x1024-2048x2048.py`,把模型转为 tensorrt-fp16 模型。 + +```{tip} +当转 tensorrt 模型时, --device 需要被设置为 "cuda" +``` + +## 模型规范 + +在使用转换后的模型进行推理之前,有必要了解转换结果的结构。 它存放在 `--work-dir` 指定的路路径下。 + +上例中的`mmdeploy_models/mmseg/ort`,结构如下: + +``` +mmdeploy_models/mmseg/ort +├── deploy.json +├── detail.json +├── end2end.onnx +└── pipeline.json +``` + +重要的是: + +- **end2end.onnx**: 推理引擎文件。可用 ONNX Runtime 推理 +- \***.json**: mmdeploy SDK 推理所需的 meta 信息 + +整个文件夹被定义为**mmdeploy SDK model**。换言之,**mmdeploy SDK model**既包括推理引擎,也包括推理 meta 信息。 + +## 模型推理 + +### 后端模型推理 + +以上述模型转换后的 `end2end.onnx` 为例,你可以使用如下代码进行推理: + +```python +from mmdeploy.apis.utils import build_task_processor +from mmdeploy.utils import get_input_shape, load_config +import torch + +deploy_cfg = 'configs/mmseg/segmentation_onnxruntime_dynamic.py' +model_cfg = './unet-s5-d16_fcn_4xb4-160k_cityscapes-512x1024.py' +device = 'cpu' +backend_model = ['./mmdeploy_models/mmseg/ort/end2end.onnx'] +image = './demo/resources/cityscapes.png' + +# read deploy_cfg and model_cfg +deploy_cfg, model_cfg = load_config(deploy_cfg, model_cfg) + +# build task and backend model +task_processor = build_task_processor(model_cfg, deploy_cfg, device) +model = task_processor.build_backend_model(backend_model) + +# process input image +input_shape = get_input_shape(deploy_cfg) +model_inputs, _ = task_processor.create_input(image, input_shape) + +# do model inference +with torch.no_grad(): + result = model.test_step(model_inputs) + +# visualize results +task_processor.visualize( + image=image, + model=model, + result=result[0], + window_name='visualize', + output_file='./output_segmentation.png') +``` + +### SDK 模型推理 + +你也可以参考如下代码,对 SDK model 进行推理: + +```python +from mmdeploy_runtime import Segmentor +import cv2 +import numpy as np + +img = cv2.imread('./demo/resources/cityscapes.png') + +# create a classifier +segmentor = Segmentor(model_path='./mmdeploy_models/mmseg/ort', device_name='cpu', device_id=0) +# perform inference +seg = segmentor(img) + +# visualize inference result +## random a palette with size 256x3 +palette = np.random.randint(0, 256, size=(256, 3)) +color_seg = np.zeros((seg.shape[0], seg.shape[1], 3), dtype=np.uint8) +for label, color in enumerate(palette): + color_seg[seg == label, :] = color +# convert to BGR +color_seg = color_seg[..., ::-1] +img = img * 0.5 + color_seg * 0.5 +img = img.astype(np.uint8) +cv2.imwrite('output_segmentation.png', img) +``` + +除了python API,mmdeploy SDK 还提供了诸如 C、C++、C#、Java等多语言接口。 +你可以参考[样例](https://github.com/open-mmlab/mmdeploy/tree/main/demo)学习其他语言接口的使用方法。 + +## 模型支持列表 + +| Model | TorchScript | OnnxRuntime | TensorRT | ncnn | PPLNN | OpenVino | +| :-------------------------------------------------------------------------------------------------------- | :---------: | :---------: | :------: | :--: | :---: | :------: | +| [FCN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fcn) | Y | Y | Y | Y | Y | Y | +| [PSPNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/pspnet)[\*](#static_shape) | Y | Y | Y | Y | Y | Y | +| [DeepLabV3](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/deeplabv3) | Y | Y | Y | Y | Y | Y | +| [DeepLabV3+](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/deeplabv3plus) | Y | Y | Y | Y | Y | Y | +| [Fast-SCNN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fastscnn)[\*](#static_shape) | Y | Y | Y | N | Y | Y | +| [UNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/unet) | Y | Y | Y | Y | Y | Y | +| [ANN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ann)[\*](#static_shape) | Y | Y | Y | N | N | N | +| [APCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/apcnet) | Y | Y | Y | Y | N | N | +| [BiSeNetV1](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/bisenetv1) | Y | Y | Y | Y | N | Y | +| [BiSeNetV2](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/bisenetv2) | Y | Y | Y | Y | N | Y | +| [CGNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/cgnet) | Y | Y | Y | Y | N | Y | +| [DMNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dmnet) | ? | Y | N | N | N | N | +| [DNLNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dnlnet) | ? | Y | Y | Y | N | Y | +| [EMANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/emanet) | Y | Y | Y | N | N | Y | +| [EncNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/encnet) | Y | Y | Y | N | N | Y | +| [ERFNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/erfnet) | Y | Y | Y | Y | N | Y | +| [FastFCN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fastfcn) | Y | Y | Y | Y | N | Y | +| [GCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/gcnet) | Y | Y | Y | N | N | N | +| [ICNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/icnet)[\*](#static_shape) | Y | Y | Y | N | N | Y | +| [ISANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/isanet)[\*](#static_shape) | N | Y | Y | N | N | Y | +| [NonLocal Net](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/nonlocal_net) | ? | Y | Y | Y | N | Y | +| [OCRNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ocrnet) | Y | Y | Y | Y | N | Y | +| [PointRend](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/point_rend)[\*](#static_shape) | Y | Y | Y | N | N | N | +| [Semantic FPN](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/sem_fpn) | Y | Y | Y | Y | N | Y | +| [STDC](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/stdc) | Y | Y | Y | Y | N | Y | +| [UPerNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/upernet)[\*](#static_shape) | N | Y | Y | N | N | N | +| [DANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/danet) | ? | Y | Y | N | N | Y | +| [Segmenter](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/segmenter)[\*](#static_shape) | N | Y | Y | Y | N | Y | +| [SegFormer](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/segformer)[\*](#static_shape) | ? | Y | Y | N | N | Y | +| [SETR](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/setr) | ? | Y | N | N | N | Y | +| [CCNet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/ccnet) | ? | N | N | N | N | N | +| [PSANet](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/psanet) | ? | N | N | N | N | N | +| [DPT](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/dpt) | ? | N | N | N | N | N | + +## 注意事项 + +- 所有 mmseg 模型仅支持 "whole" 推理模式。 + +- PSPNet,Fast-SCNN 仅支持静态输入,因为多数推理框架的 [nn.AdaptiveAvgPool2d](https://github.com/open-mmlab/mmsegmentation/blob/0c87f7a0c9099844eff8e90fa3db5b0d0ca02fee/mmseg/models/decode_heads/psp_head.py#L38) 不支持动态输入。 + +- 对于仅支持静态形状的模型,应使用静态形状的部署配置文件,例如 `configs/mmseg/segmentation_tensorrt_static-1024x2048.py` + +- 对于喜欢部署模型生成概率特征图的用户,将 `codebase_config = dict(with_argmax=False)` 放在部署配置中就足够了。 diff --git a/docs/zh_cn/user_guides/deployment.md b/docs/zh_cn/user_guides/deployment.md deleted file mode 100644 index f98110c8b5f..00000000000 --- a/docs/zh_cn/user_guides/deployment.md +++ /dev/null @@ -1 +0,0 @@ -# 模型部署 diff --git a/mmseg/apis/__init__.py b/mmseg/apis/__init__.py index d22dc3f0ada..b50a266319c 100644 --- a/mmseg/apis/__init__.py +++ b/mmseg/apis/__init__.py @@ -1,7 +1,9 @@ # Copyright (c) OpenMMLab. All rights reserved. from .inference import inference_model, init_model, show_result_pyplot from .mmseg_inferencer import MMSegInferencer +from .remote_sense_inferencer import RSImage, RSInferencer __all__ = [ - 'init_model', 'inference_model', 'show_result_pyplot', 'MMSegInferencer' + 'init_model', 'inference_model', 'show_result_pyplot', 'MMSegInferencer', + 'RSInferencer', 'RSImage' ] diff --git a/mmseg/apis/inference.py b/mmseg/apis/inference.py index 4aadffc7982..0dd70cd6155 100644 --- a/mmseg/apis/inference.py +++ b/mmseg/apis/inference.py @@ -1,14 +1,12 @@ # Copyright (c) OpenMMLab. All rights reserved. import warnings -from collections import defaultdict from pathlib import Path -from typing import Optional, Sequence, Union +from typing import Optional, Union import mmcv import numpy as np import torch from mmengine import Config -from mmengine.dataset import Compose from mmengine.registry import init_default_scope from mmengine.runner import load_checkpoint from mmengine.utils import mkdir_or_exist @@ -18,6 +16,7 @@ from mmseg.structures import SegDataSample from mmseg.utils import SampleList, dataset_aliases, get_classes, get_palette from mmseg.visualization import SegLocalVisualizer +from .utils import ImageType, _preprare_data def init_model(config: Union[str, Path, Config], @@ -90,41 +89,6 @@ def init_model(config: Union[str, Path, Config], return model -ImageType = Union[str, np.ndarray, Sequence[str], Sequence[np.ndarray]] - - -def _preprare_data(imgs: ImageType, model: BaseSegmentor): - - cfg = model.cfg - for t in cfg.test_pipeline: - if t.get('type') == 'LoadAnnotations': - cfg.test_pipeline.remove(t) - - is_batch = True - if not isinstance(imgs, (list, tuple)): - imgs = [imgs] - is_batch = False - - if isinstance(imgs[0], np.ndarray): - cfg.test_pipeline[0]['type'] = 'LoadImageFromNDArray' - - # TODO: Consider using the singleton pattern to avoid building - # a pipeline for each inference - pipeline = Compose(cfg.test_pipeline) - - data = defaultdict(list) - for img in imgs: - if isinstance(img, np.ndarray): - data_ = dict(img=img) - else: - data_ = dict(img_path=img) - data_ = pipeline(data_) - data['inputs'].append(data_['inputs']) - data['data_samples'].append(data_['data_samples']) - - return data, is_batch - - def inference_model(model: BaseSegmentor, img: ImageType) -> Union[SegDataSample, SampleList]: """Inference image(s) with the segmentor. @@ -158,6 +122,7 @@ def show_result_pyplot(model: BaseSegmentor, draw_pred: bool = True, wait_time: float = 0, show: bool = True, + withLabels: Optional[bool] = True, save_dir=None, out_file=None): """Visualize the segmentation results on the image. @@ -177,17 +142,21 @@ def show_result_pyplot(model: BaseSegmentor, that means "forever". Defaults to 0. show (bool): Whether to display the drawn image. Default to True. + withLabels(bool, optional): Add semantic labels in visualization + result, Default to True. save_dir (str, optional): Save file dir for all storage backends. If it is None, the backend storage will not save any data. out_file (str, optional): Path to output file. Default to None. + + Returns: np.ndarray: the drawn image which channel is RGB. """ if hasattr(model, 'module'): model = model.module if isinstance(img, str): - image = mmcv.imread(img) + image = mmcv.imread(img, channel_order='rgb') else: image = img if save_dir is not None: @@ -208,7 +177,8 @@ def show_result_pyplot(model: BaseSegmentor, draw_pred=draw_pred, wait_time=wait_time, out_file=out_file, - show=show) + show=show, + withLabels=withLabels) vis_img = visualizer.get_image() return vis_img diff --git a/mmseg/apis/mmseg_inferencer.py b/mmseg/apis/mmseg_inferencer.py index cb387b10b3f..095639a80fd 100644 --- a/mmseg/apis/mmseg_inferencer.py +++ b/mmseg/apis/mmseg_inferencer.py @@ -30,7 +30,7 @@ class MMSegInferencer(BaseInferencer): Args: model (str, optional): Path to the config file or the model name - defined in metafile. Take the `mmseg metafile `_ + defined in metafile. Take the `mmseg metafile `_ as an example the `model` could be "fcn_r50-d8_4xb2-40k_cityscapes-512x1024", and the weights of model will be download automatically. If use config file, like @@ -48,7 +48,7 @@ class MMSegInferencer(BaseInferencer): a list of color palette responding to the classes. If palette is not defined, visualizer will take `cityscapes` palette by default. Defaults to None. - dataset_name (str, optional): `Dataset name or alias `_ + dataset_name (str, optional): `Dataset name or alias `_ visulizer will use the meta information of the dataset i.e. classes and palette, but the `classes` and `palette` have higher priority. Defaults to None. @@ -59,7 +59,9 @@ class MMSegInferencer(BaseInferencer): preprocess_kwargs: set = set() forward_kwargs: set = {'mode', 'out_dir'} - visualize_kwargs: set = {'show', 'wait_time', 'img_out_dir', 'opacity'} + visualize_kwargs: set = { + 'show', 'wait_time', 'img_out_dir', 'opacity', 'return_vis' + } postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'} def __init__(self, @@ -82,7 +84,7 @@ def __init__(self, self.model = revert_sync_batchnorm(self.model) assert isinstance(self.visualizer, SegLocalVisualizer) - self.visualizer.set_dataset_meta(palette, classes, dataset_name) + self.visualizer.set_dataset_meta(classes, palette, dataset_name) def _load_weights_to_model(self, model: nn.Module, checkpoint: Optional[dict], @@ -137,6 +139,7 @@ def __call__(self, inputs: InputsType, return_datasamples: bool = False, batch_size: int = 1, + return_vis: bool = False, show: bool = False, wait_time: int = 0, out_dir: str = '', @@ -188,11 +191,13 @@ def __call__(self, wait_time=wait_time, img_out_dir=img_out_dir, pred_out_dir=pred_out_dir, + return_vis=return_vis, **kwargs) def visualize(self, inputs: list, preds: List[dict], + return_vis: bool = False, show: bool = False, wait_time: int = 0, img_out_dir: str = '', @@ -213,12 +218,12 @@ def visualize(self, Returns: List[np.ndarray]: Visualization results. """ - if self.visualizer is None or (not show and img_out_dir == ''): + if not show and img_out_dir == '' and not return_vis: return None - - if getattr(self, 'visualizer') is None: + if self.visualizer is None: raise ValueError('Visualization needs the "visualizer" term' - 'defined in the config, but got None') + 'defined in the config, but got None.') + self.visualizer.set_dataset_meta(**self.model.dataset_meta) self.visualizer.alpha = opacity @@ -250,10 +255,11 @@ def visualize(self, draw_gt=False, draw_pred=True, out_file=out_file) - results.append(self.visualizer.get_image()) + if return_vis: + results.append(self.visualizer.get_image()) self.num_visualized_imgs += 1 - return results + return results if return_vis else None def postprocess(self, preds: PredType, @@ -300,17 +306,28 @@ def postprocess(self, results_dict['visualization'] = [] for i, pred in enumerate(preds): - pred_data = pred.pred_sem_seg.numpy().data[0] - results_dict['predictions'].append(pred_data) + pred_data = dict() + if 'pred_sem_seg' in pred.keys(): + pred_data['sem_seg'] = pred.pred_sem_seg.numpy().data[0] + elif 'pred_depth_map' in pred.keys(): + pred_data['depth_map'] = pred.pred_depth_map.numpy().data[0] + if visualization is not None: vis = visualization[i] results_dict['visualization'].append(vis) if pred_out_dir != '': mmengine.mkdir_or_exist(pred_out_dir) - img_name = str(self.num_pred_imgs).zfill(8) + '_pred.png' - img_path = osp.join(pred_out_dir, img_name) - output = Image.fromarray(pred_data.astype(np.uint8)) - output.save(img_path) + for key, data in pred_data.items(): + post_fix = '_pred.png' if key == 'sem_seg' else '_pred.npy' + img_name = str(self.num_pred_imgs).zfill(8) + post_fix + img_path = osp.join(pred_out_dir, img_name) + if key == 'sem_seg': + output = Image.fromarray(data.astype(np.uint8)) + output.save(img_path) + else: + np.save(img_path, data) + pred_data = next(iter(pred_data.values())) + results_dict['predictions'].append(pred_data) self.num_pred_imgs += 1 if len(results_dict['predictions']) == 1: @@ -338,12 +355,13 @@ def preprocess(self, inputs, batch_size, **kwargs): """ pipeline_cfg = cfg.test_dataloader.dataset.pipeline # Loading annotations is also not applicable - idx = self._get_transform_idx(pipeline_cfg, 'LoadAnnotations') - if idx != -1: - del pipeline_cfg[idx] + for transform in ('LoadAnnotations', 'LoadDepthAnnotation'): + idx = self._get_transform_idx(pipeline_cfg, transform) + if idx != -1: + del pipeline_cfg[idx] + load_img_idx = self._get_transform_idx(pipeline_cfg, 'LoadImageFromFile') - if load_img_idx == -1: raise ValueError( 'LoadImageFromFile is not found in the test pipeline') diff --git a/mmseg/apis/remote_sense_inferencer.py b/mmseg/apis/remote_sense_inferencer.py new file mode 100644 index 00000000000..6726c6ae346 --- /dev/null +++ b/mmseg/apis/remote_sense_inferencer.py @@ -0,0 +1,279 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import threading +from queue import Queue +from typing import List, Optional, Tuple + +import numpy as np +import torch +from mmengine import Config +from mmengine.model import BaseModel +from mmengine.registry import init_default_scope +from mmengine.runner import load_checkpoint + +try: + from osgeo import gdal +except ImportError: + gdal = None + +from mmseg.registry import MODELS +from .utils import _preprare_data + + +class RSImage: + """Remote sensing image class. + + Args: + img (str or gdal.Dataset): Image file path or gdal.Dataset. + """ + + def __init__(self, image): + self.dataset = gdal.Open(image, gdal.GA_ReadOnly) if isinstance( + image, str) else image + assert isinstance(self.dataset, gdal.Dataset), \ + f'{image} is not a image' + self.width = self.dataset.RasterXSize + self.height = self.dataset.RasterYSize + self.channel = self.dataset.RasterCount + self.trans = self.dataset.GetGeoTransform() + self.proj = self.dataset.GetProjection() + self.band_list = [] + self.band_list.extend( + self.dataset.GetRasterBand(c + 1) for c in range(self.channel)) + self.grids = [] + + def read(self, grid: Optional[List] = None) -> np.ndarray: + """Read image data. If grid is None, read the whole image. + + Args: + grid (Optional[List], optional): Grid to read. Defaults to None. + Returns: + np.ndarray: Image data. + """ + if grid is None: + return np.einsum('ijk->jki', self.dataset.ReadAsArray()) + assert len( + grid) >= 4, 'grid must be a list containing at least 4 elements' + data = self.dataset.ReadAsArray(*grid[:4]) + if data.ndim == 2: + data = data[np.newaxis, ...] + return np.einsum('ijk->jki', data) + + def write(self, data: Optional[np.ndarray], grid: Optional[List] = None): + """Write image data. + + Args: + grid (Optional[List], optional): Grid to write. Defaults to None. + data (Optional[np.ndarray], optional): Data to write. + Defaults to None. + + Raises: + ValueError: Either grid or data must be provided. + """ + if grid is not None: + assert len(grid) == 8, 'grid must be a list of 8 elements' + for band in self.band_list: + band.WriteArray( + data[grid[5]:grid[5] + grid[7], grid[4]:grid[4] + grid[6]], + grid[0] + grid[4], grid[1] + grid[5]) + elif data is not None: + for i in range(self.channel): + self.band_list[i].WriteArray(data[..., i]) + else: + raise ValueError('Either grid or data must be provided.') + + def create_seg_map(self, output_path: Optional[str] = None): + if output_path is None: + output_path = 'output_label.tif' + driver = gdal.GetDriverByName('GTiff') + seg_map = driver.Create(output_path, self.width, self.height, 1, + gdal.GDT_Byte) + seg_map.SetGeoTransform(self.trans) + seg_map.SetProjection(self.proj) + seg_map_img = RSImage(seg_map) + seg_map_img.path = output_path + return seg_map_img + + def create_grids(self, + window_size: Tuple[int, int], + stride: Tuple[int, int] = (0, 0)): + """Create grids for image inference. + + Args: + window_size (Tuple[int, int]): the size of the sliding window. + stride (Tuple[int, int], optional): the stride of the sliding + window. Defaults to (0, 0). + + Raises: + AssertionError: window_size must be a tuple of 2 elements. + AssertionError: stride must be a tuple of 2 elements. + """ + assert len( + window_size) == 2, 'window_size must be a tuple of 2 elements' + assert len(stride) == 2, 'stride must be a tuple of 2 elements' + win_w, win_h = window_size + stride_x, stride_y = stride + + stride_x = win_w if stride_x == 0 else stride_x + stride_y = win_h if stride_y == 0 else stride_y + + x_half_overlap = (win_w - stride_x + 1) // 2 + y_half_overlap = (win_h - stride_y + 1) // 2 + + for y in range(0, self.height, stride_y): + y_end = y + win_h >= self.height + y_offset = self.height - win_h if y_end else y + y_size = win_h + y_crop_off = 0 if y_offset == 0 else y_half_overlap + y_crop_size = y_size if y_end else win_h - y_crop_off + + for x in range(0, self.width, stride_x): + x_end = x + win_w >= self.width + x_offset = self.width - win_w if x_end else x + x_size = win_w + x_crop_off = 0 if x_offset == 0 else x_half_overlap + x_crop_size = x_size if x_end else win_w - x_crop_off + + self.grids.append([ + x_offset, y_offset, x_size, y_size, x_crop_off, y_crop_off, + x_crop_size, y_crop_size + ]) + + +class RSInferencer: + """Remote sensing inference class. + + Args: + model (BaseModel): The loaded model. + batch_size (int, optional): Batch size. Defaults to 1. + thread (int, optional): Number of threads. Defaults to 1. + """ + + def __init__(self, model: BaseModel, batch_size: int = 1, thread: int = 1): + self.model = model + self.batch_size = batch_size + self.END_FLAG = object() + self.read_buffer = Queue(self.batch_size) + self.write_buffer = Queue(self.batch_size) + self.thread = thread + + @classmethod + def from_config_path(cls, + config_path: str, + checkpoint_path: str, + batch_size: int = 1, + thread: int = 1, + device: Optional[str] = 'cpu'): + """Initialize a segmentor from config file. + + Args: + config_path (str): Config file path. + checkpoint_path (str): Checkpoint path. + batch_size (int, optional): Batch size. Defaults to 1. + """ + init_default_scope('mmseg') + cfg = Config.fromfile(config_path) + model = MODELS.build(cfg.model) + model.cfg = cfg + load_checkpoint(model, checkpoint_path, map_location='cpu') + model.to(device) + model.eval() + return cls(model, batch_size, thread) + + @classmethod + def from_model(cls, + model: BaseModel, + checkpoint_path: Optional[str] = None, + batch_size: int = 1, + thread: int = 1, + device: Optional[str] = 'cpu'): + """Initialize a segmentor from model. + + Args: + model (BaseModel): The loaded model. + checkpoint_path (Optional[str]): Checkpoint path. + batch_size (int, optional): Batch size. Defaults to 1. + """ + if checkpoint_path is not None: + load_checkpoint(model, checkpoint_path, map_location='cpu') + model.to(device) + return cls(model, batch_size, thread) + + def read(self, + image: RSImage, + window_size: Tuple[int, int], + strides: Tuple[int, int] = (0, 0)): + """Load image data to read buffer. + + Args: + image (RSImage): The image to read. + window_size (Tuple[int, int]): The size of the sliding window. + strides (Tuple[int, int], optional): The stride of the sliding + window. Defaults to (0, 0). + """ + image.create_grids(window_size, strides) + for grid in image.grids: + self.read_buffer.put([grid, image.read(grid=grid)]) + self.read_buffer.put(self.END_FLAG) + + def inference(self): + """Inference image data from read buffer and put the result to write + buffer.""" + while True: + item = self.read_buffer.get() + if item == self.END_FLAG: + self.read_buffer.put(self.END_FLAG) + self.write_buffer.put(item) + break + data, _ = _preprare_data(item[1], self.model) + with torch.no_grad(): + result = self.model.test_step(data) + item[1] = result[0].pred_sem_seg.cpu().data.numpy()[0] + self.write_buffer.put(item) + self.read_buffer.task_done() + + def write(self, image: RSImage, output_path: Optional[str] = None): + """Write image data from write buffer. + + Args: + image (RSImage): The image to write. + output_path (Optional[str], optional): The path to save the + segmentation map. Defaults to None. + """ + seg_map = image.create_seg_map(output_path) + while True: + item = self.write_buffer.get() + if item == self.END_FLAG: + break + seg_map.write(data=item[1], grid=item[0]) + self.write_buffer.task_done() + + def run(self, + image: RSImage, + window_size: Tuple[int, int], + strides: Tuple[int, int] = (0, 0), + output_path: Optional[str] = None): + """Run inference with multi-threading. + + Args: + image (RSImage): The image to inference. + window_size (Tuple[int, int]): The size of the sliding window. + strides (Tuple[int, int], optional): The stride of the sliding + window. Defaults to (0, 0). + output_path (Optional[str], optional): The path to save the + segmentation map. Defaults to None. + """ + read_thread = threading.Thread( + target=self.read, args=(image, window_size, strides)) + read_thread.start() + inference_threads = [] + for _ in range(self.thread): + inference_thread = threading.Thread(target=self.inference) + inference_thread.start() + inference_threads.append(inference_thread) + write_thread = threading.Thread( + target=self.write, args=(image, output_path)) + write_thread.start() + read_thread.join() + for inference_thread in inference_threads: + inference_thread.join() + write_thread.join() diff --git a/mmseg/apis/utils.py b/mmseg/apis/utils.py new file mode 100644 index 00000000000..4cf87756602 --- /dev/null +++ b/mmseg/apis/utils.py @@ -0,0 +1,41 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections import defaultdict +from typing import Sequence, Union + +import numpy as np +from mmengine.dataset import Compose +from mmengine.model import BaseModel + +ImageType = Union[str, np.ndarray, Sequence[str], Sequence[np.ndarray]] + + +def _preprare_data(imgs: ImageType, model: BaseModel): + + cfg = model.cfg + for t in cfg.test_pipeline: + if t.get('type') == 'LoadAnnotations': + cfg.test_pipeline.remove(t) + + is_batch = True + if not isinstance(imgs, (list, tuple)): + imgs = [imgs] + is_batch = False + + if isinstance(imgs[0], np.ndarray): + cfg.test_pipeline[0]['type'] = 'LoadImageFromNDArray' + + # TODO: Consider using the singleton pattern to avoid building + # a pipeline for each inference + pipeline = Compose(cfg.test_pipeline) + + data = defaultdict(list) + for img in imgs: + if isinstance(img, np.ndarray): + data_ = dict(img=img) + else: + data_ = dict(img_path=img) + data_ = pipeline(data_) + data['inputs'].append(data_['inputs']) + data['data_samples'].append(data_['data_samples']) + + return data, is_batch diff --git a/mmseg/datasets/__init__.py b/mmseg/datasets/__init__.py index a90d53c88e0..a2bdb63d016 100644 --- a/mmseg/datasets/__init__.py +++ b/mmseg/datasets/__init__.py @@ -1,7 +1,8 @@ # Copyright (c) OpenMMLab. All rights reserved. # yapf: disable from .ade import ADE20KDataset -from .basesegdataset import BaseSegDataset +from .basesegdataset import BaseCDDataset, BaseSegDataset +from .bdd100k import BDD100KDataset from .chase_db1 import ChaseDB1Dataset from .cityscapes import CityscapesDataset from .coco_stuff import COCOStuffDataset @@ -9,29 +10,34 @@ from .dataset_wrappers import MultiImageMixDataset from .decathlon import DecathlonDataset from .drive import DRIVEDataset +from .dsdl import DSDLSegDataset from .hrf import HRFDataset from .isaid import iSAIDDataset from .isprs import ISPRSDataset +from .levir import LEVIRCDDataset from .lip import LIPDataset from .loveda import LoveDADataset from .mapillary import MapillaryDataset_v1, MapillaryDataset_v2 from .night_driving import NightDrivingDataset +from .nyu import NYUDataset from .pascal_context import PascalContextDataset, PascalContextDataset59 from .potsdam import PotsdamDataset from .refuge import REFUGEDataset from .stare import STAREDataset from .synapse import SynapseDataset # yapf: disable -from .transforms import (CLAHE, AdjustGamma, BioMedical3DPad, +from .transforms import (CLAHE, AdjustGamma, Albu, BioMedical3DPad, BioMedical3DRandomCrop, BioMedical3DRandomFlip, BioMedicalGaussianBlur, BioMedicalGaussianNoise, - BioMedicalRandomGamma, GenerateEdge, LoadAnnotations, - LoadBiomedicalAnnotation, LoadBiomedicalData, - LoadBiomedicalImageFromFile, LoadImageFromNDArray, - PackSegInputs, PhotoMetricDistortion, RandomCrop, - RandomCutOut, RandomMosaic, RandomRotate, - RandomRotFlip, Rerange, ResizeShortestEdge, - ResizeToMultiple, RGB2Gray, SegRescale) + BioMedicalRandomGamma, ConcatCDInput, GenerateEdge, + LoadAnnotations, LoadBiomedicalAnnotation, + LoadBiomedicalData, LoadBiomedicalImageFromFile, + LoadImageFromNDArray, LoadMultipleRSImageFromFile, + LoadSingleRSImageFromFile, PackSegInputs, + PhotoMetricDistortion, RandomCrop, RandomCutOut, + RandomMosaic, RandomRotate, RandomRotFlip, Rerange, + ResizeShortestEdge, ResizeToMultiple, RGB2Gray, + SegRescale) from .voc import PascalVOCDataset # yapf: enable @@ -51,5 +57,8 @@ 'BioMedicalGaussianNoise', 'BioMedicalGaussianBlur', 'BioMedicalRandomGamma', 'BioMedical3DPad', 'RandomRotFlip', 'SynapseDataset', 'REFUGEDataset', 'MapillaryDataset_v1', - 'MapillaryDataset_v2' + 'MapillaryDataset_v2', 'Albu', 'LEVIRCDDataset', + 'LoadMultipleRSImageFromFile', 'LoadSingleRSImageFromFile', + 'ConcatCDInput', 'BaseCDDataset', 'DSDLSegDataset', 'BDD100KDataset', + 'NYUDataset' ] diff --git a/mmseg/datasets/basesegdataset.py b/mmseg/datasets/basesegdataset.py index ddf476bae94..9c4668c1f56 100644 --- a/mmseg/datasets/basesegdataset.py +++ b/mmseg/datasets/basesegdataset.py @@ -235,7 +235,9 @@ def load_data_list(self) -> List[dict]: data_list = [] img_dir = self.data_prefix.get('img_path', None) ann_dir = self.data_prefix.get('seg_map_path', None) - if osp.isfile(self.ann_file): + if not osp.isdir(self.ann_file) and self.ann_file: + assert osp.isfile(self.ann_file), \ + f'Failed to load `ann_file` {self.ann_file}' lines = mmengine.list_from_file( self.ann_file, backend_args=self.backend_args) for line in lines: @@ -250,6 +252,7 @@ def load_data_list(self) -> List[dict]: data_info['seg_fields'] = [] data_list.append(data_info) else: + _suffix_len = len(self.img_suffix) for img in fileio.list_dir_or_file( dir_path=img_dir, list_dir=False, @@ -258,7 +261,288 @@ def load_data_list(self) -> List[dict]: backend_args=self.backend_args): data_info = dict(img_path=osp.join(img_dir, img)) if ann_dir is not None: - seg_map = img.replace(self.img_suffix, self.seg_map_suffix) + seg_map = img[:-_suffix_len] + self.seg_map_suffix + data_info['seg_map_path'] = osp.join(ann_dir, seg_map) + data_info['label_map'] = self.label_map + data_info['reduce_zero_label'] = self.reduce_zero_label + data_info['seg_fields'] = [] + data_list.append(data_info) + data_list = sorted(data_list, key=lambda x: x['img_path']) + return data_list + + +@DATASETS.register_module() +class BaseCDDataset(BaseDataset): + """Custom dataset for change detection. An example of file structure is as + followed. + + .. code-block:: none + + ├── data + │ ├── my_dataset + │ │ ├── img_dir + │ │ │ ├── train + │ │ │ │ ├── xxx{img_suffix} + │ │ │ │ ├── yyy{img_suffix} + │ │ │ │ ├── zzz{img_suffix} + │ │ │ ├── val + │ │ ├── img_dir2 + │ │ │ ├── train + │ │ │ │ ├── xxx{img_suffix} + │ │ │ │ ├── yyy{img_suffix} + │ │ │ │ ├── zzz{img_suffix} + │ │ │ ├── val + │ │ ├── ann_dir + │ │ │ ├── train + │ │ │ │ ├── xxx{seg_map_suffix} + │ │ │ │ ├── yyy{seg_map_suffix} + │ │ │ │ ├── zzz{seg_map_suffix} + │ │ │ ├── val + + The image names in img_dir and img_dir2 should be consistent. + The img/gt_semantic_seg pair of BaseSegDataset should be of the same + except suffix. A valid img/gt_semantic_seg filename pair should be like + ``xxx{img_suffix}`` and ``xxx{seg_map_suffix}`` (extension is also included + in the suffix). If split is given, then ``xxx`` is specified in txt file. + Otherwise, all files in ``img_dir/``and ``ann_dir`` will be loaded. + Please refer to ``docs/en/tutorials/new_dataset.md`` for more details. + + + Args: + ann_file (str): Annotation file path. Defaults to ''. + metainfo (dict, optional): Meta information for dataset, such as + specify classes to load. Defaults to None. + data_root (str, optional): The root directory for ``data_prefix`` and + ``ann_file``. Defaults to None. + data_prefix (dict, optional): Prefix for training data. Defaults to + dict(img_path=None, img_path2=None, seg_map_path=None). + img_suffix (str): Suffix of images. Default: '.jpg' + img_suffix2 (str): Suffix of images. Default: '.jpg' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + filter_cfg (dict, optional): Config for filter data. Defaults to None. + indices (int or Sequence[int], optional): Support using first few + data in annotation file to facilitate training/testing on a smaller + dataset. Defaults to None which means using all ``data_infos``. + serialize_data (bool, optional): Whether to hold memory using + serialized objects, when enabled, data loader workers can use + shared RAM from master process instead of making a copy. Defaults + to True. + pipeline (list, optional): Processing pipeline. Defaults to []. + test_mode (bool, optional): ``test_mode=True`` means in test phase. + Defaults to False. + lazy_init (bool, optional): Whether to load annotation during + instantiation. In some cases, such as visualization, only the meta + information of the dataset is needed, which is not necessary to + load annotation file. ``Basedataset`` can skip load annotations to + save time by set ``lazy_init=True``. Defaults to False. + max_refetch (int, optional): If ``Basedataset.prepare_data`` get a + None img. The maximum extra number of cycles to get a valid + image. Defaults to 1000. + ignore_index (int): The label index to be ignored. Default: 255 + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + backend_args (dict, Optional): Arguments to instantiate a file backend. + See https://mmengine.readthedocs.io/en/latest/api/fileio.htm + for details. Defaults to None. + Notes: mmcv>=2.0.0rc4, mmengine>=0.2.0 required. + """ + METAINFO: dict = dict() + + def __init__(self, + ann_file: str = '', + img_suffix='.jpg', + img_suffix2='.jpg', + seg_map_suffix='.png', + metainfo: Optional[dict] = None, + data_root: Optional[str] = None, + data_prefix: dict = dict( + img_path='', img_path2='', seg_map_path=''), + filter_cfg: Optional[dict] = None, + indices: Optional[Union[int, Sequence[int]]] = None, + serialize_data: bool = True, + pipeline: List[Union[dict, Callable]] = [], + test_mode: bool = False, + lazy_init: bool = False, + max_refetch: int = 1000, + ignore_index: int = 255, + reduce_zero_label: bool = False, + backend_args: Optional[dict] = None) -> None: + + self.img_suffix = img_suffix + self.img_suffix2 = img_suffix2 + self.seg_map_suffix = seg_map_suffix + self.ignore_index = ignore_index + self.reduce_zero_label = reduce_zero_label + self.backend_args = backend_args.copy() if backend_args else None + + self.data_root = data_root + self.data_prefix = copy.copy(data_prefix) + self.ann_file = ann_file + self.filter_cfg = copy.deepcopy(filter_cfg) + self._indices = indices + self.serialize_data = serialize_data + self.test_mode = test_mode + self.max_refetch = max_refetch + self.data_list: List[dict] = [] + self.data_bytes: np.ndarray + + # Set meta information. + self._metainfo = self._load_metainfo(copy.deepcopy(metainfo)) + + # Get label map for custom classes + new_classes = self._metainfo.get('classes', None) + self.label_map = self.get_label_map(new_classes) + self._metainfo.update( + dict( + label_map=self.label_map, + reduce_zero_label=self.reduce_zero_label)) + + # Update palette based on label map or generate palette + # if it is not defined + updated_palette = self._update_palette() + self._metainfo.update(dict(palette=updated_palette)) + + # Join paths. + if self.data_root is not None: + self._join_prefix() + + # Build pipeline. + self.pipeline = Compose(pipeline) + # Full initialize the dataset. + if not lazy_init: + self.full_init() + + if test_mode: + assert self._metainfo.get('classes') is not None, \ + 'dataset metainfo `classes` should be specified when testing' + + @classmethod + def get_label_map(cls, + new_classes: Optional[Sequence] = None + ) -> Union[Dict, None]: + """Require label mapping. + + The ``label_map`` is a dictionary, its keys are the old label ids and + its values are the new label ids, and is used for changing pixel + labels in load_annotations. If and only if old classes in cls.METAINFO + is not equal to new classes in self._metainfo and nether of them is not + None, `label_map` is not None. + + Args: + new_classes (list, tuple, optional): The new classes name from + metainfo. Default to None. + + + Returns: + dict, optional: The mapping from old classes in cls.METAINFO to + new classes in self._metainfo + """ + old_classes = cls.METAINFO.get('classes', None) + if (new_classes is not None and old_classes is not None + and list(new_classes) != list(old_classes)): + + label_map = {} + if not set(new_classes).issubset(cls.METAINFO['classes']): + raise ValueError( + f'new classes {new_classes} is not a ' + f'subset of classes {old_classes} in METAINFO.') + for i, c in enumerate(old_classes): + if c not in new_classes: + label_map[i] = 255 + else: + label_map[i] = new_classes.index(c) + return label_map + else: + return None + + def _update_palette(self) -> list: + """Update palette after loading metainfo. + + If length of palette is equal to classes, just return the palette. + If palette is not defined, it will randomly generate a palette. + If classes is updated by customer, it will return the subset of + palette. + + Returns: + Sequence: Palette for current dataset. + """ + palette = self._metainfo.get('palette', []) + classes = self._metainfo.get('classes', []) + # palette does match classes + if len(palette) == len(classes): + return palette + + if len(palette) == 0: + # Get random state before set seed, and restore + # random state later. + # It will prevent loss of randomness, as the palette + # may be different in each iteration if not specified. + # See: https://github.com/open-mmlab/mmdetection/issues/5844 + state = np.random.get_state() + np.random.seed(42) + # random palette + new_palette = np.random.randint( + 0, 255, size=(len(classes), 3)).tolist() + np.random.set_state(state) + elif len(palette) >= len(classes) and self.label_map is not None: + new_palette = [] + # return subset of palette + for old_id, new_id in sorted( + self.label_map.items(), key=lambda x: x[1]): + if new_id != 255: + new_palette.append(palette[old_id]) + new_palette = type(palette)(new_palette) + else: + raise ValueError('palette does not match classes ' + f'as metainfo is {self._metainfo}.') + return new_palette + + def load_data_list(self) -> List[dict]: + """Load annotation from directory or annotation file. + + Returns: + list[dict]: All data info of dataset. + """ + data_list = [] + img_dir = self.data_prefix.get('img_path', None) + img_dir2 = self.data_prefix.get('img_path2', None) + ann_dir = self.data_prefix.get('seg_map_path', None) + if osp.isfile(self.ann_file): + lines = mmengine.list_from_file( + self.ann_file, backend_args=self.backend_args) + for line in lines: + img_name = line.strip() + if '.' in osp.basename(img_name): + img_name, img_ext = osp.splitext(img_name) + self.img_suffix = img_ext + self.img_suffix2 = img_ext + data_info = dict( + img_path=osp.join(img_dir, img_name + self.img_suffix), + img_path2=osp.join(img_dir2, img_name + self.img_suffix2)) + + if ann_dir is not None: + seg_map = img_name + self.seg_map_suffix + data_info['seg_map_path'] = osp.join(ann_dir, seg_map) + data_info['label_map'] = self.label_map + data_info['reduce_zero_label'] = self.reduce_zero_label + data_info['seg_fields'] = [] + data_list.append(data_info) + else: + for img in fileio.list_dir_or_file( + dir_path=img_dir, + list_dir=False, + suffix=self.img_suffix, + recursive=True, + backend_args=self.backend_args): + if '.' in osp.basename(img): + img, img_ext = osp.splitext(img) + self.img_suffix = img_ext + self.img_suffix2 = img_ext + data_info = dict( + img_path=osp.join(img_dir, img + self.img_suffix), + img_path2=osp.join(img_dir2, img + self.img_suffix2)) + if ann_dir is not None: + seg_map = img + self.seg_map_suffix data_info['seg_map_path'] = osp.join(ann_dir, seg_map) data_info['label_map'] = self.label_map data_info['reduce_zero_label'] = self.reduce_zero_label diff --git a/mmseg/datasets/bdd100k.py b/mmseg/datasets/bdd100k.py new file mode 100644 index 00000000000..8ae70b5cb29 --- /dev/null +++ b/mmseg/datasets/bdd100k.py @@ -0,0 +1,30 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +from mmseg.datasets.basesegdataset import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class BDD100KDataset(BaseSegDataset): + METAINFO = dict( + classes=('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', + 'traffic light', 'traffic sign', 'vegetation', 'terrain', + 'sky', 'person', 'rider', 'car', 'truck', 'bus', 'train', + 'motorcycle', 'bicycle'), + palette=[[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], + [190, 153, 153], [153, 153, 153], [250, 170, + 30], [220, 220, 0], + [107, 142, 35], [152, 251, 152], [70, 130, 180], + [220, 20, 60], [255, 0, 0], [0, 0, 142], [0, 0, 70], + [0, 60, 100], [0, 80, 100], [0, 0, 230], [119, 11, 32]]) + + def __init__(self, + img_suffix='.jpg', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/mmseg/datasets/chase_db1.py b/mmseg/datasets/chase_db1.py index 5cc1fc56773..626ddf75e9a 100644 --- a/mmseg/datasets/chase_db1.py +++ b/mmseg/datasets/chase_db1.py @@ -1,4 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. +import mmengine.fileio as fileio from mmseg.registry import DATASETS from .basesegdataset import BaseSegDataset @@ -27,4 +28,5 @@ def __init__(self, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists(self.data_prefix['img_path']) + assert fileio.exists( + self.data_prefix['img_path'], backend_args=self.backend_args) diff --git a/mmseg/datasets/drive.py b/mmseg/datasets/drive.py index c42e18e711a..76c0160a6b6 100644 --- a/mmseg/datasets/drive.py +++ b/mmseg/datasets/drive.py @@ -1,4 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. +import mmengine.fileio as fileio from mmseg.registry import DATASETS from .basesegdataset import BaseSegDataset @@ -27,4 +28,5 @@ def __init__(self, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists(self.data_prefix['img_path']) + assert fileio.exists( + self.data_prefix['img_path'], backend_args=self.backend_args) diff --git a/mmseg/datasets/dsdl.py b/mmseg/datasets/dsdl.py new file mode 100644 index 00000000000..bf7e4e61b5f --- /dev/null +++ b/mmseg/datasets/dsdl.py @@ -0,0 +1,116 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os +from typing import Dict, List, Optional, Sequence, Union + +from mmseg.registry import DATASETS +from .basesegdataset import BaseSegDataset + +try: + from dsdl.dataset import DSDLDataset +except ImportError: + DSDLDataset = None + + +@DATASETS.register_module() +class DSDLSegDataset(BaseSegDataset): + """Dataset for dsdl segmentation. + + Args: + specific_key_path(dict): Path of specific key which can not + be loaded by it's field name. + pre_transform(dict): pre-transform functions before loading. + used_labels(sequence): list of actual used classes in train steps, + this must be subset of class domain. + """ + + METAINFO = {} + + def __init__(self, + specific_key_path: Dict = {}, + pre_transform: Dict = {}, + used_labels: Optional[Sequence] = None, + **kwargs) -> None: + + if DSDLDataset is None: + raise RuntimeError( + 'Package dsdl is not installed. Please run "pip install dsdl".' + ) + self.used_labels = used_labels + + loc_config = dict(type='LocalFileReader', working_dir='') + if kwargs.get('data_root'): + kwargs['ann_file'] = os.path.join(kwargs['data_root'], + kwargs['ann_file']) + required_fields = ['Image', 'LabelMap'] + + self.dsdldataset = DSDLDataset( + dsdl_yaml=kwargs['ann_file'], + location_config=loc_config, + required_fields=required_fields, + specific_key_path=specific_key_path, + transform=pre_transform, + ) + BaseSegDataset.__init__(self, **kwargs) + + def load_data_list(self) -> List[Dict]: + """Load data info from a dsdl yaml file named as ``self.ann_file`` + + Returns: + List[dict]: A list of data list. + """ + + if self.used_labels: + self._metainfo['classes'] = tuple(self.used_labels) + self.label_map = self.get_label_map(self.used_labels) + else: + self._metainfo['classes'] = tuple(['background'] + + self.dsdldataset.class_names) + data_list = [] + + for i, data in enumerate(self.dsdldataset): + datainfo = dict( + img_path=os.path.join(self.data_prefix['img_path'], + data['Image'][0].location), + seg_map_path=os.path.join(self.data_prefix['seg_map_path'], + data['LabelMap'][0].location), + label_map=self.label_map, + reduce_zero_label=self.reduce_zero_label, + seg_fields=[], + ) + data_list.append(datainfo) + + return data_list + + def get_label_map(self, + new_classes: Optional[Sequence] = None + ) -> Union[Dict, None]: + """Require label mapping. + + The ``label_map`` is a dictionary, its keys are the old label ids and + its values are the new label ids, and is used for changing pixel + labels in load_annotations. If and only if old classes in class_dom + is not equal to new classes in args and nether of them is not + None, `label_map` is not None. + Args: + new_classes (list, tuple, optional): The new classes name from + metainfo. Default to None. + Returns: + dict, optional: The mapping from old classes to new classes. + """ + old_classes = ['background'] + self.dsdldataset.class_names + if (new_classes is not None and old_classes is not None + and list(new_classes) != list(old_classes)): + + label_map = {} + if not set(new_classes).issubset(old_classes): + raise ValueError( + f'new classes {new_classes} is not a ' + f'subset of classes {old_classes} in class_dom.') + for i, c in enumerate(old_classes): + if c not in new_classes: + label_map[i] = 255 + else: + label_map[i] = new_classes.index(c) + return label_map + else: + return None diff --git a/mmseg/datasets/hrf.py b/mmseg/datasets/hrf.py index 0df6ccc49c2..fd669cce264 100644 --- a/mmseg/datasets/hrf.py +++ b/mmseg/datasets/hrf.py @@ -1,4 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. +import mmengine.fileio as fileio from mmseg.registry import DATASETS from .basesegdataset import BaseSegDataset @@ -27,4 +28,5 @@ def __init__(self, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists(self.data_prefix['img_path']) + assert fileio.exists( + self.data_prefix['img_path'], backend_args=self.backend_args) diff --git a/mmseg/datasets/levir.py b/mmseg/datasets/levir.py new file mode 100644 index 00000000000..f467481bad7 --- /dev/null +++ b/mmseg/datasets/levir.py @@ -0,0 +1,31 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +from mmseg.registry import DATASETS +from .basesegdataset import BaseCDDataset + + +@DATASETS.register_module() +class LEVIRCDDataset(BaseCDDataset): + """ISPRS dataset. + + In segmentation map annotation for ISPRS, 0 is to ignore index. + ``reduce_zero_label`` should be set to True. The ``img_suffix`` and + ``seg_map_suffix`` are both fixed to '.png'. + """ + + METAINFO = dict( + classes=('background', 'changed'), + palette=[[0, 0, 0], [255, 255, 255]]) + + def __init__(self, + img_suffix='.png', + img_suffix2='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + img_suffix2=img_suffix2, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/mmseg/datasets/nyu.py b/mmseg/datasets/nyu.py new file mode 100644 index 00000000000..fcfda46647d --- /dev/null +++ b/mmseg/datasets/nyu.py @@ -0,0 +1,123 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +from typing import List + +import mmengine.fileio as fileio + +from mmseg.registry import DATASETS +from .basesegdataset import BaseSegDataset + + +@DATASETS.register_module() +class NYUDataset(BaseSegDataset): + """NYU depth estimation dataset. The file structure should be. + + .. code-block:: none + + ├── data + │ ├── nyu + │ │ ├── images + │ │ │ ├── train + │ │ │ │ ├── scene_xxx.jpg + │ │ │ │ ├── ... + │ │ │ ├── test + │ │ ├── annotations + │ │ │ ├── train + │ │ │ │ ├── scene_xxx.png + │ │ │ │ ├── ... + │ │ │ ├── test + + Args: + ann_file (str): Annotation file path. Defaults to ''. + metainfo (dict, optional): Meta information for dataset, such as + specify classes to load. Defaults to None. + data_root (str, optional): The root directory for ``data_prefix`` and + ``ann_file``. Defaults to None. + data_prefix (dict, optional): Prefix for training data. Defaults to + dict(img_path='images', depth_map_path='annotations'). + img_suffix (str): Suffix of images. Default: '.jpg' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + filter_cfg (dict, optional): Config for filter data. Defaults to None. + indices (int or Sequence[int], optional): Support using first few + data in annotation file to facilitate training/testing on a smaller + dataset. Defaults to None which means using all ``data_infos``. + serialize_data (bool, optional): Whether to hold memory using + serialized objects, when enabled, data loader workers can use + shared RAM from master process instead of making a copy. Defaults + to True. + pipeline (list, optional): Processing pipeline. Defaults to []. + test_mode (bool, optional): ``test_mode=True`` means in test phase. + Defaults to False. + lazy_init (bool, optional): Whether to load annotation during + instantiation. In some cases, such as visualization, only the meta + information of the dataset is needed, which is not necessary to + load annotation file. ``Basedataset`` can skip load annotations to + save time by set ``lazy_init=True``. Defaults to False. + max_refetch (int, optional): If ``Basedataset.prepare_data`` get a + None img. The maximum extra number of cycles to get a valid + image. Defaults to 1000. + ignore_index (int): The label index to be ignored. Default: 255 + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + backend_args (dict, Optional): Arguments to instantiate a file backend. + See https://mmengine.readthedocs.io/en/latest/api/fileio.htm + for details. Defaults to None. + Notes: mmcv>=2.0.0rc4, mmengine>=0.2.0 required. + """ + METAINFO = dict( + classes=('printer_room', 'bathroom', 'living_room', 'study', + 'conference_room', 'study_room', 'kitchen', 'home_office', + 'bedroom', 'dinette', 'playroom', 'indoor_balcony', + 'laundry_room', 'basement', 'excercise_room', 'foyer', + 'home_storage', 'cafe', 'furniture_store', 'office_kitchen', + 'student_lounge', 'dining_room', 'reception_room', + 'computer_lab', 'classroom', 'office', 'bookstore')) + + def __init__(self, + data_prefix=dict( + img_path='images', depth_map_path='annotations'), + img_suffix='.jpg', + depth_map_suffix='.png', + **kwargs) -> None: + super().__init__( + data_prefix=data_prefix, + img_suffix=img_suffix, + seg_map_suffix=depth_map_suffix, + **kwargs) + + def _get_category_id_from_filename(self, image_fname: str) -> int: + """Retrieve the category ID from the given image filename.""" + image_fname = osp.basename(image_fname) + position = image_fname.find(next(filter(str.isdigit, image_fname)), 0) + categoty_name = image_fname[:position - 1] + if categoty_name not in self._metainfo['classes']: + return -1 + else: + return self._metainfo['classes'].index(categoty_name) + + def load_data_list(self) -> List[dict]: + """Load annotation from directory or annotation file. + + Returns: + list[dict]: All data info of dataset. + """ + data_list = [] + img_dir = self.data_prefix.get('img_path', None) + ann_dir = self.data_prefix.get('depth_map_path', None) + + _suffix_len = len(self.img_suffix) + for img in fileio.list_dir_or_file( + dir_path=img_dir, + list_dir=False, + suffix=self.img_suffix, + recursive=True, + backend_args=self.backend_args): + data_info = dict(img_path=osp.join(img_dir, img)) + if ann_dir is not None: + depth_map = img[:-_suffix_len] + self.seg_map_suffix + data_info['depth_map_path'] = osp.join(ann_dir, depth_map) + data_info['seg_fields'] = [] + data_info['category_id'] = self._get_category_id_from_filename(img) + data_list.append(data_info) + data_list = sorted(data_list, key=lambda x: x['img_path']) + return data_list diff --git a/mmseg/datasets/pascal_context.py b/mmseg/datasets/pascal_context.py index a6b2fba7b42..82d00a9b308 100644 --- a/mmseg/datasets/pascal_context.py +++ b/mmseg/datasets/pascal_context.py @@ -1,5 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. -import os.path as osp +import mmengine.fileio as fileio from mmseg.registry import DATASETS from .basesegdataset import BaseSegDataset @@ -46,18 +46,18 @@ class PascalContextDataset(BaseSegDataset): [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255]]) def __init__(self, - ann_file: str, + ann_file='', img_suffix='.jpg', seg_map_suffix='.png', + reduce_zero_label=False, **kwargs) -> None: super().__init__( img_suffix=img_suffix, seg_map_suffix=seg_map_suffix, ann_file=ann_file, - reduce_zero_label=False, + reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists( - self.data_prefix['img_path']) and osp.isfile(self.ann_file) + assert fileio.exists(self.data_prefix['img_path'], self.backend_args) @DATASETS.register_module() @@ -66,8 +66,10 @@ class PascalContextDataset59(BaseSegDataset): In segmentation map annotation for PascalContext, 0 stands for background, which is included in 60 categories. ``reduce_zero_label`` is fixed to - False. The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is + True. The ``img_suffix`` is fixed to '.jpg' and ``seg_map_suffix`` is fixed to '.png'. + Noted: If the background is 255 and the ids of categories are from 0 to 58, + ``reduce_zero_label`` needs to be set to False. Args: ann_file (str): Annotation file path. @@ -100,7 +102,7 @@ class PascalContextDataset59(BaseSegDataset): [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255]]) def __init__(self, - ann_file: str, + ann_file='', img_suffix='.jpg', seg_map_suffix='.png', reduce_zero_label=True, @@ -111,5 +113,4 @@ def __init__(self, ann_file=ann_file, reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists( - self.data_prefix['img_path']) and osp.isfile(self.ann_file) + assert fileio.exists(self.data_prefix['img_path'], self.backend_args) diff --git a/mmseg/datasets/stare.py b/mmseg/datasets/stare.py index 2bfce234494..1b997bb785f 100644 --- a/mmseg/datasets/stare.py +++ b/mmseg/datasets/stare.py @@ -1,4 +1,6 @@ # Copyright (c) OpenMMLab. All rights reserved. +import mmengine.fileio as fileio + from mmseg.registry import DATASETS from .basesegdataset import BaseSegDataset @@ -26,4 +28,5 @@ def __init__(self, seg_map_suffix=seg_map_suffix, reduce_zero_label=reduce_zero_label, **kwargs) - assert self.file_client.exists(self.data_prefix['img_path']) + assert fileio.exists( + self.data_prefix['img_path'], backend_args=self.backend_args) diff --git a/mmseg/datasets/transforms/__init__.py b/mmseg/datasets/transforms/__init__.py index 25f4ee4a987..125f0708181 100644 --- a/mmseg/datasets/transforms/__init__.py +++ b/mmseg/datasets/transforms/__init__.py @@ -2,14 +2,16 @@ from .formatting import PackSegInputs from .loading import (LoadAnnotations, LoadBiomedicalAnnotation, LoadBiomedicalData, LoadBiomedicalImageFromFile, - LoadImageFromNDArray) + LoadDepthAnnotation, LoadImageFromNDArray, + LoadMultipleRSImageFromFile, LoadSingleRSImageFromFile) # yapf: disable -from .transforms import (CLAHE, AdjustGamma, BioMedical3DPad, +from .transforms import (CLAHE, AdjustGamma, Albu, BioMedical3DPad, BioMedical3DRandomCrop, BioMedical3DRandomFlip, BioMedicalGaussianBlur, BioMedicalGaussianNoise, - BioMedicalRandomGamma, GenerateEdge, + BioMedicalRandomGamma, ConcatCDInput, GenerateEdge, PhotoMetricDistortion, RandomCrop, RandomCutOut, - RandomMosaic, RandomRotate, RandomRotFlip, Rerange, + RandomDepthMix, RandomFlip, RandomMosaic, + RandomRotate, RandomRotFlip, Rerange, Resize, ResizeShortestEdge, ResizeToMultiple, RGB2Gray, SegRescale) @@ -22,5 +24,7 @@ 'LoadBiomedicalAnnotation', 'LoadBiomedicalData', 'GenerateEdge', 'ResizeShortestEdge', 'BioMedicalGaussianNoise', 'BioMedicalGaussianBlur', 'BioMedical3DRandomFlip', 'BioMedicalRandomGamma', 'BioMedical3DPad', - 'RandomRotFlip' + 'RandomRotFlip', 'Albu', 'LoadSingleRSImageFromFile', 'ConcatCDInput', + 'LoadMultipleRSImageFromFile', 'LoadDepthAnnotation', 'RandomDepthMix', + 'RandomFlip', 'Resize' ] diff --git a/mmseg/datasets/transforms/formatting.py b/mmseg/datasets/transforms/formatting.py index 89fd8837913..bd250551e98 100644 --- a/mmseg/datasets/transforms/formatting.py +++ b/mmseg/datasets/transforms/formatting.py @@ -92,6 +92,11 @@ def transform(self, results: dict) -> dict: ...].astype(np.int64))) data_sample.set_data(dict(gt_edge_map=PixelData(**gt_edge_data))) + if 'gt_depth_map' in results: + gt_depth_data = dict( + data=to_tensor(results['gt_depth_map'][None, ...])) + data_sample.set_data(dict(gt_depth_map=PixelData(**gt_depth_data))) + img_meta = {} for key in self.meta_keys: if key in results: diff --git a/mmseg/datasets/transforms/loading.py b/mmseg/datasets/transforms/loading.py index d2e93b1abb9..438b5527f08 100644 --- a/mmseg/datasets/transforms/loading.py +++ b/mmseg/datasets/transforms/loading.py @@ -12,6 +12,11 @@ from mmseg.registry import TRANSFORMS from mmseg.utils import datafrombytes +try: + from osgeo import gdal +except ImportError: + gdal = None + @TRANSFORMS.register_module() class LoadAnnotations(MMCV_LoadAnnotations): @@ -493,3 +498,207 @@ def transform(self, single_input: Union[str, np.ndarray, dict]) -> dict: if 'img' in inputs: return self.from_ndarray(inputs) return self.from_file(inputs) + + +@TRANSFORMS.register_module() +class LoadSingleRSImageFromFile(BaseTransform): + """Load a Remote Sensing mage from file. + + Required Keys: + + - img_path + + Modified Keys: + + - img + - img_shape + - ori_shape + + Args: + to_float32 (bool): Whether to convert the loaded image to a float32 + numpy array. If set to False, the loaded image is a float64 array. + Defaults to True. + """ + + def __init__(self, to_float32: bool = True): + self.to_float32 = to_float32 + + if gdal is None: + raise RuntimeError('gdal is not installed') + + def transform(self, results: Dict) -> Dict: + """Functions to load image. + + Args: + results (dict): Result dict from :obj:``mmcv.BaseDataset``. + + Returns: + dict: The dict contains loaded image and meta information. + """ + + filename = results['img_path'] + ds = gdal.Open(filename) + if ds is None: + raise Exception(f'Unable to open file: {filename}') + img = np.einsum('ijk->jki', ds.ReadAsArray()) + + if self.to_float32: + img = img.astype(np.float32) + + results['img'] = img + results['img_shape'] = img.shape[:2] + results['ori_shape'] = img.shape[:2] + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'to_float32={self.to_float32})') + return repr_str + + +@TRANSFORMS.register_module() +class LoadMultipleRSImageFromFile(BaseTransform): + """Load two Remote Sensing mage from file. + + Required Keys: + + - img_path + - img_path2 + + Modified Keys: + + - img + - img2 + - img_shape + - ori_shape + + Args: + to_float32 (bool): Whether to convert the loaded image to a float32 + numpy array. If set to False, the loaded image is a float64 array. + Defaults to True. + """ + + def __init__(self, to_float32: bool = True): + if gdal is None: + raise RuntimeError('gdal is not installed') + self.to_float32 = to_float32 + + def transform(self, results: Dict) -> Dict: + """Functions to load image. + + Args: + results (dict): Result dict from :obj:``mmcv.BaseDataset``. + + Returns: + dict: The dict contains loaded image and meta information. + """ + + filename = results['img_path'] + filename2 = results['img_path2'] + + ds = gdal.Open(filename) + ds2 = gdal.Open(filename2) + + if ds is None: + raise Exception(f'Unable to open file: {filename}') + if ds2 is None: + raise Exception(f'Unable to open file: {filename2}') + + img = np.einsum('ijk->jki', ds.ReadAsArray()) + img2 = np.einsum('ijk->jki', ds2.ReadAsArray()) + + if self.to_float32: + img = img.astype(np.float32) + img2 = img2.astype(np.float32) + + if img.shape != img2.shape: + raise Exception(f'Image shapes do not match:' + f' {img.shape} vs {img2.shape}') + + results['img'] = img + results['img2'] = img2 + results['img_shape'] = img.shape[:2] + results['ori_shape'] = img.shape[:2] + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f'to_float32={self.to_float32})') + return repr_str + + +@TRANSFORMS.register_module() +class LoadDepthAnnotation(BaseTransform): + """Load ``depth_map`` annotation provided by depth estimation dataset. + + The annotation format is as the following: + + .. code-block:: python + + { + 'gt_depth_map': np.ndarray [Y, X] + } + + Required Keys: + + - seg_depth_path + + Added Keys: + + - gt_depth_map (np.ndarray): Depth map with shape (Y, X) by + default, and data type is float32 if set to_float32 = True. + - depth_rescale_factor (float): The rescale factor of depth map, which + can be used to recover the original value of depth map. + + Args: + decode_backend (str): The data decoding backend type. Options are + 'numpy', 'nifti', and 'cv2'. Defaults to 'cv2'. + to_float32 (bool): Whether to convert the loaded depth map to a float32 + numpy array. If set to False, the loaded image is an uint16 array. + Defaults to True. + depth_rescale_factor (float): Factor to rescale the depth value to + limit the range. Defaults to 1.0. + backend_args (dict, Optional): Arguments to instantiate a file backend. + See :class:`mmengine.fileio` for details. + Defaults to None. + Notes: mmcv>=2.0.0rc4, mmengine>=0.2.0 required. + """ + + def __init__(self, + decode_backend: str = 'cv2', + to_float32: bool = True, + depth_rescale_factor: float = 1.0, + backend_args: Optional[dict] = None) -> None: + super().__init__() + self.decode_backend = decode_backend + self.to_float32 = to_float32 + self.depth_rescale_factor = depth_rescale_factor + self.backend_args = backend_args.copy() if backend_args else None + + def transform(self, results: Dict) -> Dict: + """Functions to load depth map. + + Args: + results (dict): Result dict from :obj:``mmcv.BaseDataset``. + + Returns: + dict: The dict contains loaded depth map. + """ + data_bytes = fileio.get(results['depth_map_path'], self.backend_args) + gt_depth_map = datafrombytes(data_bytes, backend=self.decode_backend) + + if self.to_float32: + gt_depth_map = gt_depth_map.astype(np.float32) + + gt_depth_map *= self.depth_rescale_factor + results['gt_depth_map'] = gt_depth_map + results['seg_fields'].append('gt_depth_map') + results['depth_rescale_factor'] = self.depth_rescale_factor + return results + + def __repr__(self): + repr_str = (f'{self.__class__.__name__}(' + f"decode_backend='{self.decode_backend}', " + f'to_float32={self.to_float32}, ' + f'backend_args={self.backend_args})') + return repr_str diff --git a/mmseg/datasets/transforms/transforms.py b/mmseg/datasets/transforms/transforms.py index fb7e2a0e665..082ae5b4401 100644 --- a/mmseg/datasets/transforms/transforms.py +++ b/mmseg/datasets/transforms/transforms.py @@ -1,11 +1,15 @@ # Copyright (c) OpenMMLab. All rights reserved. import copy +import inspect import warnings from typing import Dict, List, Optional, Sequence, Tuple, Union import cv2 import mmcv +import mmengine import numpy as np +from mmcv.transforms import RandomFlip as MMCV_RandomFlip +from mmcv.transforms import Resize as MMCV_Resize from mmcv.transforms.base import BaseTransform from mmcv.transforms.utils import cache_randomness from mmengine.utils import is_tuple_of @@ -15,6 +19,15 @@ from mmseg.datasets.dataset_wrappers import MultiImageMixDataset from mmseg.registry import TRANSFORMS +try: + import albumentations + from albumentations import Compose + ALBU_INSTALLED = True +except ImportError: + albumentations = None + Compose = None + ALBU_INSTALLED = False + @TRANSFORMS.register_module() class ResizeToMultiple(BaseTransform): @@ -186,7 +199,7 @@ def transform(self, results: dict) -> dict: def __repr__(self): repr_str = self.__class__.__name__ - repr_str += f'(clip_limit={self.clip_limit}, '\ + repr_str += f'(clip_limit={self.clip_limit}, ' \ f'tile_grid_size={self.tile_grid_size})' return repr_str @@ -939,6 +952,152 @@ def __repr__(self): return repr_str +@TRANSFORMS.register_module() +class RandomFlip(MMCV_RandomFlip): + """Flip the image & bbox & segmentation map. Added or Updated + keys: flip, flip_direction, img, gt_bboxes, gt_seg_map, and gt_depth_map. + There are 3 flip modes: + + - ``prob`` is float, ``direction`` is string: the image will be + ``direction``ly flipped with probability of ``prob`` . + E.g., ``prob=0.5``, ``direction='horizontal'``, + then image will be horizontally flipped with probability of 0.5. + + - ``prob`` is float, ``direction`` is list of string: the image will + be ``direction[i]``ly flipped with probability of + ``prob/len(direction)``. + E.g., ``prob=0.5``, ``direction=['horizontal', 'vertical']``, + then image will be horizontally flipped with probability of 0.25, + vertically with probability of 0.25. + + - ``prob`` is list of float, ``direction`` is list of string: + given ``len(prob) == len(direction)``, the image will + be ``direction[i]``ly flipped with probability of ``prob[i]``. + E.g., ``prob=[0.3, 0.5]``, ``direction=['horizontal', + 'vertical']``, then image will be horizontally flipped with + probability of 0.3, vertically with probability of 0.5. + + Required Keys: + + - img + - gt_bboxes (optional) + - gt_seg_map (optional) + - gt_depth_map (optional) + + Modified Keys: + + - img + - gt_bboxes (optional) + - gt_seg_map (optional) + - gt_depth_map (optional) + + Added Keys: + + - flip + - flip_direction + - swap_seg_labels (optional) + + Args: + prob (float | list[float], optional): The flipping probability. + Defaults to None. + direction(str | list[str]): The flipping direction. Options + If input is a list, the length must equal ``prob``. Each + element in ``prob`` indicates the flip probability of + corresponding direction. Defaults to 'horizontal'. + swap_seg_labels (list, optional): The label pair need to be swapped + for ground truth, like 'left arm' and 'right arm' need to be + swapped after horizontal flipping. For example, ``[(1, 5)]``, + where 1/5 is the label of the left/right arm. Defaults to None. + """ + + def _flip(self, results: dict) -> None: + """Flip images, bounding boxes and semantic segmentation map.""" + # flip image + results['img'] = mmcv.imflip( + results['img'], direction=results['flip_direction']) + + img_shape = results['img'].shape[:2] + + # flip bboxes + if results.get('gt_bboxes', None) is not None: + results['gt_bboxes'] = self._flip_bbox(results['gt_bboxes'], + img_shape, + results['flip_direction']) + + # flip seg map + for key in results.get('seg_fields', []): + if results.get(key, None) is not None: + results[key] = self._flip_seg_map( + results[key], direction=results['flip_direction']).copy() + results['swap_seg_labels'] = self.swap_seg_labels + + +@TRANSFORMS.register_module() +class Resize(MMCV_Resize): + """Resize images & seg & depth map. + + This transform resizes the input image according to ``scale`` or + ``scale_factor``. Seg map, depth map and other relative annotations are + then resized with the same scale factor. + if ``scale`` and ``scale_factor`` are both set, it will use ``scale`` to + resize. + + Required Keys: + + - img + - gt_seg_map (optional) + - gt_depth_map (optional) + + Modified Keys: + + - img + - gt_seg_map + - gt_depth_map + + Added Keys: + + - scale + - scale_factor + - keep_ratio + + Args: + scale (int or tuple): Images scales for resizing. Defaults to None + scale_factor (float or tuple[float]): Scale factors for resizing. + Defaults to None. + keep_ratio (bool): Whether to keep the aspect ratio when resizing the + image. Defaults to False. + clip_object_border (bool): Whether to clip the objects + outside the border of the image. In some dataset like MOT17, the gt + bboxes are allowed to cross the border of images. Therefore, we + don't need to clip the gt bboxes in these cases. Defaults to True. + backend (str): Image resize backend, choices are 'cv2' and 'pillow'. + These two backends generates slightly different results. Defaults + to 'cv2'. + interpolation (str): Interpolation method, accepted values are + "nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' + backend, "nearest", "bilinear" for 'pillow' backend. Defaults + to 'bilinear'. + """ + + def _resize_seg(self, results: dict) -> None: + """Resize semantic segmentation map with ``results['scale']``.""" + for seg_key in results.get('seg_fields', []): + if results.get(seg_key, None) is not None: + if self.keep_ratio: + gt_seg = mmcv.imrescale( + results[seg_key], + results['scale'], + interpolation='nearest', + backend=self.backend) + else: + gt_seg = mmcv.imresize( + results[seg_key], + results['scale'], + interpolation='nearest', + backend=self.backend) + results[seg_key] = gt_seg + + @TRANSFORMS.register_module() class RandomMosaic(BaseTransform): """Mosaic augmentation. Given 4 images, mosaic transform combines them into @@ -1151,8 +1310,8 @@ def _mosaic_transform_seg(self, results: dict) -> dict: x1_c, y1_c, x2_c, y2_c = crop_coord # crop and paste image - mosaic_seg[y1_p:y2_p, x1_p:x2_p] = gt_seg_i[y1_c:y2_c, - x1_c:x2_c] + mosaic_seg[y1_p:y2_p, x1_p:x2_p] = \ + gt_seg_i[y1_c:y2_c, x1_c:x2_c] results[key] = mosaic_seg @@ -1760,9 +1919,9 @@ def __repr__(self): repr_str += f'(prob={self.prob}, ' repr_str += f'prob_per_channel={self.prob_per_channel}, ' repr_str += f'sigma_range={self.sigma_range}, ' - repr_str += 'different_sigma_per_channel='\ + repr_str += 'different_sigma_per_channel=' \ f'{self.different_sigma_per_channel}, ' - repr_str += 'different_sigma_per_axis='\ + repr_str += 'different_sigma_per_axis=' \ f'{self.different_sigma_per_axis})' return repr_str @@ -2135,3 +2294,221 @@ def __repr__(self): repr_str += f'(prob={self.prob}, axes={self.axes}, ' \ f'swap_label_pairs={self.swap_label_pairs})' return repr_str + + +@TRANSFORMS.register_module() +class Albu(BaseTransform): + """Albumentation augmentation. Adds custom transformations from + Albumentations library. Please, visit + `https://albumentations.readthedocs.io` to get more information. An example + of ``transforms`` is as followed: + + .. code-block:: + [ + dict( + type='ShiftScaleRotate', + shift_limit=0.0625, + scale_limit=0.0, + rotate_limit=0, + interpolation=1, + p=0.5), + dict( + type='RandomBrightnessContrast', + brightness_limit=[0.1, 0.3], + contrast_limit=[0.1, 0.3], + p=0.2), + dict(type='ChannelShuffle', p=0.1), + dict( + type='OneOf', + transforms=[ + dict(type='Blur', blur_limit=3, p=1.0), + dict(type='MedianBlur', blur_limit=3, p=1.0) + ], + p=0.1), + ] + Args: + transforms (list[dict]): A list of albu transformations + keymap (dict): Contains {'input key':'albumentation-style key'} + update_pad_shape (bool): Whether to update padding shape according to \ + the output shape of the last transform + """ + + def __init__(self, + transforms: List[dict], + keymap: Optional[dict] = None, + update_pad_shape: bool = False): + if not ALBU_INSTALLED: + raise ImportError( + 'albumentations is not installed, ' + 'we suggest install albumentation by ' + '"pip install albumentations>=0.3.2 --no-binary qudida,albumentations"' # noqa + ) + + # Args will be modified later, copying it will be safer + transforms = copy.deepcopy(transforms) + + self.transforms = transforms + self.keymap = keymap + self.update_pad_shape = update_pad_shape + + self.aug = Compose([self.albu_builder(t) for t in self.transforms]) + + if not keymap: + self.keymap_to_albu = {'img': 'image', 'gt_seg_map': 'mask'} + else: + self.keymap_to_albu = copy.deepcopy(keymap) + self.keymap_back = {v: k for k, v in self.keymap_to_albu.items()} + + def albu_builder(self, cfg: dict) -> object: + """Build a callable object from a dict containing albu arguments. + + Args: + cfg (dict): Config dict. It should at least contain the key "type". + + Returns: + Callable: A callable object. + """ + + assert isinstance(cfg, dict) and 'type' in cfg + args = cfg.copy() + + obj_type = args.pop('type') + if mmengine.is_str(obj_type): + if not ALBU_INSTALLED: + raise ImportError( + 'albumentations is not installed, ' + 'we suggest install albumentation by ' + '"pip install albumentations>=0.3.2 --no-binary qudida,albumentations"' # noqa + ) + obj_cls = getattr(albumentations, obj_type) + elif inspect.isclass(obj_type): + obj_cls = obj_type + else: + raise TypeError( + f'type must be a valid type or str, but got {type(obj_type)}') + + if 'transforms' in args: + args['transforms'] = [ + self.albu_builder(t) for t in args['transforms'] + ] + + return obj_cls(**args) + + @staticmethod + def mapper(d: dict, keymap: dict): + """Dictionary mapper. + + Renames keys according to keymap provided. + Args: + d (dict): old dict + keymap (dict): {'old_key':'new_key'} + Returns: + dict: new dict. + """ + + updated_dict = {} + for k, _ in zip(d.keys(), d.values()): + new_k = keymap.get(k, k) + updated_dict[new_k] = d[k] + return updated_dict + + def transform(self, results): + # dict to albumentations format + results = self.mapper(results, self.keymap_to_albu) + + # Convert to RGB since Albumentations works with RGB images + results['image'] = cv2.cvtColor(results['image'], cv2.COLOR_BGR2RGB) + + results = self.aug(**results) + + # Convert back to BGR + results['image'] = cv2.cvtColor(results['image'], cv2.COLOR_RGB2BGR) + + # back to the original format + results = self.mapper(results, self.keymap_back) + + # update final shape + if self.update_pad_shape: + results['pad_shape'] = results['img'].shape + + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + f'(transforms={self.transforms})' + return repr_str + + +@TRANSFORMS.register_module() +class ConcatCDInput(BaseTransform): + """Concat images for change detection. + + Required Keys: + + - img + - img2 + + Args: + input_keys (tuple): Input image keys for change detection. + Default: ('img', 'img2'). + """ + + def __init__(self, input_keys=('img', 'img2')): + self.input_keys = input_keys + + def transform(self, results: dict) -> dict: + img = [] + for input_key in self.input_keys: + img.append(results.pop(input_key)) + results['img'] = np.concatenate(img, axis=2) + return results + + def __repr__(self): + repr_str = self.__class__.__name__ + repr_str += f'(input_keys={self.input_keys}, ' + return repr_str + + +@TRANSFORMS.register_module() +class RandomDepthMix(BaseTransform): + """This class implements the RandomDepthMix transform. + + Args: + prob (float): Probability of applying the transformation. + Defaults to 0.25. + mix_scale_ratio (float): Ratio to scale the mix width. + Defaults to 0.75. + """ + + def __init__( + self, + prob: float = 0.25, + mix_scale_ratio: float = 0.75, + ): + super().__init__() + + self.prob = prob + self.mix_scale_ratio = mix_scale_ratio + + def transform(self, results: dict) -> dict: + if random.random() > self.prob: + return results + + h, w = results['img_shape'][:2] + left = int(w * random.random()) + width_ratio = self.mix_scale_ratio * random.random() + width = int(max(1, (w - left) * width_ratio)) + + img = results['img'] + depth_rescale_factor = results.get('depth_rescale_factor', 1) + depth_map = results['gt_depth_map'] / depth_rescale_factor + + if img.ndim == 3: + for c in range(img.shape[-1]): + img[:, left:left + width, c] = depth_map[:, left:left + width] + elif img.ndim == 2: + img[:, left:left + width] = depth_map[:, left:left + width] + else: + raise ValueError(f'Invalid image shape ({img.shape})') + + results['img'] = img + return results diff --git a/mmseg/engine/__init__.py b/mmseg/engine/__init__.py index ada40570121..98139a0047f 100644 --- a/mmseg/engine/__init__.py +++ b/mmseg/engine/__init__.py @@ -1,9 +1,12 @@ # Copyright (c) OpenMMLab. All rights reserved. from .hooks import SegVisualizationHook -from .optimizers import (LayerDecayOptimizerConstructor, +from .optimizers import (ForceDefaultOptimWrapperConstructor, + LayerDecayOptimizerConstructor, LearningRateDecayOptimizerConstructor) +from .schedulers import PolyLRRatio __all__ = [ 'LearningRateDecayOptimizerConstructor', 'LayerDecayOptimizerConstructor', - 'SegVisualizationHook' + 'SegVisualizationHook', 'PolyLRRatio', + 'ForceDefaultOptimWrapperConstructor' ] diff --git a/mmseg/engine/optimizers/__init__.py b/mmseg/engine/optimizers/__init__.py index 4fbf4ecfcd4..e4cf58741fe 100644 --- a/mmseg/engine/optimizers/__init__.py +++ b/mmseg/engine/optimizers/__init__.py @@ -1,7 +1,9 @@ # Copyright (c) OpenMMLab. All rights reserved. +from .force_default_constructor import ForceDefaultOptimWrapperConstructor from .layer_decay_optimizer_constructor import ( LayerDecayOptimizerConstructor, LearningRateDecayOptimizerConstructor) __all__ = [ - 'LearningRateDecayOptimizerConstructor', 'LayerDecayOptimizerConstructor' + 'LearningRateDecayOptimizerConstructor', 'LayerDecayOptimizerConstructor', + 'ForceDefaultOptimWrapperConstructor' ] diff --git a/mmseg/engine/optimizers/force_default_constructor.py b/mmseg/engine/optimizers/force_default_constructor.py new file mode 100644 index 00000000000..12c642ad411 --- /dev/null +++ b/mmseg/engine/optimizers/force_default_constructor.py @@ -0,0 +1,255 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging +from typing import List, Optional, Union + +import torch +import torch.nn as nn +from mmengine.logging import print_log +from mmengine.optim import DefaultOptimWrapperConstructor +from mmengine.utils.dl_utils import mmcv_full_available +from mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm, _InstanceNorm +from torch.nn import GroupNorm, LayerNorm + +from mmseg.registry import OPTIM_WRAPPER_CONSTRUCTORS + + +@OPTIM_WRAPPER_CONSTRUCTORS.register_module() +class ForceDefaultOptimWrapperConstructor(DefaultOptimWrapperConstructor): + """Default constructor with forced optimizer settings. + + This constructor extends the default constructor to add an option for + forcing default optimizer settings. This is useful for ensuring that + certain parameters or layers strictly adhere to pre-defined default + settings, regardless of any custom settings specified. + + By default, each parameter share the same optimizer settings, and we + provide an argument ``paramwise_cfg`` to specify parameter-wise settings. + It is a dict and may contain various fields like 'custom_keys', + 'bias_lr_mult', etc., as well as the additional field + `force_default_settings` which allows for enforcing default settings on + optimizer parameters. + + - ``custom_keys`` (dict): Specified parameters-wise settings by keys. If + one of the keys in ``custom_keys`` is a substring of the name of one + parameter, then the setting of the parameter will be specified by + ``custom_keys[key]`` and other setting like ``bias_lr_mult`` etc. will + be ignored. It should be noted that the aforementioned ``key`` is the + longest key that is a substring of the name of the parameter. If there + are multiple matched keys with the same length, then the key with lower + alphabet order will be chosen. + ``custom_keys[key]`` should be a dict and may contain fields ``lr_mult`` + and ``decay_mult``. See Example 2 below. + - ``bias_lr_mult`` (float): It will be multiplied to the learning + rate for all bias parameters (except for those in normalization + layers and offset layers of DCN). + - ``bias_decay_mult`` (float): It will be multiplied to the weight + decay for all bias parameters (except for those in + normalization layers, depthwise conv layers, offset layers of DCN). + - ``norm_decay_mult`` (float): It will be multiplied to the weight + decay for all weight and bias parameters of normalization + layers. + - ``flat_decay_mult`` (float): It will be multiplied to the weight + decay for all one-dimensional parameters + - ``dwconv_decay_mult`` (float): It will be multiplied to the weight + decay for all weight and bias parameters of depthwise conv + layers. + - ``dcn_offset_lr_mult`` (float): It will be multiplied to the learning + rate for parameters of offset layer in the deformable convs + of a model. + - ``bypass_duplicate`` (bool): If true, the duplicate parameters + would not be added into optimizer. Defaults to False. + - ``force_default_settings`` (bool): If true, this will override any + custom settings defined by ``custom_keys`` and enforce the use of + default settings for optimizer parameters like ``bias_lr_mult``. + This is particularly useful when you want to ensure that certain layers + or parameters adhere strictly to the pre-defined default settings. + + Note: + + 1. If the option ``dcn_offset_lr_mult`` is used, the constructor will + override the effect of ``bias_lr_mult`` in the bias of offset layer. + So be careful when using both ``bias_lr_mult`` and + ``dcn_offset_lr_mult``. If you wish to apply both of them to the offset + layer in deformable convs, set ``dcn_offset_lr_mult`` to the original + ``dcn_offset_lr_mult`` * ``bias_lr_mult``. + + 2. If the option ``dcn_offset_lr_mult`` is used, the constructor will + apply it to all the DCN layers in the model. So be careful when the + model contains multiple DCN layers in places other than backbone. + + 3. When the option ``force_default_settings`` is true, it will override + any custom settings provided in ``custom_keys``. This ensures that the + default settings for the optimizer parameters are used. + + Args: + optim_wrapper_cfg (dict): The config dict of the optimizer wrapper. + + Required fields of ``optim_wrapper_cfg`` are + + - ``type``: class name of the OptimizerWrapper + - ``optimizer``: The configuration of optimizer. + + Optional fields of ``optim_wrapper_cfg`` are + + - any arguments of the corresponding optimizer wrapper type, + e.g., accumulative_counts, clip_grad, etc. + + Required fields of ``optimizer`` are + + - `type`: class name of the optimizer. + + Optional fields of ``optimizer`` are + + - any arguments of the corresponding optimizer type, e.g., + lr, weight_decay, momentum, etc. + + paramwise_cfg (dict, optional): Parameter-wise options. + + Example 1: + >>> model = torch.nn.modules.Conv1d(1, 1, 1) + >>> optim_wrapper_cfg = dict( + >>> dict(type='OptimWrapper', optimizer=dict(type='SGD', lr=0.01, + >>> momentum=0.9, weight_decay=0.0001)) + >>> paramwise_cfg = dict(norm_decay_mult=0.) + >>> optim_wrapper_builder = DefaultOptimWrapperConstructor( + >>> optim_wrapper_cfg, paramwise_cfg) + >>> optim_wrapper = optim_wrapper_builder(model) + + Example 2: + >>> # assume model have attribute model.backbone and model.cls_head + >>> optim_wrapper_cfg = dict(type='OptimWrapper', optimizer=dict( + >>> type='SGD', lr=0.01, weight_decay=0.95)) + >>> paramwise_cfg = dict(custom_keys={ + >>> 'backbone': dict(lr_mult=0.1, decay_mult=0.9)}) + >>> optim_wrapper_builder = DefaultOptimWrapperConstructor( + >>> optim_wrapper_cfg, paramwise_cfg) + >>> optim_wrapper = optim_wrapper_builder(model) + >>> # Then the `lr` and `weight_decay` for model.backbone is + >>> # (0.01 * 0.1, 0.95 * 0.9). `lr` and `weight_decay` for + >>> # model.cls_head is (0.01, 0.95). + """ + + def add_params(self, + params: List[dict], + module: nn.Module, + prefix: str = '', + is_dcn_module: Optional[Union[int, float]] = None) -> None: + """Add all parameters of module to the params list. + + The parameters of the given module will be added to the list of param + groups, with specific rules defined by paramwise_cfg. + + Args: + params (list[dict]): A list of param groups, it will be modified + in place. + module (nn.Module): The module to be added. + prefix (str): The prefix of the module + is_dcn_module (int|float|None): If the current module is a + submodule of DCN, `is_dcn_module` will be passed to + control conv_offset layer's learning rate. Defaults to None. + """ + # get param-wise options + custom_keys = self.paramwise_cfg.get('custom_keys', {}) + # first sort with alphabet order and then sort with reversed len of str + sorted_keys = sorted(sorted(custom_keys.keys()), key=len, reverse=True) + + bias_lr_mult = self.paramwise_cfg.get('bias_lr_mult', None) + bias_decay_mult = self.paramwise_cfg.get('bias_decay_mult', None) + norm_decay_mult = self.paramwise_cfg.get('norm_decay_mult', None) + dwconv_decay_mult = self.paramwise_cfg.get('dwconv_decay_mult', None) + flat_decay_mult = self.paramwise_cfg.get('flat_decay_mult', None) + bypass_duplicate = self.paramwise_cfg.get('bypass_duplicate', False) + dcn_offset_lr_mult = self.paramwise_cfg.get('dcn_offset_lr_mult', None) + force_default_settings = self.paramwise_cfg.get( + 'force_default_settings', False) + + # special rules for norm layers and depth-wise conv layers + is_norm = isinstance(module, + (_BatchNorm, _InstanceNorm, GroupNorm, LayerNorm)) + is_dwconv = ( + isinstance(module, torch.nn.Conv2d) + and module.in_channels == module.groups) + + for name, param in module.named_parameters(recurse=False): + param_group = {'params': [param]} + if bypass_duplicate and self._is_in(param_group, params): + print_log( + f'{prefix} is duplicate. It is skipped since ' + f'bypass_duplicate={bypass_duplicate}', + logger='current', + level=logging.WARNING) + continue + if not param.requires_grad: + params.append(param_group) + continue + + # if the parameter match one of the custom keys, ignore other rules + is_custom = False + for key in sorted_keys: + if key in f'{prefix}.{name}': + is_custom = True + lr_mult = custom_keys[key].get('lr_mult', 1.) + param_group['lr'] = self.base_lr * lr_mult + if self.base_wd is not None: + decay_mult = custom_keys[key].get('decay_mult', 1.) + param_group['weight_decay'] = self.base_wd * decay_mult + # add custom settings to param_group + for k, v in custom_keys[key].items(): + param_group[k] = v + break + + if not is_custom or force_default_settings: + # bias_lr_mult affects all bias parameters + # except for norm.bias dcn.conv_offset.bias + if name == 'bias' and not ( + is_norm or is_dcn_module) and bias_lr_mult is not None: + param_group['lr'] = self.base_lr * bias_lr_mult + + if (prefix.find('conv_offset') != -1 and is_dcn_module + and dcn_offset_lr_mult is not None + and isinstance(module, torch.nn.Conv2d)): + # deal with both dcn_offset's bias & weight + param_group['lr'] = self.base_lr * dcn_offset_lr_mult + + # apply weight decay policies + if self.base_wd is not None: + # norm decay + if is_norm and norm_decay_mult is not None: + param_group[ + 'weight_decay'] = self.base_wd * norm_decay_mult + # bias lr and decay + elif (name == 'bias' and not is_dcn_module + and bias_decay_mult is not None): + param_group[ + 'weight_decay'] = self.base_wd * bias_decay_mult + # depth-wise conv + elif is_dwconv and dwconv_decay_mult is not None: + param_group[ + 'weight_decay'] = self.base_wd * dwconv_decay_mult + # flatten parameters except dcn offset + elif (param.ndim == 1 and not is_dcn_module + and flat_decay_mult is not None): + param_group[ + 'weight_decay'] = self.base_wd * flat_decay_mult + params.append(param_group) + for key, value in param_group.items(): + if key == 'params': + continue + full_name = f'{prefix}.{name}' if prefix else name + print_log( + f'paramwise_options -- {full_name}:{key}={value}', + logger='current') + + if mmcv_full_available(): + from mmcv.ops import DeformConv2d, ModulatedDeformConv2d + is_dcn_module = isinstance(module, + (DeformConv2d, ModulatedDeformConv2d)) + else: + is_dcn_module = False + for child_name, child_mod in module.named_children(): + child_prefix = f'{prefix}.{child_name}' if prefix else child_name + self.add_params( + params, + child_mod, + prefix=child_prefix, + is_dcn_module=is_dcn_module) diff --git a/mmseg/engine/schedulers/__init__.py b/mmseg/engine/schedulers/__init__.py new file mode 100644 index 00000000000..3cd3f621134 --- /dev/null +++ b/mmseg/engine/schedulers/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .poly_ratio_scheduler import PolyLRRatio + +__all__ = ['PolyLRRatio'] diff --git a/mmseg/engine/schedulers/poly_ratio_scheduler.py b/mmseg/engine/schedulers/poly_ratio_scheduler.py new file mode 100644 index 00000000000..057203acc9c --- /dev/null +++ b/mmseg/engine/schedulers/poly_ratio_scheduler.py @@ -0,0 +1,62 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Optional + +from mmengine.optim.scheduler import PolyLR + +from mmseg.registry import PARAM_SCHEDULERS + + +@PARAM_SCHEDULERS.register_module() +class PolyLRRatio(PolyLR): + """Implements polynomial learning rate decay with ratio. + + This scheduler adjusts the learning rate of each parameter group + following a polynomial decay equation. The decay can occur in + conjunction with external parameter adjustments made outside this + scheduler. + + Args: + optimizer (Optimizer or OptimWrapper): Wrapped optimizer. + eta_min (float): Minimum learning rate at the end of scheduling. + Defaults to 0. + eta_min_ratio (float, optional): The ratio of the minimum parameter + value to the base parameter value. Either `eta_min` or + `eta_min_ratio` should be specified. Defaults to None. + power (float): The power of the polynomial. Defaults to 1.0. + begin (int): Step at which to start updating the parameters. + Defaults to 0. + end (int): Step at which to stop updating the parameters. + Defaults to INF. + last_step (int): The index of last step. Used for resume without + state dict. Defaults to -1. + by_epoch (bool): Whether the scheduled parameters are updated by + epochs. Defaults to True. + verbose (bool): Whether to print the value for each update. + Defaults to False. + """ + + def __init__(self, eta_min_ratio: Optional[int] = None, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.eta_min_ratio = eta_min_ratio + + def _get_value(self): + """Compute value using chainable form of the scheduler.""" + + if self.last_step == 0: + return [ + group[self.param_name] for group in self.optimizer.param_groups + ] + + param_groups_value = [] + for base_value, param_group in zip(self.base_values, + self.optimizer.param_groups): + eta_min = self.eta_min if self.eta_min_ratio is None else \ + base_value * self.eta_min_ratio + step_ratio = (1 - 1 / + (self.total_iters - self.last_step + 1))**self.power + step_value = (param_group[self.param_name] - + eta_min) * step_ratio + eta_min + param_groups_value.append(step_value) + + return param_groups_value diff --git a/mmseg/evaluation/__init__.py b/mmseg/evaluation/__init__.py index a82008f3ad3..82b3a8d68d3 100644 --- a/mmseg/evaluation/__init__.py +++ b/mmseg/evaluation/__init__.py @@ -1,4 +1,4 @@ # Copyright (c) OpenMMLab. All rights reserved. -from .metrics import CityscapesMetric, IoUMetric +from .metrics import CityscapesMetric, DepthMetric, IoUMetric -__all__ = ['IoUMetric', 'CityscapesMetric'] +__all__ = ['IoUMetric', 'CityscapesMetric', 'DepthMetric'] diff --git a/mmseg/evaluation/metrics/__init__.py b/mmseg/evaluation/metrics/__init__.py index 0aa39e480cd..848d4713dc8 100644 --- a/mmseg/evaluation/metrics/__init__.py +++ b/mmseg/evaluation/metrics/__init__.py @@ -1,5 +1,6 @@ # Copyright (c) OpenMMLab. All rights reserved. from .citys_metric import CityscapesMetric +from .depth_metric import DepthMetric from .iou_metric import IoUMetric -__all__ = ['IoUMetric', 'CityscapesMetric'] +__all__ = ['IoUMetric', 'CityscapesMetric', 'DepthMetric'] diff --git a/mmseg/evaluation/metrics/depth_metric.py b/mmseg/evaluation/metrics/depth_metric.py new file mode 100644 index 00000000000..621d4a31c9f --- /dev/null +++ b/mmseg/evaluation/metrics/depth_metric.py @@ -0,0 +1,212 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +from collections import OrderedDict, defaultdict +from typing import Dict, List, Optional, Sequence + +import cv2 +import numpy as np +import torch +from mmengine.dist import is_main_process +from mmengine.evaluator import BaseMetric +from mmengine.logging import MMLogger, print_log +from mmengine.utils import mkdir_or_exist +from prettytable import PrettyTable +from torch import Tensor + +from mmseg.registry import METRICS + + +@METRICS.register_module() +class DepthMetric(BaseMetric): + """Depth estimation evaluation metric. + + Args: + depth_metrics (List[str], optional): List of metrics to compute. If + not specified, defaults to all metrics in self.METRICS. + min_depth_eval (float): Minimum depth value for evaluation. + Defaults to 0.0. + max_depth_eval (float): Maximum depth value for evaluation. + Defaults to infinity. + crop_type (str, optional): Specifies the type of cropping to be used + during evaluation. This option can affect how the evaluation mask + is generated. Currently, 'nyu_crop' is supported, but other + types can be added in future. Defaults to None if no cropping + should be applied. + depth_scale_factor (float): Factor to scale the depth values. + Defaults to 1.0. + collect_device (str): Device name used for collecting results from + different ranks during distributed training. Must be 'cpu' or + 'gpu'. Defaults to 'cpu'. + output_dir (str): The directory for output prediction. Defaults to + None. + format_only (bool): Only format result for results commit without + perform evaluation. It is useful when you want to save the result + to a specific format and submit it to the test server. + Defaults to False. + prefix (str, optional): The prefix that will be added in the metric + names to disambiguate homonymous metrics of different evaluators. + If prefix is not provided in the argument, self.default_prefix + will be used instead. Defaults to None. + """ + METRICS = ('d1', 'd2', 'd3', 'abs_rel', 'sq_rel', 'rmse', 'rmse_log', + 'log10', 'silog') + + def __init__(self, + depth_metrics: Optional[List[str]] = None, + min_depth_eval: float = 0.0, + max_depth_eval: float = float('inf'), + crop_type: Optional[str] = None, + depth_scale_factor: float = 1.0, + collect_device: str = 'cpu', + output_dir: Optional[str] = None, + format_only: bool = False, + prefix: Optional[str] = None, + **kwargs) -> None: + super().__init__(collect_device=collect_device, prefix=prefix) + + if depth_metrics is None: + self.metrics = self.METRICS + elif isinstance(depth_metrics, [tuple, list]): + for metric in depth_metrics: + assert metric in self.METRICS, f'the metric {metric} is not ' \ + f'supported. Please use metrics in {self.METRICS}' + self.metrics = depth_metrics + + # Validate crop_type, if provided + assert crop_type in [ + None, 'nyu_crop' + ], (f'Invalid value for crop_type: {crop_type}. Supported values are ' + 'None or \'nyu_crop\'.') + self.crop_type = crop_type + self.min_depth_eval = min_depth_eval + self.max_depth_eval = max_depth_eval + self.output_dir = output_dir + if self.output_dir and is_main_process(): + mkdir_or_exist(self.output_dir) + self.format_only = format_only + self.depth_scale_factor = depth_scale_factor + + def process(self, data_batch: dict, data_samples: Sequence[dict]) -> None: + """Process one batch of data and data_samples. + + The processed results should be stored in ``self.results``, which will + be used to compute the metrics when all batches have been processed. + + Args: + data_batch (dict): A batch of data from the dataloader. + data_samples (Sequence[dict]): A batch of outputs from the model. + """ + for data_sample in data_samples: + pred_label = data_sample['pred_depth_map']['data'].squeeze() + # format_only always for test dataset without ground truth + if not self.format_only: + gt_depth = data_sample['gt_depth_map']['data'].squeeze().to( + pred_label) + + eval_mask = self._get_eval_mask(gt_depth) + self.results.append( + (gt_depth[eval_mask], pred_label[eval_mask])) + # format_result + if self.output_dir is not None: + basename = osp.splitext(osp.basename( + data_sample['img_path']))[0] + png_filename = osp.abspath( + osp.join(self.output_dir, f'{basename}.png')) + output_mask = pred_label.cpu().numpy( + ) * self.depth_scale_factor + + cv2.imwrite(png_filename, output_mask.astype(np.uint16), + [cv2.IMWRITE_PNG_COMPRESSION, 0]) + + def _get_eval_mask(self, gt_depth: Tensor): + """Generates an evaluation mask based on ground truth depth and + cropping. + + Args: + gt_depth (Tensor): Ground truth depth map. + + Returns: + Tensor: Boolean mask where evaluation should be performed. + """ + valid_mask = torch.logical_and(gt_depth > self.min_depth_eval, + gt_depth < self.max_depth_eval) + + if self.crop_type == 'nyu_crop': + # this implementation is adapted from + # https://github.com/zhyever/Monocular-Depth-Estimation-Toolbox/blob/main/depth/datasets/nyu.py # noqa + crop_mask = torch.zeros_like(valid_mask) + crop_mask[45:471, 41:601] = 1 + else: + crop_mask = torch.ones_like(valid_mask) + + eval_mask = torch.logical_and(valid_mask, crop_mask) + return eval_mask + + @staticmethod + def _calc_all_metrics(gt_depth, pred_depth): + """Computes final evaluation metrics based on accumulated results.""" + assert gt_depth.shape == pred_depth.shape + + thresh = torch.max((gt_depth / pred_depth), (pred_depth / gt_depth)) + diff = pred_depth - gt_depth + diff_log = torch.log(pred_depth) - torch.log(gt_depth) + + d1 = torch.sum(thresh < 1.25).float() / len(thresh) + d2 = torch.sum(thresh < 1.25**2).float() / len(thresh) + d3 = torch.sum(thresh < 1.25**3).float() / len(thresh) + + abs_rel = torch.mean(torch.abs(diff) / gt_depth) + sq_rel = torch.mean(torch.pow(diff, 2) / gt_depth) + + rmse = torch.sqrt(torch.mean(torch.pow(diff, 2))) + rmse_log = torch.sqrt(torch.mean(torch.pow(diff_log, 2))) + + log10 = torch.mean( + torch.abs(torch.log10(pred_depth) - torch.log10(gt_depth))) + silog = torch.sqrt( + torch.pow(diff_log, 2).mean() - + 0.5 * torch.pow(diff_log.mean(), 2)) + + return { + 'd1': d1.item(), + 'd2': d2.item(), + 'd3': d3.item(), + 'abs_rel': abs_rel.item(), + 'sq_rel': sq_rel.item(), + 'rmse': rmse.item(), + 'rmse_log': rmse_log.item(), + 'log10': log10.item(), + 'silog': silog.item() + } + + def compute_metrics(self, results: list) -> Dict[str, float]: + """Compute the metrics from processed results. + + Args: + results (list): The processed results of each batch. + + Returns: + Dict[str, float]: The computed metrics. The keys are the names of + the metrics, and the values are corresponding results. The keys + are identical with self.metrics. + """ + logger: MMLogger = MMLogger.get_current_instance() + if self.format_only: + logger.info(f'results are saved to {osp.dirname(self.output_dir)}') + return OrderedDict() + + metrics = defaultdict(list) + for gt_depth, pred_depth in results: + for key, value in self._calc_all_metrics(gt_depth, + pred_depth).items(): + metrics[key].append(value) + metrics = {k: sum(metrics[k]) / len(metrics[k]) for k in self.metrics} + + table_data = PrettyTable() + for key, val in metrics.items(): + table_data.add_column(key, [round(val, 5)]) + + print_log('results:', logger) + print_log('\n' + table_data.get_string(), logger=logger) + + return metrics diff --git a/mmseg/models/__init__.py b/mmseg/models/__init__.py index 7a520fb2fa4..a98951283c1 100644 --- a/mmseg/models/__init__.py +++ b/mmseg/models/__init__.py @@ -1,4 +1,5 @@ # Copyright (c) OpenMMLab. All rights reserved. +from .assigners import * # noqa: F401,F403 from .backbones import * # noqa: F401,F403 from .builder import (BACKBONES, HEADS, LOSSES, SEGMENTORS, build_backbone, build_head, build_loss, build_segmentor) @@ -7,6 +8,7 @@ from .losses import * # noqa: F401,F403 from .necks import * # noqa: F401,F403 from .segmentors import * # noqa: F401,F403 +from .text_encoder import * # noqa: F401,F403 __all__ = [ 'BACKBONES', 'HEADS', 'LOSSES', 'SEGMENTORS', 'build_backbone', diff --git a/mmseg/models/assigners/__init__.py b/mmseg/models/assigners/__init__.py new file mode 100644 index 00000000000..d49b1b18b9e --- /dev/null +++ b/mmseg/models/assigners/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .base_assigner import BaseAssigner +from .hungarian_assigner import HungarianAssigner +from .match_cost import ClassificationCost, CrossEntropyLossCost, DiceCost + +__all__ = [ + 'BaseAssigner', + 'HungarianAssigner', + 'ClassificationCost', + 'CrossEntropyLossCost', + 'DiceCost', +] diff --git a/mmseg/models/assigners/base_assigner.py b/mmseg/models/assigners/base_assigner.py new file mode 100644 index 00000000000..97895cdac27 --- /dev/null +++ b/mmseg/models/assigners/base_assigner.py @@ -0,0 +1,18 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import ABCMeta, abstractmethod +from typing import Optional + +from mmengine.structures import InstanceData + + +class BaseAssigner(metaclass=ABCMeta): + """Base assigner that assigns masks to ground truth class labels.""" + + @abstractmethod + def assign(self, + pred_instances: InstanceData, + gt_instances: InstanceData, + gt_instances_ignore: Optional[InstanceData] = None, + **kwargs): + """Assign masks to either a ground truth class label or a negative + label.""" diff --git a/mmseg/models/assigners/hungarian_assigner.py b/mmseg/models/assigners/hungarian_assigner.py new file mode 100644 index 00000000000..28868f0a04e --- /dev/null +++ b/mmseg/models/assigners/hungarian_assigner.py @@ -0,0 +1,86 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List, Union + +import torch +from mmengine import ConfigDict +from mmengine.structures import InstanceData +from scipy.optimize import linear_sum_assignment +from torch.cuda.amp import autocast + +from mmseg.registry import TASK_UTILS +from .base_assigner import BaseAssigner + + +@TASK_UTILS.register_module() +class HungarianAssigner(BaseAssigner): + """Computes one-to-one matching between prediction masks and ground truth. + + This class uses bipartite matching-based assignment to computes an + assignment between the prediction masks and the ground truth. The + assignment result is based on the weighted sum of match costs. The + Hungarian algorithm is used to calculate the best matching with the + minimum cost. The prediction masks that are not matched are classified + as background. + + Args: + match_costs (ConfigDict|List[ConfigDict]): Match cost configs. + """ + + def __init__( + self, match_costs: Union[List[Union[dict, ConfigDict]], dict, + ConfigDict] + ) -> None: + + if isinstance(match_costs, dict): + match_costs = [match_costs] + elif isinstance(match_costs, list): + assert len(match_costs) > 0, \ + 'match_costs must not be a empty list.' + + self.match_costs = [ + TASK_UTILS.build(match_cost) for match_cost in match_costs + ] + + def assign(self, pred_instances: InstanceData, gt_instances: InstanceData, + **kwargs): + """Computes one-to-one matching based on the weighted costs. + + This method assign each query prediction to a ground truth or + background. The assignment first calculates the cost for each + category assigned to each query mask, and then uses the + Hungarian algorithm to calculate the minimum cost as the best + match. + + Args: + pred_instances (InstanceData): Instances of model + predictions. It includes "masks", with shape + (n, h, w) or (n, l), and "cls", with shape (n, num_classes+1) + gt_instances (InstanceData): Ground truth of instance + annotations. It includes "labels", with shape (k, ), + and "masks", with shape (k, h, w) or (k, l). + + Returns: + matched_quiery_inds (Tensor): The indexes of matched quieres. + matched_label_inds (Tensor): The indexes of matched labels. + """ + # compute weighted cost + cost_list = [] + with autocast(enabled=False): + for match_cost in self.match_costs: + cost = match_cost( + pred_instances=pred_instances, gt_instances=gt_instances) + cost_list.append(cost) + cost = torch.stack(cost_list).sum(dim=0) + + device = cost.device + # do Hungarian matching on CPU using linear_sum_assignment + cost = cost.detach().cpu() + if linear_sum_assignment is None: + raise ImportError('Please run "pip install scipy" ' + 'to install scipy first.') + + matched_quiery_inds, matched_label_inds = linear_sum_assignment(cost) + matched_quiery_inds = torch.from_numpy(matched_quiery_inds).to(device) + matched_label_inds = torch.from_numpy(matched_label_inds).to(device) + + return matched_quiery_inds, matched_label_inds diff --git a/mmseg/models/assigners/match_cost.py b/mmseg/models/assigners/match_cost.py new file mode 100644 index 00000000000..560df852902 --- /dev/null +++ b/mmseg/models/assigners/match_cost.py @@ -0,0 +1,231 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from abc import abstractmethod +from typing import Union + +import torch +import torch.nn.functional as F +from mmengine.structures import InstanceData +from torch import Tensor + +from mmseg.registry import TASK_UTILS + + +class BaseMatchCost: + """Base match cost class. + + Args: + weight (Union[float, int]): Cost weight. Defaults to 1. + """ + + def __init__(self, weight: Union[float, int] = 1.) -> None: + self.weight = weight + + @abstractmethod + def __call__(self, pred_instances: InstanceData, + gt_instances: InstanceData, **kwargs) -> Tensor: + """Compute match cost. + + Args: + pred_instances (InstanceData): Instances of model predictions. + It often includes "labels" and "scores". + gt_instances (InstanceData): Ground truth of instance + annotations. It usually includes "labels". + + Returns: + Tensor: Match Cost matrix of shape (num_preds, num_gts). + """ + pass + + +@TASK_UTILS.register_module() +class ClassificationCost(BaseMatchCost): + """ClsSoftmaxCost. + + Args: + weight (Union[float, int]): Cost weight. Defaults to 1. + + Examples: + >>> from mmseg.models.assigners import ClassificationCost + >>> import torch + >>> self = ClassificationCost() + >>> cls_pred = torch.rand(4, 3) + >>> gt_labels = torch.tensor([0, 1, 2]) + >>> factor = torch.tensor([10, 8, 10, 8]) + >>> self(cls_pred, gt_labels) + tensor([[-0.3430, -0.3525, -0.3045], + [-0.3077, -0.2931, -0.3992], + [-0.3664, -0.3455, -0.2881], + [-0.3343, -0.2701, -0.3956]]) + """ + + def __init__(self, weight: Union[float, int] = 1) -> None: + super().__init__(weight=weight) + + def __call__(self, pred_instances: InstanceData, + gt_instances: InstanceData, **kwargs) -> Tensor: + """Compute match cost. + + Args: + pred_instances (InstanceData): "scores" inside is + predicted classification logits, of shape + (num_queries, num_class). + gt_instances (InstanceData): "labels" inside should have + shape (num_gt, ). + + Returns: + Tensor: Match Cost matrix of shape (num_preds, num_gts). + """ + assert hasattr(pred_instances, 'scores'), \ + "pred_instances must contain 'scores'" + assert hasattr(gt_instances, 'labels'), \ + "gt_instances must contain 'labels'" + pred_scores = pred_instances.scores + gt_labels = gt_instances.labels + + pred_scores = pred_scores.softmax(-1) + cls_cost = -pred_scores[:, gt_labels] + + return cls_cost * self.weight + + +@TASK_UTILS.register_module() +class DiceCost(BaseMatchCost): + """Cost of mask assignments based on dice losses. + + Args: + pred_act (bool): Whether to apply sigmoid to mask_pred. + Defaults to False. + eps (float): Defaults to 1e-3. + naive_dice (bool): If True, use the naive dice loss + in which the power of the number in the denominator is + the first power. If False, use the second power that + is adopted by K-Net and SOLO. Defaults to True. + weight (Union[float, int]): Cost weight. Defaults to 1. + """ + + def __init__(self, + pred_act: bool = False, + eps: float = 1e-3, + naive_dice: bool = True, + weight: Union[float, int] = 1.) -> None: + super().__init__(weight=weight) + self.pred_act = pred_act + self.eps = eps + self.naive_dice = naive_dice + + def _binary_mask_dice_loss(self, mask_preds: Tensor, + gt_masks: Tensor) -> Tensor: + """ + Args: + mask_preds (Tensor): Mask prediction in shape (num_queries, *). + gt_masks (Tensor): Ground truth in shape (num_gt, *) + store 0 or 1, 0 for negative class and 1 for + positive class. + + Returns: + Tensor: Dice cost matrix in shape (num_queries, num_gt). + """ + mask_preds = mask_preds.flatten(1) + gt_masks = gt_masks.flatten(1).float() + numerator = 2 * torch.einsum('nc,mc->nm', mask_preds, gt_masks) + if self.naive_dice: + denominator = mask_preds.sum(-1)[:, None] + \ + gt_masks.sum(-1)[None, :] + else: + denominator = mask_preds.pow(2).sum(1)[:, None] + \ + gt_masks.pow(2).sum(1)[None, :] + loss = 1 - (numerator + self.eps) / (denominator + self.eps) + return loss + + def __call__(self, pred_instances: InstanceData, + gt_instances: InstanceData, **kwargs) -> Tensor: + """Compute match cost. + + Args: + pred_instances (InstanceData): Predicted instances which + must contain "masks". + gt_instances (InstanceData): Ground truth which must contain + "mask". + + Returns: + Tensor: Match Cost matrix of shape (num_preds, num_gts). + """ + assert hasattr(pred_instances, 'masks'), \ + "pred_instances must contain 'masks'" + assert hasattr(gt_instances, 'masks'), \ + "gt_instances must contain 'masks'" + pred_masks = pred_instances.masks + gt_masks = gt_instances.masks + + if self.pred_act: + pred_masks = pred_masks.sigmoid() + dice_cost = self._binary_mask_dice_loss(pred_masks, gt_masks) + return dice_cost * self.weight + + +@TASK_UTILS.register_module() +class CrossEntropyLossCost(BaseMatchCost): + """CrossEntropyLossCost. + + Args: + use_sigmoid (bool): Whether the prediction uses sigmoid + of softmax. Defaults to True. + weight (Union[float, int]): Cost weight. Defaults to 1. + """ + + def __init__(self, + use_sigmoid: bool = True, + weight: Union[float, int] = 1.) -> None: + super().__init__(weight=weight) + self.use_sigmoid = use_sigmoid + + def _binary_cross_entropy(self, cls_pred: Tensor, + gt_labels: Tensor) -> Tensor: + """ + Args: + cls_pred (Tensor): The prediction with shape (num_queries, 1, *) or + (num_queries, *). + gt_labels (Tensor): The learning label of prediction with + shape (num_gt, *). + + Returns: + Tensor: Cross entropy cost matrix in shape (num_queries, num_gt). + """ + cls_pred = cls_pred.flatten(1).float() + gt_labels = gt_labels.flatten(1).float() + n = cls_pred.shape[1] + pos = F.binary_cross_entropy_with_logits( + cls_pred, torch.ones_like(cls_pred), reduction='none') + neg = F.binary_cross_entropy_with_logits( + cls_pred, torch.zeros_like(cls_pred), reduction='none') + cls_cost = torch.einsum('nc,mc->nm', pos, gt_labels) + \ + torch.einsum('nc,mc->nm', neg, 1 - gt_labels) + cls_cost = cls_cost / n + + return cls_cost + + def __call__(self, pred_instances: InstanceData, + gt_instances: InstanceData, **kwargs) -> Tensor: + """Compute match cost. + + Args: + pred_instances (:obj:`InstanceData`): Predicted instances which + must contain ``masks``. + gt_instances (:obj:`InstanceData`): Ground truth which must contain + ``masks``. + + Returns: + Tensor: Match Cost matrix of shape (num_preds, num_gts). + """ + assert hasattr(pred_instances, 'masks'), \ + "pred_instances must contain 'masks'" + assert hasattr(gt_instances, 'masks'), \ + "gt_instances must contain 'masks'" + pred_masks = pred_instances.masks + gt_masks = gt_instances.masks + if self.use_sigmoid: + cls_cost = self._binary_cross_entropy(pred_masks, gt_masks) + else: + raise NotImplementedError + + return cls_cost * self.weight diff --git a/mmseg/models/backbones/__init__.py b/mmseg/models/backbones/__init__.py index e3107306eae..784d3dfdb70 100644 --- a/mmseg/models/backbones/__init__.py +++ b/mmseg/models/backbones/__init__.py @@ -3,6 +3,7 @@ from .bisenetv1 import BiSeNetV1 from .bisenetv2 import BiSeNetV2 from .cgnet import CGNet +from .ddrnet import DDRNet from .erfnet import ERFNet from .fast_scnn import FastSCNN from .hrnet import HRNet @@ -22,11 +23,13 @@ from .twins import PCPVT, SVT from .unet import UNet from .vit import VisionTransformer +from .vpd import VPD __all__ = [ 'ResNet', 'ResNetV1c', 'ResNetV1d', 'ResNeXt', 'HRNet', 'FastSCNN', 'ResNeSt', 'MobileNetV2', 'UNet', 'CGNet', 'MobileNetV3', 'VisionTransformer', 'SwinTransformer', 'MixVisionTransformer', 'BiSeNetV1', 'BiSeNetV2', 'ICNet', 'TIMMBackbone', 'ERFNet', 'PCPVT', - 'SVT', 'STDCNet', 'STDCContextPathNet', 'BEiT', 'MAE', 'PIDNet', 'MSCAN' + 'SVT', 'STDCNet', 'STDCContextPathNet', 'BEiT', 'MAE', 'PIDNet', 'MSCAN', + 'DDRNet', 'VPD' ] diff --git a/mmseg/models/backbones/ddrnet.py b/mmseg/models/backbones/ddrnet.py new file mode 100644 index 00000000000..4508aade82b --- /dev/null +++ b/mmseg/models/backbones/ddrnet.py @@ -0,0 +1,222 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn +from mmcv.cnn import ConvModule, build_norm_layer +from mmengine.model import BaseModule + +from mmseg.models.utils import DAPPM, BasicBlock, Bottleneck, resize +from mmseg.registry import MODELS +from mmseg.utils import OptConfigType + + +@MODELS.register_module() +class DDRNet(BaseModule): + """DDRNet backbone. + + This backbone is the implementation of `Deep Dual-resolution Networks for + Real-time and Accurate Semantic Segmentation of Road Scenes + `_. + Modified from https://github.com/ydhongHIT/DDRNet. + + Args: + in_channels (int): Number of input image channels. Default: 3. + channels: (int): The base channels of DDRNet. Default: 32. + ppm_channels (int): The channels of PPM module. Default: 128. + align_corners (bool): align_corners argument of F.interpolate. + Default: False. + norm_cfg (dict): Config dict to build norm layer. + Default: dict(type='BN', requires_grad=True). + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU', inplace=True). + init_cfg (dict, optional): Initialization config dict. + Default: None. + """ + + def __init__(self, + in_channels: int = 3, + channels: int = 32, + ppm_channels: int = 128, + align_corners: bool = False, + norm_cfg: OptConfigType = dict(type='BN', requires_grad=True), + act_cfg: OptConfigType = dict(type='ReLU', inplace=True), + init_cfg: OptConfigType = None): + super().__init__(init_cfg) + + self.in_channels = in_channels + self.ppm_channels = ppm_channels + + self.norm_cfg = norm_cfg + self.act_cfg = act_cfg + self.align_corners = align_corners + + # stage 0-2 + self.stem = self._make_stem_layer(in_channels, channels, num_blocks=2) + self.relu = nn.ReLU() + + # low resolution(context) branch + self.context_branch_layers = nn.ModuleList() + for i in range(3): + self.context_branch_layers.append( + self._make_layer( + block=BasicBlock if i < 2 else Bottleneck, + inplanes=channels * 2**(i + 1), + planes=channels * 8 if i > 0 else channels * 4, + num_blocks=2 if i < 2 else 1, + stride=2)) + + # bilateral fusion + self.compression_1 = ConvModule( + channels * 4, + channels * 2, + kernel_size=1, + norm_cfg=self.norm_cfg, + act_cfg=None) + self.down_1 = ConvModule( + channels * 2, + channels * 4, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=None) + + self.compression_2 = ConvModule( + channels * 8, + channels * 2, + kernel_size=1, + norm_cfg=self.norm_cfg, + act_cfg=None) + self.down_2 = nn.Sequential( + ConvModule( + channels * 2, + channels * 4, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg), + ConvModule( + channels * 4, + channels * 8, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=None)) + + # high resolution(spatial) branch + self.spatial_branch_layers = nn.ModuleList() + for i in range(3): + self.spatial_branch_layers.append( + self._make_layer( + block=BasicBlock if i < 2 else Bottleneck, + inplanes=channels * 2, + planes=channels * 2, + num_blocks=2 if i < 2 else 1, + )) + + self.spp = DAPPM( + channels * 16, ppm_channels, channels * 4, num_scales=5) + + def _make_stem_layer(self, in_channels, channels, num_blocks): + layers = [ + ConvModule( + in_channels, + channels, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg), + ConvModule( + channels, + channels, + kernel_size=3, + stride=2, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg) + ] + + layers.extend([ + self._make_layer(BasicBlock, channels, channels, num_blocks), + nn.ReLU(), + self._make_layer( + BasicBlock, channels, channels * 2, num_blocks, stride=2), + nn.ReLU(), + ]) + + return nn.Sequential(*layers) + + def _make_layer(self, block, inplanes, planes, num_blocks, stride=1): + downsample = None + if stride != 1 or inplanes != planes * block.expansion: + downsample = nn.Sequential( + nn.Conv2d( + inplanes, + planes * block.expansion, + kernel_size=1, + stride=stride, + bias=False), + build_norm_layer(self.norm_cfg, planes * block.expansion)[1]) + + layers = [ + block( + in_channels=inplanes, + channels=planes, + stride=stride, + downsample=downsample) + ] + inplanes = planes * block.expansion + for i in range(1, num_blocks): + layers.append( + block( + in_channels=inplanes, + channels=planes, + stride=1, + norm_cfg=self.norm_cfg, + act_cfg_out=None if i == num_blocks - 1 else self.act_cfg)) + + return nn.Sequential(*layers) + + def forward(self, x): + """Forward function.""" + out_size = (x.shape[-2] // 8, x.shape[-1] // 8) + + # stage 0-2 + x = self.stem(x) + + # stage3 + x_c = self.context_branch_layers[0](x) + x_s = self.spatial_branch_layers[0](x) + comp_c = self.compression_1(self.relu(x_c)) + x_c += self.down_1(self.relu(x_s)) + x_s += resize( + comp_c, + size=out_size, + mode='bilinear', + align_corners=self.align_corners) + if self.training: + temp_context = x_s.clone() + + # stage4 + x_c = self.context_branch_layers[1](self.relu(x_c)) + x_s = self.spatial_branch_layers[1](self.relu(x_s)) + comp_c = self.compression_2(self.relu(x_c)) + x_c += self.down_2(self.relu(x_s)) + x_s += resize( + comp_c, + size=out_size, + mode='bilinear', + align_corners=self.align_corners) + + # stage5 + x_s = self.spatial_branch_layers[2](self.relu(x_s)) + x_c = self.context_branch_layers[2](self.relu(x_c)) + x_c = self.spp(x_c) + x_c = resize( + x_c, + size=out_size, + mode='bilinear', + align_corners=self.align_corners) + + return (temp_context, x_s + x_c) if self.training else x_s + x_c diff --git a/mmseg/models/backbones/swin.py b/mmseg/models/backbones/swin.py index c0ace3c1391..67b28a96e15 100644 --- a/mmseg/models/backbones/swin.py +++ b/mmseg/models/backbones/swin.py @@ -716,20 +716,22 @@ def init_weights(self): ] for table_key in relative_position_bias_table_keys: table_pretrained = state_dict[table_key] - table_current = self.state_dict()[table_key] - L1, nH1 = table_pretrained.size() - L2, nH2 = table_current.size() - if nH1 != nH2: - print_log(f'Error in loading {table_key}, pass') - elif L1 != L2: - S1 = int(L1**0.5) - S2 = int(L2**0.5) - table_pretrained_resized = F.interpolate( - table_pretrained.permute(1, 0).reshape(1, nH1, S1, S1), - size=(S2, S2), - mode='bicubic') - state_dict[table_key] = table_pretrained_resized.view( - nH2, L2).permute(1, 0).contiguous() + if table_key in self.state_dict(): + table_current = self.state_dict()[table_key] + L1, nH1 = table_pretrained.size() + L2, nH2 = table_current.size() + if nH1 != nH2: + print_log(f'Error in loading {table_key}, pass') + elif L1 != L2: + S1 = int(L1**0.5) + S2 = int(L2**0.5) + table_pretrained_resized = F.interpolate( + table_pretrained.permute(1, 0).reshape( + 1, nH1, S1, S1), + size=(S2, S2), + mode='bicubic') + state_dict[table_key] = table_pretrained_resized.view( + nH2, L2).permute(1, 0).contiguous() # load state_dict self.load_state_dict(state_dict, strict=False) diff --git a/mmseg/models/backbones/vit.py b/mmseg/models/backbones/vit.py index 3c96f654937..dd0f688fcc4 100644 --- a/mmseg/models/backbones/vit.py +++ b/mmseg/models/backbones/vit.py @@ -132,12 +132,16 @@ class VisionTransformer(BaseModule): Args: img_size (int | tuple): Input image size. Default: 224. patch_size (int): The patch size. Default: 16. + patch_pad (str | int | None): The padding method in patch embedding. + Default: 'corner'. in_channels (int): Number of input channels. Default: 3. embed_dims (int): embedding dimension. Default: 768. num_layers (int): depth of transformer. Default: 12. num_heads (int): number of attention heads. Default: 12. mlp_ratio (int): ratio of mlp hidden dim to embedding dim. Default: 4. + out_origin (bool): Whether to output the original input embedding. + Default: False out_indices (list | tuple | int): Output from which stages. Default: -1. qkv_bias (bool): enable bias for qkv if True. Default: True. @@ -154,8 +158,12 @@ class VisionTransformer(BaseModule): Default: dict(type='LN') act_cfg (dict): The activation config for FFNs. Default: dict(type='GELU'). + patch_bias (dict): Whether use bias in convolution of PatchEmbed Block. + Default: True. patch_norm (bool): Whether to add a norm in PatchEmbed Block. Default: False. + pre_norm (bool): Whether to add a norm before Transformer Layers. + Default: False. final_norm (bool): Whether to add a additional layer to normalize final feature map. Default: False. interpolate_mode (str): Select the interpolate mode for position @@ -167,6 +175,8 @@ class VisionTransformer(BaseModule): and its variants only. Default: False. with_cp (bool): Use checkpoint or not. Using checkpoint will save some memory while slowing down the training speed. Default: False. + frozen_exclude (List): List of parameters that are not to be frozen. + Default: ["all"], "all" means there are no frozen parameters. pretrained (str, optional): model pretrained path. Default: None. init_cfg (dict or list[dict], optional): Initialization config dict. Default: None. @@ -175,11 +185,13 @@ class VisionTransformer(BaseModule): def __init__(self, img_size=224, patch_size=16, + patch_pad='corner', in_channels=3, embed_dims=768, num_layers=12, num_heads=12, mlp_ratio=4, + out_origin=False, out_indices=-1, qkv_bias=True, drop_rate=0., @@ -190,11 +202,14 @@ def __init__(self, norm_cfg=dict(type='LN'), act_cfg=dict(type='GELU'), patch_norm=False, + patch_bias=False, + pre_norm=False, final_norm=False, interpolate_mode='bicubic', num_fcs=2, norm_eval=False, with_cp=False, + frozen_exclude=['all'], pretrained=None, init_cfg=None): super().__init__(init_cfg=init_cfg) @@ -227,6 +242,8 @@ def __init__(self, self.norm_eval = norm_eval self.with_cp = with_cp self.pretrained = pretrained + self.out_origin = out_origin + self.frozen_exclude = frozen_exclude self.patch_embed = PatchEmbed( in_channels=in_channels, @@ -234,7 +251,8 @@ def __init__(self, conv_type='Conv2d', kernel_size=patch_size, stride=patch_size, - padding='corner', + padding=patch_pad, + bias=patch_bias, norm_cfg=norm_cfg if patch_norm else None, init_cfg=None, ) @@ -248,6 +266,12 @@ def __init__(self, self.pos_embed = nn.Parameter( torch.zeros(1, num_patches + 1, embed_dims)) self.drop_after_pos = nn.Dropout(p=drop_rate) + self.pre_norm = pre_norm + + if self.pre_norm: + self.pre_ln_name, pre_ln = build_norm_layer( + norm_cfg, embed_dims, postfix='_pre') + self.add_module(self.pre_ln_name, pre_ln) if isinstance(out_indices, int): if out_indices == -1: @@ -285,20 +309,36 @@ def __init__(self, norm_cfg, embed_dims, postfix=1) self.add_module(self.norm1_name, norm1) + self._freeze() + + @property + def pre_ln(self): + return getattr(self, self.pre_ln_name) + @property def norm1(self): return getattr(self, self.norm1_name) def init_weights(self): - if (isinstance(self.init_cfg, dict) - and self.init_cfg.get('type') == 'Pretrained'): + if isinstance(self.init_cfg, dict) and \ + self.init_cfg.get('type') in ['Pretrained', 'Pretrained_Part']: checkpoint = CheckpointLoader.load_checkpoint( self.init_cfg['checkpoint'], logger=None, map_location='cpu') - if 'state_dict' in checkpoint: - state_dict = checkpoint['state_dict'] - else: - state_dict = checkpoint + if self.init_cfg.get('type') == 'Pretrained': + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + else: + state_dict = checkpoint + + elif self.init_cfg.get('type') == 'Pretrained_Part': + state_dict = checkpoint.copy() + para_prefix = 'image_encoder' + prefix_len = len(para_prefix) + 1 + for k, v in checkpoint.items(): + state_dict.pop(k) + if para_prefix in k: + state_dict[k[prefix_len:]] = v if 'pos_embed' in state_dict.keys(): if self.pos_embed.shape != state_dict['pos_embed'].shape: @@ -334,6 +374,13 @@ def init_weights(self): elif isinstance(m, (_BatchNorm, nn.GroupNorm, nn.LayerNorm)): constant_init(m, val=1.0, bias=0.) + def _freeze(self): + if 'all' in self.frozen_exclude: + return + for name, param in self.named_parameters(): + if not any([exclude in name for exclude in self.frozen_exclude]): + param.requires_grad = False + def _pos_embeding(self, patched_img, hw_shape, pos_embed): """Positioning embeding method. @@ -409,7 +456,23 @@ def forward(self, inputs): # Remove class token for transformer encoder input x = x[:, 1:] + if self.pre_norm: + x = self.pre_ln(x) + outs = [] + if self.out_origin: + if self.with_cls_token: + # Remove class token and reshape token for decoder head + out = x[:, 1:] + else: + out = x + B, _, C = out.shape + out = out.reshape(B, hw_shape[0], hw_shape[1], + C).permute(0, 3, 1, 2).contiguous() + if self.output_cls_token: + out = [out, x[:, 0]] + outs.append(out) + for i, layer in enumerate(self.layers): x = layer(x) if i == len(self.layers) - 1: diff --git a/mmseg/models/backbones/vpd.py b/mmseg/models/backbones/vpd.py new file mode 100644 index 00000000000..e0536d31c64 --- /dev/null +++ b/mmseg/models/backbones/vpd.py @@ -0,0 +1,395 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# ------------------------------------------------------------------------------ +# Adapted from https://github.com/wl-zhao/VPD/blob/main/vpd/models.py +# Original licence: MIT License +# ------------------------------------------------------------------------------ + +import math +from typing import List, Optional, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmengine.model import BaseModule +from mmengine.runner import CheckpointLoader, load_checkpoint + +from mmseg.registry import MODELS +from mmseg.utils import ConfigType, OptConfigType + +try: + from ldm.modules.diffusionmodules.util import timestep_embedding + from ldm.util import instantiate_from_config + has_ldm = True +except ImportError: + has_ldm = False + + +def register_attention_control(model, controller): + """Registers a control function to manage attention within a model. + + Args: + model: The model to which attention is to be registered. + controller: The control function responsible for managing attention. + """ + + def ca_forward(self, place_in_unet): + """Custom forward method for attention. + + Args: + self: Reference to the current object. + place_in_unet: The location in UNet (down/mid/up). + + Returns: + The modified forward method. + """ + + def forward(x, context=None, mask=None): + h = self.heads + is_cross = context is not None + context = context or x # if context is None, use x + + q, k, v = self.to_q(x), self.to_k(context), self.to_v(context) + q, k, v = ( + tensor.view(tensor.shape[0] * h, tensor.shape[1], + tensor.shape[2] // h) for tensor in [q, k, v]) + + sim = torch.matmul(q, k.transpose(-2, -1)) * self.scale + + if mask is not None: + mask = mask.flatten(1).unsqueeze(1).repeat(h, 1, 1) + max_neg_value = -torch.finfo(sim.dtype).max + sim.masked_fill_(~mask, max_neg_value) + + attn = sim.softmax(dim=-1) + attn_mean = attn.view(h, attn.shape[0] // h, + *attn.shape[1:]).mean(0) + controller(attn_mean, is_cross, place_in_unet) + + out = torch.matmul(attn, v) + out = out.view(out.shape[0] // h, out.shape[1], out.shape[2] * h) + return self.to_out(out) + + return forward + + def register_recr(net_, count, place_in_unet): + """Recursive function to register the custom forward method to all + CrossAttention layers. + + Args: + net_: The network layer currently being processed. + count: The current count of layers processed. + place_in_unet: The location in UNet (down/mid/up). + + Returns: + The updated count of layers processed. + """ + if net_.__class__.__name__ == 'CrossAttention': + net_.forward = ca_forward(net_, place_in_unet) + return count + 1 + if hasattr(net_, 'children'): + return sum( + register_recr(child, 0, place_in_unet) + for child in net_.children()) + return count + + cross_att_count = sum( + register_recr(net[1], 0, place) for net, place in [ + (child, 'down') if 'input_blocks' in name else ( + child, 'up') if 'output_blocks' in name else + (child, + 'mid') if 'middle_block' in name else (None, None) # Default case + for name, child in model.diffusion_model.named_children() + ] if net is not None) + + controller.num_att_layers = cross_att_count + + +class AttentionStore: + """A class for storing attention information in the UNet model. + + Attributes: + base_size (int): Base size for storing attention information. + max_size (int): Maximum size for storing attention information. + """ + + def __init__(self, base_size=64, max_size=None): + """Initialize AttentionStore with default or custom sizes.""" + self.reset() + self.base_size = base_size + self.max_size = max_size or (base_size // 2) + self.num_att_layers = -1 + + @staticmethod + def get_empty_store(): + """Returns an empty store for holding attention values.""" + return { + key: [] + for key in [ + 'down_cross', 'mid_cross', 'up_cross', 'down_self', 'mid_self', + 'up_self' + ] + } + + def reset(self): + """Resets the step and attention stores to their initial states.""" + self.cur_step = 0 + self.cur_att_layer = 0 + self.step_store = self.get_empty_store() + self.attention_store = {} + + def forward(self, attn, is_cross: bool, place_in_unet: str): + """Processes a single forward step, storing the attention. + + Args: + attn: The attention tensor. + is_cross (bool): Whether it's cross attention. + place_in_unet (str): The location in UNet (down/mid/up). + + Returns: + The unmodified attention tensor. + """ + key = f"{place_in_unet}_{'cross' if is_cross else 'self'}" + if attn.shape[1] <= (self.max_size)**2: + self.step_store[key].append(attn) + return attn + + def between_steps(self): + """Processes and stores attention information between steps.""" + if not self.attention_store: + self.attention_store = self.step_store + else: + for key in self.attention_store: + self.attention_store[key] = [ + stored + step for stored, step in zip( + self.attention_store[key], self.step_store[key]) + ] + self.step_store = self.get_empty_store() + + def get_average_attention(self): + """Calculates and returns the average attention across all steps.""" + return { + key: [item for item in self.step_store[key]] + for key in self.step_store + } + + def __call__(self, attn, is_cross: bool, place_in_unet: str): + """Allows the class instance to be callable.""" + return self.forward(attn, is_cross, place_in_unet) + + @property + def num_uncond_att_layers(self): + """Returns the number of unconditional attention layers (default is + 0).""" + return 0 + + def step_callback(self, x_t): + """A placeholder for a step callback. + + Returns the input unchanged. + """ + return x_t + + +class UNetWrapper(nn.Module): + """A wrapper for UNet with optional attention mechanisms. + + Args: + unet (nn.Module): The UNet model to wrap + use_attn (bool): Whether to use attention. Defaults to True + base_size (int): Base size for the attention store. Defaults to 512 + max_attn_size (int, optional): Maximum size for the attention store. + Defaults to None + attn_selector (str): The types of attention to use. + Defaults to 'up_cross+down_cross' + """ + + def __init__(self, + unet, + use_attn=True, + base_size=512, + max_attn_size=None, + attn_selector='up_cross+down_cross'): + super().__init__() + + assert has_ldm, 'To use UNetWrapper, please install required ' \ + 'packages via `pip install -r requirements/optional.txt`.' + + self.unet = unet + self.attention_store = AttentionStore( + base_size=base_size // 8, max_size=max_attn_size) + self.attn_selector = attn_selector.split('+') + self.use_attn = use_attn + self.init_sizes(base_size) + if self.use_attn: + register_attention_control(unet, self.attention_store) + + def init_sizes(self, base_size): + """Initialize sizes based on the base size.""" + self.size16 = base_size // 32 + self.size32 = base_size // 16 + self.size64 = base_size // 8 + + def forward(self, x, timesteps=None, context=None, y=None, **kwargs): + """Forward pass through the model.""" + diffusion_model = self.unet.diffusion_model + if self.use_attn: + self.attention_store.reset() + hs, emb, out_list = self._unet_forward(x, timesteps, context, y, + diffusion_model) + if self.use_attn: + self._append_attn_to_output(out_list) + return out_list[::-1] + + def _unet_forward(self, x, timesteps, context, y, diffusion_model): + hs = [] + t_emb = timestep_embedding( + timesteps, diffusion_model.model_channels, repeat_only=False) + emb = diffusion_model.time_embed(t_emb) + h = x.type(diffusion_model.dtype) + for module in diffusion_model.input_blocks: + h = module(h, emb, context) + hs.append(h) + h = diffusion_model.middle_block(h, emb, context) + out_list = [] + for i_out, module in enumerate(diffusion_model.output_blocks): + h = torch.cat([h, hs.pop()], dim=1) + h = module(h, emb, context) + if i_out in [1, 4, 7]: + out_list.append(h) + h = h.type(x.dtype) + out_list.append(h) + return hs, emb, out_list + + def _append_attn_to_output(self, out_list): + avg_attn = self.attention_store.get_average_attention() + attns = {self.size16: [], self.size32: [], self.size64: []} + for k in self.attn_selector: + for up_attn in avg_attn[k]: + size = int(math.sqrt(up_attn.shape[1])) + up_attn = up_attn.transpose(-1, -2).reshape( + *up_attn.shape[:2], size, -1) + attns[size].append(up_attn) + attn16 = torch.stack(attns[self.size16]).mean(0) + attn32 = torch.stack(attns[self.size32]).mean(0) + attn64 = torch.stack(attns[self.size64]).mean(0) if len( + attns[self.size64]) > 0 else None + out_list[1] = torch.cat([out_list[1], attn16], dim=1) + out_list[2] = torch.cat([out_list[2], attn32], dim=1) + if attn64 is not None: + out_list[3] = torch.cat([out_list[3], attn64], dim=1) + + +class TextAdapter(nn.Module): + """A PyTorch Module that serves as a text adapter. + + This module takes text embeddings and adjusts them based on a scaling + factor gamma. + """ + + def __init__(self, text_dim=768): + super().__init__() + self.fc = nn.Sequential( + nn.Linear(text_dim, text_dim), nn.GELU(), + nn.Linear(text_dim, text_dim)) + + def forward(self, texts, gamma): + texts_after = self.fc(texts) + texts = texts + gamma * texts_after + return texts + + +@MODELS.register_module() +class VPD(BaseModule): + """VPD (Visual Perception Diffusion) model. + + .. _`VPD`: https://arxiv.org/abs/2303.02153 + + Args: + diffusion_cfg (dict): Configuration for diffusion model. + class_embed_path (str): Path for class embeddings. + unet_cfg (dict, optional): Configuration for U-Net. + gamma (float, optional): Gamma for text adaptation. Defaults to 1e-4. + class_embed_select (bool, optional): If True, enables class embedding + selection. Defaults to False. + pad_shape (Optional[Union[int, List[int]]], optional): Padding shape. + Defaults to None. + pad_val (Union[int, List[int]], optional): Padding value. + Defaults to 0. + init_cfg (dict, optional): Configuration for network initialization. + """ + + def __init__(self, + diffusion_cfg: ConfigType, + class_embed_path: str, + unet_cfg: OptConfigType = dict(), + gamma: float = 1e-4, + class_embed_select=False, + pad_shape: Optional[Union[int, List[int]]] = None, + pad_val: Union[int, List[int]] = 0, + init_cfg: OptConfigType = None): + + super().__init__(init_cfg=init_cfg) + + assert has_ldm, 'To use VPD model, please install required packages' \ + ' via `pip install -r requirements/optional.txt`.' + + if pad_shape is not None: + if not isinstance(pad_shape, (list, tuple)): + pad_shape = (pad_shape, pad_shape) + + self.pad_shape = pad_shape + self.pad_val = pad_val + + # diffusion model + diffusion_checkpoint = diffusion_cfg.pop('checkpoint', None) + sd_model = instantiate_from_config(diffusion_cfg) + if diffusion_checkpoint is not None: + load_checkpoint(sd_model, diffusion_checkpoint, strict=False) + + self.encoder_vq = sd_model.first_stage_model + self.unet = UNetWrapper(sd_model.model, **unet_cfg) + + # class embeddings & text adapter + class_embeddings = CheckpointLoader.load_checkpoint(class_embed_path) + text_dim = class_embeddings.size(-1) + self.text_adapter = TextAdapter(text_dim=text_dim) + self.class_embed_select = class_embed_select + if class_embed_select: + class_embeddings = torch.cat( + (class_embeddings, class_embeddings.mean(dim=0, + keepdims=True)), + dim=0) + self.register_buffer('class_embeddings', class_embeddings) + self.gamma = nn.Parameter(torch.ones(text_dim) * gamma) + + def forward(self, x): + """Extract features from images.""" + + # calculate cross-attn map + if self.class_embed_select: + if isinstance(x, (tuple, list)): + x, class_ids = x[:2] + class_ids = class_ids.tolist() + else: + class_ids = [-1] * x.size(0) + class_embeddings = self.class_embeddings[class_ids] + c_crossattn = self.text_adapter(class_embeddings, self.gamma) + c_crossattn = c_crossattn.unsqueeze(1) + else: + class_embeddings = self.class_embeddings + c_crossattn = self.text_adapter(class_embeddings, self.gamma) + c_crossattn = c_crossattn.unsqueeze(0).repeat(x.size(0), 1, 1) + + # pad to required input shape for pretrained diffusion model + if self.pad_shape is not None: + pad_width = max(0, self.pad_shape[1] - x.shape[-1]) + pad_height = max(0, self.pad_shape[0] - x.shape[-2]) + x = F.pad(x, (0, pad_width, 0, pad_height), value=self.pad_val) + + # forward the denoising model + with torch.no_grad(): + latents = self.encoder_vq.encode(x).mode().detach() + t = torch.ones((x.shape[0], ), device=x.device).long() + outs = self.unet(latents, t, context=c_crossattn) + + return outs diff --git a/mmseg/models/data_preprocessor.py b/mmseg/models/data_preprocessor.py index deef365a9e8..8d32bc647b7 100644 --- a/mmseg/models/data_preprocessor.py +++ b/mmseg/models/data_preprocessor.py @@ -132,9 +132,9 @@ def forward(self, data: dict, training: bool = False) -> Dict[str, Any]: inputs, data_samples = self.batch_augments( inputs, data_samples) else: - assert len(inputs) == 1, ( - 'Batch inference is not support currently, ' - 'as the image size might be different in a batch') + img_size = inputs[0].shape[1:] + assert all(input_.shape[1:] == img_size for input_ in inputs), \ + 'The image size in a batch should be the same.' # pad images when testing if self.test_cfg: inputs, padded_samples = stack_batch( diff --git a/mmseg/models/decode_heads/__init__.py b/mmseg/models/decode_heads/__init__.py index 18235456bc9..4229763816e 100644 --- a/mmseg/models/decode_heads/__init__.py +++ b/mmseg/models/decode_heads/__init__.py @@ -4,6 +4,7 @@ from .aspp_head import ASPPHead from .cc_head import CCHead from .da_head import DAHead +from .ddr_head import DDRHead from .dm_head import DMHead from .dnl_head import DNLHead from .dpt_head import DPTHead @@ -24,6 +25,7 @@ from .point_head import PointHead from .psa_head import PSAHead from .psp_head import PSPHead +from .san_head import SideAdapterCLIPHead from .segformer_head import SegformerHead from .segmenter_mask_head import SegmenterMaskTransformerHead from .sep_aspp_head import DepthwiseSeparableASPPHead @@ -32,6 +34,7 @@ from .setr_up_head import SETRUPHead from .stdc_head import STDCHead from .uper_head import UPerHead +from .vpd_depth_head import VPDDepthHead __all__ = [ 'FCNHead', 'PSPHead', 'ASPPHead', 'PSAHead', 'NLHead', 'GCHead', 'CCHead', @@ -41,5 +44,5 @@ 'SETRMLAHead', 'DPTHead', 'SETRMLAHead', 'SegmenterMaskTransformerHead', 'SegformerHead', 'ISAHead', 'STDCHead', 'IterativeDecodeHead', 'KernelUpdateHead', 'KernelUpdator', 'MaskFormerHead', 'Mask2FormerHead', - 'LightHamHead', 'PIDHead' + 'LightHamHead', 'PIDHead', 'DDRHead', 'VPDDepthHead', 'SideAdapterCLIPHead' ] diff --git a/mmseg/models/decode_heads/ddr_head.py b/mmseg/models/decode_heads/ddr_head.py new file mode 100644 index 00000000000..ba26d6503c0 --- /dev/null +++ b/mmseg/models/decode_heads/ddr_head.py @@ -0,0 +1,116 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Tuple, Union + +import torch.nn as nn +from mmcv.cnn import ConvModule, build_activation_layer, build_norm_layer +from torch import Tensor + +from mmseg.models.decode_heads.decode_head import BaseDecodeHead +from mmseg.models.losses import accuracy +from mmseg.models.utils import resize +from mmseg.registry import MODELS +from mmseg.utils import OptConfigType, SampleList + + +@MODELS.register_module() +class DDRHead(BaseDecodeHead): + """Decode head for DDRNet. + + Args: + in_channels (int): Number of input channels. + channels (int): Number of output channels. + num_classes (int): Number of classes. + norm_cfg (dict, optional): Config dict for normalization layer. + Default: dict(type='BN'). + act_cfg (dict, optional): Config dict for activation layer. + Default: dict(type='ReLU', inplace=True). + """ + + def __init__(self, + in_channels: int, + channels: int, + num_classes: int, + norm_cfg: OptConfigType = dict(type='BN'), + act_cfg: OptConfigType = dict(type='ReLU', inplace=True), + **kwargs): + super().__init__( + in_channels, + channels, + num_classes=num_classes, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + **kwargs) + + self.head = self._make_base_head(self.in_channels, self.channels) + self.aux_head = self._make_base_head(self.in_channels // 2, + self.channels) + self.aux_cls_seg = nn.Conv2d( + self.channels, self.out_channels, kernel_size=1) + + def init_weights(self): + for m in self.modules(): + if isinstance(m, nn.Conv2d): + nn.init.kaiming_normal_( + m.weight, mode='fan_out', nonlinearity='relu') + elif isinstance(m, nn.BatchNorm2d): + nn.init.constant_(m.weight, 1) + nn.init.constant_(m.bias, 0) + + def forward( + self, + inputs: Union[Tensor, + Tuple[Tensor]]) -> Union[Tensor, Tuple[Tensor]]: + if self.training: + c3_feat, c5_feat = inputs + x_c = self.head(c5_feat) + x_c = self.cls_seg(x_c) + x_s = self.aux_head(c3_feat) + x_s = self.aux_cls_seg(x_s) + + return x_c, x_s + else: + x_c = self.head(inputs) + x_c = self.cls_seg(x_c) + return x_c + + def _make_base_head(self, in_channels: int, + channels: int) -> nn.Sequential: + layers = [ + ConvModule( + in_channels, + channels, + kernel_size=3, + padding=1, + norm_cfg=self.norm_cfg, + act_cfg=self.act_cfg, + order=('norm', 'act', 'conv')), + build_norm_layer(self.norm_cfg, channels)[1], + build_activation_layer(self.act_cfg), + ] + + return nn.Sequential(*layers) + + def loss_by_feat(self, seg_logits: Tuple[Tensor], + batch_data_samples: SampleList) -> dict: + loss = dict() + context_logit, spatial_logit = seg_logits + seg_label = self._stack_batch_gt(batch_data_samples) + + context_logit = resize( + context_logit, + size=seg_label.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + spatial_logit = resize( + spatial_logit, + size=seg_label.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + seg_label = seg_label.squeeze(1) + + loss['loss_context'] = self.loss_decode[0](context_logit, seg_label) + loss['loss_spatial'] = self.loss_decode[1](spatial_logit, seg_label) + loss['acc_seg'] = accuracy( + context_logit, seg_label, ignore_index=self.ignore_index) + + return loss diff --git a/mmseg/models/decode_heads/decode_head.py b/mmseg/models/decode_heads/decode_head.py index 8bdbb24a1cc..4faf54559dc 100644 --- a/mmseg/models/decode_heads/decode_head.py +++ b/mmseg/models/decode_heads/decode_head.py @@ -45,7 +45,7 @@ class BaseDecodeHead(BaseModule, metaclass=ABCMeta): in_channels (int|Sequence[int]): Input channels. channels (int): Channels after modules, before conv_seg. num_classes (int): Number of classes. - out_channels (int): Output channels of conv_seg. + out_channels (int): Output channels of conv_seg. Default: None. threshold (float): Threshold for binary segmentation in the case of `num_classes==1`. Default: None. dropout_ratio (float): Ratio of dropout layer. Default: 0.1. diff --git a/mmseg/models/decode_heads/ham_head.py b/mmseg/models/decode_heads/ham_head.py index d80025f77d2..073d8011b05 100644 --- a/mmseg/models/decode_heads/ham_head.py +++ b/mmseg/models/decode_heads/ham_head.py @@ -5,6 +5,7 @@ import torch.nn as nn import torch.nn.functional as F from mmcv.cnn import ConvModule +from mmengine.device import get_device from mmseg.registry import MODELS from ..utils import resize @@ -52,7 +53,7 @@ def __init__(self, self.rand_init = rand_init - def _build_bases(self, B, S, D, R, cuda=False): + def _build_bases(self, B, S, D, R, device=None): raise NotImplementedError def local_step(self, x, bases, coef): @@ -80,14 +81,13 @@ def forward(self, x, return_bases=False): D = C // self.S N = H * W x = x.view(B * self.S, D, N) - cuda = 'cuda' in str(x.device) if not self.rand_init and not hasattr(self, 'bases'): - bases = self._build_bases(1, self.S, D, self.R, cuda=cuda) + bases = self._build_bases(1, self.S, D, self.R, device=x.device) self.register_buffer('bases', bases) # (S, D, R) -> (B * S, D, R) if self.rand_init: - bases = self._build_bases(B, self.S, D, self.R, cuda=cuda) + bases = self._build_bases(B, self.S, D, self.R, device=x.device) else: bases = self.bases.repeat(B, 1, 1) @@ -116,13 +116,11 @@ def __init__(self, args=dict()): self.inv_t = 1 - def _build_bases(self, B, S, D, R, cuda=False): + def _build_bases(self, B, S, D, R, device=None): """Build bases in initialization.""" - if cuda: - bases = torch.rand((B * S, D, R)).cuda() - else: - bases = torch.rand((B * S, D, R)) - + if device is None: + device = get_device() + bases = torch.rand((B * S, D, R)).to(device) bases = F.normalize(bases, dim=1) return bases diff --git a/mmseg/models/decode_heads/san_head.py b/mmseg/models/decode_heads/san_head.py new file mode 100644 index 00000000000..03dedf2e495 --- /dev/null +++ b/mmseg/models/decode_heads/san_head.py @@ -0,0 +1,733 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from functools import partial +from typing import Dict, List, Tuple + +import torch +import torch.nn as nn +from mmcv.cnn import ConvModule, build_norm_layer +from mmcv.cnn.bricks.transformer import BaseTransformerLayer +from mmcv.ops import point_sample +from mmengine.dist import all_reduce +from mmengine.model.weight_init import (caffe2_xavier_init, normal_init, + trunc_normal_) +from mmengine.runner.checkpoint import CheckpointLoader, load_state_dict +from mmengine.structures import InstanceData +from torch import Tensor +from torch.nn import functional as F + +from mmseg.models.backbones.vit import TransformerEncoderLayer +from mmseg.registry import MODELS +from mmseg.utils import (ConfigType, MatchMasks, SampleList, + seg_data_to_instance_data) +from ..utils import (MLP, LayerNorm2d, PatchEmbed, cross_attn_layer, + get_uncertain_point_coords_with_randomness, resize) +from .decode_head import BaseDecodeHead + + +class MLPMaskDecoder(nn.Module): + """Module for decoding query and visual features with MLP layers to + generate the attention biases and the mask proposals.""" + + def __init__( + self, + *, + in_channels: int, + total_heads: int = 1, + total_layers: int = 1, + embed_channels: int = 256, + mlp_channels: int = 256, + mlp_num_layers: int = 3, + rescale_attn_bias: bool = False, + ): + super().__init__() + self.total_heads = total_heads + self.total_layers = total_layers + + dense_affine_func = partial(nn.Conv2d, kernel_size=1) + # Query Branch + self.query_mlp = MLP(in_channels, mlp_channels, embed_channels, + mlp_num_layers) + # Pixel Branch + self.pix_mlp = MLP( + in_channels, + mlp_channels, + embed_channels, + mlp_num_layers, + affine_func=dense_affine_func, + ) + # Attention Bias Branch + self.attn_mlp = MLP( + in_channels, + mlp_channels, + embed_channels * self.total_heads * self.total_layers, + mlp_num_layers, + affine_func=dense_affine_func, + ) + if rescale_attn_bias: + self.bias_scaling = nn.Linear(1, 1) + else: + self.bias_scaling = nn.Identity() + + def forward(self, query: torch.Tensor, + x: torch.Tensor) -> Tuple[torch.Tensor, List[torch.Tensor]]: + """Forward function. + Args: + query (Tensor): Query Tokens [B,N,C]. + x (Tensor): Visual features [B,C,H,W] + + Return: + mask_preds (Tensor): Mask proposals. + attn_bias (List[Tensor]): List of attention bias. + """ + query = self.query_mlp(query) + pix = self.pix_mlp(x) + b, c, h, w = pix.shape + # preidict mask + mask_preds = torch.einsum('bqc,bchw->bqhw', query, pix) + # generate attn bias + attn = self.attn_mlp(x) + attn = attn.reshape(b, self.total_layers, self.total_heads, c, h, w) + attn_bias = torch.einsum('bqc,blnchw->blnqhw', query, attn) + attn_bias = self.bias_scaling(attn_bias[..., None]).squeeze(-1) + attn_bias = attn_bias.chunk(self.total_layers, dim=1) + attn_bias = [attn.squeeze(1) for attn in attn_bias] + return mask_preds, attn_bias + + +class SideAdapterNetwork(nn.Module): + """Side Adapter Network for predicting mask proposals and attention bias. + + Args: + in_channels (int): Number of input channels. Default: 3. + clip_channels (int): Number of channels of visual features. + Default: 768. + embed_dims (int): embedding dimension. Default: 240. + patch_size (int): The patch size. Default: 16. + patch_bias (bool): Whether use bias in patch embedding. + Default: True. + num_queries (int): Number of queries for mask proposals. + Default: 100. + fusion_index (List[int]): The layer number of the encode + transformer to fuse with the CLIP feature. + Default: [0, 1, 2, 3]. + cfg_encoder (ConfigType): Configs for the encode layers. + cfg_decoder (ConfigType): Configs for the decode layers. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN'). + """ + + def __init__( + self, + in_channels: int = 3, + clip_channels: int = 768, + embed_dims: int = 240, + patch_size: int = 16, + patch_bias: bool = True, + num_queries: int = 100, + fusion_index: list = [0, 1, 2, 3], + cfg_encoder: ConfigType = ..., + cfg_decoder: ConfigType = ..., + norm_cfg: dict = dict(type='LN'), + ): + super().__init__() + + self.patch_embed = PatchEmbed( + in_channels=in_channels, + embed_dims=embed_dims, + conv_type='Conv2d', + kernel_size=patch_size, + stride=patch_size, + padding=0, + input_size=(640, 640), + bias=patch_bias, + norm_cfg=None, + init_cfg=None, + ) + ori_h, ori_w = self.patch_embed.init_out_size + num_patches = ori_h * ori_w + self.pos_embed = nn.Parameter( + torch.randn(1, num_patches, embed_dims) * .02) + self.query_pos_embed = nn.Parameter( + torch.zeros(1, num_queries, embed_dims)) + self.query_embed = nn.Parameter( + torch.zeros(1, num_queries, embed_dims)) + encode_layers = [] + for i in range(cfg_encoder.num_encode_layer): + encode_layers.append( + TransformerEncoderLayer( + embed_dims=embed_dims, + num_heads=cfg_encoder.num_heads, + feedforward_channels=cfg_encoder.mlp_ratio * embed_dims, + norm_cfg=norm_cfg)) + self.encode_layers = nn.ModuleList(encode_layers) + conv_clips = [] + for i in range(len(fusion_index)): + conv_clips.append( + nn.Sequential( + LayerNorm2d(clip_channels), + ConvModule( + clip_channels, + embed_dims, + kernel_size=1, + norm_cfg=None, + act_cfg=None))) + self.conv_clips = nn.ModuleList(conv_clips) + self.fusion_index = fusion_index + self.mask_decoder = MLPMaskDecoder( + in_channels=embed_dims, + total_heads=cfg_decoder.num_heads, + total_layers=cfg_decoder.num_layers, + embed_channels=cfg_decoder.embed_channels, + mlp_channels=cfg_decoder.mlp_channels, + mlp_num_layers=cfg_decoder.num_mlp, + rescale_attn_bias=cfg_decoder.rescale) + + def init_weights(self): + trunc_normal_(self.pos_embed, std=0.02) + nn.init.normal_(self.query_embed, std=0.02) + nn.init.normal_(self.query_pos_embed, std=0.02) + for i in range(len(self.conv_clips)): + caffe2_xavier_init(self.conv_clips[i][1].conv) + + def fuse_clip(self, fused_index: int, x: torch.Tensor, + clip_feature: torch.Tensor, hwshape: Tuple[int, + int], L: int): + """Fuse CLIP feature and visual tokens.""" + fused_clip = (resize( + self.conv_clips[fused_index](clip_feature.contiguous()), + size=hwshape, + mode='bilinear', + align_corners=False)).permute(0, 2, 3, 1).reshape(x[:, -L:, + ...].shape) + x = torch.cat([x[:, :-L, ...], x[:, -L:, ...] + fused_clip], dim=1) + return x + + def encode_feature(self, image: torch.Tensor, + clip_features: List[torch.Tensor], + deep_supervision_idxs: List[int]) -> List[List]: + """Encode images by a lightweight vision transformer.""" + assert len(self.fusion_index) == len(clip_features) + x, hwshape = self.patch_embed(image) + ori_h, ori_w = self.patch_embed.init_out_size + pos_embed = self.pos_embed + if self.pos_embed.shape[1] != x.shape[1]: + # resize the position embedding + pos_embed = ( + resize( + self.pos_embed.reshape(1, ori_h, ori_w, + -1).permute(0, 3, 1, 2), + size=hwshape, + mode='bicubic', + align_corners=False, + ).flatten(2).permute(0, 2, 1)) + pos_embed = torch.cat([ + self.query_pos_embed.expand(pos_embed.shape[0], -1, -1), pos_embed + ], + dim=1) + x = torch.cat([self.query_embed.expand(x.shape[0], -1, -1), x], dim=1) + x = x + pos_embed + L = hwshape[0] * hwshape[1] + fused_index = 0 + if self.fusion_index[fused_index] == 0: + x = self.fuse_clip(fused_index, x, clip_features[0][0], hwshape, L) + fused_index += 1 + outs = [] + for index, block in enumerate(self.encode_layers, start=1): + x = block(x) + if index < len(self.fusion_index + ) and index == self.fusion_index[fused_index]: + x = self.fuse_clip(fused_index, x, + clip_features[fused_index][0], hwshape, L) + fused_index += 1 + x_query = x[:, :-L, ...] + x_feat = x[:, -L:, ...].permute(0, 2, 1)\ + .reshape(x.shape[0], x.shape[-1], hwshape[0], hwshape[1]) + + if index in deep_supervision_idxs or index == len( + self.encode_layers): + outs.append({'query': x_query, 'x': x_feat}) + + if index < len(self.encode_layers): + x = x + pos_embed + return outs + + def decode_feature(self, features): + mask_embeds = [] + attn_biases = [] + for feature in features: + mask_embed, attn_bias = self.mask_decoder(**feature) + mask_embeds.append(mask_embed) + attn_biases.append(attn_bias) + return mask_embeds, attn_biases + + def forward( + self, image: torch.Tensor, clip_features: List[torch.Tensor], + deep_supervision_idxs: List[int] + ) -> Tuple[List[torch.Tensor], List[List[torch.Tensor]]]: + """Forward function.""" + features = self.encode_feature(image, clip_features, + deep_supervision_idxs) + mask_embeds, attn_biases = self.decode_feature(features) + return mask_embeds, attn_biases + + +class RecWithAttnbias(nn.Module): + """Mask recognition module by applying the attention biases to rest deeper + CLIP layers. + + Args: + sos_token_format (str): The format of sos token. It should be + chosen from ["cls_token", "learnable_token", "pos_embedding"]. + Default: 'cls_token'. + sos_token_num (int): Number of sos token. It should be equal to + the number of quries. Default: 100. + num_layers (int): Number of rest CLIP layers for mask recognition. + Default: 3. + cross_attn (bool): Whether use cross attention to update sos token. + Default: False. + embed_dims (int): The feature dimension of CLIP layers. + Default: 768. + num_heads (int): Parallel attention heads of CLIP layers. + Default: 768. + mlp_ratio (int): Ratio of mlp hidden dim to embedding dim. + Default: 4. + qkv_bias (bool): Whether to use bias in multihead-attention. + Default: True. + out_dims (int): Number of channels of the output mask proposals. + It should be equal to the out_dims of text_encoder. + Default: 512. + final_norm (True): Whether use norm layer for sos token. + act_cfg (dict): The activation config for FFNs. + Default: dict(type='GELU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN'). + frozen_exclude (List): List of parameters that are not to be frozen. + """ + + def __init__(self, + sos_token_format: str = 'cls_token', + sos_token_num: int = 100, + num_layers: int = 3, + cross_attn: bool = False, + embed_dims: int = 768, + num_heads: int = 12, + mlp_ratio: int = 4, + num_fcs: int = 2, + qkv_bias: bool = True, + out_dims: int = 512, + final_norm: bool = True, + act_cfg: dict = dict(type='GELU'), + norm_cfg: dict = dict(type='LN'), + frozen_exclude: List = []): + super().__init__() + + assert sos_token_format in [ + 'cls_token', 'learnable_token', 'pos_embedding' + ] + self.sos_token_format = sos_token_format + self.sos_token_num = sos_token_num + self.frozen_exclude = frozen_exclude + self.cross_attn = cross_attn + self.num_layers = num_layers + self.num_heads = num_heads + if sos_token_format in ['learnable_token', 'pos_embedding']: + self.sos_token = nn.Parameter( + torch.randn(sos_token_num, 1, self.proj.shape[0])) + self.frozen.append('sos_token') + + layers = [] + for i in range(num_layers): + layers.append( + BaseTransformerLayer( + attn_cfgs=dict( + type='MultiheadAttention', + embed_dims=embed_dims, + num_heads=num_heads, + batch_first=False, + bias=qkv_bias), + ffn_cfgs=dict( + type='FFN', + embed_dims=embed_dims, + feedforward_channels=mlp_ratio * embed_dims, + act_cfg=act_cfg), + operation_order=('norm', 'self_attn', 'norm', 'ffn'))) + self.layers = nn.ModuleList(layers) + + self.ln_post = build_norm_layer(norm_cfg, embed_dims)[1] + self.proj = nn.Linear(embed_dims, out_dims, bias=False) + + self.final_norm = final_norm + self._freeze() + + def init_weights(self, rec_state_dict): + if hasattr(self, 'sos_token'): + normal_init(self.sos_token, std=0.02) + if rec_state_dict is not None: + load_state_dict(self, rec_state_dict, strict=False, logger=None) + else: + super().init_weights() + + def _freeze(self): + if 'all' in self.frozen_exclude: + return + for name, param in self.named_parameters(): + if not any([exclude in name for exclude in self.frozen_exclude]): + param.requires_grad = False + + def _build_attn_biases(self, attn_biases, target_shape): + formatted_attn_biases = [] + for attn_bias in attn_biases: + # convert it to proper format: N*num_head,L,L + # attn_bias: [N, num_head/1, num_sos,H,W] + n, num_head, num_sos, h, w = attn_bias.shape + # reshape and downsample + attn_bias = F.adaptive_max_pool2d( + attn_bias.reshape(n, num_head * num_sos, h, w), + output_size=target_shape) + attn_bias = attn_bias.reshape(n, num_head, num_sos, *target_shape) + + true_num_head = self.num_heads + assert (num_head == 1 or num_head + == true_num_head), f'num_head={num_head} is not supported.' + if num_head == 1: + attn_bias = attn_bias.repeat(1, true_num_head, 1, 1, 1) + attn_bias = attn_bias.reshape(n * true_num_head, num_sos, -1) + L = attn_bias.shape[-1] + if self.cross_attn: + # [n*num_head, num_sos, L] + formatted_attn_biases.append(attn_bias) + else: + # [n*num_head, num_sos+1+L, num_sos+1+L] + new_attn_bias = attn_bias.new_zeros(num_sos + 1 + L, + num_sos + 1 + L) + new_attn_bias[:, :num_sos] = -100 + new_attn_bias[torch.arange(num_sos), torch.arange(num_sos)] = 0 + new_attn_bias[:num_sos, num_sos] = -100 + new_attn_bias = ( + new_attn_bias[None, ...].expand(n * true_num_head, -1, + -1).clone()) + new_attn_bias[..., :num_sos, -L:] = attn_bias + formatted_attn_biases.append(new_attn_bias) + + if len(formatted_attn_biases) == 1: + formatted_attn_biases = [ + formatted_attn_biases[0] for _ in range(self.num_layers) + ] + return formatted_attn_biases + + def forward(self, bias: List[Tensor], feature: List[Tensor]): + """Forward function to recognize the category of masks + Args: + bias (List[Tensor]): Attention bias for transformer layers + feature (List[Tensor]): Output of the image encoder, + including cls_token and img_feature. + """ + cls_token = feature[1].unsqueeze(0) + img_feature = feature[0] + b, c, h, w = img_feature.shape + # construct clip shadow features + x = torch.cat( + [cls_token, + img_feature.reshape(b, c, -1).permute(2, 0, 1)]) + + # construct sos token + if self.sos_token_format == 'cls_token': + sos_token = cls_token.repeat(self.sos_token_num, 1, 1) + elif self.sos_token_format == 'learnable_token': + sos_token = self.sos_token.expand(-1, b, -1) + elif self.sos_token_format == 'pos_embedding': + sos_token = self.sos_token.expand(-1, b, -1) + cls_token + + # construct attn bias + attn_biases = self._build_attn_biases(bias, target_shape=(h, w)) + + if self.cross_attn: + for i, block in enumerate(self.layers): + if self.cross_attn: + sos_token = cross_attn_layer( + block, + sos_token, + x[1:, ], + attn_biases[i], + ) + if i < len(self.layers) - 1: + x = block(x) + else: + x = torch.cat([sos_token, x], dim=0) + for i, block in enumerate(self.layers): + x = block(x, attn_masks=[attn_biases[i]]) + sos_token = x[:self.sos_token_num] + + sos_token = sos_token.permute(1, 0, 2) # LND -> NLD + sos_token = self.ln_post(sos_token) + sos_token = self.proj(sos_token) + if self.final_norm: + sos_token = F.normalize(sos_token, dim=-1) + return sos_token + + +@MODELS.register_module() +class SideAdapterCLIPHead(BaseDecodeHead): + """Side Adapter Network (SAN) for open-vocabulary semantic segmentation + with pre-trained vision-language model. + + This decode head is the implementation of `Side Adapter Network + for Open-Vocabulary Semantic Segmentation` + . + Modified from https://github.com/MendelXu/SAN/blob/main/san/model/side_adapter/side_adapter.py # noqa:E501 + Copyright (c) 2023 MendelXu. + Licensed under the MIT License + + Args: + num_classes (int): the number of classes. + san_cfg (ConfigType): Configs for SideAdapterNetwork module + maskgen_cfg (ConfigType): Configs for RecWithAttnbias module + """ + + def __init__(self, num_classes: int, san_cfg: ConfigType, + maskgen_cfg: ConfigType, deep_supervision_idxs: List[int], + train_cfg: ConfigType, **kwargs): + super().__init__( + in_channels=san_cfg.in_channels, + channels=san_cfg.embed_dims, + num_classes=num_classes, + **kwargs) + assert san_cfg.num_queries == maskgen_cfg.sos_token_num, \ + 'num_queries in san_cfg should be equal to sos_token_num ' \ + 'in maskgen_cfg' + del self.conv_seg + self.side_adapter_network = SideAdapterNetwork(**san_cfg) + self.rec_with_attnbias = RecWithAttnbias(**maskgen_cfg) + self.deep_supervision_idxs = deep_supervision_idxs + self.train_cfg = train_cfg + if train_cfg: + self.match_masks = MatchMasks( + num_points=train_cfg.num_points, + num_queries=san_cfg.num_queries, + num_classes=num_classes, + assigner=train_cfg.assigner) + + def init_weights(self): + + rec_state_dict = None + if isinstance(self.init_cfg, dict) and \ + self.init_cfg.get('type') == 'Pretrained_Part': + checkpoint = CheckpointLoader.load_checkpoint( + self.init_cfg['checkpoint'], logger=None, map_location='cpu') + + rec_state_dict = checkpoint.copy() + para_prefix = 'decode_head.rec_with_attnbias' + prefix_len = len(para_prefix) + 1 + for k, v in checkpoint.items(): + rec_state_dict.pop(k) + if para_prefix in k: + rec_state_dict[k[prefix_len:]] = v + + self.side_adapter_network.init_weights() + self.rec_with_attnbias.init_weights(rec_state_dict) + + def forward(self, inputs: Tuple[Tensor], + deep_supervision_idxs) -> Tuple[List]: + """Forward function. + + Args: + inputs (Tuple[Tensor]): A triplet including images, + list of multi-level visual features from image encoder and + class embeddings from text_encoder. + + Returns: + mask_props (List[Tensor]): Mask proposals predicted by SAN. + mask_logits (List[Tensor]): Class logits of mask proposals. + """ + imgs, clip_feature, class_embeds = inputs + # predict mask proposals and attention bias + mask_props, attn_biases = self.side_adapter_network( + imgs, clip_feature, deep_supervision_idxs) + + # mask recognition with attention bias + mask_embeds = [ + self.rec_with_attnbias(att_bias, clip_feature[-1]) + for att_bias in attn_biases + ] + # Obtain class prediction of masks by comparing the similarity + # between the image token and the text embedding of class names. + mask_logits = [ + torch.einsum('bqc,nc->bqn', mask_embed, class_embeds) + for mask_embed in mask_embeds + ] + return mask_props, mask_logits + + def predict(self, inputs: Tuple[Tensor], batch_img_metas: List[dict], + test_cfg: ConfigType) -> Tensor: + """Forward function for prediction. + + Args: + inputs (Tuple[Tensor]): Images, visual features from image encoder + and class embedding from text encoder. + batch_img_metas (dict): List Image info where each dict may also + contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', and 'pad_shape'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + test_cfg (dict): The testing config. + + Returns: + Tensor: Outputs segmentation logits map. + """ + mask_props, mask_logits = self.forward(inputs, []) + + return self.predict_by_feat([mask_props[-1], mask_logits[-1]], + batch_img_metas) + + def predict_by_feat(self, seg_logits: List[Tensor], + batch_img_metas: List[dict]) -> Tensor: + """1. Transform a batch of mask proposals to the input shape. + 2. Generate segmentation map with mask proposals and class logits. + """ + mask_pred = seg_logits[0] + cls_score = seg_logits[1] + if 'pad_shape' in batch_img_metas[0]: + size = batch_img_metas[0]['pad_shape'] + else: + size = batch_img_metas[0]['img_shape'] + # upsample mask + mask_pred = F.interpolate( + mask_pred, size=size, mode='bilinear', align_corners=False) + + mask_cls = F.softmax(cls_score, dim=-1)[..., :-1] + mask_pred = mask_pred.sigmoid() + seg_logits = torch.einsum('bqc,bqhw->bchw', mask_cls, mask_pred) + return seg_logits + + def loss(self, x: Tuple[Tensor], batch_data_samples: SampleList, + train_cfg: ConfigType) -> dict: + """Perform forward propagation and loss calculation of the decoder head + on the features of the upstream network. + + Args: + x (tuple[Tensor]): Multi-level features from the upstream + network, each is a 4D-tensor. + batch_data_samples (List[:obj:`SegDataSample`]): The Data + Samples. It usually includes information such as + `gt_sem_seg`. + train_cfg (ConfigType): Training config. + + Returns: + dict[str, Tensor]: a dictionary of loss components. + """ + # batch SegDataSample to InstanceDataSample + batch_gt_instances = seg_data_to_instance_data(self.ignore_index, + batch_data_samples) + + # forward + all_mask_props, all_mask_logits = self.forward( + x, self.deep_supervision_idxs) + + # loss + losses = self.loss_by_feat(all_mask_logits, all_mask_props, + batch_gt_instances) + + return losses + + def loss_by_feat( + self, all_cls_scores: Tensor, all_mask_preds: Tensor, + batch_gt_instances: List[InstanceData]) -> Dict[str, Tensor]: + """Loss function. + + Args: + all_cls_scores (Tensor): Classification scores for all decoder + layers with shape (num_decoder, batch_size, num_queries, + cls_out_channels). Note `cls_out_channels` should includes + background. + all_mask_preds (Tensor): Mask scores for all decoder layers with + shape (num_decoder, batch_size, num_queries, h, w). + batch_gt_instances (list[obj:`InstanceData`]): each contains + ``labels`` and ``masks``. + + Returns: + dict[str, Tensor]: A dictionary of loss components. + """ + num_dec_layers = len(all_cls_scores) + batch_gt_instances_list = [ + batch_gt_instances for _ in range(num_dec_layers) + ] + + losses = [] + for i in range(num_dec_layers): + cls_scores = all_cls_scores[i] + mask_preds = all_mask_preds[i] + # matching N mask predictions to K category labels + (labels, mask_targets, mask_weights, + avg_factor) = self.match_masks.get_targets( + cls_scores, mask_preds, batch_gt_instances_list[i]) + cls_scores = cls_scores.flatten(0, 1) + labels = labels.flatten(0, 1) + num_total_masks = cls_scores.new_tensor([avg_factor], + dtype=torch.float) + all_reduce(num_total_masks, op='mean') + num_total_masks = max(num_total_masks, 1) + + # extract positive ones + # shape (batch_size, num_queries, h, w) -> (num_total_gts, h, w) + mask_preds = mask_preds[mask_weights > 0] + + if mask_targets.shape[0] != 0: + with torch.no_grad(): + points_coords = get_uncertain_point_coords_with_randomness( + mask_preds.unsqueeze(1), None, + self.train_cfg.num_points, + self.train_cfg.oversample_ratio, + self.train_cfg.importance_sample_ratio) + # shape (num_total_gts, h, w) + # -> (num_total_gts, num_points) + mask_point_targets = point_sample( + mask_targets.unsqueeze(1).float(), + points_coords).squeeze(1) + # shape (num_queries, h, w) -> (num_queries, num_points) + mask_point_preds = point_sample( + mask_preds.unsqueeze(1), points_coords).squeeze(1) + + if not isinstance(self.loss_decode, nn.ModuleList): + losses_decode = [self.loss_decode] + else: + losses_decode = self.loss_decode + loss = dict() + for loss_decode in losses_decode: + if 'loss_cls' in loss_decode.loss_name: + if loss_decode.loss_name == 'loss_cls_ce': + loss[loss_decode.loss_name] = loss_decode( + cls_scores, labels) + else: + assert False, "Only support 'CrossEntropyLoss' in" \ + ' classification loss' + + elif 'loss_mask' in loss_decode.loss_name: + if mask_targets.shape[0] == 0: + loss[loss_decode.loss_name] = mask_preds.sum() + elif loss_decode.loss_name == 'loss_mask_ce': + loss[loss_decode.loss_name] = loss_decode( + mask_point_preds, + mask_point_targets, + avg_factor=num_total_masks * + self.train_cfg.num_points) + elif loss_decode.loss_name == 'loss_mask_dice': + loss[loss_decode.loss_name] = loss_decode( + mask_point_preds, + mask_point_targets, + avg_factor=num_total_masks) + else: + assert False, "Only support 'CrossEntropyLoss' and" \ + " 'DiceLoss' in mask loss" + else: + assert False, "Only support for 'loss_cls' and 'loss_mask'" + + losses.append(loss) + + loss_dict = dict() + # loss from the last decoder layer + loss_dict.update(losses[-1]) + # loss from other decoder layers + for i, loss in enumerate(losses[:-1]): + for k, v in loss.items(): + loss_dict[f'd{self.deep_supervision_idxs[i]}.{k}'] = v + return loss_dict diff --git a/mmseg/models/decode_heads/vpd_depth_head.py b/mmseg/models/decode_heads/vpd_depth_head.py new file mode 100644 index 00000000000..0c54c2da1b1 --- /dev/null +++ b/mmseg/models/decode_heads/vpd_depth_head.py @@ -0,0 +1,254 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Dict, List, Optional, Sequence, Union + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import build_conv_layer, build_norm_layer, build_upsample_layer +from mmengine.model import BaseModule +from torch import Tensor + +from mmseg.registry import MODELS +from mmseg.utils import SampleList +from ..builder import build_loss +from ..utils import resize +from .decode_head import BaseDecodeHead + + +class VPDDepthDecoder(BaseModule): + """VPD Depth Decoder class. + + Args: + in_channels (int): Number of input channels. + out_channels (int): Number of output channels. + num_deconv_layers (int): Number of deconvolution layers. + num_deconv_filters (List[int]): List of output channels for + deconvolution layers. + init_cfg (Optional[Union[Dict, List[Dict]]], optional): Configuration + for weight initialization. Defaults to Normal for Conv2d and + ConvTranspose2d layers. + """ + + def __init__(self, + in_channels: int, + out_channels: int, + num_deconv_layers: int, + num_deconv_filters: List[int], + init_cfg: Optional[Union[Dict, List[Dict]]] = dict( + type='Normal', + std=0.001, + layer=['Conv2d', 'ConvTranspose2d'])): + super().__init__(init_cfg=init_cfg) + self.in_channels = in_channels + + self.deconv_layers = self._make_deconv_layer( + num_deconv_layers, + num_deconv_filters, + ) + + conv_layers = [] + conv_layers.append( + build_conv_layer( + dict(type='Conv2d'), + in_channels=num_deconv_filters[-1], + out_channels=out_channels, + kernel_size=3, + stride=1, + padding=1)) + conv_layers.append(build_norm_layer(dict(type='BN'), out_channels)[1]) + conv_layers.append(nn.ReLU(inplace=True)) + self.conv_layers = nn.Sequential(*conv_layers) + + self.up_sample = nn.Upsample( + scale_factor=2, mode='bilinear', align_corners=False) + + def forward(self, x): + """Forward pass through the decoder network.""" + out = self.deconv_layers(x) + out = self.conv_layers(out) + + out = self.up_sample(out) + out = self.up_sample(out) + + return out + + def _make_deconv_layer(self, num_layers, num_deconv_filters): + """Make deconv layers.""" + + layers = [] + in_channels = self.in_channels + for i in range(num_layers): + + num_channels = num_deconv_filters[i] + layers.append( + build_upsample_layer( + dict(type='deconv'), + in_channels=in_channels, + out_channels=num_channels, + kernel_size=2, + stride=2, + padding=0, + output_padding=0, + bias=False)) + layers.append(nn.BatchNorm2d(num_channels)) + layers.append(nn.ReLU(inplace=True)) + in_channels = num_channels + + return nn.Sequential(*layers) + + +@MODELS.register_module() +class VPDDepthHead(BaseDecodeHead): + """Depth Prediction Head for VPD. + + .. _`VPD`: https://arxiv.org/abs/2303.02153 + + Args: + max_depth (float): Maximum depth value. Defaults to 10.0. + in_channels (Sequence[int]): Number of input channels for each + convolutional layer. + embed_dim (int): Dimension of embedding. Defaults to 192. + feature_dim (int): Dimension of aggregated feature. Defaults to 1536. + num_deconv_layers (int): Number of deconvolution layers in the + decoder. Defaults to 3. + num_deconv_filters (Sequence[int]): Number of filters for each deconv + layer. Defaults to (32, 32, 32). + fmap_border (Union[int, Sequence[int]]): Feature map border for + cropping. Defaults to 0. + align_corners (bool): Flag for align_corners in interpolation. + Defaults to False. + loss_decode (dict): Configurations for the loss function. Defaults to + dict(type='SiLogLoss'). + init_cfg (dict): Initialization configurations. Defaults to + dict(type='TruncNormal', std=0.02, layer=['Conv2d', 'Linear']). + """ + + num_classes = 1 + out_channels = 1 + input_transform = None + + def __init__( + self, + max_depth: float = 10.0, + in_channels: Sequence[int] = [320, 640, 1280, 1280], + embed_dim: int = 192, + feature_dim: int = 1536, + num_deconv_layers: int = 3, + num_deconv_filters: Sequence[int] = (32, 32, 32), + fmap_border: Union[int, Sequence[int]] = 0, + align_corners: bool = False, + loss_decode: dict = dict(type='SiLogLoss'), + init_cfg=dict( + type='TruncNormal', std=0.02, layer=['Conv2d', 'Linear']), + ): + + super(BaseDecodeHead, self).__init__(init_cfg=init_cfg) + + # initialize parameters + self.in_channels = in_channels + self.max_depth = max_depth + self.align_corners = align_corners + + # feature map border + if isinstance(fmap_border, int): + fmap_border = (fmap_border, fmap_border) + self.fmap_border = fmap_border + + # define network layers + self.conv1 = nn.Sequential( + nn.Conv2d(in_channels[0], in_channels[0], 3, stride=2, padding=1), + nn.GroupNorm(16, in_channels[0]), + nn.ReLU(), + nn.Conv2d(in_channels[0], in_channels[0], 3, stride=2, padding=1), + ) + self.conv2 = nn.Conv2d( + in_channels[1], in_channels[1], 3, stride=2, padding=1) + + self.conv_aggregation = nn.Sequential( + nn.Conv2d(sum(in_channels), feature_dim, 1), + nn.GroupNorm(16, feature_dim), + nn.ReLU(), + ) + + self.decoder = VPDDepthDecoder( + in_channels=embed_dim * 8, + out_channels=embed_dim, + num_deconv_layers=num_deconv_layers, + num_deconv_filters=num_deconv_filters) + + self.depth_pred_layer = nn.Sequential( + nn.Conv2d( + embed_dim, embed_dim, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=False), + nn.Conv2d(embed_dim, 1, kernel_size=3, stride=1, padding=1)) + + # build loss + if isinstance(loss_decode, dict): + self.loss_decode = build_loss(loss_decode) + elif isinstance(loss_decode, (list, tuple)): + self.loss_decode = nn.ModuleList() + for loss in loss_decode: + self.loss_decode.append(build_loss(loss)) + else: + raise TypeError(f'loss_decode must be a dict or sequence of dict,\ + but got {type(loss_decode)}') + + def _stack_batch_gt(self, batch_data_samples: SampleList) -> Tensor: + gt_depth_maps = [ + data_sample.gt_depth_map.data for data_sample in batch_data_samples + ] + return torch.stack(gt_depth_maps, dim=0) + + def forward(self, x): + x = [ + x[0], x[1], + torch.cat([x[2], F.interpolate(x[3], scale_factor=2)], dim=1) + ] + x = torch.cat([self.conv1(x[0]), self.conv2(x[1]), x[2]], dim=1) + x = self.conv_aggregation(x) + + x = x[:, :, :x.size(2) - self.fmap_border[0], :x.size(3) - + self.fmap_border[1]].contiguous() + x = self.decoder(x) + out = self.depth_pred_layer(x) + + depth = torch.sigmoid(out) * self.max_depth + + return depth + + def loss_by_feat(self, pred_depth_map: Tensor, + batch_data_samples: SampleList) -> dict: + """Compute depth estimation loss. + + Args: + pred_depth_map (Tensor): The output from decode head forward + function. + batch_data_samples (List[:obj:`SegDataSample`]): The seg + data samples. It usually includes information such + as `metainfo` and `gt_dpeth_map`. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + + gt_depth_map = self._stack_batch_gt(batch_data_samples) + loss = dict() + pred_depth_map = resize( + input=pred_depth_map, + size=gt_depth_map.shape[2:], + mode='bilinear', + align_corners=self.align_corners) + + if not isinstance(self.loss_decode, nn.ModuleList): + losses_decode = [self.loss_decode] + else: + losses_decode = self.loss_decode + for loss_decode in losses_decode: + if loss_decode.loss_name not in loss: + loss[loss_decode.loss_name] = loss_decode( + pred_depth_map, gt_depth_map) + else: + loss[loss_decode.loss_name] += loss_decode( + pred_depth_map, gt_depth_map) + + return loss diff --git a/mmseg/models/losses/__init__.py b/mmseg/models/losses/__init__.py index 2f7e39cb28b..0467cb3ad89 100644 --- a/mmseg/models/losses/__init__.py +++ b/mmseg/models/losses/__init__.py @@ -5,8 +5,10 @@ cross_entropy, mask_cross_entropy) from .dice_loss import DiceLoss from .focal_loss import FocalLoss +from .huasdorff_distance_loss import HuasdorffDisstanceLoss from .lovasz_loss import LovaszLoss from .ohem_cross_entropy_loss import OhemCrossEntropy +from .silog_loss import SiLogLoss from .tversky_loss import TverskyLoss from .utils import reduce_loss, weight_reduce_loss, weighted_loss @@ -14,5 +16,6 @@ 'accuracy', 'Accuracy', 'cross_entropy', 'binary_cross_entropy', 'mask_cross_entropy', 'CrossEntropyLoss', 'reduce_loss', 'weight_reduce_loss', 'weighted_loss', 'LovaszLoss', 'DiceLoss', - 'FocalLoss', 'TverskyLoss', 'OhemCrossEntropy', 'BoundaryLoss' + 'FocalLoss', 'TverskyLoss', 'OhemCrossEntropy', 'BoundaryLoss', + 'HuasdorffDisstanceLoss', 'SiLogLoss' ] diff --git a/mmseg/models/losses/cross_entropy_loss.py b/mmseg/models/losses/cross_entropy_loss.py index 770b9974861..65553472c0f 100644 --- a/mmseg/models/losses/cross_entropy_loss.py +++ b/mmseg/models/losses/cross_entropy_loss.py @@ -53,8 +53,22 @@ def cross_entropy(pred, # average loss over non-ignored elements # pytorch's official cross_entropy average loss over non-ignored elements # refer to https://github.com/pytorch/pytorch/blob/56b43f4fec1f76953f15a627694d4bba34588969/torch/nn/functional.py#L2660 # noqa - if (avg_factor is None) and avg_non_ignore and reduction == 'mean': - avg_factor = label.numel() - (label == ignore_index).sum().item() + if (avg_factor is None) and reduction == 'mean': + if class_weight is None: + if avg_non_ignore: + avg_factor = label.numel() - (label + == ignore_index).sum().item() + else: + avg_factor = label.numel() + + else: + # the average factor should take the class weights into account + label_weights = torch.tensor([class_weight[cls] for cls in label], + device=class_weight.device) + if avg_non_ignore: + label_weights[label == ignore_index] = 0 + avg_factor = label_weights.sum() + if weight is not None: weight = weight.float() loss = weight_reduce_loss( @@ -124,7 +138,7 @@ def binary_cross_entropy(pred, assert label[label != ignore_index].max() <= 1, \ 'For pred with shape [N, 1, H, W], its label must have at ' \ 'most 2 classes' - pred = pred.squeeze() + pred = pred.squeeze(1) if pred.dim() != label.dim(): assert (pred.dim() == 2 and label.dim() == 1) or ( pred.dim() == 4 and label.dim() == 3), \ diff --git a/mmseg/models/losses/dice_loss.py b/mmseg/models/losses/dice_loss.py index 2ee89a81f4e..fb2ffdba8da 100644 --- a/mmseg/models/losses/dice_loss.py +++ b/mmseg/models/losses/dice_loss.py @@ -1,125 +1,190 @@ # Copyright (c) OpenMMLab. All rights reserved. -"""Modified from https://github.com/LikeLy-Journey/SegmenTron/blob/master/ -segmentron/solver/loss.py (Apache-2.0 License)""" +from typing import Union + import torch import torch.nn as nn -import torch.nn.functional as F from mmseg.registry import MODELS -from .utils import get_class_weight, weighted_loss - - -@weighted_loss -def dice_loss(pred, - target, - valid_mask, - smooth=1, - exponent=2, - class_weight=None, - ignore_index=255): - assert pred.shape[0] == target.shape[0] - total_loss = 0 - num_classes = pred.shape[1] - for i in range(num_classes): - if i != ignore_index: - dice_loss = binary_dice_loss( - pred[:, i], - target[..., i], - valid_mask=valid_mask, - smooth=smooth, - exponent=exponent) - if class_weight is not None: - dice_loss *= class_weight[i] - total_loss += dice_loss - return total_loss / num_classes +from .utils import weight_reduce_loss -@weighted_loss -def binary_dice_loss(pred, target, valid_mask, smooth=1, exponent=2, **kwards): - assert pred.shape[0] == target.shape[0] - pred = pred.reshape(pred.shape[0], -1) - target = target.reshape(target.shape[0], -1) - valid_mask = valid_mask.reshape(valid_mask.shape[0], -1) +def _expand_onehot_labels_dice(pred: torch.Tensor, + target: torch.Tensor) -> torch.Tensor: + """Expand onehot labels to match the size of prediction. - num = torch.sum(torch.mul(pred, target) * valid_mask, dim=1) * 2 + smooth - den = torch.sum(pred.pow(exponent) + target.pow(exponent), dim=1) + smooth + Args: + pred (torch.Tensor): The prediction, has a shape (N, num_class, H, W). + target (torch.Tensor): The learning label of the prediction, + has a shape (N, H, W). - return 1 - num / den + Returns: + torch.Tensor: The target after one-hot encoding, + has a shape (N, num_class, H, W). + """ + num_classes = pred.shape[1] + one_hot_target = torch.clamp(target, min=0, max=num_classes) + one_hot_target = torch.nn.functional.one_hot(one_hot_target, + num_classes + 1) + one_hot_target = one_hot_target[..., :num_classes].permute(0, 3, 1, 2) + return one_hot_target + + +def dice_loss(pred: torch.Tensor, + target: torch.Tensor, + weight: Union[torch.Tensor, None], + eps: float = 1e-3, + reduction: Union[str, None] = 'mean', + naive_dice: Union[bool, None] = False, + avg_factor: Union[int, None] = None, + ignore_index: Union[int, None] = 255) -> float: + """Calculate dice loss, there are two forms of dice loss is supported: + + - the one proposed in `V-Net: Fully Convolutional Neural + Networks for Volumetric Medical Image Segmentation + `_. + - the dice loss in which the power of the number in the + denominator is the first power instead of the second + power. + + Args: + pred (torch.Tensor): The prediction, has a shape (n, *) + target (torch.Tensor): The learning label of the prediction, + shape (n, *), same shape of pred. + weight (torch.Tensor, optional): The weight of loss for each + prediction, has a shape (n,). Defaults to None. + eps (float): Avoid dividing by zero. Default: 1e-3. + reduction (str, optional): The method used to reduce the loss into + a scalar. Defaults to 'mean'. + Options are "none", "mean" and "sum". + naive_dice (bool, optional): If false, use the dice + loss defined in the V-Net paper, otherwise, use the + naive dice loss in which the power of the number in the + denominator is the first power instead of the second + power.Defaults to False. + avg_factor (int, optional): Average factor that is used to average + the loss. Defaults to None. + ignore_index (int, optional): The label index to be ignored. + Defaults to 255. + """ + if ignore_index is not None: + num_classes = pred.shape[1] + pred = pred[:, torch.arange(num_classes) != ignore_index, :, :] + target = target[:, torch.arange(num_classes) != ignore_index, :, :] + assert pred.shape[1] != 0 # if the ignored index is the only class + input = pred.flatten(1) + target = target.flatten(1).float() + a = torch.sum(input * target, 1) + if naive_dice: + b = torch.sum(input, 1) + c = torch.sum(target, 1) + d = (2 * a + eps) / (b + c + eps) + else: + b = torch.sum(input * input, 1) + eps + c = torch.sum(target * target, 1) + eps + d = (2 * a) / (b + c) + + loss = 1 - d + if weight is not None: + assert weight.ndim == loss.ndim + assert len(weight) == len(pred) + loss = weight_reduce_loss(loss, weight, reduction, avg_factor) + return loss @MODELS.register_module() class DiceLoss(nn.Module): - """DiceLoss. - - This loss is proposed in `V-Net: Fully Convolutional Neural Networks for - Volumetric Medical Image Segmentation `_. - - Args: - smooth (float): A float number to smooth loss, and avoid NaN error. - Default: 1 - exponent (float): An float number to calculate denominator - value: \\sum{x^exponent} + \\sum{y^exponent}. Default: 2. - reduction (str, optional): The method used to reduce the loss. Options - are "none", "mean" and "sum". This parameter only works when - per_image is True. Default: 'mean'. - class_weight (list[float] | str, optional): Weight of each class. If in - str format, read them from a file. Defaults to None. - loss_weight (float, optional): Weight of the loss. Default to 1.0. - ignore_index (int | None): The label index to be ignored. Default: 255. - loss_name (str, optional): Name of the loss item. If you want this loss - item to be included into the backward graph, `loss_` must be the - prefix of the name. Defaults to 'loss_dice'. - """ def __init__(self, - smooth=1, - exponent=2, + use_sigmoid=True, + activate=True, reduction='mean', - class_weight=None, + naive_dice=False, loss_weight=1.0, ignore_index=255, - loss_name='loss_dice', - **kwards): + eps=1e-3, + loss_name='loss_dice'): + """Compute dice loss. + + Args: + use_sigmoid (bool, optional): Whether to the prediction is + used for sigmoid or softmax. Defaults to True. + activate (bool): Whether to activate the predictions inside, + this will disable the inside sigmoid operation. + Defaults to True. + reduction (str, optional): The method used + to reduce the loss. Options are "none", + "mean" and "sum". Defaults to 'mean'. + naive_dice (bool, optional): If false, use the dice + loss defined in the V-Net paper, otherwise, use the + naive dice loss in which the power of the number in the + denominator is the first power instead of the second + power. Defaults to False. + loss_weight (float, optional): Weight of loss. Defaults to 1.0. + ignore_index (int, optional): The label index to be ignored. + Default: 255. + eps (float): Avoid dividing by zero. Defaults to 1e-3. + loss_name (str, optional): Name of the loss item. If you want this + loss item to be included into the backward graph, `loss_` must + be the prefix of the name. Defaults to 'loss_dice'. + """ + super().__init__() - self.smooth = smooth - self.exponent = exponent + self.use_sigmoid = use_sigmoid self.reduction = reduction - self.class_weight = get_class_weight(class_weight) + self.naive_dice = naive_dice self.loss_weight = loss_weight + self.eps = eps + self.activate = activate self.ignore_index = ignore_index self._loss_name = loss_name def forward(self, pred, target, + weight=None, avg_factor=None, reduction_override=None, - **kwards): + ignore_index=255, + **kwargs): + """Forward function. + + Args: + pred (torch.Tensor): The prediction, has a shape (n, *). + target (torch.Tensor): The label of the prediction, + shape (n, *), same shape of pred. + weight (torch.Tensor, optional): The weight of loss for each + prediction, has a shape (n,). Defaults to None. + avg_factor (int, optional): Average factor that is used to average + the loss. Defaults to None. + reduction_override (str, optional): The reduction method used to + override the original reduction method of the loss. + Options are "none", "mean" and "sum". + + Returns: + torch.Tensor: The calculated loss + """ + one_hot_target = target + if (pred.shape != target.shape): + one_hot_target = _expand_onehot_labels_dice(pred, target) assert reduction_override in (None, 'none', 'mean', 'sum') reduction = ( reduction_override if reduction_override else self.reduction) - if self.class_weight is not None: - class_weight = pred.new_tensor(self.class_weight) - else: - class_weight = None - - pred = F.softmax(pred, dim=1) - num_classes = pred.shape[1] - one_hot_target = F.one_hot( - torch.clamp(target.long(), 0, num_classes - 1), - num_classes=num_classes) - valid_mask = (target != self.ignore_index).long() - + if self.activate: + if self.use_sigmoid: + pred = pred.sigmoid() + elif pred.shape[1] != 1: + # softmax does not work when there is only 1 class + pred = pred.softmax(dim=1) loss = self.loss_weight * dice_loss( pred, one_hot_target, - valid_mask=valid_mask, + weight, + eps=self.eps, reduction=reduction, + naive_dice=self.naive_dice, avg_factor=avg_factor, - smooth=self.smooth, - exponent=self.exponent, - class_weight=class_weight, ignore_index=self.ignore_index) + return loss @property diff --git a/mmseg/models/losses/focal_loss.py b/mmseg/models/losses/focal_loss.py index 104d6602c80..6507ed7a911 100644 --- a/mmseg/models/losses/focal_loss.py +++ b/mmseg/models/losses/focal_loss.py @@ -271,7 +271,13 @@ def forward(self, num_classes = pred.size(1) if torch.cuda.is_available() and pred.is_cuda: if target.dim() == 1: - one_hot_target = F.one_hot(target, num_classes=num_classes) + one_hot_target = F.one_hot( + target, num_classes=num_classes + 1) + if num_classes == 1: + one_hot_target = one_hot_target[:, 1] + target = 1 - target + else: + one_hot_target = one_hot_target[:, :num_classes] else: one_hot_target = target target = target.argmax(dim=1) @@ -280,7 +286,11 @@ def forward(self, else: one_hot_target = None if target.dim() == 1: - target = F.one_hot(target, num_classes=num_classes) + target = F.one_hot(target, num_classes=num_classes + 1) + if num_classes == 1: + target = target[:, 1] + else: + target = target[:, num_classes] else: valid_mask = (target.argmax(dim=1) != ignore_index).view( -1, 1) diff --git a/mmseg/models/losses/huasdorff_distance_loss.py b/mmseg/models/losses/huasdorff_distance_loss.py new file mode 100644 index 00000000000..d950ba728f8 --- /dev/null +++ b/mmseg/models/losses/huasdorff_distance_loss.py @@ -0,0 +1,160 @@ +# Copyright (c) OpenMMLab. All rights reserved. +"""Modified from https://github.com/JunMa11/SegWithDistMap/blob/ +master/code/train_LA_HD.py (Apache-2.0 License)""" +import torch +import torch.nn as nn +import torch.nn.functional as F +from scipy.ndimage import distance_transform_edt as distance +from torch import Tensor + +from mmseg.registry import MODELS +from .utils import get_class_weight, weighted_loss + + +def compute_dtm(img_gt: Tensor, pred: Tensor) -> Tensor: + """ + compute the distance transform map of foreground in mask + Args: + img_gt: Ground truth of the image, (b, h, w) + pred: Predictions of the segmentation head after softmax, (b, c, h, w) + + Returns: + output: the foreground Distance Map (SDM) + dtm(x) = 0; x in segmentation boundary + inf|x-y|; x in segmentation + """ + + fg_dtm = torch.zeros_like(pred) + out_shape = pred.shape + for b in range(out_shape[0]): # batch size + for c in range(1, out_shape[1]): # default 0 channel is background + posmask = img_gt[b].byte() + if posmask.any(): + posdis = distance(posmask) + fg_dtm[b][c] = torch.from_numpy(posdis) + + return fg_dtm + + +@weighted_loss +def hd_loss(seg_soft: Tensor, + gt: Tensor, + seg_dtm: Tensor, + gt_dtm: Tensor, + class_weight=None, + ignore_index=255) -> Tensor: + """ + compute huasdorff distance loss for segmentation + Args: + seg_soft: softmax results, shape=(b,c,x,y) + gt: ground truth, shape=(b,x,y) + seg_dtm: segmentation distance transform map, shape=(b,c,x,y) + gt_dtm: ground truth distance transform map, shape=(b,c,x,y) + + Returns: + output: hd_loss + """ + assert seg_soft.shape[0] == gt.shape[0] + total_loss = 0 + num_class = seg_soft.shape[1] + if class_weight is not None: + assert class_weight.ndim == num_class + for i in range(1, num_class): + if i != ignore_index: + delta_s = (seg_soft[:, i, ...] - gt.float())**2 + s_dtm = seg_dtm[:, i, ...]**2 + g_dtm = gt_dtm[:, i, ...]**2 + dtm = s_dtm + g_dtm + multiplied = torch.einsum('bxy, bxy->bxy', delta_s, dtm) + hd_loss = multiplied.mean() + if class_weight is not None: + hd_loss *= class_weight[i] + total_loss += hd_loss + + return total_loss / num_class + + +@MODELS.register_module() +class HuasdorffDisstanceLoss(nn.Module): + """HuasdorffDisstanceLoss. This loss is proposed in `How Distance Transform + Maps Boost Segmentation CNNs: An Empirical Study. + + `_. + Args: + reduction (str, optional): The method used to reduce the loss into + a scalar. Defaults to 'mean'. + class_weight (list[float] | str, optional): Weight of each class. If in + str format, read them from a file. Defaults to None. + loss_weight (float): Weight of the loss. Defaults to 1.0. + ignore_index (int | None): The label index to be ignored. Default: 255. + loss_name (str): Name of the loss item. If you want this loss + item to be included into the backward graph, `loss_` must be the + prefix of the name. Defaults to 'loss_boundary'. + """ + + def __init__(self, + reduction='mean', + class_weight=None, + loss_weight=1.0, + ignore_index=255, + loss_name='loss_huasdorff_disstance', + **kwargs): + super().__init__() + self.reduction = reduction + self.loss_weight = loss_weight + self.class_weight = get_class_weight(class_weight) + self._loss_name = loss_name + self.ignore_index = ignore_index + + def forward(self, + pred: Tensor, + target: Tensor, + avg_factor=None, + reduction_override=None, + **kwargs) -> Tensor: + """Forward function. + + Args: + pred (Tensor): Predictions of the segmentation head. (B, C, H, W) + target (Tensor): Ground truth of the image. (B, H, W) + avg_factor (int, optional): Average factor that is used to + average the loss. Defaults to None. + reduction_override (str, optional): The reduction method used + to override the original reduction method of the loss. + Options are "none", "mean" and "sum". + Returns: + Tensor: Loss tensor. + """ + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + if self.class_weight is not None: + class_weight = pred.new_tensor(self.class_weight) + else: + class_weight = None + + pred_soft = F.softmax(pred, dim=1) + valid_mask = (target != self.ignore_index).long() + target = target * valid_mask + + with torch.no_grad(): + gt_dtm = compute_dtm(target.cpu(), pred_soft) + gt_dtm = gt_dtm.float() + seg_dtm2 = compute_dtm( + pred_soft.argmax(dim=1, keepdim=False).cpu(), pred_soft) + seg_dtm2 = seg_dtm2.float() + + loss_hd = self.loss_weight * hd_loss( + pred_soft, + target, + seg_dtm=seg_dtm2, + gt_dtm=gt_dtm, + reduction=reduction, + avg_factor=avg_factor, + class_weight=class_weight, + ignore_index=self.ignore_index) + return loss_hd + + @property + def loss_name(self): + return self._loss_name diff --git a/mmseg/models/losses/kldiv_loss.py b/mmseg/models/losses/kldiv_loss.py new file mode 100644 index 00000000000..496ef9713f0 --- /dev/null +++ b/mmseg/models/losses/kldiv_loss.py @@ -0,0 +1,99 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F + +from mmseg.registry import MODELS + + +@MODELS.register_module() +class KLDivLoss(nn.Module): + + def __init__(self, + temperature: float = 1.0, + reduction: str = 'mean', + loss_name: str = 'loss_kld'): + """Kullback-Leibler divergence Loss. + + + + Args: + temperature (float, optional): Temperature param + reduction (str, optional): The method to reduce the loss into a + scalar. Default is "mean". Options are "none", "sum", + and "mean" + """ + + assert isinstance(temperature, (float, int)), \ + 'Expected temperature to be' \ + f'float or int, but got {temperature.__class__.__name__} instead' + assert temperature != 0., 'Temperature must not be zero' + + assert reduction in ['mean', 'none', 'sum'], \ + 'Reduction must be one of the options ("mean", ' \ + f'"sum", "none"), but got {reduction}' + + super().__init__() + self.temperature = temperature + self.reduction = reduction + self._loss_name = loss_name + + def forward(self, input: torch.Tensor, target: torch.Tensor): + """Forward function. Calculate KL divergence Loss. + + Args: + input (Tensor): Logit tensor, + the data type is float32 or float64. + The shape is (N, C) where N is batchsize and C is number of + channels. + If there more than 2 dimensions, shape is (N, C, D1, D2, ... + Dk), k>= 1 + target (Tensor): Logit tensor, + the data type is float32 or float64. + input and target must be with the same shape. + + Returns: + (Tensor): Reduced loss. + """ + assert isinstance(input, torch.Tensor), 'Expected input to' \ + f'be Tensor, but got {input.__class__.__name__} instead' + assert isinstance(target, torch.Tensor), 'Expected target to' \ + f'be Tensor, but got {target.__class__.__name__} instead' + + assert input.shape == target.shape, 'Input and target ' \ + 'must have same shape,' \ + f'but got shapes {input.shape} and {target.shape}' + + input = F.softmax(input / self.temperature, dim=1) + target = F.softmax(target / self.temperature, dim=1) + + loss = F.kl_div(input, target, reduction='none', log_target=False) + loss = loss * self.temperature**2 + + batch_size = input.shape[0] + + if self.reduction == 'sum': + # Change view to calculate instance-wise sum + loss = loss.view(batch_size, -1) + return torch.sum(loss, dim=1) + + elif self.reduction == 'mean': + # Change view to calculate instance-wise mean + loss = loss.view(batch_size, -1) + return torch.mean(loss, dim=1) + + return loss + + @property + def loss_name(self): + """Loss Name. + + This function must be implemented and will return the name of this + loss function. This name will be used to combine different loss items + by simple sum operation. In addition, if you want this loss item to be + included into the backward graph, `loss_` must be the prefix of the + name. + Returns: + str: The name of this loss item. + """ + return self._loss_name diff --git a/mmseg/models/losses/silog_loss.py b/mmseg/models/losses/silog_loss.py new file mode 100644 index 00000000000..ecc07aac424 --- /dev/null +++ b/mmseg/models/losses/silog_loss.py @@ -0,0 +1,122 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Optional, Union + +import torch +import torch.nn as nn +from torch import Tensor + +from mmseg.registry import MODELS +from .utils import weight_reduce_loss + + +def silog_loss(pred: Tensor, + target: Tensor, + weight: Optional[Tensor] = None, + eps: float = 1e-4, + reduction: Union[str, None] = 'mean', + avg_factor: Optional[int] = None) -> Tensor: + """Computes the Scale-Invariant Logarithmic (SI-Log) loss between + prediction and target. + + Args: + pred (Tensor): Predicted output. + target (Tensor): Ground truth. + weight (Optional[Tensor]): Optional weight to apply on the loss. + eps (float): Epsilon value to avoid division and log(0). + reduction (Union[str, None]): Specifies the reduction to apply to the + output: 'mean', 'sum' or None. + avg_factor (Optional[int]): Optional average factor for the loss. + + Returns: + Tensor: The calculated SI-Log loss. + """ + pred, target = pred.flatten(1), target.flatten(1) + valid_mask = (target > eps).detach().float() + + diff_log = torch.log(target.clamp(min=eps)) - torch.log( + pred.clamp(min=eps)) + + valid_mask = (target > eps).detach() & (~torch.isnan(diff_log)) + diff_log[~valid_mask] = 0.0 + valid_mask = valid_mask.float() + + diff_log_sq_mean = (diff_log.pow(2) * valid_mask).sum( + dim=1) / valid_mask.sum(dim=1).clamp(min=eps) + diff_log_mean = (diff_log * valid_mask).sum(dim=1) / valid_mask.sum( + dim=1).clamp(min=eps) + + loss = torch.sqrt(diff_log_sq_mean - 0.5 * diff_log_mean.pow(2)) + + if weight is not None: + weight = weight.float() + + loss = weight_reduce_loss(loss, weight, reduction, avg_factor) + return loss + + +@MODELS.register_module() +class SiLogLoss(nn.Module): + """Compute SiLog loss. + + Args: + reduction (str, optional): The method used + to reduce the loss. Options are "none", + "mean" and "sum". Defaults to 'mean'. + loss_weight (float, optional): Weight of loss. Defaults to 1.0. + eps (float): Avoid dividing by zero. Defaults to 1e-3. + loss_name (str, optional): Name of the loss item. If you want this + loss item to be included into the backward graph, `loss_` must + be the prefix of the name. Defaults to 'loss_silog'. + """ + + def __init__(self, + reduction='mean', + loss_weight=1.0, + eps=1e-6, + loss_name='loss_silog'): + super().__init__() + self.reduction = reduction + self.loss_weight = loss_weight + self.eps = eps + self._loss_name = loss_name + + def forward( + self, + pred, + target, + weight=None, + avg_factor=None, + reduction_override=None, + ): + + assert pred.shape == target.shape, 'the shapes of pred ' \ + f'({pred.shape}) and target ({target.shape}) are mismatch' + + assert reduction_override in (None, 'none', 'mean', 'sum') + reduction = ( + reduction_override if reduction_override else self.reduction) + + loss = self.loss_weight * silog_loss( + pred, + target, + weight, + eps=self.eps, + reduction=reduction, + avg_factor=avg_factor, + ) + + return loss + + @property + def loss_name(self): + """Loss Name. + + This function must be implemented and will return the name of this + loss function. This name will be used to combine different loss items + by simple sum operation. In addition, if you want this loss item to be + included into the backward graph, `loss_` must be the prefix of the + name. + Returns: + str: The name of this loss item. + """ + return self._loss_name diff --git a/mmseg/models/losses/utils.py b/mmseg/models/losses/utils.py index f74efcf35ce..04780347331 100644 --- a/mmseg/models/losses/utils.py +++ b/mmseg/models/losses/utils.py @@ -25,7 +25,7 @@ def get_class_weight(class_weight): return class_weight -def reduce_loss(loss, reduction): +def reduce_loss(loss, reduction) -> torch.Tensor: """Reduce loss as specified. Args: @@ -45,7 +45,10 @@ def reduce_loss(loss, reduction): return loss.sum() -def weight_reduce_loss(loss, weight=None, reduction='mean', avg_factor=None): +def weight_reduce_loss(loss, + weight=None, + reduction='mean', + avg_factor=None) -> torch.Tensor: """Apply element-wise weight and reduce loss. Args: diff --git a/mmseg/models/segmentors/__init__.py b/mmseg/models/segmentors/__init__.py index fec0d52c3a4..59b012f4172 100644 --- a/mmseg/models/segmentors/__init__.py +++ b/mmseg/models/segmentors/__init__.py @@ -1,9 +1,12 @@ # Copyright (c) OpenMMLab. All rights reserved. from .base import BaseSegmentor from .cascade_encoder_decoder import CascadeEncoderDecoder +from .depth_estimator import DepthEstimator from .encoder_decoder import EncoderDecoder +from .multimodal_encoder_decoder import MultimodalEncoderDecoder from .seg_tta import SegTTAModel __all__ = [ - 'BaseSegmentor', 'EncoderDecoder', 'CascadeEncoderDecoder', 'SegTTAModel' + 'BaseSegmentor', 'EncoderDecoder', 'CascadeEncoderDecoder', 'SegTTAModel', + 'MultimodalEncoderDecoder', 'DepthEstimator' ] diff --git a/mmseg/models/segmentors/base.py b/mmseg/models/segmentors/base.py index 25487de5ab8..17a0bb2b33e 100644 --- a/mmseg/models/segmentors/base.py +++ b/mmseg/models/segmentors/base.py @@ -187,6 +187,7 @@ def postprocess_result(self, if C > 1: i_seg_pred = i_seg_logits.argmax(dim=0, keepdim=True) else: + i_seg_logits = i_seg_logits.sigmoid() i_seg_pred = (i_seg_logits > self.decode_head.threshold).to(i_seg_logits) data_samples[i].set_data({ diff --git a/mmseg/models/segmentors/depth_estimator.py b/mmseg/models/segmentors/depth_estimator.py new file mode 100644 index 00000000000..1020637e737 --- /dev/null +++ b/mmseg/models/segmentors/depth_estimator.py @@ -0,0 +1,392 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import logging +from typing import List, Optional + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmengine.logging import print_log +from mmengine.structures import PixelData +from torch import Tensor + +from mmseg.registry import MODELS +from mmseg.structures import SegDataSample +from mmseg.utils import (ConfigType, OptConfigType, OptMultiConfig, + OptSampleList, SampleList, add_prefix) +from ..utils import resize +from .encoder_decoder import EncoderDecoder + + +@MODELS.register_module() +class DepthEstimator(EncoderDecoder): + """Encoder Decoder depth estimator. + + EncoderDecoder typically consists of backbone, decode_head, auxiliary_head. + Note that auxiliary_head is only used for deep supervision during training, + which could be dumped during inference. + + 1. The ``loss`` method is used to calculate the loss of model, + which includes two steps: (1) Extracts features to obtain the feature maps + (2) Call the decode head loss function to forward decode head model and + calculate losses. + + .. code:: text + + loss(): extract_feat() -> _decode_head_forward_train() -> _auxiliary_head_forward_train (optional) + _decode_head_forward_train(): decode_head.loss() + _auxiliary_head_forward_train(): auxiliary_head.loss (optional) + + 2. The ``predict`` method is used to predict depth estimation results, + which includes two steps: (1) Run inference function to obtain the list of + depth (2) Call post-processing function to obtain list of + ``SegDataSample`` including ``pred_depth_map``. + + .. code:: text + + predict(): inference() -> postprocess_result() + inference(): whole_inference()/slide_inference() + whole_inference()/slide_inference(): encoder_decoder() + encoder_decoder(): extract_feat() -> decode_head.predict() + + 3. The ``_forward`` method is used to output the tensor by running the model, + which includes two steps: (1) Extracts features to obtain the feature maps + (2)Call the decode head forward function to forward decode head model. + + .. code:: text + + _forward(): extract_feat() -> _decode_head.forward() + + Args: + + backbone (ConfigType): The config for the backnone of depth estimator. + decode_head (ConfigType): The config for the decode head of depth estimator. + neck (OptConfigType): The config for the neck of depth estimator. + Defaults to None. + auxiliary_head (OptConfigType): The config for the auxiliary head of + depth estimator. Defaults to None. + train_cfg (OptConfigType): The config for training. Defaults to None. + test_cfg (OptConfigType): The config for testing. Defaults to None. + data_preprocessor (dict, optional): The pre-process config of + :class:`BaseDataPreprocessor`. + pretrained (str, optional): The path for pretrained model. + Defaults to None. + init_cfg (dict, optional): The weight initialized config for + :class:`BaseModule`. + """ # noqa: E501 + + def __init__(self, + backbone: ConfigType, + decode_head: ConfigType, + neck: OptConfigType = None, + auxiliary_head: OptConfigType = None, + train_cfg: OptConfigType = None, + test_cfg: OptConfigType = None, + data_preprocessor: OptConfigType = None, + pretrained: Optional[str] = None, + init_cfg: OptMultiConfig = None): + super().__init__( + backbone=backbone, + decode_head=decode_head, + neck=neck, + auxiliary_head=auxiliary_head, + train_cfg=train_cfg, + test_cfg=test_cfg, + data_preprocessor=data_preprocessor, + pretrained=pretrained, + init_cfg=init_cfg) + + def extract_feat(self, + inputs: Tensor, + batch_img_metas: Optional[List[dict]] = None) -> Tensor: + """Extract features from images.""" + + if getattr(self.backbone, 'class_embed_select', False) and \ + isinstance(batch_img_metas, list) and \ + 'category_id' in batch_img_metas[0]: + cat_ids = [meta['category_id'] for meta in batch_img_metas] + cat_ids = torch.tensor(cat_ids).to(inputs.device) + inputs = (inputs, cat_ids) + + x = self.backbone(inputs) + if self.with_neck: + x = self.neck(x) + return x + + def encode_decode(self, inputs: Tensor, + batch_img_metas: List[dict]) -> Tensor: + """Encode images with backbone and decode into a depth map of the same + size as input.""" + x = self.extract_feat(inputs, batch_img_metas) + depth = self.decode_head.predict(x, batch_img_metas, self.test_cfg) + + return depth + + def _decode_head_forward_train(self, inputs: List[Tensor], + data_samples: SampleList) -> dict: + """Run forward function and calculate loss for decode head in + training.""" + losses = dict() + loss_decode = self.decode_head.loss(inputs, data_samples, + self.train_cfg) + + losses.update(add_prefix(loss_decode, 'decode')) + return losses + + def _auxiliary_head_forward_train(self, inputs: List[Tensor], + data_samples: SampleList) -> dict: + """Run forward function and calculate loss for auxiliary head in + training.""" + losses = dict() + if isinstance(self.auxiliary_head, nn.ModuleList): + for idx, aux_head in enumerate(self.auxiliary_head): + loss_aux = aux_head.loss(inputs, data_samples, self.train_cfg) + losses.update(add_prefix(loss_aux, f'aux_{idx}')) + else: + loss_aux = self.auxiliary_head.loss(inputs, data_samples, + self.train_cfg) + losses.update(add_prefix(loss_aux, 'aux')) + + return losses + + def loss(self, inputs: Tensor, data_samples: SampleList) -> dict: + """Calculate losses from a batch of inputs and data samples. + + Args: + inputs (Tensor): Input images. + data_samples (list[:obj:`SegDataSample`]): The seg data samples. + It usually includes information such as `metainfo` and + `gt_depth_map`. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + if data_samples is not None: + batch_img_metas = [ + data_sample.metainfo for data_sample in data_samples + ] + else: + batch_img_metas = [ + dict( + ori_shape=inputs.shape[2:], + img_shape=inputs.shape[2:], + pad_shape=inputs.shape[2:], + padding_size=[0, 0, 0, 0]) + ] * inputs.shape[0] + + x = self.extract_feat(inputs, batch_img_metas) + + losses = dict() + + loss_decode = self._decode_head_forward_train(x, data_samples) + losses.update(loss_decode) + + if self.with_auxiliary_head: + loss_aux = self._auxiliary_head_forward_train(x, data_samples) + losses.update(loss_aux) + + return losses + + def predict(self, + inputs: Tensor, + data_samples: OptSampleList = None) -> SampleList: + """Predict results from a batch of inputs and data samples with post- + processing. + + Args: + inputs (Tensor): Inputs with shape (N, C, H, W). + data_samples (List[:obj:`SegDataSample`], optional): The seg data + samples. It usually includes information such as `metainfo` + and `gt_depth_map`. + + Returns: + list[:obj:`SegDataSample`]: Depth estimation results of the + input images. Each SegDataSample usually contain: + + - ``pred_depth_max``(PixelData): Prediction of depth estimation. + """ + if data_samples is not None: + batch_img_metas = [ + data_sample.metainfo for data_sample in data_samples + ] + else: + batch_img_metas = [ + dict( + ori_shape=inputs.shape[2:], + img_shape=inputs.shape[2:], + pad_shape=inputs.shape[2:], + padding_size=[0, 0, 0, 0]) + ] * inputs.shape[0] + + depth = self.inference(inputs, batch_img_metas) + + return self.postprocess_result(depth, data_samples) + + def _forward(self, + inputs: Tensor, + data_samples: OptSampleList = None) -> Tensor: + """Network forward process. + + Args: + inputs (Tensor): Inputs with shape (N, C, H, W). + data_samples (List[:obj:`SegDataSample`]): The seg + data samples. It usually includes information such + as `metainfo` and `gt_depth_map`. + + Returns: + Tensor: Forward output of model without any post-processes. + """ + x = self.extract_feat(inputs) + return self.decode_head.forward(x) + + def slide_flip_inference(self, inputs: Tensor, + batch_img_metas: List[dict]) -> Tensor: + """Inference by sliding-window with overlap and flip. + + If h_crop > h_img or w_crop > w_img, the small patch will be used to + decode without padding. + + Args: + inputs (tensor): the tensor should have a shape NxCxHxW, + which contains all images in the batch. + batch_img_metas (List[dict]): List of image metainfo where each may + also contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', and 'pad_shape'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + + Returns: + Tensor: The depth estimation results. + """ + + h_stride, w_stride = self.test_cfg.stride + h_crop, w_crop = self.test_cfg.crop_size + batch_size, _, h_img, w_img = inputs.size() + out_channels = self.out_channels + h_grids = max(h_img - h_crop + h_stride - 1, 0) // h_stride + 1 + w_grids = max(w_img - w_crop + w_stride - 1, 0) // w_stride + 1 + preds = inputs.new_zeros((batch_size, out_channels, h_img, w_img)) + count_mat = inputs.new_zeros((batch_size, 1, h_img, w_img)) + for h_idx in range(h_grids): + for w_idx in range(w_grids): + y1 = h_idx * h_stride + x1 = w_idx * w_stride + y2 = min(y1 + h_crop, h_img) + x2 = min(x1 + w_crop, w_img) + y1 = max(y2 - h_crop, 0) + x1 = max(x2 - w_crop, 0) + crop_img = inputs[:, :, y1:y2, x1:x2] + # change the image shape to patch shape + batch_img_metas[0]['img_shape'] = crop_img.shape[2:] + # the output of encode_decode is depth tensor map + # with shape [N, C, H, W] + crop_depth_map = self.encode_decode(crop_img, batch_img_metas) + + # average out the original and flipped prediction + crop_depth_map_flip = self.encode_decode( + crop_img.flip(dims=(3, )), batch_img_metas) + crop_depth_map_flip = crop_depth_map_flip.flip(dims=(3, )) + crop_depth_map = (crop_depth_map + crop_depth_map_flip) / 2.0 + + preds += F.pad(crop_depth_map, + (int(x1), int(preds.shape[3] - x2), int(y1), + int(preds.shape[2] - y2))) + + count_mat[:, :, y1:y2, x1:x2] += 1 + assert (count_mat == 0).sum() == 0 + depth = preds / count_mat + + return depth + + def inference(self, inputs: Tensor, batch_img_metas: List[dict]) -> Tensor: + """Inference with slide/whole style. + + Args: + inputs (Tensor): The input image of shape (N, 3, H, W). + batch_img_metas (List[dict]): List of image metainfo where each may + also contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', 'pad_shape', and 'padding_size'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + + Returns: + Tensor: The depth estimation results. + """ + assert self.test_cfg.get('mode', 'whole') in ['slide', 'whole', + 'slide_flip'], \ + f'Only "slide", "slide_flip" or "whole" test mode are ' \ + f'supported, but got {self.test_cfg["mode"]}.' + ori_shape = batch_img_metas[0]['ori_shape'] + if not all(_['ori_shape'] == ori_shape for _ in batch_img_metas): + print_log( + 'Image shapes are different in the batch.', + logger='current', + level=logging.WARN) + if self.test_cfg.mode == 'slide': + depth_map = self.slide_inference(inputs, batch_img_metas) + if self.test_cfg.mode == 'slide_flip': + depth_map = self.slide_flip_inference(inputs, batch_img_metas) + else: + depth_map = self.whole_inference(inputs, batch_img_metas) + + return depth_map + + def postprocess_result(self, + depth: Tensor, + data_samples: OptSampleList = None) -> SampleList: + """ Convert results list to `SegDataSample`. + Args: + depth (Tensor): The depth estimation results. + data_samples (list[:obj:`SegDataSample`]): The seg data samples. + It usually includes information such as `metainfo` and + `gt_depth_map`. Default to None. + Returns: + list[:obj:`SegDataSample`]: Depth estomation results of the + input images. Each SegDataSample usually contain: + + - ``pred_depth_map``(PixelData): Prediction of depth estimation. + """ + batch_size, C, H, W = depth.shape + + if data_samples is None: + data_samples = [SegDataSample() for _ in range(batch_size)] + only_prediction = True + else: + only_prediction = False + + for i in range(batch_size): + if not only_prediction: + img_meta = data_samples[i].metainfo + # remove padding area + if 'img_padding_size' not in img_meta: + padding_size = img_meta.get('padding_size', [0] * 4) + else: + padding_size = img_meta['img_padding_size'] + padding_left, padding_right, padding_top, padding_bottom =\ + padding_size + # i_depth shape is 1, C, H, W after remove padding + i_depth = depth[i:i + 1, :, padding_top:H - padding_bottom, + padding_left:W - padding_right] + + flip = img_meta.get('flip', None) + if flip: + flip_direction = img_meta.get('flip_direction', None) + assert flip_direction in ['horizontal', 'vertical'] + if flip_direction == 'horizontal': + i_depth = i_depth.flip(dims=(3, )) + else: + i_depth = i_depth.flip(dims=(2, )) + + # resize as original shape + i_depth = resize( + i_depth, + size=img_meta['ori_shape'], + mode='bilinear', + align_corners=self.align_corners, + warning=False).squeeze(0) + else: + i_depth = depth[i] + + data_samples[i].set_data( + {'pred_depth_map': PixelData(**{'data': i_depth})}) + + return data_samples diff --git a/mmseg/models/segmentors/encoder_decoder.py b/mmseg/models/segmentors/encoder_decoder.py index 0a8db3ec7de..fa4050e0b73 100644 --- a/mmseg/models/segmentors/encoder_decoder.py +++ b/mmseg/models/segmentors/encoder_decoder.py @@ -1,8 +1,10 @@ # Copyright (c) OpenMMLab. All rights reserved. +import logging from typing import List, Optional import torch.nn as nn import torch.nn.functional as F +from mmengine.logging import print_log from torch import Tensor from mmseg.registry import MODELS @@ -33,7 +35,7 @@ class EncoderDecoder(BaseSegmentor): 2. The ``predict`` method is used to predict segmentation results, which includes two steps: (1) Run inference function to obtain the list of seg_logits (2) Call post-processing function to obtain list of - ``SegDataSampel`` including ``pred_sem_seg`` and ``seg_logits``. + ``SegDataSample`` including ``pred_sem_seg`` and ``seg_logits``. .. code:: text @@ -260,10 +262,10 @@ def slide_inference(self, inputs: Tensor, h_stride, w_stride = self.test_cfg.stride h_crop, w_crop = self.test_cfg.crop_size batch_size, _, h_img, w_img = inputs.size() - num_classes = self.num_classes + out_channels = self.out_channels h_grids = max(h_img - h_crop + h_stride - 1, 0) // h_stride + 1 w_grids = max(w_img - w_crop + w_stride - 1, 0) // w_stride + 1 - preds = inputs.new_zeros((batch_size, num_classes, h_img, w_img)) + preds = inputs.new_zeros((batch_size, out_channels, h_img, w_img)) count_mat = inputs.new_zeros((batch_size, 1, h_img, w_img)) for h_idx in range(h_grids): for w_idx in range(w_grids): @@ -326,10 +328,15 @@ def inference(self, inputs: Tensor, batch_img_metas: List[dict]) -> Tensor: Tensor: The segmentation results, seg_logits from model of each input image. """ - - assert self.test_cfg.mode in ['slide', 'whole'] + assert self.test_cfg.get('mode', 'whole') in ['slide', 'whole'], \ + f'Only "slide" or "whole" test mode are supported, but got ' \ + f'{self.test_cfg["mode"]}.' ori_shape = batch_img_metas[0]['ori_shape'] - assert all(_['ori_shape'] == ori_shape for _ in batch_img_metas) + if not all(_['ori_shape'] == ori_shape for _ in batch_img_metas): + print_log( + 'Image shapes are different in the batch.', + logger='current', + level=logging.WARN) if self.test_cfg.mode == 'slide': seg_logit = self.slide_inference(inputs, batch_img_metas) else: diff --git a/mmseg/models/segmentors/multimodal_encoder_decoder.py b/mmseg/models/segmentors/multimodal_encoder_decoder.py new file mode 100644 index 00000000000..75aa8b9b176 --- /dev/null +++ b/mmseg/models/segmentors/multimodal_encoder_decoder.py @@ -0,0 +1,350 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List, Optional + +import torch.nn.functional as F +from torch import Tensor + +from mmseg.registry import MODELS +from mmseg.utils import (ConfigType, OptConfigType, OptMultiConfig, + OptSampleList, SampleList, add_prefix) +from .base import BaseSegmentor + + +@MODELS.register_module() +class MultimodalEncoderDecoder(BaseSegmentor): + """Multimodal Encoder-Decoder segmentors. + + Multimodal segmentation architecture is used for open-vocabulary + semantic segmentation with combining the visual and language + pretrain models. It consists of a image_encoder (backbone) to extract + visual feature, a text encoder to extract text feature, and a decode + head to generate semantic maps. + Note that the deep supervision during training is implemented in decode head. + + 1. The ``loss`` method is used to calculate the loss of model, + which includes two steps: (1) Extracts features to obtain the feature maps + (2) Call the decode head loss function to forward decode head model and + calculate losses. + + .. code:: text + + loss(): extract_feat() -> _decode_head_forward_train() + _decode_head_forward_train(): decode_head.loss() + + 2. The ``predict`` method is used to predict segmentation results, + which includes two steps: (1) Run inference function to obtain the list of + seg_logits (2) Call post-processing function to obtain list of + ``SegDataSampel`` including ``pred_sem_seg`` and ``seg_logits``. + + .. code:: text + + predict(): inference() -> postprocess_result() + inference(): whole_inference()/slide_inference() + whole_inference()/slide_inference(): encoder_decoder() + encoder_decoder(): extract_feat() -> decode_head.predict() + + 3. The ``_forward`` method is used to output the tensor by running the model, + which includes two steps: (1) Extracts features to obtain the feature maps + (2)Call the decode head forward function to forward decode head model. + + .. code:: text + + _forward(): extract_feat() -> _decode_head.forward() + + Args: + + image_encoder (ConfigType): The config for the visual encoder of segmentor. + text_encoder ((ConfigType): The config for the text encoder of segmentor. + decode_head (ConfigType): The config for the decode head of segmentor. + train_cfg (OptConfigType): The config for training. Defaults to None. + test_cfg (OptConfigType): The config for testing. Defaults to None. + data_preprocessor (dict, optional): The pre-process config of + :class:`BaseDataPreprocessor`. + pretrained (str, optional): The path for pretrained model. + Defaults to None. + asymetric_input (bool): whether to use different size of input for image encoder + and decode head. Defaults to False. + encoder_resolution (float): resize scale of input images for image encoder. + Defaults to None. + init_cfg (dict, optional): The weight initialized config for + :class:`BaseModule`. + """ # noqa: E501 + + def __init__(self, + image_encoder: ConfigType, + text_encoder: ConfigType, + decode_head: ConfigType, + train_cfg: OptConfigType = None, + test_cfg: OptConfigType = None, + data_preprocessor: OptConfigType = None, + pretrained: Optional[str] = None, + asymetric_input: bool = True, + encoder_resolution: float = None, + init_cfg: OptMultiConfig = None): + super().__init__( + data_preprocessor=data_preprocessor, init_cfg=init_cfg) + if pretrained is not None: + image_encoder.init_cfg = dict( + type='Pretrained_Part', checkpoint=pretrained) + text_encoder.init_cfg = dict( + type='Pretrained_Part', checkpoint=pretrained) + decode_head.init_cfg = dict( + type='Pretrained_Part', checkpoint=pretrained) + + if asymetric_input: + assert encoder_resolution is not None, \ + 'if asymetric_input set True, ' \ + 'clip_resolution must be a certain value' + self.asymetric_input = asymetric_input + self.encoder_resolution = encoder_resolution + self.image_encoder = MODELS.build(image_encoder) + self.text_encoder = MODELS.build(text_encoder) + self._init_decode_head(decode_head) + + self.train_cfg = train_cfg + self.test_cfg = test_cfg + + assert self.with_decode_head + + def _init_decode_head(self, decode_head: ConfigType) -> None: + """Initialize ``decode_head``""" + self.decode_head = MODELS.build(decode_head) + self.align_corners = self.decode_head.align_corners + self.num_classes = self.decode_head.num_classes + self.out_channels = self.decode_head.out_channels + + def extract_feat(self, inputs: Tensor) -> List[Tensor]: + """Extract visual features from images.""" + x = self.image_encoder(inputs) + return x + + def encode_decode(self, inputs: Tensor, + batch_img_metas: List[dict]) -> Tensor: + """Encode the name of classes with text_encoder and encode images with + image_encoder. + + Then decode the class embedding and visual feature into a semantic + segmentation map of the same size as input. + """ + classifier_embeds = self.text_encoder() + clip_inputs = inputs + if self.asymetric_input: + clip_inputs = F.interpolate( + inputs, scale_factor=self.encoder_resolution, mode='bilinear') + x = self.image_encoder(clip_inputs) + seg_logits = self.decode_head.predict([inputs, x, classifier_embeds], + batch_img_metas, self.test_cfg) + + return seg_logits + + def _decode_head_forward_train(self, inputs: List[Tensor], + data_samples: SampleList) -> dict: + """Run forward function and calculate loss for decode head in + training.""" + losses = dict() + loss_decode = self.decode_head.loss(inputs, data_samples, + self.train_cfg) + + losses.update(add_prefix(loss_decode, 'decode')) + return losses + + def loss(self, inputs: Tensor, data_samples: SampleList) -> dict: + """Calculate losses from a batch of inputs and data samples. + + Args: + inputs (Tensor): Input images. + data_samples (list[:obj:`SegDataSample`]): The seg data samples. + It usually includes information such as `metainfo` and + `gt_sem_seg`. + + Returns: + dict[str, Tensor]: a dictionary of loss components + """ + classifier_embeds = self.text_encoder() + clip_inputs = inputs + if self.asymetric_input: + clip_inputs = F.interpolate( + inputs, scale_factor=self.encoder_resolution, mode='bilinear') + x = self.image_encoder(clip_inputs) + + losses = dict() + + loss_decode = self._decode_head_forward_train( + [inputs, x, classifier_embeds], data_samples) + losses.update(loss_decode) + + return losses + + def predict(self, + inputs: Tensor, + data_samples: OptSampleList = None) -> SampleList: + """Predict results from a batch of inputs and data samples with post- + processing. + + Args: + inputs (Tensor): Inputs with shape (N, C, H, W). + data_samples (List[:obj:`SegDataSample`], optional): The seg data + samples. It usually includes information such as `metainfo` + and `gt_sem_seg`. + + Returns: + list[:obj:`SegDataSample`]: Segmentation results of the + input images. Each SegDataSample usually contain: + + - ``pred_sem_seg``(PixelData): Prediction of semantic segmentation. + - ``seg_logits``(PixelData): Predicted logits of semantic + segmentation before normalization. + """ + if data_samples is not None: + batch_img_metas = [ + data_sample.metainfo for data_sample in data_samples + ] + else: + batch_img_metas = [ + dict( + ori_shape=inputs.shape[2:], + img_shape=inputs.shape[2:], + pad_shape=inputs.shape[2:], + padding_size=[0, 0, 0, 0]) + ] * inputs.shape[0] + + seg_logits = self.inference(inputs, batch_img_metas) + + return self.postprocess_result(seg_logits, data_samples) + + def _forward(self, + inputs: Tensor, + data_samples: OptSampleList = None) -> Tensor: + """Network forward process. + + Args: + inputs (Tensor): Inputs with shape (N, C, H, W). + data_samples (List[:obj:`SegDataSample`]): The seg + data samples. It usually includes information such + as `metainfo` and `gt_sem_seg`. + + Returns: + Tensor: Forward output of model without any post-processes. + """ + x = self.extract_feat(inputs) + return self.decode_head.forward(x) + + def slide_inference(self, inputs: Tensor, + batch_img_metas: List[dict]) -> Tensor: + """Inference by sliding-window with overlap. + + If h_crop > h_img or w_crop > w_img, the small patch will be used to + decode without padding. + + Args: + inputs (tensor): the tensor should have a shape NxCxHxW, + which contains all images in the batch. + batch_img_metas (List[dict]): List of image metainfo where each may + also contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', and 'pad_shape'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + + Returns: + Tensor: The segmentation results, seg_logits from model of each + input image. + """ + + h_stride, w_stride = self.test_cfg.stride + h_crop, w_crop = self.test_cfg.crop_size + batch_size, _, h_img, w_img = inputs.size() + out_channels = self.out_channels + h_grids = max(h_img - h_crop + h_stride - 1, 0) // h_stride + 1 + w_grids = max(w_img - w_crop + w_stride - 1, 0) // w_stride + 1 + preds = inputs.new_zeros((batch_size, out_channels, h_img, w_img)) + count_mat = inputs.new_zeros((batch_size, 1, h_img, w_img)) + for h_idx in range(h_grids): + for w_idx in range(w_grids): + y1 = h_idx * h_stride + x1 = w_idx * w_stride + y2 = min(y1 + h_crop, h_img) + x2 = min(x1 + w_crop, w_img) + y1 = max(y2 - h_crop, 0) + x1 = max(x2 - w_crop, 0) + crop_img = inputs[:, :, y1:y2, x1:x2] + # change the image shape to patch shape + batch_img_metas[0]['img_shape'] = crop_img.shape[2:] + # the output of encode_decode is seg logits tensor map + # with shape [N, C, H, W] + crop_seg_logit = self.encode_decode(crop_img, batch_img_metas) + preds += F.pad(crop_seg_logit, + (int(x1), int(preds.shape[3] - x2), int(y1), + int(preds.shape[2] - y2))) + + count_mat[:, :, y1:y2, x1:x2] += 1 + assert (count_mat == 0).sum() == 0 + seg_logits = preds / count_mat + + return seg_logits + + def whole_inference(self, inputs: Tensor, + batch_img_metas: List[dict]) -> Tensor: + """Inference with full image. + + Args: + inputs (Tensor): The tensor should have a shape NxCxHxW, which + contains all images in the batch. + batch_img_metas (List[dict]): List of image metainfo where each may + also contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', and 'pad_shape'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + + Returns: + Tensor: The segmentation results, seg_logits from model of each + input image. + """ + + seg_logits = self.encode_decode(inputs, batch_img_metas) + + return seg_logits + + def inference(self, inputs: Tensor, batch_img_metas: List[dict]) -> Tensor: + """Inference with slide/whole style. + + Args: + inputs (Tensor): The input image of shape (N, 3, H, W). + batch_img_metas (List[dict]): List of image metainfo where each may + also contain: 'img_shape', 'scale_factor', 'flip', 'img_path', + 'ori_shape', 'pad_shape', and 'padding_size'. + For details on the values of these keys see + `mmseg/datasets/pipelines/formatting.py:PackSegInputs`. + + Returns: + Tensor: The segmentation results, seg_logits from model of each + input image. + """ + + assert self.test_cfg.mode in ['slide', 'whole'] + ori_shape = batch_img_metas[0]['ori_shape'] + assert all(_['ori_shape'] == ori_shape for _ in batch_img_metas) + if self.test_cfg.mode == 'slide': + seg_logit = self.slide_inference(inputs, batch_img_metas) + else: + seg_logit = self.whole_inference(inputs, batch_img_metas) + + return seg_logit + + def aug_test(self, inputs, batch_img_metas, rescale=True): + """Test with augmentations. + + Only rescale=True is supported. + """ + # aug_test rescale all imgs back to ori_shape for now + assert rescale + # to save memory, we get augmented seg logit inplace + seg_logit = self.inference(inputs[0], batch_img_metas[0], rescale) + for i in range(1, len(inputs)): + cur_seg_logit = self.inference(inputs[i], batch_img_metas[i], + rescale) + seg_logit += cur_seg_logit + seg_logit /= len(inputs) + seg_pred = seg_logit.argmax(dim=1) + # unravel batch dim + seg_pred = list(seg_pred) + return seg_pred diff --git a/mmseg/models/segmentors/seg_tta.py b/mmseg/models/segmentors/seg_tta.py index eacb6c00a9a..63ef61d223a 100644 --- a/mmseg/models/segmentors/seg_tta.py +++ b/mmseg/models/segmentors/seg_tta.py @@ -6,7 +6,6 @@ from mmengine.structures import PixelData from mmseg.registry import MODELS -from mmseg.structures import SegDataSample from mmseg.utils import SampleList @@ -39,10 +38,10 @@ def merge_preds(self, data_samples_list: List[SampleList]) -> SampleList: ).to(logits).squeeze(1) else: seg_pred = logits.argmax(dim=0) - data_sample = SegDataSample( - **{ - 'pred_sem_seg': PixelData(data=seg_pred), - 'gt_sem_seg': data_samples[0].gt_sem_seg - }) + data_sample.set_data({'pred_sem_seg': PixelData(data=seg_pred)}) + if hasattr(data_samples[0], 'gt_sem_seg'): + data_sample.set_data( + {'gt_sem_seg': data_samples[0].gt_sem_seg}) + data_sample.set_metainfo({'img_path': data_samples[0].img_path}) predictions.append(data_sample) return predictions diff --git a/mmseg/models/text_encoder/__init__.py b/mmseg/models/text_encoder/__init__.py new file mode 100644 index 00000000000..199856d9d79 --- /dev/null +++ b/mmseg/models/text_encoder/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .clip_text_encoder import CLIPTextEncoder + +__all__ = ['CLIPTextEncoder'] diff --git a/mmseg/models/text_encoder/clip_text_encoder.py b/mmseg/models/text_encoder/clip_text_encoder.py new file mode 100644 index 00000000000..1a18b86395e --- /dev/null +++ b/mmseg/models/text_encoder/clip_text_encoder.py @@ -0,0 +1,229 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List + +import numpy as np +import torch +import torch.nn as nn +from mmcv.cnn import build_norm_layer +from mmcv.cnn.bricks.transformer import BaseTransformerLayer +from mmengine.model import BaseModule, ModuleList +from mmengine.runner.checkpoint import CheckpointLoader, load_state_dict +from torch.nn import functional as F + +from mmseg.registry import MODELS +from mmseg.utils import get_classes, get_predefined_templates, tokenizer + + +@MODELS.register_module() +class CLIPTextEncoder(BaseModule): + """A text encoder with transformer architecture to encode the label text. + + Modified from https://github.com/MendelXu/SAN/blob/main/san/model/clip_utils/classifier.py # noqa:E501 + Copyright (c) 2023 MendelXu. + Licensed under the MIT License + + Args: + dataset_name: (str|None): The name of the dataset to which + the data belongs. + vocabulary: (List[str]|None): The list of class names. Default: None. + templates: (List[str]|None): The prompt template used for labels. + Default: None. + total_vocab_size: (int): Number of all words used by the pre-trained + model. Default: 49408 (CLIP). + context_length: (int): The max length of prompt text. + Default: 77 (CLIP). + embed_dims: (int): Width of transformer model. Default: 512. + num_layers: (int): Depth of transformer. Default: 12, + num_heads: (int): Number of attention heads in transformer. + Default: 8, + mlp_ratio: (int) Ratio of mlp hidden dim to embedding dim in + transformer. Default: 4, + output_dims: (int) Dim of output text embeddings. Default: 512, + cache_feature: (bool) Whether to save class embeddings in cache. + Default: True, + cat_bg: (bool) Whether to add background embedding. Default: True. + norm_cfg (dict|None): Config for norm layer. Default: dict(type='LN') + init_cfg (dict or list[dict], optional): Initialization config dict. + Default: None. + """ + + def __init__(self, + dataset_name: str = None, + vocabulary: List[str] = None, + templates: str = 'vild', + total_vocab_size: int = 49408, + context_length: int = 77, + embed_dims: int = 512, + num_layers: int = 12, + num_heads: int = 8, + mlp_ratio: int = 4, + output_dims: int = 512, + cache_feature: bool = True, + cat_bg: bool = True, + norm_cfg: dict = dict(type='LN'), + init_cfg: dict = None): + super().__init__(init_cfg) + if isinstance(templates, List): + self.templates = templates + else: + self.templates = get_predefined_templates(templates) + + assert dataset_name is not None or vocabulary is not None, \ + "text_encoder required either 'dataset_name' or 'vocabulary'" + assert dataset_name is None or vocabulary is None, \ + "there is conflict between 'dataset_name' and 'vocabulary'" + self.dataset_name = dataset_name + self.vocabulary = vocabulary + self.num_pos = context_length + self.token_embedding = nn.Embedding(total_vocab_size, embed_dims) + self.positional_embedding = nn.Parameter( + torch.empty(context_length, embed_dims)) + self.text_projection = nn.Parameter( + torch.empty(embed_dims, output_dims)) + self.logit_scale = nn.Parameter(torch.ones([]) * np.log(1 / 0.07)) + self.transformer = ModuleList() + self.register_buffer( + 'attn_mask', self.build_attention_mask(), persistent=False) + for i in range(num_layers): + self.transformer.append( + BaseTransformerLayer( + attn_cfgs=dict( + type='MultiheadAttention', + embed_dims=embed_dims, + num_heads=num_heads, + batch_first=False, + bias=True), + ffn_cfgs=dict( + type='FFN', + embed_dims=embed_dims, + feedforward_channels=mlp_ratio * embed_dims, + act_cfg=dict(type='QuickGELU')), + operation_order=('norm', 'self_attn', 'norm', 'ffn'))) + self.ln_final = build_norm_layer( + norm_cfg, embed_dims, postfix='_final')[1] + + self.cache_feature = cache_feature + if self.cache_feature: + self.cache = {} + + self._freeze() + + self.cat_bg = cat_bg + if self.cat_bg: + self.bg_embed = nn.Parameter( + torch.randn(1, self.text_projection.shape[1])) + + @property + def ln_final(self): + return getattr(self, self.final_name) + + def build_attention_mask(self): + """lazily create causal attention mask, with full attention between the + tokens. + + pytorch uses additive attention mask; fill with -inf + """ + mask = torch.empty(self.num_pos, self.num_pos) + mask.fill_(float('-inf')) + mask.triu_(1) # zero out the lower diagonal + return mask + + def _freeze(self): + for param in self.parameters(): + param.requires_grad = False + + def init_weights(self): + if self.cat_bg: + nn.init.normal_( + self.bg_embed, + std=self.bg_embed.shape[1]**-0.5, + ) + if isinstance(self.init_cfg, dict) and \ + self.init_cfg.get('type') == 'Pretrained_Part': + checkpoint = CheckpointLoader.load_checkpoint( + self.init_cfg['checkpoint'], logger=None, map_location='cpu') + + state_dict = checkpoint.copy() + para_prefix = 'text_encoder' + prefix_len = len(para_prefix) + 1 + for k, v in checkpoint.items(): + state_dict.pop(k) + if para_prefix in k: + state_dict[k[prefix_len:]] = v + + load_state_dict(self, state_dict, strict=False, logger=None) + + else: + super().init_weights() + + @torch.no_grad() + def encode_text(self, text, normalize=False): + """encode class token.""" + + embed_device = self.token_embedding.weight.device + x = self.token_embedding( + text.to(embed_device)) # [batch_size, n_ctx, d_model] + x = x + self.positional_embedding + x = x.permute(1, 0, 2) # NLD -> LND + for block in self.transformer: + x = block(query=x, attn_masks=self.attn_mask) + x = x.permute(1, 0, 2) # LND -> NLD + x = self.ln_final(x) # [batch_size, n_ctx, transformer.width] + # take features from the eot embedding + # (eot_token is the highest number in each sequence) + x = x[torch.arange(x.shape[0]), + text.argmax(dim=-1)] @ self.text_projection + return F.normalize(x, dim=-1) if normalize else x + + def template_encode(self, vocabulary): + """Prompt engineering.""" + text_embed_bucket = [] + for template in self.templates: + text_inputs = tokenizer.tokenize( + [template.format(noun) for noun in vocabulary]) + text_embed = self.encode_text(text_inputs, normalize=True) + text_embed_bucket.append(text_embed) + text_embed = torch.stack(text_embed_bucket).mean(dim=0) + text_embed = text_embed / text_embed.norm(dim=-1, keepdim=True) + return text_embed + + def forward(self): + """Forward function.""" + if self.dataset_name is None: # encoding vocabulary directly + class_names = self.vocabulary + if self.cache_feature: + new_classes = [ + word for word in class_names if word not in self.cache + ] + if len(new_classes) > 0: + class_embeds = self.template_encode(new_classes) + self.cache.update(dict(zip(new_classes, class_embeds))) + class_embeds = torch.stack( + [self.cache[word] for word in class_names]) + else: + class_embeds = self.template_encode(class_names) + + else: # encoding the classes of the dataset + class_names = get_classes(self.dataset_name) + if class_names[0] == 'background': + class_names = class_names[1:] + if self.cache_feature: + if self.dataset_name not in self.cache: + class_embeds = self.template_encode(class_names) + self.cache[self.dataset_name] = class_embeds + else: + class_embeds = self.cache[self.dataset_name] + else: + class_embeds = self.template_encode(class_names) + + if self.cat_bg: + class_embeds = torch.cat([class_embeds, self.bg_embed]) + class_embeds = F.normalize(class_embeds, p=2, dim=-1) + return self.logit_scale.exp() * class_embeds + + +@MODELS.register_module() +class QuickGELU(nn.Module): + # From https://github.com/openai/CLIP/blob/main/clip/model.py + def forward(self, x: torch.Tensor): + return x * torch.sigmoid(1.702 * x) diff --git a/mmseg/models/utils/__init__.py b/mmseg/models/utils/__init__.py index fc142f16fc9..c0751b17c02 100644 --- a/mmseg/models/utils/__init__.py +++ b/mmseg/models/utils/__init__.py @@ -4,6 +4,7 @@ from .encoding import Encoding from .inverted_residual import InvertedResidual, InvertedResidualV3 from .make_divisible import make_divisible +from .point_sample import get_uncertain_point_coords_with_randomness from .ppm import DAPPM, PAPPM from .res_layer import ResLayer from .se_layer import SELayer @@ -11,11 +12,16 @@ from .shape_convert import (nchw2nlc2nchw, nchw_to_nlc, nlc2nchw2nlc, nlc_to_nchw) from .up_conv_block import UpConvBlock + +# isort: off from .wrappers import Upsample, resize +from .san_layers import MLP, LayerNorm2d, cross_attn_layer __all__ = [ 'ResLayer', 'SelfAttentionBlock', 'make_divisible', 'InvertedResidual', 'UpConvBlock', 'InvertedResidualV3', 'SELayer', 'PatchEmbed', 'nchw_to_nlc', 'nlc_to_nchw', 'nchw2nlc2nchw', 'nlc2nchw2nlc', 'Encoding', - 'Upsample', 'resize', 'DAPPM', 'PAPPM', 'BasicBlock', 'Bottleneck' + 'Upsample', 'resize', 'DAPPM', 'PAPPM', 'BasicBlock', 'Bottleneck', + 'cross_attn_layer', 'LayerNorm2d', 'MLP', + 'get_uncertain_point_coords_with_randomness' ] diff --git a/mmseg/models/utils/point_sample.py b/mmseg/models/utils/point_sample.py new file mode 100644 index 00000000000..1afc957f3da --- /dev/null +++ b/mmseg/models/utils/point_sample.py @@ -0,0 +1,88 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from mmcv.ops import point_sample +from torch import Tensor + + +def get_uncertainty(mask_preds: Tensor, labels: Tensor) -> Tensor: + """Estimate uncertainty based on pred logits. + + We estimate uncertainty as L1 distance between 0.0 and the logits + prediction in 'mask_preds' for the foreground class in `classes`. + + Args: + mask_preds (Tensor): mask predication logits, shape (num_rois, + num_classes, mask_height, mask_width). + + labels (Tensor): Either predicted or ground truth label for + each predicted mask, of length num_rois. + + Returns: + scores (Tensor): Uncertainty scores with the most uncertain + locations having the highest uncertainty score, + shape (num_rois, 1, mask_height, mask_width) + """ + if mask_preds.shape[1] == 1: + gt_class_logits = mask_preds.clone() + else: + inds = torch.arange(mask_preds.shape[0], device=mask_preds.device) + gt_class_logits = mask_preds[inds, labels].unsqueeze(1) + return -torch.abs(gt_class_logits) + + +def get_uncertain_point_coords_with_randomness( + mask_preds: Tensor, labels: Tensor, num_points: int, + oversample_ratio: float, importance_sample_ratio: float) -> Tensor: + """Get ``num_points`` most uncertain points with random points during + train. + + Sample points in [0, 1] x [0, 1] coordinate space based on their + uncertainty. The uncertainties are calculated for each point using + 'get_uncertainty()' function that takes point's logit prediction as + input. + + Args: + mask_preds (Tensor): A tensor of shape (num_rois, num_classes, + mask_height, mask_width) for class-specific or class-agnostic + prediction. + labels (Tensor): The ground truth class for each instance. + num_points (int): The number of points to sample. + oversample_ratio (float): Oversampling parameter. + importance_sample_ratio (float): Ratio of points that are sampled + via importnace sampling. + + Returns: + point_coords (Tensor): A tensor of shape (num_rois, num_points, 2) + that contains the coordinates sampled points. + """ + assert oversample_ratio >= 1 + assert 0 <= importance_sample_ratio <= 1 + batch_size = mask_preds.shape[0] + num_sampled = int(num_points * oversample_ratio) + point_coords = torch.rand( + batch_size, num_sampled, 2, device=mask_preds.device) + point_logits = point_sample(mask_preds, point_coords) + # It is crucial to calculate uncertainty based on the sampled + # prediction value for the points. Calculating uncertainties of the + # coarse predictions first and sampling them for points leads to + # incorrect results. To illustrate this: assume uncertainty func( + # logits)=-abs(logits), a sampled point between two coarse + # predictions with -1 and 1 logits has 0 logits, and therefore 0 + # uncertainty value. However, if we calculate uncertainties for the + # coarse predictions first, both will have -1 uncertainty, + # and sampled point will get -1 uncertainty. + point_uncertainties = get_uncertainty(point_logits, labels) + num_uncertain_points = int(importance_sample_ratio * num_points) + num_random_points = num_points - num_uncertain_points + idx = torch.topk( + point_uncertainties[:, 0, :], k=num_uncertain_points, dim=1)[1] + shift = num_sampled * torch.arange( + batch_size, dtype=torch.long, device=mask_preds.device) + idx += shift[:, None] + point_coords = point_coords.view(-1, 2)[idx.view(-1), :].view( + batch_size, num_uncertain_points, 2) + if num_random_points > 0: + rand_roi_coords = torch.rand( + batch_size, num_random_points, 2, device=mask_preds.device) + point_coords = torch.cat((point_coords, rand_roi_coords), dim=1) + return point_coords diff --git a/mmseg/models/utils/san_layers.py b/mmseg/models/utils/san_layers.py new file mode 100644 index 00000000000..2267686daf6 --- /dev/null +++ b/mmseg/models/utils/san_layers.py @@ -0,0 +1,418 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# Modified from https://github.com/MendelXu/SAN/blob/main/san/model/attn_helper.py # noqa: E501 +# Copyright (c) 2023 MendelXu. +# Licensed under the MIT License + +import warnings +from typing import Optional + +import torch +from mmcv.cnn.bricks.transformer import BaseTransformerLayer +from torch import Tensor, nn +from torch.nn import functional as F + + +def cross_attn_with_self_bias( + query: Tensor, + key: Tensor, + value: Tensor, + embed_dim_to_check: int, + num_heads: int, + in_proj_weight: Tensor, + in_proj_bias: Tensor, + bias_k: Optional[Tensor], + bias_v: Optional[Tensor], + add_zero_attn: bool, + dropout_p: float, + out_proj_weight: Tensor, + out_proj_bias: Tensor, + training: bool = True, + key_padding_mask: Optional[Tensor] = None, + need_weights: bool = True, + attn_mask: Optional[Tensor] = None, + use_separate_proj_weight: bool = False, + q_proj_weight: Optional[Tensor] = None, + k_proj_weight: Optional[Tensor] = None, + v_proj_weight: Optional[Tensor] = None, + static_k: Optional[Tensor] = None, + static_v: Optional[Tensor] = None, +): + """Forward function of multi-head attention. Modified from + multi_head_attention_forward in + https://github.com/pytorch/pytorch/blob/main/torch/nn/functional.py. + + Args: + query, key, value: map a query and a set of key-value pairs to an output. + See "Attention Is All You Need" for more details. + embed_dim_to_check: total dimension of the model. + num_heads: parallel attention heads. + in_proj_weight, in_proj_bias: input projection weight and bias. + bias_k, bias_v: bias of the key and value sequences to be added at dim=0. + add_zero_attn: add a new batch of zeros to the key and + value sequences at dim=1. + dropout_p: probability of an element to be zeroed. + out_proj_weight, out_proj_bias: the output projection weight and bias. + training: apply dropout if is ``True``. + key_padding_mask: if provided, specified padding elements in the key will + be ignored by the attention. This is an binary mask. When the value is True, + the corresponding value on the attention layer will be filled with -inf. + need_weights: output attn_output_weights. + Default: `True` + Note: `needs_weight` defaults to `True`, but should be set to `False` + For best performance when attention weights are not needed. + *Setting needs_weights to `True` + leads to a significant performance degradation.* + attn_mask: 2D mask that prevents attention to certain positions. A 2D mask will be broadcasted for all + the batches while a 3D mask allows to specify a different mask for the entries of each batch. + use_separate_proj_weight: the function accept the proj. weights for query, key, + and value in different forms. If false, in_proj_weight will be used, which is + a combination of q_proj_weight, k_proj_weight, v_proj_weight. + q_proj_weight, k_proj_weight, v_proj_weight, in_proj_bias: input projection weight and bias. + static_k, static_v: static key and value used for attention operators. + """ # noqa: E501 + tgt_len, bsz, embed_dim = query.size() + assert embed_dim == embed_dim_to_check + # allow MHA to have different sizes for the feature dimension + assert key.size(0) == value.size(0) and key.size(1) == value.size(1) + + head_dim = embed_dim // num_heads + assert head_dim * num_heads == embed_dim, \ + 'embed_dim must be divisible by num_heads' + scaling = float(head_dim)**-0.5 + + if not use_separate_proj_weight: + if (query is key or torch.equal( + query, key)) and (key is value or torch.equal(key, value)): + # self-attention + raise NotImplementedError('self-attention is not implemented') + + elif key is value or torch.equal(key, value): + # encoder-decoder attention + # This is inline in_proj function + # with in_proj_weight and in_proj_bias + _b = in_proj_bias + _start = 0 + _end = embed_dim + _w = in_proj_weight[_start:_end, :] + if _b is not None: + _b = _b[_start:_end] + q = F.linear(query, _w, _b) + + if key is None: + assert value is None + k = None + v = None + q_k = None + q_v = None + else: + # This is inline in_proj function with + # in_proj_weight and in_proj_bias + _b = in_proj_bias + _start = embed_dim + _end = None + _w = in_proj_weight[_start:, :] + if _b is not None: + _b = _b[_start:] + k, v = F.linear(key, _w, _b).chunk(2, dim=-1) + q_k, q_v = F.linear(query, _w, _b).chunk(2, dim=-1) + else: + # This is inline in_proj function with + # in_proj_weight and in_proj_bias + _b = in_proj_bias + _start = 0 + _end = embed_dim + _w = in_proj_weight[_start:_end, :] + if _b is not None: + _b = _b[_start:_end] + q = F.linear(query, _w, _b) + + # This is inline in_proj function with + # in_proj_weight and in_proj_bias + _b = in_proj_bias + _start = embed_dim + _end = embed_dim * 2 + _w = in_proj_weight[_start:_end, :] + if _b is not None: + _b = _b[_start:_end] + k = F.linear(key, _w, _b) + q_k = F.linear(query, _w, _b) + # This is inline in_proj function with + # in_proj_weight and in_proj_bias + _b = in_proj_bias + _start = embed_dim * 2 + _end = None + _w = in_proj_weight[_start:, :] + if _b is not None: + _b = _b[_start:] + v = F.linear(value, _w, _b) + q_v = F.linear(query, _w, _b) + else: + q_proj_weight_non_opt = \ + torch.jit._unwrap_optional(q_proj_weight) + len1, len2 = q_proj_weight_non_opt.size() + assert len1 == embed_dim and len2 == query.size(-1) + + k_proj_weight_non_opt = \ + torch.jit._unwrap_optional(k_proj_weight) + len1, len2 = k_proj_weight_non_opt.size() + assert len1 == embed_dim and len2 == key.size(-1) + + v_proj_weight_non_opt = \ + torch.jit._unwrap_optional(v_proj_weight) + len1, len2 = v_proj_weight_non_opt.size() + assert len1 == embed_dim and len2 == value.size(-1) + + if in_proj_bias is not None: + q = F.linear(query, q_proj_weight_non_opt, + in_proj_bias[0:embed_dim]) + k = F.linear(key, k_proj_weight_non_opt, + in_proj_bias[embed_dim:(embed_dim * 2)]) + v = F.linear(value, v_proj_weight_non_opt, + in_proj_bias[(embed_dim * 2):]) + else: + q = F.linear(query, q_proj_weight_non_opt, in_proj_bias) + k = F.linear(key, k_proj_weight_non_opt, in_proj_bias) + v = F.linear(value, v_proj_weight_non_opt, in_proj_bias) + q = q * scaling + + if attn_mask is not None: + assert ( + attn_mask.dtype == torch.float32 + or attn_mask.dtype == torch.float64 + or attn_mask.dtype == torch.float16 + or attn_mask.dtype == torch.uint8 or attn_mask.dtype == torch.bool + ), 'Only float, byte, and bool types are supported for ' \ + 'attn_mask, not {}'.format(attn_mask.dtype) + if attn_mask.dtype == torch.uint8: + warnings.warn('Byte tensor for attn_mask in nn.MultiheadAttention ' + 'is deprecated. Use bool tensor instead.') + attn_mask = attn_mask.to(torch.bool) + + if attn_mask.dim() == 2: + attn_mask = attn_mask.unsqueeze(0) + if list(attn_mask.size()) != [1, query.size(0), key.size(0)]: + raise RuntimeError( + 'The size of the 2D attn_mask is not correct.') + elif attn_mask.dim() == 3: + if list(attn_mask.size()) != [ + bsz * num_heads, + query.size(0), key.size(0) + ]: + raise RuntimeError( + 'The size of the 3D attn_mask is not correct.') + else: + raise RuntimeError( + "attn_mask's dimension {} is not supported".format( + attn_mask.dim())) + # attn_mask's dim is 3 now. + + # convert ByteTensor key_padding_mask to bool + if key_padding_mask is not None and key_padding_mask.dtype == torch.uint8: + warnings.warn( + 'Byte tensor for key_padding_mask in nn.MultiheadAttention ' + 'is deprecated. Use bool tensor instead.') + key_padding_mask = key_padding_mask.to(torch.bool) + + if bias_k is not None and bias_v is not None: + if static_k is None and static_v is None: + k = torch.cat([k, bias_k.repeat(1, bsz, 1)]) + v = torch.cat([v, bias_v.repeat(1, bsz, 1)]) + if attn_mask is not None: + attn_mask = F.pad(attn_mask, (0, 1)) + if key_padding_mask is not None: + key_padding_mask = F.pad(key_padding_mask, (0, 1)) + else: + assert static_k is None, 'bias cannot be added to static key.' + assert static_v is None, 'bias cannot be added to static value.' + else: + assert bias_k is None + assert bias_v is None + + q = q.contiguous().view(tgt_len, bsz * num_heads, head_dim).transpose(0, 1) + if k is not None: + k = k.contiguous().view(-1, bsz * num_heads, head_dim).transpose(0, 1) + q_k = q_k.contiguous().view(tgt_len, bsz * num_heads, + head_dim).transpose(0, 1) + if v is not None: + v = v.contiguous().view(-1, bsz * num_heads, head_dim).transpose(0, 1) + q_v = q_v.contiguous().view(tgt_len, bsz * num_heads, + head_dim).transpose(0, 1) + + if static_k is not None: + assert static_k.size(0) == bsz * num_heads + assert static_k.size(2) == head_dim + k = static_k + + if static_v is not None: + assert static_v.size(0) == bsz * num_heads + assert static_v.size(2) == head_dim + v = static_v + + src_len = k.size(1) + + if key_padding_mask is not None: + assert key_padding_mask.size(0) == bsz + assert key_padding_mask.size(1) == src_len + + if add_zero_attn: + src_len += 1 + k = torch.cat( + [ + k, + torch.zeros( + (k.size(0), 1) + k.size()[2:], + dtype=k.dtype, + device=k.device), + ], + dim=1, + ) + v = torch.cat( + [ + v, + torch.zeros( + (v.size(0), 1) + v.size()[2:], + dtype=v.dtype, + device=v.device), + ], + dim=1, + ) + if attn_mask is not None: + attn_mask = F.pad(attn_mask, (0, 1)) + if key_padding_mask is not None: + key_padding_mask = F.pad(key_padding_mask, (0, 1)) + + attn_output_weights = torch.bmm(q, k.transpose(1, 2)) + assert list( + attn_output_weights.size()) == [bsz * num_heads, tgt_len, src_len] + + if attn_mask is not None: + if attn_mask.dtype == torch.bool: + attn_output_weights.masked_fill_(attn_mask, float('-inf')) + else: + attn_output_weights += attn_mask + + if key_padding_mask is not None: + attn_output_weights = attn_output_weights.view(bsz, num_heads, tgt_len, + src_len) + attn_output_weights = attn_output_weights.masked_fill( + key_padding_mask.unsqueeze(1).unsqueeze(2), + float('-inf'), + ) + attn_output_weights = attn_output_weights.view(bsz * num_heads, + tgt_len, src_len) + # attn_out_weights: [bsz * num_heads, tgt_len, src_len] + # ->[bsz * num_heads, tgt_len, src_len+1] + self_weight = (q * q_k).sum( + dim=-1, keepdim=True) # [bsz * num_heads, tgt_len, 1] + total_attn_output_weights = torch.cat([attn_output_weights, self_weight], + dim=-1) + total_attn_output_weights = F.softmax(total_attn_output_weights, dim=-1) + total_attn_output_weights = F.dropout( + total_attn_output_weights, p=dropout_p, training=training) + attn_output_weights = \ + total_attn_output_weights[:, :, : -1] + # [bsz * num_heads, tgt_len, src_len] + self_weight = \ + total_attn_output_weights[:, :, -1:] # [bsz * num_heads, tgt_len, 1] + + attn_output = torch.bmm(attn_output_weights, + v) # [bsz * num_heads, tgt_len, head_dim] + attn_output = (attn_output + self_weight * q_v + ) # [bsz * num_heads, tgt_len, head_dim] + assert list(attn_output.size()) == [bsz * num_heads, tgt_len, head_dim] + attn_output = attn_output.transpose(0, 1).contiguous().view( + tgt_len, bsz, embed_dim) + attn_output = F.linear(attn_output, out_proj_weight, out_proj_bias) + + if need_weights: + # average attention weights over heads + attn_output_weights = attn_output_weights.view(bsz, num_heads, tgt_len, + src_len) + return attn_output, attn_output_weights # .sum(dim=1) / num_heads + else: + return attn_output, None + + +def cross_attn_layer(tf_layer: BaseTransformerLayer, x, mem, attn_bias): + """Implementation of transformer layer with cross attention. The cross + attention shares the embedding weights with self-attention of tf_layer. + Args: + tf_layer: (TransformerEncoderLayer): The Module of transformer layer. + x (Tensor): query [K,N,C] + mem (Tensor): key and value [L,N,C] + attn_bias (Tensor): attention bias [N*num_head,K,L] + + Return: + x (Tensor): cross attention output [K,N,C] + """ + self_attn_layer = tf_layer.attentions[0].attn + attn_layer_paras = { + 'embed_dim_to_check': self_attn_layer.embed_dim, + 'num_heads': self_attn_layer.num_heads, + 'in_proj_weight': self_attn_layer.in_proj_weight, + 'in_proj_bias': self_attn_layer.in_proj_bias, + 'bias_k': self_attn_layer.bias_k, + 'bias_v': self_attn_layer.bias_v, + 'add_zero_attn': self_attn_layer.add_zero_attn, + 'dropout_p': self_attn_layer.dropout, + 'out_proj_weight': self_attn_layer.out_proj.weight, + 'out_proj_bias': self_attn_layer.out_proj.bias, + 'training': self_attn_layer.training + } + + q_x = tf_layer.norms[0](x) + k_x = v_x = tf_layer.norms[0](mem) + x = x + cross_attn_with_self_bias( + q_x, + k_x, + v_x, + attn_mask=attn_bias, + need_weights=False, + **attn_layer_paras)[0] + x = tf_layer.ffns[0](tf_layer.norms[1](x), identity=x) + return x + + +class LayerNorm2d(nn.Module): + """A LayerNorm variant, popularized by Transformers, that performs point- + wise mean and variance normalization over the channel dimension for inputs + that have shape (batch_size, channels, height, width). + + https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa B950 + """ + + def __init__(self, normalized_shape, eps=1e-6): + super().__init__() + self.weight = nn.Parameter(torch.ones(normalized_shape)) + self.bias = nn.Parameter(torch.zeros(normalized_shape)) + self.eps = eps + self.normalized_shape = (normalized_shape, ) + + def forward(self, x: torch.Tensor): + u = x.mean(1, keepdim=True) + s = (x - u).pow(2).mean(1, keepdim=True) + x = (x - u) / torch.sqrt(s + self.eps) + x = self.weight[:, None, None] * x + self.bias[:, None, None] + return x + + +class MLP(nn.Module): + """Very simple multi-layer perceptron (also called FFN)""" + + def __init__(self, + input_dim, + hidden_dim, + output_dim, + num_layers, + affine_func=nn.Linear): + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList( + affine_func(n, k) + for n, k in zip([input_dim] + h, h + [output_dim])) + + def forward(self, x: torch.Tensor): + for i, layer in enumerate(self.layers): + x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + return x diff --git a/mmseg/registry/registry.py b/mmseg/registry/registry.py index 32684e758f9..37b6a776095 100644 --- a/mmseg/registry/registry.py +++ b/mmseg/registry/registry.py @@ -1,9 +1,9 @@ # Copyright (c) OpenMMLab. All rights reserved. -"""MMSegmentation provides 17 registry nodes to support using modules across +"""MMSegmentation provides 21 registry nodes to support using modules across projects. Each node is a child of the root registry in MMEngine. More details can be found at -https://mmengine.readthedocs.io/en/latest/tutorials/registry.html. +https://mmengine.readthedocs.io/en/latest/advanced_tutorials/registry.html. """ from mmengine.registry import DATA_SAMPLERS as MMENGINE_DATA_SAMPLERS @@ -46,10 +46,7 @@ # manage data-related modules DATASETS = Registry( 'dataset', parent=MMENGINE_DATASETS, locations=['mmseg.datasets']) -DATA_SAMPLERS = Registry( - 'data sampler', - parent=MMENGINE_DATA_SAMPLERS, - locations=['mmseg.datasets.samplers']) +DATA_SAMPLERS = Registry('data sampler', parent=MMENGINE_DATA_SAMPLERS) TRANSFORMS = Registry( 'transform', parent=MMENGINE_TRANSFORMS, diff --git a/mmseg/utils/__init__.py b/mmseg/utils/__init__.py index cb1436c1980..0a2af58c6e0 100644 --- a/mmseg/utils/__init__.py +++ b/mmseg/utils/__init__.py @@ -1,6 +1,7 @@ # Copyright (c) OpenMMLab. All rights reserved. # yapf: disable -from .class_names import (ade_classes, ade_palette, cityscapes_classes, +from .class_names import (ade_classes, ade_palette, bdd100k_classes, + bdd100k_palette, cityscapes_classes, cityscapes_palette, cocostuff_classes, cocostuff_palette, dataset_aliases, get_classes, get_palette, isaid_classes, isaid_palette, @@ -10,22 +11,60 @@ vaihingen_palette, voc_classes, voc_palette) # yapf: enable from .collect_env import collect_env +from .get_templates import get_predefined_templates from .io import datafrombytes from .misc import add_prefix, stack_batch from .set_env import register_all_modules +from .tokenizer import tokenize from .typing_utils import (ConfigType, ForwardResults, MultiConfig, OptConfigType, OptMultiConfig, OptSampleList, SampleList, TensorDict, TensorList) +# isort: off +from .mask_classification import MatchMasks, seg_data_to_instance_data + __all__ = [ - 'collect_env', 'register_all_modules', 'stack_batch', 'add_prefix', - 'ConfigType', 'OptConfigType', 'MultiConfig', 'OptMultiConfig', - 'SampleList', 'OptSampleList', 'TensorDict', 'TensorList', - 'ForwardResults', 'cityscapes_classes', 'ade_classes', 'voc_classes', - 'cocostuff_classes', 'loveda_classes', 'potsdam_classes', - 'vaihingen_classes', 'isaid_classes', 'stare_classes', - 'cityscapes_palette', 'ade_palette', 'voc_palette', 'cocostuff_palette', - 'loveda_palette', 'potsdam_palette', 'vaihingen_palette', 'isaid_palette', - 'stare_palette', 'dataset_aliases', 'get_classes', 'get_palette', - 'datafrombytes', 'synapse_palette', 'synapse_classes' + 'collect_env', + 'register_all_modules', + 'stack_batch', + 'add_prefix', + 'ConfigType', + 'OptConfigType', + 'MultiConfig', + 'OptMultiConfig', + 'SampleList', + 'OptSampleList', + 'TensorDict', + 'TensorList', + 'ForwardResults', + 'cityscapes_classes', + 'ade_classes', + 'voc_classes', + 'cocostuff_classes', + 'loveda_classes', + 'potsdam_classes', + 'vaihingen_classes', + 'isaid_classes', + 'stare_classes', + 'cityscapes_palette', + 'ade_palette', + 'voc_palette', + 'cocostuff_palette', + 'loveda_palette', + 'potsdam_palette', + 'vaihingen_palette', + 'isaid_palette', + 'stare_palette', + 'dataset_aliases', + 'get_classes', + 'get_palette', + 'datafrombytes', + 'synapse_palette', + 'synapse_classes', + 'get_predefined_templates', + 'tokenize', + 'seg_data_to_instance_data', + 'MatchMasks', + 'bdd100k_classes', + 'bdd100k_palette', ] diff --git a/mmseg/utils/bpe_simple_vocab_16e6.txt.gz b/mmseg/utils/bpe_simple_vocab_16e6.txt.gz new file mode 100644 index 00000000000..7b5088a527f Binary files /dev/null and b/mmseg/utils/bpe_simple_vocab_16e6.txt.gz differ diff --git a/mmseg/utils/class_names.py b/mmseg/utils/class_names.py index 961a08520d2..5ab35f99dca 100644 --- a/mmseg/utils/class_names.py +++ b/mmseg/utils/class_names.py @@ -52,6 +52,21 @@ def voc_classes(): ] +def pcontext_classes(): + """Pascal Context class names for external use.""" + return [ + 'aeroplane', 'bag', 'bed', 'bedclothes', 'bench', 'bicycle', 'bird', + 'boat', 'book', 'bottle', 'building', 'bus', 'cabinet', 'car', 'cat', + 'ceiling', 'chair', 'cloth', 'computer', 'cow', 'cup', 'curtain', + 'dog', 'door', 'fence', 'floor', 'flower', 'food', 'grass', 'ground', + 'horse', 'keyboard', 'light', 'motorbike', 'mountain', 'mouse', + 'person', 'plate', 'platform', 'pottedplant', 'road', 'rock', 'sheep', + 'shelves', 'sidewalk', 'sign', 'sky', 'snow', 'sofa', 'table', 'track', + 'train', 'tree', 'truck', 'tvmonitor', 'wall', 'water', 'window', + 'wood' + ] + + def cocostuff_classes(): """CocoStuff class names for external use.""" return [ @@ -306,6 +321,25 @@ def voc_palette(): [128, 64, 0], [0, 192, 0], [128, 192, 0], [0, 64, 128]] +def pcontext_palette(): + """Pascal Context palette for external use.""" + return [[180, 120, 120], [6, 230, 230], [80, 50, 50], [4, 200, 3], + [120, 120, 80], [140, 140, 140], [204, 5, 255], [230, 230, 230], + [4, 250, 7], [224, 5, 255], [235, 255, 7], [150, 5, 61], + [120, 120, 70], [8, 255, 51], [255, 6, 82], [143, 255, 140], + [204, 255, 4], [255, 51, 7], [204, 70, 3], [0, 102, 200], + [61, 230, 250], [255, 6, 51], [11, 102, 255], [255, 7, 71], + [255, 9, 224], [9, 7, 230], [220, 220, 220], [255, 9, 92], + [112, 9, 255], [8, 255, 214], [7, 255, 224], [255, 184, 6], + [10, 255, 71], [255, 41, 10], [7, 255, 255], [224, 255, 8], + [102, 8, 255], [255, 61, 6], [255, 194, 7], [255, 122, 8], + [0, 255, 20], [255, 8, 41], [255, 5, 153], [6, 51, 255], + [235, 12, 255], [160, 150, 20], [0, 163, 255], [140, 140, 140], + [250, 10, 15], [20, 255, 0], [31, 255, 0], [255, 31, 0], + [255, 224, 0], [153, 255, 0], [0, 0, 255], [255, 71, 0], + [0, 235, 255], [0, 173, 255], [31, 0, 255]] + + def cocostuff_palette(): """CocoStuff palette for external use.""" return [[0, 192, 64], [0, 192, 64], [0, 64, 96], [128, 192, 192], @@ -419,10 +453,31 @@ def lip_palette(): ] +def bdd100k_classes(): + """BDD100K class names for external use(the class name is compatible with + Cityscapes ).""" + return [ + 'road', 'sidewalk', 'building', 'wall', 'fence', 'pole', + 'traffic light', 'traffic sign', 'vegetation', 'terrain', 'sky', + 'person', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', + 'bicycle' + ] + + +def bdd100k_palette(): + """bdd100k palette for external use(same with cityscapes)""" + return [[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], + [190, 153, 153], [153, 153, 153], [250, 170, 30], [220, 220, 0], + [107, 142, 35], [152, 251, 152], [70, 130, 180], [220, 20, 60], + [255, 0, 0], [0, 0, 142], [0, 0, 70], [0, 60, 100], [0, 80, 100], + [0, 0, 230], [119, 11, 32]] + + dataset_aliases = { 'cityscapes': ['cityscapes'], 'ade': ['ade', 'ade20k'], 'voc': ['voc', 'pascal_voc', 'voc12', 'voc12aug'], + 'pcontext': ['pcontext', 'pascal_context', 'voc2010'], 'loveda': ['loveda'], 'potsdam': ['potsdam'], 'vaihingen': ['vaihingen'], @@ -435,7 +490,8 @@ def lip_palette(): 'stare': ['stare', 'STARE'], 'lip': ['LIP', 'lip'], 'mapillary_v1': ['mapillary_v1'], - 'mapillary_v2': ['mapillary_v2'] + 'mapillary_v2': ['mapillary_v2'], + 'bdd100k': ['bdd100k'] } diff --git a/mmseg/utils/get_templates.py b/mmseg/utils/get_templates.py new file mode 100644 index 00000000000..7e9032ba96c --- /dev/null +++ b/mmseg/utils/get_templates.py @@ -0,0 +1,109 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List + +PREDEFINED_TEMPLATES = { + 'imagenet': [ + 'a bad photo of a {}.', + 'a photo of many {}.', + 'a sculpture of a {}.', + 'a photo of the hard to see {}.', + 'a low resolution photo of the {}.', + 'a rendering of a {}.', + 'graffiti of a {}.', + 'a bad photo of the {}.', + 'a cropped photo of the {}.', + 'a tattoo of a {}.', + 'the embroidered {}.', + 'a photo of a hard to see {}.', + 'a bright photo of a {}.', + 'a photo of a clean {}.', + 'a photo of a dirty {}.', + 'a dark photo of the {}.', + 'a drawing of a {}.', + 'a photo of my {}.', + 'the plastic {}.', + 'a photo of the cool {}.', + 'a close-up photo of a {}.', + 'a black and white photo of the {}.', + 'a painting of the {}.', + 'a painting of a {}.', + 'a pixelated photo of the {}.', + 'a sculpture of the {}.', + 'a bright photo of the {}.', + 'a cropped photo of a {}.', + 'a plastic {}.', + 'a photo of the dirty {}.', + 'a jpeg corrupted photo of a {}.', + 'a blurry photo of the {}.', + 'a photo of the {}.', + 'a good photo of the {}.', + 'a rendering of the {}.', + 'a {} in a video game.', + 'a photo of one {}.', + 'a doodle of a {}.', + 'a close-up photo of the {}.', + 'a photo of a {}.', + 'the origami {}.', + 'the {} in a video game.', + 'a sketch of a {}.', + 'a doodle of the {}.', + 'a origami {}.', + 'a low resolution photo of a {}.', + 'the toy {}.', + 'a rendition of the {}.', + 'a photo of the clean {}.', + 'a photo of a large {}.', + 'a rendition of a {}.', + 'a photo of a nice {}.', + 'a photo of a weird {}.', + 'a blurry photo of a {}.', + 'a cartoon {}.', + 'art of a {}.', + 'a sketch of the {}.', + 'a embroidered {}.', + 'a pixelated photo of a {}.', + 'itap of the {}.', + 'a jpeg corrupted photo of the {}.', + 'a good photo of a {}.', + 'a plushie {}.', + 'a photo of the nice {}.', + 'a photo of the small {}.', + 'a photo of the weird {}.', + 'the cartoon {}.', + 'art of the {}.', + 'a drawing of the {}.', + 'a photo of the large {}.', + 'a black and white photo of a {}.', + 'the plushie {}.', + 'a dark photo of a {}.', + 'itap of a {}.', + 'graffiti of the {}.', + 'a toy {}.', + 'itap of my {}.', + 'a photo of a cool {}.', + 'a photo of a small {}.', + 'a tattoo of the {}.', + ], + 'vild': [ + 'a photo of a {}.', + 'This is a photo of a {}', + 'There is a {} in the scene', + 'There is the {} in the scene', + 'a photo of a {} in the scene', + 'a photo of a small {}.', + 'a photo of a medium {}.', + 'a photo of a large {}.', + 'This is a photo of a small {}.', + 'This is a photo of a medium {}.', + 'This is a photo of a large {}.', + 'There is a small {} in the scene.', + 'There is a medium {} in the scene.', + 'There is a large {} in the scene.', + ], +} + + +def get_predefined_templates(template_set_name: str) -> List[str]: + if template_set_name not in PREDEFINED_TEMPLATES: + raise ValueError(f'Template set {template_set_name} not found') + return PREDEFINED_TEMPLATES[template_set_name] diff --git a/mmseg/utils/io.py b/mmseg/utils/io.py index d03517401c5..7029c3cddda 100644 --- a/mmseg/utils/io.py +++ b/mmseg/utils/io.py @@ -3,6 +3,7 @@ import io import pickle +import cv2 import numpy as np @@ -12,7 +13,7 @@ def datafrombytes(content: bytes, backend: str = 'numpy') -> np.ndarray: Args: content (bytes): The data bytes got from files or other streams. backend (str): The data decoding backend type. Options are 'numpy', - 'nifti' and 'pickle'. Defaults to 'numpy'. + 'nifti', 'cv2' and 'pickle'. Defaults to 'numpy'. Returns: numpy.ndarray: Loaded data array. @@ -33,6 +34,9 @@ def datafrombytes(content: bytes, backend: str = 'numpy') -> np.ndarray: data = Nifti1Image.from_bytes(data.to_bytes()).get_fdata() elif backend == 'numpy': data = np.load(f) + elif backend == 'cv2': + data = np.frombuffer(f.read(), dtype=np.uint8) + data = cv2.imdecode(data, cv2.IMREAD_UNCHANGED) else: raise ValueError return data diff --git a/mmseg/utils/mask_classification.py b/mmseg/utils/mask_classification.py new file mode 100644 index 00000000000..205d5259754 --- /dev/null +++ b/mmseg/utils/mask_classification.py @@ -0,0 +1,205 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List, Tuple + +import torch +from mmcv.ops import point_sample +from mmengine.structures import InstanceData +from torch import Tensor + +from mmseg.registry import TASK_UTILS +from mmseg.utils import ConfigType, SampleList + + +def seg_data_to_instance_data(ignore_index: int, + batch_data_samples: SampleList): + """Convert the paradigm of ground truth from semantic segmentation to + instance segmentation. + + Args: + ignore_index (int): The label index to be ignored. + batch_data_samples (List[SegDataSample]): The Data + Samples. It usually includes information such as + `gt_sem_seg`. + + Returns: + tuple[Tensor]: A tuple contains two lists. + - batch_gt_instances (List[InstanceData]): Batch of + gt_instance. It usually includes ``labels``, each is + unique ground truth label id of images, with + shape (num_gt, ) and ``masks``, each is ground truth + masks of each instances of a image, shape (num_gt, h, w). + - batch_img_metas (List[Dict]): List of image meta information. + """ + batch_gt_instances = [] + + for data_sample in batch_data_samples: + gt_sem_seg = data_sample.gt_sem_seg.data + classes = torch.unique( + gt_sem_seg, + sorted=False, + return_inverse=False, + return_counts=False) + + # remove ignored region + gt_labels = classes[classes != ignore_index] + + masks = [] + for class_id in gt_labels: + masks.append(gt_sem_seg == class_id) + + if len(masks) == 0: + gt_masks = torch.zeros( + (0, gt_sem_seg.shape[-2], + gt_sem_seg.shape[-1])).to(gt_sem_seg).long() + else: + gt_masks = torch.stack(masks).squeeze(1).long() + + instance_data = InstanceData(labels=gt_labels, masks=gt_masks) + batch_gt_instances.append(instance_data) + return batch_gt_instances + + +class MatchMasks: + """Match the predictions to category labels. + + Args: + num_points (int): the number of sampled points to compute cost. + num_queries (int): the number of prediction masks. + num_classes (int): the number of classes. + assigner (BaseAssigner): the assigner to compute matching. + """ + + def __init__(self, + num_points: int, + num_queries: int, + num_classes: int, + assigner: ConfigType = None): + assert assigner is not None, "\'assigner\' in decode_head.train_cfg" \ + 'cannot be None' + assert num_points > 0, 'num_points should be a positive integer.' + self.num_points = num_points + self.num_queries = num_queries + self.num_classes = num_classes + self.assigner = TASK_UTILS.build(assigner) + + def get_targets(self, cls_scores: List[Tensor], mask_preds: List[Tensor], + batch_gt_instances: List[InstanceData]) -> Tuple: + """Compute best mask matches for all images for a decoder layer. + + Args: + cls_scores (List[Tensor]): Mask score logits from a single + decoder layer for all images. Each with shape (num_queries, + cls_out_channels). + mask_preds (List[Tensor]): Mask logits from a single decoder + layer for all images. Each with shape (num_queries, h, w). + batch_gt_instances (List[InstanceData]): each contains + ``labels`` and ``masks``. + + Returns: + tuple: a tuple containing the following targets. + + - labels (List[Tensor]): Labels of all images.\ + Each with shape (num_queries, ). + - mask_targets (List[Tensor]): Mask targets of\ + all images. Each with shape (num_queries, h, w). + - mask_weights (List[Tensor]): Mask weights of\ + all images. Each with shape (num_queries, ). + - avg_factor (int): Average factor that is used to + average the loss. `avg_factor` is usually equal + to the number of positive priors. + """ + batch_size = cls_scores.shape[0] + results = dict({ + 'labels': [], + 'mask_targets': [], + 'mask_weights': [], + }) + for i in range(batch_size): + labels, mask_targets, mask_weights\ + = self._get_targets_single(cls_scores[i], + mask_preds[i], + batch_gt_instances[i]) + results['labels'].append(labels) + results['mask_targets'].append(mask_targets) + results['mask_weights'].append(mask_weights) + + # shape (batch_size, num_queries) + labels = torch.stack(results['labels'], dim=0) + # shape (batch_size, num_gts, h, w) + mask_targets = torch.cat(results['mask_targets'], dim=0) + # shape (batch_size, num_queries) + mask_weights = torch.stack(results['mask_weights'], dim=0) + + avg_factor = sum( + [len(gt_instances.labels) for gt_instances in batch_gt_instances]) + + res = (labels, mask_targets, mask_weights, avg_factor) + + return res + + def _get_targets_single(self, cls_score: Tensor, mask_pred: Tensor, + gt_instances: InstanceData) \ + -> Tuple[Tensor, Tensor, Tensor]: + """Compute a set of best mask matches for one image. + + Args: + cls_score (Tensor): Mask score logits from a single decoder layer + for one image. Shape (num_queries, cls_out_channels). + mask_pred (Tensor): Mask logits for a single decoder layer for one + image. Shape (num_queries, h, w). + gt_instances (:obj:`InstanceData`): It contains ``labels`` and + ``masks``. + + Returns: + tuple[Tensor]: A tuple containing the following for one image. + + - labels (Tensor): Labels of each image. \ + shape (num_queries, ). + - mask_targets (Tensor): Mask targets of each image. \ + shape (num_queries, h, w). + - mask_weights (Tensor): Mask weights of each image. \ + shape (num_queries, ). + """ + gt_labels = gt_instances.labels + gt_masks = gt_instances.masks + # when "gt_labels" is empty, classify all queries to background + if len(gt_labels) == 0: + labels = gt_labels.new_full((self.num_queries, ), + self.num_classes, + dtype=torch.long) + mask_targets = gt_labels + mask_weights = gt_labels.new_zeros((self.num_queries, )) + return labels, mask_targets, mask_weights + # sample points + num_queries = cls_score.shape[0] + num_gts = gt_labels.shape[0] + + point_coords = torch.rand((1, self.num_points, 2), + device=cls_score.device) + # shape (num_queries, num_points) + mask_points_pred = point_sample( + mask_pred.unsqueeze(1), point_coords.repeat(num_queries, 1, + 1)).squeeze(1) + # shape (num_gts, num_points) + gt_points_masks = point_sample( + gt_masks.unsqueeze(1).float(), point_coords.repeat(num_gts, 1, + 1)).squeeze(1) + + sampled_gt_instances = InstanceData( + labels=gt_labels, masks=gt_points_masks) + sampled_pred_instances = InstanceData( + scores=cls_score, masks=mask_points_pred) + # assign and sample + matched_quiery_inds, matched_label_inds = self.assigner.assign( + pred_instances=sampled_pred_instances, + gt_instances=sampled_gt_instances) + labels = gt_labels.new_full((self.num_queries, ), + self.num_classes, + dtype=torch.long) + labels[matched_quiery_inds] = gt_labels[matched_label_inds] + + mask_weights = gt_labels.new_zeros((self.num_queries, )) + mask_weights[matched_quiery_inds] = 1 + mask_targets = gt_masks[matched_label_inds] + + return labels, mask_targets, mask_weights diff --git a/mmseg/utils/misc.py b/mmseg/utils/misc.py index 0a561732e9a..dfc469e8320 100644 --- a/mmseg/utils/misc.py +++ b/mmseg/utils/misc.py @@ -94,18 +94,28 @@ def stack_batch(inputs: List[torch.Tensor], # pad gt_sem_seg if data_samples is not None: data_sample = data_samples[i] - gt_sem_seg = data_sample.gt_sem_seg.data - del data_sample.gt_sem_seg.data - data_sample.gt_sem_seg.data = F.pad( - gt_sem_seg, padding_size, value=seg_pad_val) + pad_shape = None + if 'gt_sem_seg' in data_sample: + gt_sem_seg = data_sample.gt_sem_seg.data + del data_sample.gt_sem_seg.data + data_sample.gt_sem_seg.data = F.pad( + gt_sem_seg, padding_size, value=seg_pad_val) + pad_shape = data_sample.gt_sem_seg.shape if 'gt_edge_map' in data_sample: gt_edge_map = data_sample.gt_edge_map.data del data_sample.gt_edge_map.data data_sample.gt_edge_map.data = F.pad( gt_edge_map, padding_size, value=seg_pad_val) + pad_shape = data_sample.gt_edge_map.shape + if 'gt_depth_map' in data_sample: + gt_depth_map = data_sample.gt_depth_map.data + del data_sample.gt_depth_map.data + data_sample.gt_depth_map.data = F.pad( + gt_depth_map, padding_size, value=seg_pad_val) + pad_shape = data_sample.gt_depth_map.shape data_sample.set_metainfo({ 'img_shape': tensor.shape[-2:], - 'pad_shape': data_sample.gt_sem_seg.shape, + 'pad_shape': pad_shape, 'padding_size': padding_size }) padded_samples.append(data_sample) diff --git a/mmseg/utils/tokenizer.py b/mmseg/utils/tokenizer.py new file mode 100644 index 00000000000..d56f5fae602 --- /dev/null +++ b/mmseg/utils/tokenizer.py @@ -0,0 +1,240 @@ +# Copyright (c) OpenMMLab. All rights reserved. +"""CLIP tokenizer. + +Copied from https://github.com/openai/CLIP. Originally MIT License, Copyright +(c) 2021 OpenAI. +""" +import gzip +import html +import os +from functools import lru_cache +from typing import List, Union + +import ftfy +import regex as re +import torch + +os.environ['TOKENIZERS_PARALLELISM'] = 'false' + + +@lru_cache() +def default_bpe(): + return os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'bpe_simple_vocab_16e6.txt.gz') + + +@lru_cache() +def bytes_to_unicode(): + """Returns list of utf-8 byte and a corresponding list of unicode strings. + + The reversible bpe codes work on unicode strings. This means you need a + large # of unicode characters in your vocab if you want to avoid UNKs. When + you're at something like a 10B token dataset you end up needing around 5K + for decent coverage. This is a significant percentage of your normal, say, + 32K bpe vocab. To avoid that, we want lookup tables between utf-8 bytes and + unicode strings. And avoids mapping to whitespace/control characters the + bpe code barfs on. + """ + bs = list(range(ord('!'), + ord('~') + 1)) + list(range( + ord('¡'), + ord('¬') + 1)) + list(range(ord('®'), + ord('ÿ') + 1)) + cs = bs[:] + n = 0 + for b in range(2**8): + if b not in bs: + bs.append(b) + cs.append(2**8 + n) + n += 1 + cs = [chr(n) for n in cs] + return dict(zip(bs, cs)) + + +def get_pairs(word): + """Return set of symbol pairs in a word. + + Word is represented as tuple of symbols (symbols being variable-length + strings). + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +def basic_clean(text): + text = ftfy.fix_text(text) + text = html.unescape(html.unescape(text)) + return text.strip() + + +def whitespace_clean(text): + text = re.sub(r'\s+', ' ', text) + text = text.strip() + return text + + +class SimpleTokenizer: + + def __init__(self, bpe_path: str = default_bpe(), special_tokens=None): + self.byte_encoder = bytes_to_unicode() + self.byte_decoder = {v: k for k, v in self.byte_encoder.items()} + merges = gzip.open(bpe_path).read().decode('utf-8').split('\n') + merges = merges[1:49152 - 256 - 2 + 1] + merges = [tuple(merge.split()) for merge in merges] + vocab = list(bytes_to_unicode().values()) + vocab = vocab + [v + '' for v in vocab] + for merge in merges: + vocab.append(''.join(merge)) + if not special_tokens: + special_tokens = ['', ''] + else: + special_tokens = ['', '' + ] + special_tokens + vocab.extend(special_tokens) + self.encoder = dict(zip(vocab, range(len(vocab)))) + self.decoder = {v: k for k, v in self.encoder.items()} + self.bpe_ranks = dict(zip(merges, range(len(merges)))) + self.cache = {t: t for t in special_tokens} + special = '|'.join(special_tokens) + self.pat = re.compile( + special + + r"""|'s|'t|'re|'ve|'m|'ll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", + re.IGNORECASE) + + self.vocab_size = len(self.encoder) + self.all_special_ids = [self.encoder[t] for t in special_tokens] + + def bpe(self, token): + if token in self.cache: + return self.cache[token] + word = tuple(token[:-1]) + (token[-1] + '', ) + pairs = get_pairs(word) + + if not pairs: + return token + '' + + while True: + bigram = min( + pairs, key=lambda pair: self.bpe_ranks.get(pair, float('inf'))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + new_word.extend(word[i:j]) + i = j + except: # noqa: E722, E261 + new_word.extend(word[i:]) + break + + if word[i] == first and i < len(word) - 1 and word[ + i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = ' '.join(word) + self.cache[token] = word + return word + + def encode(self, text): + bpe_tokens = [] + text = whitespace_clean(basic_clean(text)).lower() + for token in re.findall(self.pat, text): + token = ''.join(self.byte_encoder[b] + for b in token.encode('utf-8')) + bpe_tokens.extend(self.encoder[bpe_token] + for bpe_token in self.bpe(token).split(' ')) + return bpe_tokens + + def decode(self, tokens): + text = ''.join([self.decoder[token] for token in tokens]) + text = bytearray([self.byte_decoder[c] for c in text]).decode( + 'utf-8', errors='replace').replace('', ' ') + return text + + +_tokenizer = SimpleTokenizer() + + +def decode(output_ids: torch.Tensor): + output_ids = output_ids.cpu().numpy() + return _tokenizer.decode(output_ids) + + +def tokenize(texts: Union[str, List[str]], + context_length: int = 77) -> torch.LongTensor: + """Returns the tokenized representation of given input string(s) + + Parameters + ---------- + texts : Union[str, List[str]] + An input string or a list of input strings to tokenize + context_length : int + The context length to use; all CLIP models use 77 as the context length + + Returns + ------- + A two-dimensional tensor containing the resulting tokens, + shape = [number of input strings, context_length] + """ + if isinstance(texts, str): + texts = [texts] + + sot_token = _tokenizer.encoder[''] + eot_token = _tokenizer.encoder[''] + all_tokens = [[sot_token] + _tokenizer.encode(text) + [eot_token] + for text in texts] + result = torch.zeros(len(all_tokens), context_length, dtype=torch.long) + + for i, tokens in enumerate(all_tokens): + if len(tokens) > context_length: + tokens = tokens[:context_length] # Truncate + tokens[-1] = eot_token + result[i, :len(tokens)] = torch.tensor(tokens) + + return result + + +class HFTokenizer: + """HuggingFace tokenizer wrapper.""" + + def __init__(self, tokenizer_name: str): + from transformers import AutoTokenizer + self.tokenizer = AutoTokenizer.from_pretrained(tokenizer_name) + + def save_pretrained(self, dest): + self.tokenizer.save_pretrained(dest) + + def __call__(self, + texts: Union[str, List[str]], + context_length: int = 77) -> torch.Tensor: + # same cleaning as for default tokenizer, except lowercasing + # adding lower (for case-sensitive tokenizers) will make it + # more robust but less sensitive to nuance + if isinstance(texts, str): + texts = [texts] + texts = [whitespace_clean(basic_clean(text)) for text in texts] + input_ids = self.tokenizer( + texts, + return_tensors='pt', + max_length=context_length, + padding='max_length', + truncation=True, + ).input_ids + return input_ids diff --git a/mmseg/version.py b/mmseg/version.py index ef8e391a299..a654604da72 100644 --- a/mmseg/version.py +++ b/mmseg/version.py @@ -1,6 +1,6 @@ # Copyright (c) Open-MMLab. All rights reserved. -__version__ = '1.0.0rc6' +__version__ = '1.1.2' def parse_version_info(version_str): diff --git a/mmseg/visualization/local_visualizer.py b/mmseg/visualization/local_visualizer.py index d11ad79c816..3096e3183bd 100644 --- a/mmseg/visualization/local_visualizer.py +++ b/mmseg/visualization/local_visualizer.py @@ -1,8 +1,10 @@ # Copyright (c) OpenMMLab. All rights reserved. from typing import Dict, List, Optional +import cv2 import mmcv import numpy as np +import torch from mmengine.dist import master_only from mmengine.structures import PixelData from mmengine.visualization import Visualizer @@ -31,7 +33,7 @@ class SegLocalVisualizer(Visualizer): `cityscapes` classes by default. Defaults to None. palette (list, optional): Input palette for result rendering, which is a list of color palette responding to the classes. Defaults to None. - dataset_name (str, optional): `Dataset name or alias `_ + dataset_name (str, optional): `Dataset name or alias `_ visulizer will use the meta information of the dataset i.e. classes and palette, but the `classes` and `palette` have higher priority. Defaults to None. @@ -42,8 +44,8 @@ class SegLocalVisualizer(Visualizer): >>> import numpy as np >>> import torch >>> from mmengine.structures import PixelData - >>> from mmseg.data import SegDataSample - >>> from mmseg.engine.visualization import SegLocalVisualizer + >>> from mmseg.structures import SegDataSample + >>> from mmseg.visualization import SegLocalVisualizer >>> seg_local_visualizer = SegLocalVisualizer() >>> image = np.random.randint(0, 256, @@ -60,7 +62,7 @@ class SegLocalVisualizer(Visualizer): >>> seg_local_visualizer.add_datasample( ... 'visualizer_example', image, ... gt_seg_data_sample, show=True) - """ # noqa + """ # noqa def __init__(self, name: str = 'visualizer', @@ -76,9 +78,32 @@ def __init__(self, self.alpha: float = alpha self.set_dataset_meta(palette, classes, dataset_name) - def _draw_sem_seg(self, image: np.ndarray, sem_seg: PixelData, + def _get_center_loc(self, mask: np.ndarray) -> np.ndarray: + """Get semantic seg center coordinate. + + Args: + mask: np.ndarray: get from sem_seg + """ + loc = np.argwhere(mask == 1) + + loc_sort = np.array( + sorted(loc.tolist(), key=lambda row: (row[0], row[1]))) + y_list = loc_sort[:, 0] + unique, indices, counts = np.unique( + y_list, return_index=True, return_counts=True) + y_loc = unique[counts.argmax()] + y_most_freq_loc = loc[loc_sort[:, 0] == y_loc] + center_num = len(y_most_freq_loc) // 2 + x = y_most_freq_loc[center_num][1] + y = y_most_freq_loc[center_num][0] + return np.array([x, y]) + + def _draw_sem_seg(self, + image: np.ndarray, + sem_seg: PixelData, classes: Optional[List], - palette: Optional[List]) -> np.ndarray: + palette: Optional[List], + withLabels: Optional[bool] = True) -> np.ndarray: """Draw semantic seg of GT or prediction. Args: @@ -94,6 +119,8 @@ def _draw_sem_seg(self, image: np.ndarray, sem_seg: PixelData, palette (list, optional): Input palette for result rendering, which is a list of color palette responding to the classes. Defaults to None. + withLabels(bool, optional): Add semantic labels in visualization + result, Default to True. Returns: np.ndarray: the drawn image which channel is RGB. @@ -108,14 +135,90 @@ def _draw_sem_seg(self, image: np.ndarray, sem_seg: PixelData, colors = [palette[label] for label in labels] - self.set_image(image) - - # draw semantic masks + mask = np.zeros_like(image, dtype=np.uint8) for label, color in zip(labels, colors): - self.draw_binary_masks( - sem_seg == label, colors=[color], alphas=self.alpha) + mask[sem_seg[0] == label, :] = color + + if withLabels: + font = cv2.FONT_HERSHEY_SIMPLEX + # (0,1] to change the size of the text relative to the image + scale = 0.05 + fontScale = min(image.shape[0], image.shape[1]) / (25 / scale) + fontColor = (255, 255, 255) + if image.shape[0] < 300 or image.shape[1] < 300: + thickness = 1 + rectangleThickness = 1 + else: + thickness = 2 + rectangleThickness = 2 + lineType = 2 + + if isinstance(sem_seg[0], torch.Tensor): + masks = sem_seg[0].numpy() == labels[:, None, None] + else: + masks = sem_seg[0] == labels[:, None, None] + masks = masks.astype(np.uint8) + for mask_num in range(len(labels)): + classes_id = labels[mask_num] + classes_color = colors[mask_num] + loc = self._get_center_loc(masks[mask_num]) + text = classes[classes_id] + (label_width, label_height), baseline = cv2.getTextSize( + text, font, fontScale, thickness) + mask = cv2.rectangle(mask, loc, + (loc[0] + label_width + baseline, + loc[1] + label_height + baseline), + classes_color, -1) + mask = cv2.rectangle(mask, loc, + (loc[0] + label_width + baseline, + loc[1] + label_height + baseline), + (0, 0, 0), rectangleThickness) + mask = cv2.putText(mask, text, (loc[0], loc[1] + label_height), + font, fontScale, fontColor, thickness, + lineType) + color_seg = (image * (1 - self.alpha) + mask * self.alpha).astype( + np.uint8) + self.set_image(color_seg) + return color_seg + + def _draw_depth_map(self, image: np.ndarray, + depth_map: PixelData) -> np.ndarray: + """Draws a depth map on a given image. + + This function takes an image and a depth map as input, + renders the depth map, and concatenates it with the original image. + Finally, it updates the internal image state of the visualizer with + the concatenated result. + + Args: + image (np.ndarray): The original image where the depth map will + be drawn. The array should be in the format HxWx3 where H is + the height, W is the width. + + depth_map (PixelData): Depth map to be drawn. The depth map + should be in the form of a PixelData object. It will be + converted to a torch tensor if it is a numpy array. + + Returns: + np.ndarray: The concatenated image with the depth map drawn. + + Example: + >>> depth_map_data = PixelData(data=torch.rand(1, 10, 10)) + >>> image = np.random.randint(0, 256, + >>> size=(10, 10, 3)).astype('uint8') + >>> visualizer = SegLocalVisualizer() + >>> visualizer._draw_depth_map(image, depth_map_data) + """ + depth_map = depth_map.cpu().data + if isinstance(depth_map, np.ndarray): + depth_map = torch.from_numpy(depth_map) + if depth_map.ndim == 2: + depth_map = depth_map[None] - return self.get_image() + depth_map = self.draw_featmap(depth_map, resize_shape=image.shape[:2]) + out_image = np.concatenate((image, depth_map), axis=0) + self.set_image(out_image) + return out_image def set_dataset_meta(self, classes: Optional[List] = None, @@ -133,11 +236,11 @@ def set_dataset_meta(self, palette (list, optional): Input palette for result rendering, which is a list of color palette responding to the classes. Defaults to None. - dataset_name (str, optional): `Dataset name or alias `_ + dataset_name (str, optional): `Dataset name or alias `_ visulizer will use the meta information of the dataset i.e. classes and palette, but the `classes` and `palette` have higher priority. Defaults to None. - """ # noqa + """ # noqa # Set default value. When calling # `SegLocalVisualizer().dataset_meta=xxx`, # it will override the default value. @@ -161,7 +264,8 @@ def add_datasample( wait_time: float = 0, # TODO: Supported in mmengine's Viusalizer. out_file: Optional[str] = None, - step: int = 0) -> None: + step: int = 0, + withLabels: Optional[bool] = True) -> None: """Draw datasample and save to all backends. - If GT and prediction are plotted at the same time, they are @@ -187,6 +291,8 @@ def add_datasample( wait_time (float): The interval of show (s). Defaults to 0. out_file (str): Path to output file. Defaults to None. step (int): Global step value to record. Defaults to 0. + withLabels(bool, optional): Add semantic labels in visualization + result, Defaults to True. """ classes = self.dataset_meta.get('classes', None) palette = self.dataset_meta.get('palette', None) @@ -194,26 +300,38 @@ def add_datasample( gt_img_data = None pred_img_data = None - if draw_gt and data_sample is not None and 'gt_sem_seg' in data_sample: - gt_img_data = image - assert classes is not None, 'class information is ' \ - 'not provided when ' \ - 'visualizing semantic ' \ - 'segmentation results.' - gt_img_data = self._draw_sem_seg(gt_img_data, - data_sample.gt_sem_seg, classes, - palette) - - if (draw_pred and data_sample is not None - and 'pred_sem_seg' in data_sample): - pred_img_data = image - assert classes is not None, 'class information is ' \ - 'not provided when ' \ - 'visualizing semantic ' \ - 'segmentation results.' - pred_img_data = self._draw_sem_seg(pred_img_data, - data_sample.pred_sem_seg, - classes, palette) + if draw_gt and data_sample is not None: + if 'gt_sem_seg' in data_sample: + assert classes is not None, 'class information is ' \ + 'not provided when ' \ + 'visualizing semantic ' \ + 'segmentation results.' + gt_img_data = self._draw_sem_seg(image, data_sample.gt_sem_seg, + classes, palette, withLabels) + + if 'gt_depth_map' in data_sample: + gt_img_data = gt_img_data if gt_img_data is not None else image + gt_img_data = self._draw_depth_map(gt_img_data, + data_sample.gt_depth_map) + + if draw_pred and data_sample is not None: + + if 'pred_sem_seg' in data_sample: + + assert classes is not None, 'class information is ' \ + 'not provided when ' \ + 'visualizing semantic ' \ + 'segmentation results.' + pred_img_data = self._draw_sem_seg(image, + data_sample.pred_sem_seg, + classes, palette, + withLabels) + + if 'pred_depth_map' in data_sample: + pred_img_data = pred_img_data if pred_img_data is not None \ + else image + pred_img_data = self._draw_depth_map( + pred_img_data, data_sample.pred_depth_map) if gt_img_data is not None and pred_img_data is not None: drawn_img = np.concatenate((gt_img_data, pred_img_data), axis=1) @@ -226,6 +344,6 @@ def add_datasample( self.show(drawn_img, win_name=name, wait_time=wait_time) if out_file is not None: - mmcv.imwrite(mmcv.bgr2rgb(drawn_img), out_file) + mmcv.imwrite(mmcv.rgb2bgr(drawn_img), out_file) else: self.add_image(name, drawn_img, step) diff --git a/model-index.yml b/model-index.yml index 5e87c386ddf..4026bb9e6e4 100644 --- a/model-index.yml +++ b/model-index.yml @@ -8,6 +8,7 @@ Import: - configs/cgnet/metafile.yaml - configs/convnext/metafile.yaml - configs/danet/metafile.yaml +- configs/ddrnet/metafile.yaml - configs/deeplabv3/metafile.yaml - configs/deeplabv3plus/metafile.yaml - configs/dmnet/metafile.yaml @@ -37,6 +38,7 @@ Import: - configs/psanet/metafile.yaml - configs/pspnet/metafile.yaml - configs/resnest/metafile.yaml +- configs/san/metafile.yaml - configs/segformer/metafile.yaml - configs/segmenter/metafile.yaml - configs/segnext/metafile.yaml @@ -48,3 +50,4 @@ Import: - configs/unet/metafile.yaml - configs/upernet/metafile.yaml - configs/vit/metafile.yaml +- configs/vpd/metafile.yaml diff --git a/projects/Adabins/README.md b/projects/Adabins/README.md new file mode 100644 index 00000000000..8a23e92d74a --- /dev/null +++ b/projects/Adabins/README.md @@ -0,0 +1,46 @@ +# AdaBins: Depth Estimation Using Adaptive Bins + +## Reference + +> [AdaBins: Depth Estimation Using Adaptive Bins](https://arxiv.org/abs/2011.14141) + +## Introduction + +Official Repo + +Code Snippet + +## Abstract + +We address the problem of estimating a high quality dense depth map from a single RGB input image. We start out with a baseline encoder-decoder convolutional neural network architecture and pose the question of how the global processing of information can help improve overall depth estimation. To this end, we propose a transformer-based architecture block that divides the depth range into bins whose center value is estimated adaptively per image. The final depth values are estimated as linear combinations of the bin centers. We call our new building block AdaBins. Our results show a decisive improvement over the state-of-the-art on several popular depth datasets across all metrics.We also validate the effectiveness of the proposed block with an ablation study and provide the code and corresponding pre-trained weights of the new state-of-the-art model. + +Our main contributions are the following: + +- We propose an architecture building block that performs global processing of the scene’s information.We propose to divide the predicted depth range into bins where the bin widths change per image. The final depth estimation is a linear combination of the bin center values. +- We show a decisive improvement for supervised single image depth estimation across all metrics for the two most popular datasets, NYU and KITTI. +- We analyze our findings and investigate different modifications on the proposed AdaBins block and study their effect on the accuracy of the depth estimation. + +
+ +
+ +## Performance + +### NYU and KITTI + +| Model | Encoder | Training epoch | Batchsize | Train Resolution | δ1 | δ2 | δ3 | REL | RMS | RMS log | params(M) | Links | +| ------------- | --------------- | -------------- | --------- | ---------------- | ----- | ----- | ----- | ----- | ----- | ------- | --------- | ----------------------------------------------------------------------------------------------------------------------- | +| AdaBins_nyu | EfficientNet-B5 | 25 | 16 | 416x544 | 0.903 | 0.984 | 0.997 | 0.103 | 0.364 | 0.044 | 78 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/adabins/adabins_efficient_b5_nyu_third-party-f68d6bd3.pth) | +| AdaBins_kitti | EfficientNet-B5 | 25 | 16 | 352x764 | 0.964 | 0.995 | 0.999 | 0.058 | 2.360 | 0.088 | 78 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/adabins/adabins_efficient-b5_kitty_third-party-a1aa6f36.pth) | + +## Citation + +```bibtex +@article{10.1109/cvpr46437.2021.00400, + author = {Bhat, S. A. and Alhashim, I. and Wonka, P.}, + title = {Adabins: depth estimation using adaptive bins}, + journal = {2021 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)}, + year = {2021}, + doi = {10.1109/cvpr46437.2021.00400} +} +``` diff --git a/projects/Adabins/backbones/__init__.py b/projects/Adabins/backbones/__init__.py new file mode 100644 index 00000000000..04ae180be5f --- /dev/null +++ b/projects/Adabins/backbones/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .adabins_backbone import AdabinsBackbone + +__all__ = ['AdabinsBackbone'] diff --git a/projects/Adabins/backbones/adabins_backbone.py b/projects/Adabins/backbones/adabins_backbone.py new file mode 100644 index 00000000000..07d73809e39 --- /dev/null +++ b/projects/Adabins/backbones/adabins_backbone.py @@ -0,0 +1,141 @@ +import timm +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import ConvModule, build_conv_layer +from mmengine.model import BaseModule + +from mmseg.registry import MODELS + + +class UpSampleBN(nn.Module): + """ UpSample module + Args: + skip_input (int): the input feature + output_features (int): the output feature + norm_cfg (dict, optional): Config dict for normalization layer. + Default: dict(type='BN', requires_grad=True). + act_cfg (dict, optional): The activation layer of AAM: + Aggregate Attention Module. + """ + + def __init__(self, + skip_input, + output_features, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='LeakyReLU')): + super().__init__() + + self._net = nn.Sequential( + ConvModule( + in_channels=skip_input, + out_channels=output_features, + kernel_size=3, + stride=1, + padding=1, + bias=True, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + ), + ConvModule( + in_channels=output_features, + out_channels=output_features, + kernel_size=3, + stride=1, + padding=1, + bias=True, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + )) + + def forward(self, x, concat_with): + up_x = F.interpolate( + x, + size=[concat_with.size(2), + concat_with.size(3)], + mode='bilinear', + align_corners=True) + f = torch.cat([up_x, concat_with], dim=1) + return self._net(f) + + +class Encoder(nn.Module): + """ the efficientnet_b5 model + Args: + basemodel_name (str): the name of base model + """ + + def __init__(self, basemodel_name): + super().__init__() + self.original_model = timm.create_model( + basemodel_name, pretrained=True) + # Remove last layer + self.original_model.global_pool = nn.Identity() + self.original_model.classifier = nn.Identity() + + def forward(self, x): + features = [x] + for k, v in self.original_model._modules.items(): + if k == 'blocks': + for ki, vi in v._modules.items(): + features.append(vi(features[-1])) + else: + features.append(v(features[-1])) + return features + + +@MODELS.register_module() +class AdabinsBackbone(BaseModule): + """ the backbone of the adabins + Args: + basemodel_name (str):the name of base model + num_features (int): the middle feature + num_classes (int): the classes number + bottleneck_features (int): the bottleneck features + conv_cfg (dict): Config dict for convolution layer. + """ + + def __init__(self, + basemodel_name, + num_features=2048, + num_classes=128, + bottleneck_features=2048, + conv_cfg=dict(type='Conv')): + super().__init__() + self.encoder = Encoder(basemodel_name) + features = int(num_features) + self.conv2 = build_conv_layer( + conv_cfg, + bottleneck_features, + features, + kernel_size=1, + stride=1, + padding=1) + self.up1 = UpSampleBN( + skip_input=features // 1 + 112 + 64, output_features=features // 2) + self.up2 = UpSampleBN( + skip_input=features // 2 + 40 + 24, output_features=features // 4) + self.up3 = UpSampleBN( + skip_input=features // 4 + 24 + 16, output_features=features // 8) + self.up4 = UpSampleBN( + skip_input=features // 8 + 16 + 8, output_features=features // 16) + + self.conv3 = build_conv_layer( + conv_cfg, + features // 16, + num_classes, + kernel_size=3, + stride=1, + padding=1) + + def forward(self, x): + features = self.encoder(x) + x_block0, x_block1, x_block2, x_block3, x_block4 = features[ + 3], features[4], features[5], features[7], features[10] + x_d0 = self.conv2(x_block4) + x_d1 = self.up1(x_d0, x_block3) + x_d2 = self.up2(x_d1, x_block2) + x_d3 = self.up3(x_d2, x_block1) + x_d4 = self.up4(x_d3, x_block0) + out = self.conv3(x_d4) + return out diff --git a/projects/Adabins/configs/_base_/datasets/nyu.py b/projects/Adabins/configs/_base_/datasets/nyu.py new file mode 100644 index 00000000000..1b49ec7e8de --- /dev/null +++ b/projects/Adabins/configs/_base_/datasets/nyu.py @@ -0,0 +1,32 @@ +dataset_type = 'NYUDataset' +data_root = 'data/nyu' + +test_pipeline = [ + dict(dict(type='LoadImageFromFile', to_float32=True)), + dict(dict(type='LoadDepthAnnotation', depth_rescale_factor=1e-3)), + dict( + type='PackSegInputs', + meta_keys=('img_path', 'depth_map_path', 'ori_shape', 'img_shape', + 'pad_shape', 'scale_factor', 'flip', 'flip_direction', + 'category_id')) +] + +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + test_mode=True, + data_prefix=dict( + img_path='images/test', depth_map_path='annotations/test'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict( + type='DepthMetric', max_depth_eval=10.0, crop_type='nyu_crop') +test_evaluator = val_evaluator +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') diff --git a/projects/Adabins/configs/_base_/default_runtime.py b/projects/Adabins/configs/_base_/default_runtime.py new file mode 100644 index 00000000000..272b4d24679 --- /dev/null +++ b/projects/Adabins/configs/_base_/default_runtime.py @@ -0,0 +1,15 @@ +default_scope = 'mmseg' +env_cfg = dict( + cudnn_benchmark=True, + mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), + dist_cfg=dict(backend='nccl'), +) +vis_backends = [dict(type='LocalVisBackend')] +visualizer = dict( + type='SegLocalVisualizer', vis_backends=vis_backends, name='visualizer') +log_processor = dict(by_epoch=False) +log_level = 'INFO' +load_from = None +resume = False + +tta_model = dict(type='SegTTAModel') diff --git a/projects/Adabins/configs/_base_/models/Adabins.py b/projects/Adabins/configs/_base_/models/Adabins.py new file mode 100644 index 00000000000..35cbd8c5777 --- /dev/null +++ b/projects/Adabins/configs/_base_/models/Adabins.py @@ -0,0 +1,35 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +model = dict( + type='DepthEstimator', + data_preprocessor=data_preprocessor, + # pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='AdabinsBackbone', + basemodel_name='tf_efficientnet_b5_ap', + num_features=2048, + num_classes=128, + bottleneck_features=2048, + ), + decode_head=dict( + type='AdabinsHead', + in_channels=128, + n_query_channels=128, + patch_size=16, + embedding_dim=128, + num_heads=4, + n_bins=256, + min_val=0.001, + max_val=10, + norm='linear'), + + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_NYU_416x544.py b/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_NYU_416x544.py new file mode 100644 index 00000000000..5c00ea152bf --- /dev/null +++ b/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_NYU_416x544.py @@ -0,0 +1,15 @@ +_base_ = [ + '../_base_/models/Adabins.py', '../_base_/datasets/nyu.py', + '../_base_/default_runtime.py' +] +custom_imports = dict( + imports=['projects.Adabins.backbones', 'projects.Adabins.decode_head'], + allow_failed_imports=False) +crop_size = (416, 544) +data_preprocessor = dict(size=crop_size) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + data_preprocessor=data_preprocessor, + backbone=dict(), + decode_head=dict(), +) diff --git a/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_kitti_352x704.py b/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_kitti_352x704.py new file mode 100644 index 00000000000..330cdf41a5b --- /dev/null +++ b/projects/Adabins/configs/adabins/adabins_efficient_b5_4x16_25e_kitti_352x704.py @@ -0,0 +1,12 @@ +_base_ = ['../_base_/models/Adabins.py'] +custom_imports = dict( + imports=['projects.Adabins.backbones', 'projects.Adabins.decode_head'], + allow_failed_imports=False) +crop_size = (352, 704) +data_preprocessor = dict(size=crop_size) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + data_preprocessor=data_preprocessor, + backbone=dict(), + decode_head=dict(min_val=0.001, max_val=80), +) diff --git a/projects/Adabins/decode_head/__init__.py b/projects/Adabins/decode_head/__init__.py new file mode 100644 index 00000000000..c7d62df12bb --- /dev/null +++ b/projects/Adabins/decode_head/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .adabins_head import AdabinsHead + +__all__ = ['AdabinsHead'] diff --git a/projects/Adabins/decode_head/adabins_head.py b/projects/Adabins/decode_head/adabins_head.py new file mode 100644 index 00000000000..ee043172ab9 --- /dev/null +++ b/projects/Adabins/decode_head/adabins_head.py @@ -0,0 +1,179 @@ +from typing import List, Tuple + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import build_conv_layer +from torch import Tensor + +from mmseg.registry import MODELS + + +class PatchTransformerEncoder(nn.Module): + """the Patch Transformer Encoder. + + Args: + in_channels (int): the channels of input + patch_size (int): the path size + embedding_dim (int): The feature dimension. + num_heads (int): the number of encoder head + conv_cfg (dict): Config dict for convolution layer. + """ + + def __init__(self, + in_channels, + patch_size=10, + embedding_dim=128, + num_heads=4, + conv_cfg=dict(type='Conv')): + super().__init__() + encoder_layers = nn.TransformerEncoderLayer( + embedding_dim, num_heads, dim_feedforward=1024) + self.transformer_encoder = nn.TransformerEncoder( + encoder_layers, num_layers=4) # takes shape S,N,E + + self.embedding_convPxP = build_conv_layer( + conv_cfg, + in_channels, + embedding_dim, + kernel_size=patch_size, + stride=patch_size) + self.positional_encodings = nn.Parameter( + torch.rand(500, embedding_dim), requires_grad=True) + + def forward(self, x): + embeddings = self.embedding_convPxP(x).flatten( + 2) # .shape = n,c,s = n, embedding_dim, s + embeddings = embeddings + self.positional_encodings[:embeddings.shape[ + 2], :].T.unsqueeze(0) + + # change to S,N,E format required by transformer + embeddings = embeddings.permute(2, 0, 1) + x = self.transformer_encoder(embeddings) # .shape = S, N, E + return x + + +class PixelWiseDotProduct(nn.Module): + """the pixel wise dot product.""" + + def __init__(self): + super().__init__() + + def forward(self, x, K): + n, c, h, w = x.size() + _, cout, ck = K.size() + assert c == ck, 'Number of channels in x and Embedding dimension ' \ + '(at dim 2) of K matrix must match' + y = torch.matmul( + x.view(n, c, h * w).permute(0, 2, 1), + K.permute(0, 2, 1)) # .shape = n, hw, cout + return y.permute(0, 2, 1).view(n, cout, h, w) + + +@MODELS.register_module() +class AdabinsHead(nn.Module): + """the head of the adabins,include mViT. + + Args: + in_channels (int):the channels of the input + n_query_channels (int):the channels of the query + patch_size (int): the patch size + embedding_dim (int):The feature dimension. + num_heads (int):the number of head + n_bins (int):the number of bins + min_val (float): the min width of bin + max_val (float): the max width of bin + conv_cfg (dict): Config dict for convolution layer. + norm (str): the activate method + align_corners (bool, optional): Geometrically, we consider the pixels + of the input and output as squares rather than points. + """ + + def __init__(self, + in_channels, + n_query_channels=128, + patch_size=16, + embedding_dim=128, + num_heads=4, + n_bins=100, + min_val=0.1, + max_val=10, + conv_cfg=dict(type='Conv'), + norm='linear', + align_corners=False, + threshold=0): + super().__init__() + self.out_channels = n_bins + self.align_corners = align_corners + self.norm = norm + self.num_classes = n_bins + self.min_val = min_val + self.max_val = max_val + self.n_query_channels = n_query_channels + self.patch_transformer = PatchTransformerEncoder( + in_channels, patch_size, embedding_dim, num_heads) + self.dot_product_layer = PixelWiseDotProduct() + self.threshold = threshold + self.conv3x3 = build_conv_layer( + conv_cfg, + in_channels, + embedding_dim, + kernel_size=3, + stride=1, + padding=1) + self.regressor = nn.Sequential( + nn.Linear(embedding_dim, 256), nn.LeakyReLU(), nn.Linear(256, 256), + nn.LeakyReLU(), nn.Linear(256, n_bins)) + self.conv_out = nn.Sequential( + build_conv_layer(conv_cfg, in_channels, n_bins, kernel_size=1), + nn.Softmax(dim=1)) + + def forward(self, x): + # n, c, h, w = x.size() + tgt = self.patch_transformer(x.clone()) # .shape = S, N, E + + x = self.conv3x3(x) + + regression_head, queries = tgt[0, + ...], tgt[1:self.n_query_channels + 1, + ...] + + # Change from S, N, E to N, S, E + queries = queries.permute(1, 0, 2) + range_attention_maps = self.dot_product_layer( + x, queries) # .shape = n, n_query_channels, h, w + + y = self.regressor(regression_head) # .shape = N, dim_out + if self.norm == 'linear': + y = torch.relu(y) + eps = 0.1 + y = y + eps + elif self.norm == 'softmax': + return torch.softmax(y, dim=1), range_attention_maps + else: + y = torch.sigmoid(y) + bin_widths_normed = y / y.sum(dim=1, keepdim=True) + out = self.conv_out(range_attention_maps) + + bin_widths = (self.max_val - + self.min_val) * bin_widths_normed # .shape = N, dim_out + bin_widths = F.pad( + bin_widths, (1, 0), mode='constant', value=self.min_val) + bin_edges = torch.cumsum(bin_widths, dim=1) + + centers = 0.5 * (bin_edges[:, :-1] + bin_edges[:, 1:]) + n, dim_out = centers.size() + centers = centers.view(n, dim_out, 1, 1) + + pred = torch.sum(out * centers, dim=1, keepdim=True) + return bin_edges, pred + + def predict(self, inputs: Tuple[Tensor], batch_img_metas: List[dict], + test_cfg, **kwargs) -> Tensor: + """Forward function for testing, only ``pam_cam`` is used.""" + pred = self.forward(inputs)[-1] + final = torch.clamp(pred, self.min_val, self.max_val) + + final[torch.isinf(final)] = self.max_val + final[torch.isnan(final)] = self.min_val + return final diff --git a/projects/CAT-Seg/README.md b/projects/CAT-Seg/README.md new file mode 100644 index 00000000000..890e461ce4c --- /dev/null +++ b/projects/CAT-Seg/README.md @@ -0,0 +1,92 @@ +# CAT-Seg + +> [CAT-Seg: Cost Aggregation for Open-Vocabulary Semantic Segmentation](https://arxiv.org/abs/2303.11797) + +## Introduction + + + +Official Repo + +Code Snippet + +## Abstract + + + +Existing works on open-vocabulary semantic segmentation have utilized large-scale vision-language models, such as CLIP, to leverage their exceptional open-vocabulary recognition capabilities. However, the problem of transferring these capabilities learned from image-level supervision to the pixel-level task of segmentation and addressing arbitrary unseen categories at inference makes this task challenging. To address these issues, we aim to attentively relate objects within an image to given categories by leveraging relational information among class categories and visual semantics through aggregation, while also adapting the CLIP representations to the pixel-level task. However, we observe that direct optimization of the CLIP embeddings can harm its open-vocabulary capabilities. In this regard, we propose an alternative approach to optimize the imagetext similarity map, i.e. the cost map, using a novel cost aggregation-based method. Our framework, namely CATSeg, achieves state-of-the-art performance across all benchmarks. We provide extensive ablation studies to validate our choices. [Project page](https://ku-cvlab.github.io/CAT-Seg). + + + +
+CAT-Seg +CAT-Seg model structure +
+ +## Usage + +CAT-Seg model training needs pretrained `CLIP` model. We have implemented `ViT-B` and `ViT-L` based `CLIP` model. To further use `ViT-bigG` or `ViT-H` ones, you need additional dependencies. Please install [open_clip](https://github.com/mlfoundations/open_clip) first. The pretrained `CLIP` model state dicts are loaded from [Huggingface-OpenCLIP](https://huggingface.co/models?library=open_clip). **If you come up with `ConnectionError` when downloading CLIP weights**, you can manually download them from the given repo and use `custom_clip_weights=/path/to/you/folder` of backbone in config file. Related tools are as shown in [requirements/optional.txt](requirements/optional.txt): + +```shell +pip install ftfy==6.0.1 +pip install huggingface-hub +pip install regex +``` + +In addition to the necessary [data preparation](https://github.com/open-mmlab/mmsegmentation/blob/main/docs/en/user_guides/2_dataset_prepare.md), you also need class texts for clip text encoder. Please download the class text json file first [cls_texts](https://github.com/open-mmlab/mmsegmentation/files/11714914/cls_texts.zip) and arrange the folder as follows: + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── VOCdevkit +│ │ ├── VOC2012 +│ │ ├── VOC2010 +│ │ ├── VOCaug +│ ├── ade +│ ├── coco_stuff164k +│ ├── coco.json +│ ├── pc59.json +│ ├── pc459.json +│ ├── ade150.json +│ ├── ade847.json +│ ├── voc20b.json +│ ├── voc20.json +``` + +```shell +# setup PYTHONPATH +export PYTHONPATH=`pwd`:$PYTHONPATH +# run evaluation +mim test mmsegmentation ${CONFIG} --checkpoint ${CHECKPOINT} --launcher pytorch --gpus=8 +``` + +## Results and models + +### ADE20K-150-ZeroShot + +| Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | Device | mIoU | mIoU(ms+flip) | config | download | +| ------- | ------------- | --------- | ------- | -------: | -------------- | ------- | ---- | ------------: | ------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------- | +| CAT-Seg | R-101 & ViT-B | 384x384 | 80000 | - | - | RTX3090 | 27.2 | - | [config](./configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_ade20k-384x384.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_ade20k-384x384-54194d72.pth) | + +Note: + +- All experiments of CAT-Seg are implemented with 4 RTX3090 GPUs, except the last one with pretrained ViT-bigG CLIP model (GPU Memory insufficient, you may need A100). +- Due to the feature size bottleneck of the CLIP image encoder, the inference and testing can only be done under `slide` mode, the inference time is longer since the test size is much more bigger that training size of `(384, 384)`. +- The ResNet backbones utilized in CAT-Seg models are standard `ResNet` rather than `ResNetV1c`. +- The zero-shot segmentation results on PASCAL VOC and ADE20K are from the original paper. Our results are coming soon. We appreatiate your contribution! +- In additional to zero-shot segmentation performance results, we also provided the evaluation results on the `val2017` set of **COCO-stuff164k** for reference, which is the training dataset of CAT-Seg. The testing was done **without TTA**. +- The number behind the dataset name is the category number for segmentation evaluation (except training data **COCO-stuff 164k**). **PASCAL VOC-20b** defines the "background" as classes present in **PASCAL-Context-59** but not in **PASCAL VOC-20**. + +## Citation + +```bibtex +@inproceedings{cheng2021mask2former, + title={CAT-Seg: Cost Aggregation for Open-Vocabulary Semantic Segmentation}, + author={Seokju Cho and Heeseong Shin and Sunghwan Hong and Seungjun An and Seungjun Lee and Anurag Arnab and Paul Hongsuck Seo and Seungryong Kim}, + journal={CVPR}, + year={2023} +} +``` diff --git a/projects/CAT-Seg/cat_seg/__init__.py b/projects/CAT-Seg/cat_seg/__init__.py new file mode 100644 index 00000000000..2c51fbaa2e3 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/__init__.py @@ -0,0 +1,2 @@ +from .models import * # noqa: F401,F403 +from .utils import * # noqa: F401,F403 diff --git a/projects/CAT-Seg/cat_seg/models/__init__.py b/projects/CAT-Seg/cat_seg/models/__init__.py new file mode 100644 index 00000000000..cd0e15d3ec9 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/models/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .cat_aggregator import (AggregatorLayer, CATSegAggregator, + ClassAggregateLayer, SpatialAggregateLayer) +from .cat_head import CATSegHead +from .clip_ovseg import CLIPOVCATSeg + +__all__ = [ + 'AggregatorLayer', 'CATSegAggregator', 'ClassAggregateLayer', + 'SpatialAggregateLayer', 'CATSegHead', 'CLIPOVCATSeg' +] diff --git a/projects/CAT-Seg/cat_seg/models/cat_aggregator.py b/projects/CAT-Seg/cat_seg/models/cat_aggregator.py new file mode 100644 index 00000000000..a0483fe505b --- /dev/null +++ b/projects/CAT-Seg/cat_seg/models/cat_aggregator.py @@ -0,0 +1,763 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import build_norm_layer +from mmcv.cnn.bricks.transformer import FFN, build_dropout +from mmengine.model import BaseModule +from mmengine.utils import to_2tuple + +from mmseg.registry import MODELS +from ..utils import FullAttention, LinearAttention + + +class AGWindowMSA(BaseModule): + """Appearance Guidance Window based multi-head self-attention (W-MSA) + module with relative position bias. + + Args: + embed_dims (int): Number of input channels. + appearance_dims (int): Number of appearance guidance feature channels. + num_heads (int): Number of attention heads. + window_size (tuple[int]): The height and width of the window. + qkv_bias (bool, optional): If True, add a learnable bias to q, k, v. + Default: True. + qk_scale (float | None, optional): Override default qk scale of + head_dim ** -0.5 if set. Default: None. + attn_drop_rate (float, optional): Dropout ratio of attention weight. + Default: 0.0 + proj_drop_rate (float, optional): Dropout ratio of output. Default: 0. + init_cfg (dict | None, optional): The Config for initialization. + Default: None. + """ + + def __init__(self, + embed_dims, + appearance_dims, + num_heads, + window_size, + qkv_bias=True, + qk_scale=None, + attn_drop_rate=0., + proj_drop_rate=0., + init_cfg=None): + + super().__init__(init_cfg=init_cfg) + self.embed_dims = embed_dims + self.appearance_dims = appearance_dims + self.window_size = window_size # Wh, Ww + self.num_heads = num_heads + head_embed_dims = embed_dims // num_heads + self.scale = qk_scale or head_embed_dims**-0.5 + + # About 2x faster than original impl + Wh, Ww = self.window_size + rel_index_coords = self.double_step_seq(2 * Ww - 1, Wh, 1, Ww) + rel_position_index = rel_index_coords + rel_index_coords.T + rel_position_index = rel_position_index.flip(1).contiguous() + self.register_buffer('relative_position_index', rel_position_index) + + self.qk = nn.Linear( + embed_dims + appearance_dims, embed_dims * 2, bias=qkv_bias) + self.v = nn.Linear(embed_dims, embed_dims, bias=qkv_bias) + self.attn_drop = nn.Dropout(attn_drop_rate) + self.proj = nn.Linear(embed_dims, embed_dims) + self.proj_drop = nn.Dropout(proj_drop_rate) + + self.softmax = nn.Softmax(dim=-1) + + def forward(self, x, mask=None): + """ + Args: + x (tensor): input features with shape of (num_windows*B, N, C), + C = embed_dims + appearance_dims. + mask (tensor | None, Optional): mask with shape of (num_windows, + Wh*Ww, Wh*Ww), value should be between (-inf, 0]. + """ + B, N, _ = x.shape + qk = self.qk(x).reshape(B, N, 2, self.num_heads, + self.embed_dims // self.num_heads).permute( + 2, 0, 3, 1, + 4) # 2 B NUM_HEADS N embed_dims//NUM_HEADS + v = self.v(x[:, :, :self.embed_dims]).reshape( + B, N, self.num_heads, self.embed_dims // self.num_heads).permute( + 0, 2, 1, 3) # B NUM_HEADS N embed_dims//NUM_HEADS + # make torchscript happy (cannot use tensor as tuple) + q, k = qk[0], qk[1] + + q = q * self.scale + attn = (q @ k.transpose(-2, -1)) + + if mask is not None: + nW = mask.shape[0] + attn = attn.view(B // nW, nW, self.num_heads, N, + N) + mask.unsqueeze(1).unsqueeze(0) + attn = attn.view(-1, self.num_heads, N, N) + attn = self.softmax(attn) + + attn = self.attn_drop(attn) + + x = (attn @ v).transpose(1, 2).reshape(B, N, self.embed_dims) + x = self.proj(x) + x = self.proj_drop(x) + return x + + @staticmethod + def double_step_seq(step1, len1, step2, len2): + """Double step sequence.""" + seq1 = torch.arange(0, step1 * len1, step1) + seq2 = torch.arange(0, step2 * len2, step2) + return (seq1[:, None] + seq2[None, :]).reshape(1, -1) + + +class AGShiftWindowMSA(BaseModule): + """Appearance Guidance Shifted Window Multihead Self-Attention Module. + + Args: + embed_dims (int): Number of input channels. + appearance_dims (int): Number of appearance guidance channels + num_heads (int): Number of attention heads. + window_size (int): The height and width of the window. + shift_size (int, optional): The shift step of each window towards + right-bottom. If zero, act as regular window-msa. Defaults to 0. + qkv_bias (bool, optional): If True, add a learnable bias to q, k, v. + Default: True + qk_scale (float | None, optional): Override default qk scale of + head_dim ** -0.5 if set. Defaults: None. + attn_drop_rate (float, optional): Dropout ratio of attention weight. + Defaults: 0. + proj_drop_rate (float, optional): Dropout ratio of output. + Defaults: 0. + dropout_layer (dict, optional): The dropout_layer used before output. + Defaults: dict(type='DropPath', drop_prob=0.). + init_cfg (dict, optional): The extra config for initialization. + Default: None. + """ + + def __init__(self, + embed_dims, + appearance_dims, + num_heads, + window_size, + shift_size=0, + qkv_bias=True, + qk_scale=None, + attn_drop_rate=0, + proj_drop_rate=0, + dropout_layer=dict(type='DropPath', drop_prob=0.), + init_cfg=None): + super().__init__(init_cfg=init_cfg) + + self.window_size = window_size + self.shift_size = shift_size + assert 0 <= self.shift_size < self.window_size + + self.w_msa = AGWindowMSA( + embed_dims=embed_dims, + appearance_dims=appearance_dims, + num_heads=num_heads, + window_size=to_2tuple(window_size), + qkv_bias=qkv_bias, + qk_scale=qk_scale, + attn_drop_rate=attn_drop_rate, + proj_drop_rate=proj_drop_rate, + init_cfg=None) + + self.drop = build_dropout(dropout_layer) + + def forward(self, query, hw_shape): + """ + Args: + query: The input query. + hw_shape: The shape of the feature height and width. + """ + B, L, C = query.shape + H, W = hw_shape + assert L == H * W, 'input feature has wrong size' + query = query.view(B, H, W, C) + + # pad feature maps to multiples of window size + pad_r = (self.window_size - W % self.window_size) % self.window_size + pad_b = (self.window_size - H % self.window_size) % self.window_size + query = F.pad(query, (0, 0, 0, pad_r, 0, pad_b)) + H_pad, W_pad = query.shape[1], query.shape[2] + + # cyclic shift + if self.shift_size > 0: + shifted_query = torch.roll( + query, + shifts=(-self.shift_size, -self.shift_size), + dims=(1, 2)) + + # calculate attention mask for SW-MSA + img_mask = torch.zeros((1, H_pad, W_pad, 1), device=query.device) + h_slices = (slice(0, -self.window_size), + slice(-self.window_size, + -self.shift_size), slice(-self.shift_size, None)) + w_slices = (slice(0, -self.window_size), + slice(-self.window_size, + -self.shift_size), slice(-self.shift_size, None)) + cnt = 0 + for h in h_slices: + for w in w_slices: + img_mask[:, h, w, :] = cnt + cnt += 1 + + # nW, window_size, window_size, 1 + mask_windows = self.window_partition(img_mask) + mask_windows = mask_windows.view( + -1, self.window_size * self.window_size) + attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2) + attn_mask = attn_mask.masked_fill(attn_mask != 0, + float(-100.0)).masked_fill( + attn_mask == 0, float(0.0)) + else: + shifted_query = query + attn_mask = None + + # nW*B, window_size, window_size, C + query_windows = self.window_partition(shifted_query) + # nW*B, window_size*window_size, C + query_windows = query_windows.view(-1, self.window_size**2, C) + + # W-MSA/SW-MSA (nW*B, window_size*window_size, C) + attn_windows = self.w_msa(query_windows, mask=attn_mask) + + # merge windows + attn_windows = attn_windows.view(-1, self.window_size, + self.window_size, + self.w_msa.embed_dims) + + # B H' W' self.w_msa.embed_dims + shifted_x = self.window_reverse(attn_windows, H_pad, W_pad) + # reverse cyclic shift + if self.shift_size > 0: + x = torch.roll( + shifted_x, + shifts=(self.shift_size, self.shift_size), + dims=(1, 2)) + else: + x = shifted_x + + if pad_r > 0 or pad_b: + x = x[:, :H, :W, :].contiguous() + + x = x.view(B, H * W, self.w_msa.embed_dims) + + x = self.drop(x) + return x + + def window_reverse(self, windows, H, W): + """ + Args: + windows: (num_windows*B, window_size, window_size, C) + H (int): Height of image + W (int): Width of image + Returns: + x: (B, H, W, C) + """ + window_size = self.window_size + B = int(windows.shape[0] / (H * W / window_size / window_size)) + x = windows.view(B, H // window_size, W // window_size, window_size, + window_size, -1) + x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1) + return x + + def window_partition(self, x): + """ + Args: + x: (B, H, W, C) + Returns: + windows: (num_windows*B, window_size, window_size, C) + """ + B, H, W, C = x.shape + window_size = self.window_size + x = x.view(B, H // window_size, window_size, W // window_size, + window_size, C) + windows = x.permute(0, 1, 3, 2, 4, 5).contiguous() + windows = windows.view(-1, window_size, window_size, C) + return windows + + +class AGSwinBlock(BaseModule): + """Appearance Guidance Swin Transformer Block. + + Args: + embed_dims (int): The feature dimension. + appearance_dims (int): The appearance guidance dimension. + num_heads (int): Parallel attention heads. + mlp_ratios (int): The hidden dimension ratio w.r.t. embed_dims + for FFNs. + window_size (int, optional): The local window scale. + Default: 7. + shift (bool, optional): whether to shift window or not. + Default False. + qkv_bias (bool, optional): enable bias for qkv if True. + Default: True. + qk_scale (float | None, optional): Override default qk scale of + head_dim ** -0.5 if set. Default: None. + drop_rate (float, optional): Dropout rate. Default: 0. + attn_drop_rate (float, optional): Attention dropout rate. + Default: 0. + drop_path_rate (float, optional): Stochastic depth rate. + Default: 0. + act_cfg (dict, optional): The config dict of activation function. + Default: dict(type='GELU'). + norm_cfg (dict, optional): The config dict of normalization. + Default: dict(type='LN'). + init_cfg (dict | list | None, optional): The init config. + Default: None. + """ + + def __init__(self, + embed_dims, + appearance_dims, + num_heads, + mlp_ratios=4, + window_size=7, + shift=False, + qkv_bias=True, + qk_scale=None, + drop_rate=0., + attn_drop_rate=0., + drop_path_rate=0., + act_cfg=dict(type='GELU'), + norm_cfg=dict(type='LN'), + init_cfg=None): + super().__init__(init_cfg=init_cfg) + self.norm1 = build_norm_layer(norm_cfg, embed_dims)[1] + self.attn = AGShiftWindowMSA( + embed_dims=embed_dims, + appearance_dims=appearance_dims, + num_heads=num_heads, + window_size=window_size, + shift_size=window_size // 2 if shift else 0, + qkv_bias=qkv_bias, + qk_scale=qk_scale, + attn_drop_rate=attn_drop_rate, + proj_drop_rate=drop_rate, + dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate), + init_cfg=None) + + self.norm2 = build_norm_layer(norm_cfg, embed_dims)[1] + self.ffn = FFN( + embed_dims=embed_dims, + feedforward_channels=embed_dims * mlp_ratios, + num_fcs=2, + ffn_drop=drop_rate, + dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate), + act_cfg=act_cfg, + add_identity=True, + init_cfg=None) + + def forward(self, inputs, hw_shape): + """ + Args: + inputs (list[Tensor]): appearance_guidance (B, H, W, C); + x (B, L, C) + hw_shape (tuple[int]): shape of feature. + """ + x, appearance_guidance = inputs + B, L, C = x.shape + H, W = hw_shape + assert L == H * W, 'input feature has wrong size' + + identity = x + x = self.norm1(x) + + # appearance guidance + x = x.view(B, H, W, C) + if appearance_guidance is not None: + x = torch.cat([x, appearance_guidance], dim=-1).flatten(1, 2) + + x = self.attn(x, hw_shape) + + x = x + identity + + identity = x + x = self.norm2(x) + x = self.ffn(x, identity=identity) + + return x + + +@MODELS.register_module() +class SpatialAggregateLayer(BaseModule): + """Spatial aggregation layer of CAT-Seg. + + Args: + embed_dims (int): The feature dimension. + appearance_dims (int): The appearance guidance dimension. + num_heads (int): Parallel attention heads. + mlp_ratios (int): The hidden dimension ratio w.r.t. embed_dims + for FFNs. + window_size (int, optional): The local window scale. Default: 7. + qk_scale (float | None, optional): Override default qk scale of + head_dim ** -0.5 if set. Default: None. + init_cfg (dict | list | None, optional): The init config. + Default: None. + """ + + def __init__(self, + embed_dims, + appearance_dims, + num_heads, + mlp_ratios, + window_size=7, + qk_scale=None, + init_cfg=None): + super().__init__(init_cfg=init_cfg) + self.block_1 = AGSwinBlock( + embed_dims, + appearance_dims, + num_heads, + mlp_ratios, + window_size=window_size, + shift=False, + qk_scale=qk_scale) + self.block_2 = AGSwinBlock( + embed_dims, + appearance_dims, + num_heads, + mlp_ratios, + window_size=window_size, + shift=True, + qk_scale=qk_scale) + self.guidance_norm = nn.LayerNorm( + appearance_dims) if appearance_dims > 0 else None + + def forward(self, x, appearance_guidance): + """ + Args: + x (torch.Tensor): B C T H W. + appearance_guidance (torch.Tensor): B C H W. + """ + B, C, T, H, W = x.shape + x = x.permute(0, 2, 3, 4, 1).flatten(0, 1).flatten(1, 2) # BT, HW, C + if appearance_guidance is not None: + appearance_guidance = appearance_guidance.repeat( + T, 1, 1, 1).permute(0, 2, 3, 1) # BT, HW, C + appearance_guidance = self.guidance_norm(appearance_guidance) + else: + assert self.appearance_dims == 0 + x = self.block_1((x, appearance_guidance), (H, W)) + x = self.block_2((x, appearance_guidance), (H, W)) + x = x.transpose(1, 2).reshape(B, T, C, -1) + x = x.transpose(1, 2).reshape(B, C, T, H, W) + return x + + +class AttentionLayer(nn.Module): + """Attention layer for ClassAggregration of CAT-Seg. + + Source: https://github.com/KU-CVLAB/CAT-Seg/blob/main/cat_seg/modeling/transformer/model.py#L310 # noqa + """ + + def __init__(self, + hidden_dim, + guidance_dim, + nheads=8, + attention_type='linear'): + super().__init__() + self.nheads = nheads + self.q = nn.Linear(hidden_dim + guidance_dim, hidden_dim) + self.k = nn.Linear(hidden_dim + guidance_dim, hidden_dim) + self.v = nn.Linear(hidden_dim, hidden_dim) + + if attention_type == 'linear': + self.attention = LinearAttention() + elif attention_type == 'full': + self.attention = FullAttention() + else: + raise NotImplementedError + + def forward(self, x, guidance=None): + """ + Args: + x: B*H_p*W_p, T, C + guidance: B*H_p*W_p, T, C + """ + B, L, _ = x.shape + q = self.q(torch.cat([x, guidance], + dim=-1)) if guidance is not None else self.q(x) + k = self.k(torch.cat([x, guidance], + dim=-1)) if guidance is not None else self.k(x) + v = self.v(x) + + q = q.reshape(B, L, self.nheads, -1) + k = k.reshape(B, L, self.nheads, -1) + v = v.reshape(B, L, self.nheads, -1) + + out = self.attention(q, k, v) + out = out.reshape(B, L, -1) + return out + + +@MODELS.register_module() +class ClassAggregateLayer(BaseModule): + """Class aggregation layer of CAT-Seg. + + Args: + hidden_dims (int): The feature dimension. + guidance_dims (int): The appearance guidance dimension. + num_heads (int): Parallel attention heads. + attention_type (str): Type of attention layer. Default: 'linear'. + pooling_size (tuple[int] | list[int]): Pooling size. + init_cfg (dict | list | None, optional): The init config. + Default: None. + """ + + def __init__( + self, + hidden_dims=64, + guidance_dims=64, + num_heads=8, + attention_type='linear', + pooling_size=(4, 4), + init_cfg=None, + ): + super().__init__(init_cfg=init_cfg) + self.pool = nn.AvgPool2d(pooling_size) + self.attention = AttentionLayer( + hidden_dims, + guidance_dims, + nheads=num_heads, + attention_type=attention_type) + self.MLP = FFN( + embed_dims=hidden_dims, + feedforward_channels=hidden_dims * 4, + num_fcs=2) + self.norm1 = nn.LayerNorm(hidden_dims) + self.norm2 = nn.LayerNorm(hidden_dims) + + def pool_features(self, x): + """Intermediate pooling layer for computational efficiency. + + Args: + x: B, C, T, H, W + """ + B, C, T, H, W = x.shape + x = x.transpose(1, 2).reshape(-1, C, H, W) + x = self.pool(x) + *_, H_, W_ = x.shape + x = x.reshape(B, T, C, H_, W_).transpose(1, 2) + return x + + def forward(self, x, guidance): + """ + Args: + x: B, C, T, H, W + guidance: B, T, C + """ + B, C, T, H, W = x.size() + x_pool = self.pool_features(x) + *_, H_pool, W_pool = x_pool.size() + + x_pool = x_pool.permute(0, 3, 4, 2, 1).reshape(-1, T, C) + # B*H_p*W_p T C + if guidance is not None: + guidance = guidance.repeat(H_pool * W_pool, 1, 1) + + x_pool = x_pool + self.attention(self.norm1(x_pool), + guidance) # Attention + x_pool = x_pool + self.MLP(self.norm2(x_pool)) # MLP + + x_pool = x_pool.reshape(B, H_pool * W_pool, T, + C).permute(0, 2, 3, 1).reshape( + B, T, C, H_pool, + W_pool).flatten(0, 1) # BT C H_p W_p + x_pool = F.interpolate( + x_pool, size=(H, W), mode='bilinear', align_corners=True) + x_pool = x_pool.reshape(B, T, C, H, W).transpose(1, 2) # B C T H W + x = x + x_pool # Residual + + return x + + +@MODELS.register_module() +class AggregatorLayer(BaseModule): + """Single Aggregator Layer of CAT-Seg.""" + + def __init__(self, + embed_dims=64, + text_guidance_dims=512, + appearance_guidance_dims=512, + num_heads=4, + mlp_ratios=4, + window_size=7, + attention_type='linear', + pooling_size=(2, 2), + init_cfg=None) -> None: + super().__init__(init_cfg=init_cfg) + self.spatial_agg = SpatialAggregateLayer( + embed_dims, + appearance_guidance_dims, + num_heads=num_heads, + mlp_ratios=mlp_ratios, + window_size=window_size) + self.class_agg = ClassAggregateLayer( + embed_dims, + text_guidance_dims, + num_heads=num_heads, + attention_type=attention_type, + pooling_size=pooling_size) + + def forward(self, x, appearance_guidance, text_guidance): + """ + Args: + x: B C T H W + """ + x = self.spatial_agg(x, appearance_guidance) + x = self.class_agg(x, text_guidance) + return x + + +@MODELS.register_module() +class CATSegAggregator(BaseModule): + """CATSeg Aggregator. + + This Aggregator is the mmseg implementation of + `CAT-Seg `_. + + Args: + text_guidance_dim (int): Text guidance dimensions. Default: 512. + text_guidance_proj_dim (int): Text guidance projection dimensions. + Default: 128. + appearance_guidance_dim (int): Appearance guidance dimensions. + Default: 512. + appearance_guidance_proj_dim (int): Appearance guidance projection + dimensions. Default: 128. + num_layers (int): Aggregator layer number. Default: 4. + num_heads (int): Attention layer head number. Default: 4. + embed_dims (int): Input feature dimensions. Default: 128. + pooling_size (tuple | list): Pooling size of the class aggregator + layer. Default: (6, 6). + mlp_ratios (int): The hidden dimension ratio w.r.t. input dimension. + Default: 4. + window_size (int): Swin block window size. Default:12. + attention_type (str): Attention type of class aggregator layer. + Default:'linear'. + prompt_channel (int): Prompt channels. Default: 80. + """ + + def __init__(self, + text_guidance_dim=512, + text_guidance_proj_dim=128, + appearance_guidance_dim=512, + appearance_guidance_proj_dim=128, + num_layers=4, + num_heads=4, + embed_dims=128, + pooling_size=(6, 6), + mlp_ratios=4, + window_size=12, + attention_type='linear', + prompt_channel=80, + **kwargs): + super().__init__(**kwargs) + self.num_layers = num_layers + self.embed_dims = embed_dims + + self.layers = nn.ModuleList([ + AggregatorLayer( + embed_dims=embed_dims, + text_guidance_dims=text_guidance_proj_dim, + appearance_guidance_dims=appearance_guidance_proj_dim, + num_heads=num_heads, + mlp_ratios=mlp_ratios, + window_size=window_size, + attention_type=attention_type, + pooling_size=pooling_size) for _ in range(num_layers) + ]) + + self.conv1 = nn.Conv2d( + prompt_channel, embed_dims, kernel_size=7, stride=1, padding=3) + + self.guidance_projection = nn.Sequential( + nn.Conv2d( + appearance_guidance_dim, + appearance_guidance_proj_dim, + kernel_size=3, + stride=1, + padding=1), + nn.ReLU(), + ) if appearance_guidance_dim > 0 else None + + self.text_guidance_projection = nn.Sequential( + nn.Linear(text_guidance_dim, text_guidance_proj_dim), + nn.ReLU(), + ) if text_guidance_dim > 0 else None + + def feature_map(self, img_feats, text_feats): + """Concatenation type cost volume. + + For ablation study of cost volume type. + """ + img_feats = F.normalize(img_feats, dim=1) # B C H W + img_feats = img_feats.unsqueeze(2).repeat(1, 1, text_feats.shape[1], 1, + 1) + text_feats = F.normalize(text_feats, dim=-1) # B T P C + text_feats = text_feats.mean(dim=-2) + text_feats = F.normalize(text_feats, dim=-1) # B T C + text_feats = text_feats.unsqueeze(-1).unsqueeze(-1).repeat( + 1, 1, 1, img_feats.shape[-2], img_feats.shape[-1]).transpose(1, 2) + return torch.cat((img_feats, text_feats), dim=1) # B 2C T H W + + def correlation(self, img_feats, text_feats): + """Correlation of image features and text features.""" + img_feats = F.normalize(img_feats, dim=1) # B C H W + text_feats = F.normalize(text_feats, dim=-1) # B T P C + corr = torch.einsum('bchw, btpc -> bpthw', img_feats, text_feats) + return corr + + def corr_embed(self, x): + """Correlation embeddings encoding.""" + B = x.shape[0] + corr_embed = x.permute(0, 2, 1, 3, 4).flatten(0, 1) + corr_embed = self.conv1(corr_embed) + corr_embed = corr_embed.reshape(B, -1, self.embed_dims, x.shape[-2], + x.shape[-1]).transpose(1, 2) + return corr_embed + + def forward(self, inputs): + """ + Args: + inputs (dict): including the following keys, + 'appearance_feat': list[torch.Tensor], w.r.t. out_indices of + `self.feature_extractor`. + 'clip_text_feat': the text feature extracted by clip text + encoder. + 'clip_text_feat_test': the text feature extracted by clip text + encoder for testing. + 'clip_img_feat': the image feature extracted clip image + encoder. + """ + img_feats = inputs['clip_img_feat'] + B = img_feats.size(0) + appearance_guidance = inputs[ + 'appearance_feat'][::-1] # order (out_indices) 2, 1, 0 + text_feats = inputs['clip_text_feat'] if self.training else inputs[ + 'clip_text_feat_test'] + text_feats = text_feats.repeat(B, 1, 1, 1) + + corr = self.correlation(img_feats, text_feats) + # corr = self.feature_map(img_feats, text_feats) + corr_embed = self.corr_embed(corr) + + projected_guidance, projected_text_guidance = None, None + + if self.guidance_projection is not None: + projected_guidance = self.guidance_projection( + appearance_guidance[0]) + + if self.text_guidance_projection is not None: + text_feats = text_feats.mean(dim=-2) + text_feats = text_feats / text_feats.norm(dim=-1, keepdim=True) + projected_text_guidance = self.text_guidance_projection(text_feats) + + for layer in self.layers: + corr_embed = layer(corr_embed, projected_guidance, + projected_text_guidance) + + return dict( + corr_embed=corr_embed, appearance_feats=appearance_guidance[1:]) diff --git a/projects/CAT-Seg/cat_seg/models/cat_head.py b/projects/CAT-Seg/cat_seg/models/cat_head.py new file mode 100644 index 00000000000..36bb1c56179 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/models/cat_head.py @@ -0,0 +1,116 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +import torch.nn as nn +from mmcv.cnn import ConvModule + +from mmseg.models.decode_heads.decode_head import BaseDecodeHead +from mmseg.registry import MODELS + + +class UpBlock(nn.Module): + """Upsample Block with two consecutive convolution layers.""" + + def __init__(self, in_channels, out_channels, guidance_channels): + super().__init__() + self.up = nn.ConvTranspose2d( + in_channels, + in_channels - guidance_channels, + kernel_size=2, + stride=2) + self.conv1 = ConvModule( + in_channels, + out_channels, + 3, + padding=1, + bias=False, + norm_cfg=dict(type='GN', num_groups=out_channels // 16)) + self.conv2 = ConvModule( + out_channels, + out_channels, + 3, + padding=1, + bias=False, + norm_cfg=dict(type='GN', num_groups=out_channels // 16)) + + def forward(self, x, guidance=None): + """Forward function with visual guidance.""" + x = self.up(x) + if guidance is not None: + T = x.size(0) // guidance.size(0) + # guidance = repeat(guidance, "B C H W -> (B T) C H W", T=T) + guidance = guidance.repeat(T, 1, 1, 1) + x = torch.cat([x, guidance], dim=1) + x = self.conv1(x) + + return self.conv2(x) + + +@MODELS.register_module() +class CATSegHead(BaseDecodeHead): + """CATSeg Head. + + This segmentation head is the mmseg implementation of + `CAT-Seg `_. + + Args: + embed_dims (int): The number of input dimensions. + decoder_dims (list): The number of decoder dimensions. + decoder_guidance_proj_dims (list): The number of appearance + guidance dimensions. + init_cfg + """ + + def __init__(self, + embed_dims=128, + decoder_dims=(64, 32), + decoder_guidance_dims=(256, 128), + decoder_guidance_proj_dims=(32, 16), + **kwargs): + super().__init__(**kwargs) + self.decoder_guidance_projection = nn.ModuleList([ + nn.Sequential( + nn.Conv2d( + dec_dims, + dec_dims_proj, + kernel_size=3, + stride=1, + padding=1), + nn.ReLU(), + ) for dec_dims, dec_dims_proj in zip(decoder_guidance_dims, + decoder_guidance_proj_dims) + ]) if decoder_guidance_dims[0] > 0 else None + + self.decoder1 = UpBlock(embed_dims, decoder_dims[0], + decoder_guidance_proj_dims[0]) + self.decoder2 = UpBlock(decoder_dims[0], decoder_dims[1], + decoder_guidance_proj_dims[1]) + self.conv_seg = nn.Conv2d( + decoder_dims[1], 1, kernel_size=3, stride=1, padding=1) + + def forward(self, inputs): + """Forward function. + + Args: + inputs (dict): Input features including the following features, + corr_embed: aggregated correlation embeddings. + appearance_feats: decoder appearance feature guidance. + """ + # decoder guidance projection + if self.decoder_guidance_projection is not None: + projected_decoder_guidance = [ + proj(g) for proj, g in zip(self.decoder_guidance_projection, + inputs['appearance_feats']) + ] + + # decoder layers + B = inputs['corr_embed'].size(0) + corr_embed = inputs['corr_embed'].transpose(1, 2).flatten(0, 1) + corr_embed = self.decoder1(corr_embed, projected_decoder_guidance[0]) + corr_embed = self.decoder2(corr_embed, projected_decoder_guidance[1]) + + output = self.cls_seg(corr_embed) + + # rearrange the output to (B, T, H, W) + H_ori, W_ori = output.shape[-2:] + output = output.reshape(B, -1, H_ori, W_ori) + return output diff --git a/projects/CAT-Seg/cat_seg/models/clip_ovseg.py b/projects/CAT-Seg/cat_seg/models/clip_ovseg.py new file mode 100644 index 00000000000..cb67744e34a --- /dev/null +++ b/projects/CAT-Seg/cat_seg/models/clip_ovseg.py @@ -0,0 +1,293 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import json +import os +from typing import List + +import torch +import torch.nn.functional as F +from huggingface_hub.utils._errors import LocalEntryNotFoundError +from mmengine.model import BaseModule + +from mmseg.registry import MODELS +from mmseg.utils import ConfigType +from ..utils import clip_wrapper +from ..utils.clip_templates import (IMAGENET_TEMPLATES, + IMAGENET_TEMPLATES_SELECT) + + +@MODELS.register_module() +class CLIPOVCATSeg(BaseModule): + """CLIP based Open Vocabulary CAT-Seg model backbone. + + This backbone is the modified implementation of `CAT-Seg Backbone + `_. It combines the CLIP model and + another feature extractor, a.k.a the appearance guidance extractor + in the original `CAT-Seg`. + + Args: + feature_extractor (ConfigType): Appearance guidance extractor + config dict. + train_class_json (str): The training class json file. + test_class_json (str): The path to test class json file. + clip_pretrained (str): The pre-trained clip type. + clip_finetune (str): The finetuning settings of clip model. + custom_clip_weights (str): The custmized clip weights directory. When + encountering huggingface model download errors, you can manually + download the pretrained weights. + backbone_multiplier (float): The learning rate multiplier. + Default: 0.01. + prompt_depth (int): The prompt depth. Default: 0. + prompt_length (int): The prompt length. Default: 0. + prompt_ensemble_type (str): The prompt ensemble type. + Default: "imagenet". + pixel_mean (List[float]): The pixel mean for feature extractor. + pxiel_std (List[float]): The pixel std for feature extractor. + clip_pixel_mean (List[float]): The pixel mean for clip model. + clip_pxiel_std (List[float]): The pixel std for clip model. + clip_img_feat_size: (List[int]: Clip image embedding size from + image encoder. + init_cfg (dict or list[dict], optional): Initialization config dict. + Default: None. + """ + + def __init__( + self, + feature_extractor: ConfigType, + train_class_json: str, + test_class_json: str, + clip_pretrained: str, + clip_finetune: str, + custom_clip_weights: str = None, + backbone_multiplier=0.01, + prompt_depth: int = 0, + prompt_length: int = 0, + prompt_ensemble_type: str = 'imagenet', + pixel_mean: List[float] = [123.675, 116.280, 103.530], + pixel_std: List[float] = [58.395, 57.120, 57.375], + clip_pixel_mean: List[float] = [ + 122.7709383, 116.7460125, 104.09373615 + ], + clip_pixel_std: List[float] = [68.5005327, 66.6321579, 70.3231630], + clip_img_feat_size: List[int] = [24, 24], + init_cfg=None): + super().__init__(init_cfg=init_cfg) + # normalization parameters + self.register_buffer('pixel_mean', + torch.Tensor(pixel_mean).view(1, -1, 1, 1), False) + self.register_buffer('pixel_std', + torch.Tensor(pixel_std).view(1, -1, 1, 1), False) + self.register_buffer('clip_pixel_mean', + torch.Tensor(clip_pixel_mean).view(1, -1, 1, 1), + False) + self.register_buffer('clip_pixel_std', + torch.Tensor(clip_pixel_std).view(1, -1, 1, 1), + False) + self.clip_resolution = ( + 384, 384) if clip_pretrained == 'ViT-B/16' else (336, 336) + # modified clip image encoder with fixed size dense output + self.clip_img_feat_size = clip_img_feat_size + + # prepare clip templates + self.prompt_ensemble_type = prompt_ensemble_type + if self.prompt_ensemble_type == 'imagenet_select': + prompt_templates = IMAGENET_TEMPLATES_SELECT + elif self.prompt_ensemble_type == 'imagenet': + prompt_templates = IMAGENET_TEMPLATES + elif self.prompt_ensemble_type == 'single': + prompt_templates = [ + 'A photo of a {} in the scene', + ] + else: + raise NotImplementedError + self.prompt_templates = prompt_templates + + # build the feature extractor + self.feature_extractor = MODELS.build(feature_extractor) + + # build CLIP model + with open(train_class_json) as f_in: + self.class_texts = json.load(f_in) + with open(test_class_json) as f_in: + self.test_class_texts = json.load(f_in) + assert self.class_texts is not None + if self.test_class_texts is None: + self.test_class_texts = self.class_texts + device = 'cuda' if torch.cuda.is_available() else 'cpu' + self.tokenizer = None + if clip_pretrained == 'ViT-G' or clip_pretrained == 'ViT-H': + # for OpenCLIP models + import open_clip + name, pretrain = ( + 'ViT-H-14', + 'laion2b_s32b_b79k') if clip_pretrained == 'ViT-H' else ( + 'ViT-bigG-14', 'laion2b_s39b_b160k') + try: + open_clip_model = open_clip.create_model_and_transforms( + name, + pretrained=pretrain, + device=device, + force_image_size=336, + ) + clip_model, _, clip_preprocess = open_clip_model + except ConnectionError or LocalEntryNotFoundError as e: + print(f'Has {e} when loading weights from huggingface!') + print( + f'Will load {pretrain} weights from {custom_clip_weights}.' + ) + assert custom_clip_weights is not None, 'Please specify custom weights directory.' # noqa + assert os.path.exists( + os.path.join(custom_clip_weights, + 'open_clip_pytorch_model.bin') + ), 'Please provide a valid directory for manually downloaded model.' # noqa + open_clip_model = open_clip.create_model_and_transforms( + name, + pretrained=None, + device='cpu', + force_image_size=336, + ) + clip_model, _, clip_preprocess = open_clip_model + + open_clip.load_checkpoint( + clip_model, + os.path.expanduser( + os.path.join(custom_clip_weights, + 'open_clip_pytorch_model.bin'))) + clip_model.to(torch.device(device)) + + self.tokenizer = open_clip.get_tokenizer(name) + else: + # for OpenAI models + clip_model, clip_preprocess = clip_wrapper.load( + clip_pretrained, + device=device, + jit=False, + prompt_depth=prompt_depth, + prompt_length=prompt_length) + + # pre-encode classes text prompts + text_features = self.class_embeddings(self.class_texts, + prompt_templates, clip_model, + device).permute(1, 0, 2).float() + text_features_test = self.class_embeddings(self.test_class_texts, + prompt_templates, + clip_model, + device).permute(1, 0, + 2).float() + self.register_buffer('text_features', text_features, False) + self.register_buffer('text_features_test', text_features_test, False) + + # prepare CLIP model finetune + self.clip_finetune = clip_finetune + self.clip_model = clip_model.float() + self.clip_preprocess = clip_preprocess + + for name, params in self.clip_model.named_parameters(): + if 'visual' in name: + if clip_finetune == 'prompt': + params.requires_grad = True if 'prompt' in name else False + elif clip_finetune == 'attention': + if 'attn' in name or 'position' in name: + params.requires_grad = True + else: + params.requires_grad = False + elif clip_finetune == 'full': + params.requires_grad = True + else: + params.requires_grad = False + else: + params.requires_grad = False + + finetune_backbone = backbone_multiplier > 0. + for name, params in self.feature_extractor.named_parameters(): + if 'norm0' in name: + params.requires_grad = False + else: + params.requires_grad = finetune_backbone + + @torch.no_grad() + def class_embeddings(self, + classnames, + templates, + clip_model, + device='cpu'): + """Convert class names to text embeddings by clip model. + + Args: + classnames (list): loaded from json file. + templates (dict): text template. + clip_model (nn.Module): prepared clip model. + device (str | torch.device): loading device of text + encoder results. + """ + zeroshot_weights = [] + for classname in classnames: + if ', ' in classname: + classname_splits = classname.split(', ') + texts = [] + for template in templates: + for cls_split in classname_splits: + texts.append(template.format(cls_split)) + else: + texts = [template.format(classname) + for template in templates] # format with class + if self.tokenizer is not None: + texts = self.tokenizer(texts).to(device) + else: + texts = clip_wrapper.tokenize(texts).to(device) + class_embeddings = clip_model.encode_text(texts) + class_embeddings /= class_embeddings.norm(dim=-1, keepdim=True) + if len(templates) != class_embeddings.shape[0]: + class_embeddings = class_embeddings.reshape( + len(templates), -1, class_embeddings.shape[-1]).mean(dim=1) + class_embeddings /= class_embeddings.norm(dim=-1, keepdim=True) + class_embedding = class_embeddings + zeroshot_weights.append(class_embedding) + zeroshot_weights = torch.stack(zeroshot_weights, dim=1).to(device) + return zeroshot_weights + + def custom_normalize(self, inputs): + """Input normalization for clip model and feature extractor + respectively. + + Args: + inputs: batched input images. + """ + # clip images + batched_clip = (inputs - self.clip_pixel_mean) / self.clip_pixel_std + batched_clip = F.interpolate( + batched_clip, + size=self.clip_resolution, + mode='bilinear', + align_corners=False) + # feature extractor images + batched = (inputs - self.pixel_mean) / self.pixel_std + return batched, batched_clip + + def forward(self, inputs): + """ + Args: + inputs: minibatch image. (B, 3, H, W) + Returns: + outputs (dict): + 'appearance_feat': list[torch.Tensor], w.r.t. out_indices of + `self.feature_extractor`. + 'clip_text_feat': the text feature extracted by clip text encoder. + 'clip_text_feat_test': the text feature extracted by clip text + encoder for testing. + 'clip_img_feat': the image feature extracted clip image encoder. + """ + inputs, clip_inputs = self.custom_normalize(inputs) + outputs = dict() + # extract appearance guidance feature + outputs['appearance_feat'] = self.feature_extractor(inputs) + + # extract clip features + outputs['clip_text_feat'] = self.text_features + outputs['clip_text_feat_test'] = self.text_features_test + clip_features = self.clip_model.encode_image( + clip_inputs, dense=True) # B, 577(24x24+1), C + B = clip_features.size(0) + outputs['clip_img_feat'] = clip_features[:, 1:, :].permute( + 0, 2, 1).reshape(B, -1, *self.clip_img_feat_size) + + return outputs diff --git a/projects/CAT-Seg/cat_seg/utils/__init__.py b/projects/CAT-Seg/cat_seg/utils/__init__.py new file mode 100644 index 00000000000..88746b2cba6 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .clip_templates import (IMAGENET_TEMPLATES, IMAGENET_TEMPLATES_SELECT, + IMAGENET_TEMPLATES_SELECT_CLIP, ViLD_templates) +from .self_attention_block import FullAttention, LinearAttention + +__all__ = [ + 'FullAttention', 'LinearAttention', 'IMAGENET_TEMPLATES', + 'IMAGENET_TEMPLATES_SELECT', 'IMAGENET_TEMPLATES_SELECT_CLIP', + 'ViLD_templates' +] diff --git a/projects/CAT-Seg/cat_seg/utils/bpe_vocab/bpe_simple_vocab_16e6.txt.gz b/projects/CAT-Seg/cat_seg/utils/bpe_vocab/bpe_simple_vocab_16e6.txt.gz new file mode 100644 index 00000000000..7b5088a527f Binary files /dev/null and b/projects/CAT-Seg/cat_seg/utils/bpe_vocab/bpe_simple_vocab_16e6.txt.gz differ diff --git a/projects/CAT-Seg/cat_seg/utils/clip_model.py b/projects/CAT-Seg/cat_seg/utils/clip_model.py new file mode 100644 index 00000000000..977444f5b52 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/clip_model.py @@ -0,0 +1,651 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from collections import OrderedDict +from typing import Tuple, Union + +import torch +import torch.nn.functional as F +from torch import nn + + +class Bottleneck(nn.Module): + """Custom implementation of Bottleneck in ResNet.""" + expansion = 4 + + def __init__(self, inplanes, planes, stride=1): + super().__init__() + # all conv layers have stride 1. + # an avgpool is performed after the second convolution when stride > 1 + self.conv1 = nn.Conv2d(inplanes, planes, 1, bias=False) + self.bn1 = nn.BatchNorm2d(planes) + + self.conv2 = nn.Conv2d(planes, planes, 3, padding=1, bias=False) + self.bn2 = nn.BatchNorm2d(planes) + + self.avgpool = nn.AvgPool2d(stride) if stride > 1 else nn.Identity() + + self.conv3 = nn.Conv2d(planes, planes * self.expansion, 1, bias=False) + self.bn3 = nn.BatchNorm2d(planes * self.expansion) + + self.relu = nn.ReLU(inplace=True) + self.downsample = None + self.stride = stride + + if stride > 1 or inplanes != planes * Bottleneck.expansion: + # downsampling layer is prepended with an avgpool, + # and the subsequent convolution has stride 1 + self.downsample = nn.Sequential( + OrderedDict([('-1', nn.AvgPool2d(stride)), + ('0', + nn.Conv2d( + inplanes, + planes * self.expansion, + 1, + stride=1, + bias=False)), + ('1', nn.BatchNorm2d(planes * self.expansion))])) + + def forward(self, x: torch.Tensor): + """ + Args: + x (torch.Tensor): the input feature. + """ + identity = x + + out = self.relu(self.bn1(self.conv1(x))) + out = self.relu(self.bn2(self.conv2(out))) + out = self.avgpool(out) + out = self.bn3(self.conv3(out)) + + if self.downsample is not None: + identity = self.downsample(x) + + out += identity + out = self.relu(out) + return out + + +class AttentionPool2d(nn.Module): + """Attention Pool2d.""" + + def __init__(self, + spacial_dim: int, + embed_dim: int, + num_heads: int, + output_dim: int = None): + super().__init__() + self.positional_embedding = nn.Parameter( + torch.randn(spacial_dim**2 + 1, embed_dim) / embed_dim**0.5) + self.k_proj = nn.Linear(embed_dim, embed_dim) + self.q_proj = nn.Linear(embed_dim, embed_dim) + self.v_proj = nn.Linear(embed_dim, embed_dim) + self.c_proj = nn.Linear(embed_dim, output_dim or embed_dim) + self.num_heads = num_heads + + def forward(self, x): + """ + Args: + x (torch.Tensor): the input feature. + """ + x = x.flatten(start_dim=2).permute(2, 0, 1) # NCHW -> (HW)NC + x = torch.cat([x.mean(dim=0, keepdim=True), x], dim=0) # (HW+1)NC + x = x + self.positional_embedding[:, None, :].to(x.dtype) # (HW+1)NC + x, _ = F.multi_head_attention_forward( + query=x[:1], + key=x, + value=x, + embed_dim_to_check=x.shape[-1], + num_heads=self.num_heads, + q_proj_weight=self.q_proj.weight, + k_proj_weight=self.k_proj.weight, + v_proj_weight=self.v_proj.weight, + in_proj_weight=None, + in_proj_bias=torch.cat( + [self.q_proj.bias, self.k_proj.bias, self.v_proj.bias]), + bias_k=None, + bias_v=None, + add_zero_attn=False, + dropout_p=0, + out_proj_weight=self.c_proj.weight, + out_proj_bias=self.c_proj.bias, + use_separate_proj_weight=True, + training=self.training, + need_weights=False) + return x.squeeze(0) + + +class ModifiedResNet(nn.Module): + """A ResNet class that is similar to torchvision's but contains the + following changes: + + - There are now 3 "stem" convolutions as opposed to 1, with an average + pool instead of a max pool. + - Performs anti-aliasing strided convolutions, where an avgpool is + prepended to convolutions with stride > 1 + - The final pooling layer is a QKV attention instead of an average pool + """ + + def __init__(self, + layers, + output_dim, + heads, + input_resolution=224, + width=64): + super().__init__() + self.output_dim = output_dim + self.input_resolution = input_resolution + + # the 3-layer stem + self.conv1 = nn.Conv2d( + 3, width // 2, kernel_size=3, stride=2, padding=1, bias=False) + self.bn1 = nn.BatchNorm2d(width // 2) + self.relu1 = nn.ReLU(inplace=True) + self.conv2 = nn.Conv2d( + width // 2, width // 2, kernel_size=3, padding=1, bias=False) + self.bn2 = nn.BatchNorm2d(width // 2) + self.relu2 = nn.ReLU(inplace=True) + self.conv3 = nn.Conv2d( + width // 2, width, kernel_size=3, padding=1, bias=False) + self.bn3 = nn.BatchNorm2d(width) + self.relu3 = nn.ReLU(inplace=True) + self.avgpool = nn.AvgPool2d(2) + + # residual layers + # this is a *mutable* variable used during construction + self._inplanes = width + self.layer1 = self._make_layer(width, layers[0]) + self.layer2 = self._make_layer(width * 2, layers[1], stride=2) + self.layer3 = self._make_layer(width * 4, layers[2], stride=2) + self.layer4 = self._make_layer(width * 8, layers[3], stride=2) + + embed_dim = width * 32 # the ResNet feature dimension + self.attnpool = AttentionPool2d(input_resolution // 32, embed_dim, + heads, output_dim) + + def _make_layer(self, planes, blocks, stride=1): + """Build resnet layers.""" + layers = [Bottleneck(self._inplanes, planes, stride)] + + self._inplanes = planes * Bottleneck.expansion + for _ in range(1, blocks): + layers.append(Bottleneck(self._inplanes, planes)) + + return nn.Sequential(*layers) + + def forward(self, x): + """ + Args: + x (torch.Tensor): the input mini-batch images. + """ + + def stem(x): + x = self.relu1(self.bn1(self.conv1(x))) + x = self.relu2(self.bn2(self.conv2(x))) + x = self.relu3(self.bn3(self.conv3(x))) + x = self.avgpool(x) + return x + + x = x.type(self.conv1.weight.dtype) + x = stem(x) + x = self.layer1(x) + x = self.layer2(x) + x = self.layer3(x) + x = self.layer4(x) + x = self.attnpool(x) + + return x + + +class LayerNorm(nn.LayerNorm): + """Subclass torch's LayerNorm to handle fp16.""" + + def forward(self, x: torch.Tensor): + """ + Args: + x (torch.Tensor): the input feature. + """ + orig_type = x.dtype + ret = super().forward(x.type(torch.float32)) + return ret.type(orig_type) + + +class QuickGELU(nn.Module): + """Wrapper of GELU activation layer.""" + + def forward(self, x: torch.Tensor): + """ + Args: + x (torch.Tensor): the input feature. + """ + return x * torch.sigmoid(1.702 * x) + + +class ResidualAttentionBlock(nn.Module): + """Attention block with residual connection.""" + + def __init__(self, + d_model: int, + n_head: int, + attn_mask: torch.Tensor = None): + super().__init__() + + self.attn = nn.MultiheadAttention(d_model, n_head) + self.ln_1 = LayerNorm(d_model) + self.mlp = nn.Sequential( + OrderedDict([('c_fc', nn.Linear(d_model, d_model * 4)), + ('gelu', QuickGELU()), + ('c_proj', nn.Linear(d_model * 4, d_model))])) + self.ln_2 = LayerNorm(d_model) + self.attn_mask = attn_mask + self.mask_pre_mlp = True + + def attention(self, x: torch.Tensor): + """Calculate mask multi-head-attention.""" + self.attn_mask = self.attn_mask.to( + dtype=x.dtype, + device=x.device) if self.attn_mask is not None else None + return self.attn( + x, x, x, need_weights=False, attn_mask=self.attn_mask)[0] + + def forward(self, x: torch.Tensor): + """ + Args: + x (torch.Tensor): the input feature. + """ + x = x + self.attention(self.ln_1(x)) + x = x + self.mlp(self.ln_2(x)) + return x + + def forward_dense(self, x: torch.Tensor): + """Reinplementation of forward function for dense prediction of image + encoder in CLIP model. + + Args: + x (torch.Tensor): the input feature. + """ + y = self.ln_1(x) + y = F.linear(y, self.attn.in_proj_weight, self.attn.in_proj_bias) + L, N, D = y.shape # L N 3D + + y = y.reshape(L, N, 3, D // 3).permute(2, 1, 0, + 3).reshape(3 * N, L, D // 3) + y = F.linear(y, self.attn.out_proj.weight, self.attn.out_proj.bias) + + q, k, v = y.tensor_split(3, dim=0) + v = v.transpose(1, 0) + x # L N D + + v = v + self.mlp(self.ln_2(v)) + return v + + +class Transformer(nn.Module): + """General Transformer Architecture for both image and text encoder.""" + + def __init__(self, + width: int, + layers: int, + heads: int, + attn_mask: torch.Tensor = None, + prompt_length=0, + prompt_depth=0): + super().__init__() + self.width = width + self.layers = layers + self.resblocks = nn.Sequential(*[ + ResidualAttentionBlock(width, heads, attn_mask) + for _ in range(layers) + ]) + + self.prompt_length = prompt_length + self.prompt_depth = prompt_depth + self.prompt_tokens = nn.Parameter( + torch.zeros(prompt_depth, prompt_length, + width)) if prompt_length > 0 else None + if self.prompt_tokens is not None: + nn.init.xavier_uniform_(self.prompt_tokens) + + def forward(self, x: torch.Tensor, dense=False): + """ + Args: + x (torch.Tensor): input features. + dense (bool): whether use reimplemented dense forward + function in the last layer. + """ + for i, resblock in enumerate(self.resblocks): + if self.prompt_length > 0 and i < self.prompt_depth: + length = self.prompt_length + 1 if i > 0 else 1 + x = torch.cat((x[0:1, :, :], self.prompt_tokens[i].repeat( + x.shape[1], 1, 1).permute(1, 0, 2), x[length:, :, :])) + + if i == self.layers - 1 and dense: + x = resblock.forward_dense(x) + x = torch.cat((x[0:1, :, :], x[self.prompt_length + 1::, :]), + dim=0) + else: + x = resblock(x) + + return x + + +class VisualTransformer(nn.Module): + """Visual encoder for CLIP model.""" + + def __init__(self, input_resolution: int, patch_size: int, width: int, + layers: int, heads: int, output_dim: int, prompt_depth: int, + prompt_length: int): + super().__init__() + self.output_dim = output_dim + self.conv1 = nn.Conv2d( + in_channels=3, + out_channels=width, + kernel_size=patch_size, + stride=patch_size, + bias=False) + + scale = width**-0.5 + self.class_embedding = nn.Parameter(scale * torch.randn(width)) + self.positional_embedding = nn.Parameter(scale * torch.randn( + (input_resolution // patch_size)**2 + 1, width)) + self.ln_pre = LayerNorm(width) + + self.transformer = Transformer( + width, + layers, + heads, + prompt_depth=prompt_depth, + prompt_length=prompt_length) + + self.ln_post = LayerNorm(width) + self.proj = nn.Parameter(scale * torch.randn(width, output_dim)) + + self.patch_size = patch_size + self.input_resolution = input_resolution + + def forward(self, x: torch.Tensor, dense=False): + """ + Args: + x (torch.Tensor): input features. + dense (bool): whether use reimplemented dense forward + function in the last layer. + """ + x = self.conv1(x) # shape = [*, width, grid, grid] + x = x.reshape(x.shape[0], x.shape[1], + -1) # shape = [*, width, grid ** 2] + x = x.permute(0, 2, 1) # shape = [*, grid ** 2, width] + x = torch.cat([ + self.class_embedding.to(x.dtype) + torch.zeros( + x.shape[0], 1, x.shape[-1], dtype=x.dtype, device=x.device), x + ], + dim=1) # shape = [*, grid ** 2 + 1, width] + + if dense and (x.shape[1] != self.positional_embedding.shape[0]): + x = x + self.resized_pos_embed(self.input_resolution, + x.shape[1]).to(x.dtype) + else: + x = x + self.positional_embedding.to(x.dtype) + + x = self.ln_pre(x) + + x = x.permute(1, 0, 2) # NLD -> LND + x = self.transformer(x, dense) + x = x.permute(1, 0, 2) # LND -> NLD + + if dense: + x = self.ln_post(x[:, :, :]) + else: + x = self.ln_post(x[:, 0, :]) + + if self.proj is not None: + x = x @ self.proj + + return x + + def resized_pos_embed(self, in_res, tgt_res, mode='bicubic'): + """Resize the position embedding.""" + # assert L == (input_resolution // self.patch_size) ** 2 + 1 + L, D = self.positional_embedding.shape + + in_side = in_res // self.patch_size + # tgt_side = tgt_res // self.patch_size + tgt_side = int((tgt_res - 1)**0.5) + + cls_pos = self.positional_embedding[0].unsqueeze(0) # 1 D + pos_embed = self.positional_embedding[1:].reshape( + 1, in_side, in_side, D).permute(0, 3, 1, 2) # L-1 D -> 1 D S S + resized_pos_embed = F.interpolate( + pos_embed, + size=(tgt_side, tgt_side), + mode=mode, + align_corners=False, + ) # 1 D S S -> 1 D S' S' + resized_pos_embed = resized_pos_embed.squeeze(0).reshape( + D, -1).T # L'-1 D + + return torch.cat((cls_pos, resized_pos_embed), dim=0) + + +class CLIP(nn.Module): + """Custom implementation of CLIP model. + + Refer to: https://github.com/openai/CLIP + """ + + def __init__( + self, + embed_dim: int, + # vision + image_resolution: int, + vision_layers: Union[Tuple[int, int, int, int], int], + vision_width: int, + vision_patch_size: int, + # text + context_length: int, + vocab_size: int, + transformer_width: int, + transformer_heads: int, + transformer_layers: int, + # prompt + prompt_depth: int = 0, + prompt_length: int = 0, + ): + super().__init__() + + self.context_length = context_length + + self.image_resolution = image_resolution + + if isinstance(vision_layers, (tuple, list)): + assert prompt_length == 0 and prompt_depth == 0 + vision_heads = vision_width * 32 // 64 + self.visual = ModifiedResNet( + layers=vision_layers, + output_dim=embed_dim, + heads=vision_heads, + input_resolution=image_resolution, + width=vision_width) + else: + vision_heads = vision_width // 64 + self.visual = VisualTransformer( + input_resolution=image_resolution, + patch_size=vision_patch_size, + width=vision_width, + layers=vision_layers, + heads=vision_heads, + output_dim=embed_dim, + prompt_depth=prompt_depth, + prompt_length=prompt_length, + ) + + self.transformer = Transformer( + width=transformer_width, + layers=transformer_layers, + heads=transformer_heads, + attn_mask=self.build_attention_mask()) + + self.vocab_size = vocab_size + self.token_embedding = nn.Embedding(vocab_size, transformer_width) + self.positional_embedding = nn.Parameter( + torch.empty(self.context_length, transformer_width)) + self.ln_final = LayerNorm(transformer_width) + + self.text_projection = nn.Parameter( + torch.empty(transformer_width, embed_dim)) + self.logit_scale = nn.Parameter(torch.ones([])) + + def build_attention_mask(self): + """Create causal attention mask.""" + # lazily create causal attention mask, with full attention between + # the vision tokens pytorch uses additive attention mask; fill with + # -inf + mask = torch.empty(self.context_length, self.context_length) + mask.fill_(float('-inf')) + mask.triu_(1) # zero out the lower diagonal + return mask + + @property + def dtype(self): + """Return the dtype of the model.""" + return self.visual.conv1.weight.dtype + + def encode_image(self, image, masks=None, pool_mask=None, dense=False): + """Image encoding.""" + if pool_mask is not None: + return self.visual( + image.type(self.dtype), mask=pool_mask, dense=dense) + if masks is None: + return self.visual(image.type(self.dtype), dense=dense) + else: + return self.visual(image.type(self.dtype), masks.type(self.dtype)) + + def encode_text(self, text): + """Texts encoding.""" + x = self.token_embedding(text).type( + self.dtype) # [batch_size, n_ctx, d_model] + + x = x + self.positional_embedding.type(self.dtype) + x = x.permute(1, 0, 2) # NLD -> LND + x = self.transformer(x) + x = x.permute(1, 0, 2) # LND -> NLD + x = self.ln_final(x).type(self.dtype) + + # x.shape = [batch_size, n_ctx, transformer.width] + # take features from the eot embedding (eot_token is the highest number + # in each sequence) + x = x[torch.arange(x.shape[0]), + text.argmax(dim=-1)] @ self.text_projection + + return x + + def forward(self, image, text): + """ + Args: + image (torch.Tensor): input images. + text (torch.Tensor): input text. + """ + image_features = self.encode_image(image) + text_features = self.encode_text(text) + # import pdb; pdb.set_trace() + # normalized features + # image_features shape: [1, 1024] + image_features = image_features / image_features.norm( + dim=-1, keepdim=True) + text_features = text_features / text_features.norm( + dim=-1, keepdim=True) + + # cosine similarity as logits + logit_scale = self.logit_scale.exp() + logits_per_iamge = logit_scale * image_features @ text_features.t() + logits_per_text = logit_scale * text_features @ image_features.t() + + # shape = [global_batch_size, global_batch_size] + return logits_per_iamge, logits_per_text + + +def convert_weights(model: nn.Module): + """Convert applicable model parameters to fp16.""" + + def _convert_weights_to_fp16(layer): + if isinstance(layer, (nn.Conv1d, nn.Conv2d, nn.Linear)): + layer.weight.data = layer.weight.data.half() + if layer.bias is not None: + layer.bias.data = layer.bias.data.half() + + if isinstance(layer, nn.MultiheadAttention): + for attr in [ + *[f'{s}_proj_weight' for s in ['in', 'q', 'k', 'v']], + 'in_proj_bias', 'bias_k', 'bias_v' + ]: + tensor = getattr(layer, attr) + if tensor is not None: + tensor.data = tensor.data.half() + + for name in ['text_projection', 'proj']: + if hasattr(layer, name): + attr = getattr(layer, name) + if attr is not None: + attr.data = attr.data.half() + + model.apply(_convert_weights_to_fp16) + + +def build_model(state_dict: dict, prompt_depth=0, prompt_length=0): + """Build a CLIP model from given pretrained weights.""" + vit = 'visual.proj' in state_dict + + if vit: + vision_width = state_dict['visual.conv1.weight'].shape[0] + vision_layers = len([ + k for k in state_dict.keys() + if k.startswith('visual.') and k.endswith('.attn.in_proj_weight') + ]) + vision_patch_size = state_dict['visual.conv1.weight'].shape[-1] + grid_size = round( + (state_dict['visual.positional_embedding'].shape[0] - 1)**0.5) + image_resolution = vision_patch_size * grid_size + else: + counts: list = [ + len({ + k.split('.')[2] + for k in state_dict if k.startswith(f'visual.layer{b}') + }) for b in [1, 2, 3, 4] + ] + vision_layers = tuple(counts) + vision_width = state_dict['visual.layer1.0.conv1.weight'].shape[0] + output_width = round( + (state_dict['visual.attnpool.positional_embedding'].shape[0] - + 1)**0.5) + vision_patch_size = None + assert output_width**2 + 1 == state_dict[ + 'visual.attnpool.positional_embedding'].shape[0] + image_resolution = output_width * 32 + + embed_dim = state_dict['text_projection'].shape[1] + context_length = state_dict['positional_embedding'].shape[0] + vocab_size = state_dict['token_embedding.weight'].shape[0] + transformer_width = state_dict['ln_final.weight'].shape[0] + transformer_heads = transformer_width // 64 + transformer_layers = len({ + k.split('.')[2] + for k in state_dict if k.startswith('transformer.resblocks') + }) + + model = CLIP( + embed_dim, + image_resolution, + vision_layers, + vision_width, + vision_patch_size, + context_length, + vocab_size, + transformer_width, + transformer_heads, + transformer_layers, + prompt_depth=prompt_depth, + prompt_length=prompt_length, + ) + + for key in ['input_resolution', 'context_length', 'vocab_size']: + del state_dict[key] + + convert_weights(model) + model.load_state_dict(state_dict, strict=False) + return model.eval() diff --git a/projects/CAT-Seg/cat_seg/utils/clip_templates.py b/projects/CAT-Seg/cat_seg/utils/clip_templates.py new file mode 100644 index 00000000000..bfc32dfc56f --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/clip_templates.py @@ -0,0 +1,204 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +# Source: https://github.com/openai/CLIP. + +IMAGENET_TEMPLATES = [ + 'a bad photo of a {}.', + 'a photo of many {}.', + 'a sculpture of a {}.', + 'a photo of the hard to see {}.', + 'a low resolution photo of the {}.', + 'a rendering of a {}.', + 'graffiti of a {}.', + 'a bad photo of the {}.', + 'a cropped photo of the {}.', + 'a tattoo of a {}.', + 'the embroidered {}.', + 'a photo of a hard to see {}.', + 'a bright photo of a {}.', + 'a photo of a clean {}.', + 'a photo of a dirty {}.', + 'a dark photo of the {}.', + 'a drawing of a {}.', + 'a photo of my {}.', + 'the plastic {}.', + 'a photo of the cool {}.', + 'a close-up photo of a {}.', + 'a black and white photo of the {}.', + 'a painting of the {}.', + 'a painting of a {}.', + 'a pixelated photo of the {}.', + 'a sculpture of the {}.', + 'a bright photo of the {}.', + 'a cropped photo of a {}.', + 'a plastic {}.', + 'a photo of the dirty {}.', + 'a jpeg corrupted photo of a {}.', + 'a blurry photo of the {}.', + 'a photo of the {}.', + 'a good photo of the {}.', + 'a rendering of the {}.', + 'a {} in a video game.', + 'a photo of one {}.', + 'a doodle of a {}.', + 'a close-up photo of the {}.', + 'a photo of a {}.', + 'the origami {}.', + 'the {} in a video game.', + 'a sketch of a {}.', + 'a doodle of the {}.', + 'a origami {}.', + 'a low resolution photo of a {}.', + 'the toy {}.', + 'a rendition of the {}.', + 'a photo of the clean {}.', + 'a photo of a large {}.', + 'a rendition of a {}.', + 'a photo of a nice {}.', + 'a photo of a weird {}.', + 'a blurry photo of a {}.', + 'a cartoon {}.', + 'art of a {}.', + 'a sketch of the {}.', + 'a embroidered {}.', + 'a pixelated photo of a {}.', + 'itap of the {}.', + 'a jpeg corrupted photo of the {}.', + 'a good photo of a {}.', + 'a plushie {}.', + 'a photo of the nice {}.', + 'a photo of the small {}.', + 'a photo of the weird {}.', + 'the cartoon {}.', + 'art of the {}.', + 'a drawing of the {}.', + 'a photo of the large {}.', + 'a black and white photo of a {}.', + 'the plushie {}.', + 'a dark photo of a {}.', + 'itap of a {}.', + 'graffiti of the {}.', + 'a toy {}.', + 'itap of my {}.', + 'a photo of a cool {}.', + 'a photo of a small {}.', + 'a tattoo of the {}.', + # 'A photo of a {} in the scene.', +] + +# v1: 59.0875 +IMAGENET_TEMPLATES_SELECT = [ + 'itap of a {}.', + 'a bad photo of the {}.', + 'a origami {}.', + 'a photo of the large {}.', + 'a {} in a video game.', + 'art of the {}.', + 'a photo of the small {}.', + 'A photo of a {} in the scene', +] + +# v9 +IMAGENET_TEMPLATES_SELECT_CLIP = [ + 'a bad photo of the {}.', + 'a photo of the large {}.', + 'a photo of the small {}.', + 'a cropped photo of a {}.', + 'This is a photo of a {}', + 'This is a photo of a small {}', + 'This is a photo of a medium {}', + 'This is a photo of a large {}', + 'This is a masked photo of a {}', + 'This is a masked photo of a small {}', + 'This is a masked photo of a medium {}', + 'This is a masked photo of a large {}', + 'This is a cropped photo of a {}', + 'This is a cropped photo of a small {}', + 'This is a cropped photo of a medium {}', + 'This is a cropped photo of a large {}', + 'A photo of a {} in the scene', + 'a bad photo of the {} in the scene', + 'a photo of the large {} in the scene', + 'a photo of the small {} in the scene', + 'a cropped photo of a {} in the scene', + 'a photo of a masked {} in the scene', + 'There is a {} in the scene', + 'There is the {} in the scene', + 'This is a {} in the scene', + 'This is the {} in the scene', + 'This is one {} in the scene', + 'There is a masked {} in the scene', + 'There is the masked {} in the scene', + 'This is a masked {} in the scene', + 'This is the masked {} in the scene', + 'This is one masked {} in the scene', +] + +# v10, for comparison +# IMAGENET_TEMPLATES_SELECT_CLIP = [ +# 'a photo of a {}.', +# +# 'This is a photo of a {}', +# 'This is a photo of a small {}', +# 'This is a photo of a medium {}', +# 'This is a photo of a large {}', +# +# 'This is a photo of a {}', +# 'This is a photo of a small {}', +# 'This is a photo of a medium {}', +# 'This is a photo of a large {}', +# +# 'a photo of a {} in the scene', +# 'a photo of a {} in the scene', +# +# 'There is a {} in the scene', +# 'There is the {} in the scene', +# 'This is a {} in the scene', +# 'This is the {} in the scene', +# 'This is one {} in the scene', +# ] + +ViLD_templates = [ + 'There is {article} {category} in the scene.', + 'There is the {category} in the scene.', + 'a photo of {article} {category} in the scene.', + 'a photo of the {category} in the scene.', + 'a photo of one {category} in the scene.', 'itap of {article} {category}.', + 'itap of my {category}.', 'itap of the {category}.', + 'a photo of {article} {category}.', 'a photo of my {category}.', + 'a photo of the {category}.', 'a photo of one {category}.', + 'a photo of many {category}.', 'a good photo of {article} {category}.', + 'a good photo of the {category}.', 'a bad photo of {article} {category}.', + 'a bad photo of the {category}.', 'a photo of a nice {category}.', + 'a photo of the nice {category}.', 'a photo of a cool {category}.', + 'a photo of the cool {category}.', 'a photo of a weird {category}.', + 'a photo of the weird {category}.', 'a photo of a small {category}.', + 'a photo of the small {category}.', 'a photo of a large {category}.', + 'a photo of the large {category}.', 'a photo of a clean {category}.', + 'a photo of the clean {category}.', 'a photo of a dirty {category}.', + 'a photo of the dirty {category}.', + 'a bright photo of {article} {category}.', + 'a bright photo of the {category}.', + 'a dark photo of {article} {category}.', 'a dark photo of the {category}.', + 'a photo of a hard to see {category}.', + 'a photo of the hard to see {category}.', + 'a low resolution photo of {article} {category}.', + 'a low resolution photo of the {category}.', + 'a cropped photo of {article} {category}.', + 'a cropped photo of the {category}.', + 'a close-up photo of {article} {category}.', + 'a close-up photo of the {category}.', + 'a jpeg corrupted photo of {article} {category}.', + 'a jpeg corrupted photo of the {category}.', + 'a blurry photo of {article} {category}.', + 'a blurry photo of the {category}.', + 'a pixelated photo of {article} {category}.', + 'a pixelated photo of the {category}.', + 'a black and white photo of the {category}.', + 'a black and white photo of {article} {category}.', + 'a plastic {category}.', 'the plastic {category}.', 'a toy {category}.', + 'the toy {category}.', 'a plushie {category}.', 'the plushie {category}.', + 'a cartoon {category}.', 'the cartoon {category}.', + 'an embroidered {category}.', 'the embroidered {category}.', + 'a painting of the {category}.', 'a painting of a {category}.' +] diff --git a/projects/CAT-Seg/cat_seg/utils/clip_wrapper.py b/projects/CAT-Seg/cat_seg/utils/clip_wrapper.py new file mode 100644 index 00000000000..f809d2b8280 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/clip_wrapper.py @@ -0,0 +1,275 @@ +# Copyright (c) OpenMMLab. All rights reserved. +# Referred to: https://github.com/KU-CVLAB/CAT-Seg/blob/main/cat_seg/third_party/clip.py # noqa +import hashlib +import os +import urllib +import warnings +from typing import List, Union + +import torch +from PIL import Image +from torchvision.transforms import (CenterCrop, Compose, Normalize, Resize, + ToTensor) +from tqdm import tqdm + +from .clip_model import build_model +from .tokenizer import SimpleTokenizer as _Tokenizer + +__all__ = ['available_models', 'load', 'tokenize'] +_tokenizer = _Tokenizer() + +_MODELS = { + 'RN50': + 'https://openaipublic.azureedge.net/clip/models/afeb0e10f9e5a86da6080e35cf09123aca3b358a0c3e3b6c78a7b63bc04b6762/RN50.pt', # noqa + 'RN101': + 'https://openaipublic.azureedge.net/clip/models/8fa8567bab74a42d41c5915025a8e4538c3bdbe8804a470a72f30b0d94fab599/RN101.pt', # noqa + 'RN50x4': + 'https://openaipublic.azureedge.net/clip/models/7e526bd135e493cef0776de27d5f42653e6b4c8bf9e0f653bb11773263205fdd/RN50x4.pt', # noqa + 'RN50x16': + 'https://openaipublic.azureedge.net/clip/models/52378b407f34354e150460fe41077663dd5b39c54cd0bfd2b27167a4a06ec9aa/RN50x16.pt', # noqa + 'RN50x64': + 'https://openaipublic.azureedge.net/clip/models/be1cfb55d75a9666199fb2206c106743da0f6468c9d327f3e0d0a543a9919d9c/RN50x64.pt', # noqa + 'ViT-B/32': + 'https://openaipublic.azureedge.net/clip/models/40d365715913c9da98579312b702a82c18be219cc2a73407c4526f58eba950af/ViT-B-32.pt', # noqa + 'ViT-B/16': + 'https://openaipublic.azureedge.net/clip/models/5806e77cd80f8b59890b7e101eabd078d9fb84e6937f9e85e4ecb61988df416f/ViT-B-16.pt', # noqa + 'ViT-L/14': + 'https://openaipublic.azureedge.net/clip/models/b8cca3fd41ae0c99ba7e8951adf17d267cdb84cd88be6f7c2e0eca1737a03836/ViT-L-14.pt', # noqa + 'ViT-L/14@336px': + 'https://openaipublic.azureedge.net/clip/models/3035c92b350959924f9f00213499208652fc7ea050643e8b385c2dac08641f02/ViT-L-14-336px.pt', # noqa +} + + +def _download(url: str, root: str = os.path.expanduser('~/.cache/clip')): + """Download clip pretrained weights.""" + os.makedirs(root, exist_ok=True) + filename = os.path.basename(url) + + expected_sha256 = url.split('/')[-2] + download_target = os.path.join(root, filename) + + if os.path.exists(download_target) and not os.path.isfile(download_target): + raise RuntimeError( + f'{download_target} exists and is not a regular file') + + if os.path.isfile(download_target): + if hashlib.sha256(open(download_target, + 'rb').read()).hexdigest() == expected_sha256: + return download_target + else: + warnings.warn( + f'{download_target} exists, but the SHA256 checksum does not\ + match; re-downloading the file') + + with urllib.request.urlopen(url) as source, open(download_target, + 'wb') as output: + with tqdm( + total=int(source.info().get('Content-Length')), + ncols=80) as loop: + while True: + buffer = source.read(8192) + if not buffer: + break + + output.write(buffer) + loop.update(len(buffer)) + + if hashlib.sha256(open(download_target, + 'rb').read()).hexdigest() != expected_sha256: + raise RuntimeError( + 'Model has been downloaded but the SHA256 checksum does not not\ + match') + + return download_target + + +def available_models(): + """Returns a list of available models.""" + return list(_MODELS.keys()) + + +def load(name: str, + device: Union[str, torch.device] = 'cuda' + if torch.cuda.is_available() else 'cpu', + jit=True, + prompt_depth=0, + prompt_length=0): + """Load target clip model.""" + if name not in _MODELS: + raise RuntimeError( + f'Model {name} not found; available models = {available_models()}') + + model_path = _download(_MODELS[name]) + model = torch.jit.load( + model_path, map_location=device if jit else 'cpu').eval() + n_px = model.input_resolution.item() + + transform = Compose([ + Resize(n_px, interpolation=Image.BICUBIC), + CenterCrop(n_px), + lambda image: image.convert('RGB'), + ToTensor(), + Normalize((0.48145466, 0.4578275, 0.40821073), + (0.26862954, 0.26130258, 0.27577711)), + ]) + + if not jit: + model = build_model(model.state_dict(), prompt_depth, + prompt_length).to(device) + return model, transform + + # patch the device names + device_holder = torch.jit.trace( + lambda: torch.ones([]).to(torch.device(device)), example_inputs=[]) + device_node = [ + n for n in device_holder.graph.findAllNodes('prim::Constant') + if 'Device' in repr(n) + ][-1] + + def patch_device(module): + graphs = [module.graph] if hasattr(module, 'graph') else [] + if hasattr(module, 'forward1'): + graphs.append(module.forward1.graph) + + for graph in graphs: + for node in graph.findAllNodes('prim::Constant'): + if 'value' in node.attributeNames() and str( + node['value']).startswith('cuda'): + node.copyAttributes(device_node) + + model.apply(patch_device) + patch_device(model.encode_image) + patch_device(model.encode_text) + + # patch dtype to float32 on CPU + if device == 'cpu': + float_holder = torch.jit.trace( + lambda: torch.ones([]).float(), example_inputs=[]) + float_input = list(float_holder.graph.findNode('aten::to').inputs())[1] + float_node = float_input.node() + + def patch_float(module): + graphs = [module.graph] if hasattr(module, 'graph') else [] + if hasattr(module, 'forward1'): + graphs.append(module.forward1.graph) + + for graph in graphs: + for node in graph.findAllNodes('aten::to'): + inputs = list(node.inputs()) + for i in [1, 2]: + # dtype can be the second or third argument to + # aten::to() + if inputs[i].node()['value'] == 5: + inputs[i].node().copyAttributes(float_node) + + model.apply(patch_float) + patch_float(model.encode_image) + patch_float(model.encode_text) + + model.float() + + return model, transform + + +def load_custom(name: str, + device: Union[str, torch.device] = 'cuda' + if torch.cuda.is_available() else 'cpu', + jit=True, + n_px=224): + """Load a customized clip model.""" + if name not in _MODELS: + raise RuntimeError( + f'Model {name} not found; available models = {available_models()}') + + model_path = _download(_MODELS[name]) + model = torch.jit.load( + model_path, map_location=device if jit else 'cpu').eval() + # n_px = model.input_resolution.item() + + transform = Compose([ + Resize(n_px, interpolation=Image.BICUBIC), + CenterCrop(n_px), + lambda image: image.convert('RGB'), + ToTensor(), + Normalize((0.48145466, 0.4578275, 0.40821073), + (0.26862954, 0.26130258, 0.27577711)), + ]) + + if not jit: + model = build_model(model.state_dict()).to(device) + return model, transform + + # patch the device names + device_holder = torch.jit.trace( + lambda: torch.ones([]).to(torch.device(device)), example_inputs=[]) + device_node = [ + n for n in device_holder.graph.findAllNodes('prim::Constant') + if 'Device' in repr(n) + ][-1] + + def patch_device(module): + graphs = [module.graph] if hasattr(module, 'graph') else [] + if hasattr(module, 'forward1'): + graphs.append(module.forward1.graph) + + for graph in graphs: + for node in graph.findAllNodes('prim::Constant'): + if 'value' in node.attributeNames() and str( + node['value']).startswith('cuda'): + node.copyAttributes(device_node) + + model.apply(patch_device) + patch_device(model.encode_image) + patch_device(model.encode_text) + + # patch dtype to float32 on CPU + if device == 'cpu': + float_holder = torch.jit.trace( + lambda: torch.ones([]).float(), example_inputs=[]) + float_input = list(float_holder.graph.findNode('aten::to').inputs())[1] + float_node = float_input.node() + + def patch_float(module): + graphs = [module.graph] if hasattr(module, 'graph') else [] + if hasattr(module, 'forward1'): + graphs.append(module.forward1.graph) + + for graph in graphs: + for node in graph.findAllNodes('aten::to'): + inputs = list(node.inputs()) + for i in [ + 1, 2 + ]: # dtype can be the second or third argument to + # aten::to() + if inputs[i].node()['value'] == 5: + inputs[i].node().copyAttributes(float_node) + + model.apply(patch_float) + patch_float(model.encode_image) + patch_float(model.encode_text) + + model.float() + + return model, transform + + +def tokenize(texts: Union[str, List[str]], context_length: int = 77): + """Convert texts to tokens.""" + if isinstance(texts, str): + texts = [texts] + + sot_token = _tokenizer.encoder['<|startoftext|>'] + eot_token = _tokenizer.encoder['<|endoftext|>'] + # encode each template text phrase + all_tokens = [[sot_token] + _tokenizer.encode(text) + [eot_token] + for text in texts] + result = torch.zeros(len(all_tokens), context_length, dtype=torch.long) + + for i, tokens in enumerate(all_tokens): + if len(tokens) > context_length: + raise RuntimeError( + f'Input {texts[i]} is too long for context length\ + {context_length}') + result[i, :len(tokens)] = torch.tensor(tokens) + + return result diff --git a/projects/CAT-Seg/cat_seg/utils/self_attention_block.py b/projects/CAT-Seg/cat_seg/utils/self_attention_block.py new file mode 100644 index 00000000000..1c06cbd99e0 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/self_attention_block.py @@ -0,0 +1,79 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from torch import nn as nn +from torch.nn import functional as F + + +class LinearAttention(nn.Module): + """Multi-Head linear attention proposed in "Transformers are RNNs". + + Source: https://github.com/KU-CVLAB/CAT-Seg/blob/main/cat_seg/modeling/transformer/model.py#L247 # noqa + """ + + def __init__(self, eps=1e-6): + super().__init__() + self.eps = eps + + def forward(self, queries, keys, values): + """ + Args: + queries: [N, L, H, D] + keys: [N, S, H, D] + values: [N, S, H, D] + q_mask: [N, L] + kv_mask: [N, S] + Returns: + queried_values: (N, L, H, D) + """ + Q = F.elu(queries) + 1 + K = F.elu(keys) + 1 + + v_length = values.size(1) + values = values / v_length # prevent fp16 overflow + KV = torch.einsum('nshd,nshv->nhdv', K, values) # (S,D)' @ S,V + Z = 1 / (torch.einsum('nlhd,nhd->nlh', Q, K.sum(dim=1)) + self.eps) + queried_values = torch.einsum('nlhd,nhdv,nlh->nlhv', Q, KV, + Z) * v_length + + return queried_values.contiguous() + + +class FullAttention(nn.Module): + """Multi-head scaled dot-product attention, a.k.a full attention. + + Source: https://github.com/KU-CVLAB/CAT-Seg/blob/main/cat_seg/modeling/transformer/model.py#L276 # noqa + """ + + def __init__(self, use_dropout=False, attention_dropout=0.1): + super().__init__() + self.use_dropout = use_dropout + self.dropout = nn.Dropout(attention_dropout) + + def forward(self, queries, keys, values, q_mask=None, kv_mask=None): + """ + Args: + queries: [N, L, H, D] + keys: [N, S, H, D] + values: [N, S, H, D] + q_mask: [N, L] + kv_mask: [N, S] + Returns: + queried_values: (N, L, H, D) + """ + + # Compute the unnormalized attention and apply the masks + QK = torch.einsum('nlhd,nshd->nlsh', queries, keys) + if kv_mask is not None: + QK.masked_fill_( + ~(q_mask[:, :, None, None] * kv_mask[:, None, :, None]), + float('-inf')) + + # Compute the attention and the weighted average + softmax_temp = 1. / queries.size(3)**.5 # sqrt(D) + A = torch.softmax(softmax_temp * QK, dim=2) + if self.use_dropout: + A = self.dropout(A) + + queried_values = torch.einsum('nlsh,nshd->nlhd', A, values) + + return queried_values.contiguous() diff --git a/projects/CAT-Seg/cat_seg/utils/tokenizer.py b/projects/CAT-Seg/cat_seg/utils/tokenizer.py new file mode 100644 index 00000000000..c84711b0678 --- /dev/null +++ b/projects/CAT-Seg/cat_seg/utils/tokenizer.py @@ -0,0 +1,160 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import gzip +import html +import os +from functools import lru_cache + +import ftfy +import regex as re + + +@lru_cache() +def default_bpe(): + """Return default BPE vocabulary path.""" + return os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'bpe_vocab/bpe_simple_vocab_16e6.txt.gz') + + +@lru_cache() +def bytes_to_unicode(): + """Returns list of utf-8 byte and a corresponding list of unicode strings. + + The reversible bpe codes work on unicode strings. This means you need a + large # of unicode characters in your vocab if you want to avoid UNKs. When + you're at something like a 10B token dataset you end up needing around 5K + for decent coverage. This is a significant percentage of your normal, say, + 32K bpe vocab. To avoid that, we want lookup tables between utf-8 bytes and + unicode strings. And avoids mapping to whitespace/control characters the + bpe code barfs on. + """ + bs = list(range(ord('!'), + ord('~') + 1)) + list(range( + ord('¡'), + ord('¬') + 1)) + list(range(ord('®'), + ord('ÿ') + 1)) + cs = bs[:] + n = 0 + for b in range(2**8): + if b not in bs: + bs.append(b) + cs.append(2**8 + n) + n += 1 + cs = [chr(n) for n in cs] + return dict(zip(bs, cs)) + + +def get_pairs(word): + """Return set of symbol pairs in a word. + + Word is represented as tuple of symbols (symbols being variable-length + strings). + """ + pairs = set() + prev_char = word[0] + for char in word[1:]: + pairs.add((prev_char, char)) + prev_char = char + return pairs + + +def basic_clean(text): + """Clean string.""" + text = ftfy.fix_text(text) + text = html.unescape(html.unescape(text)) + return text.strip() + + +def whitespace_clean(text): + """Clean whitespace in string.""" + text = re.sub(r'\s+', ' ', text) + text = text.strip() + return text + + +class SimpleTokenizer: + """Customized Tokenizer implementation.""" + + def __init__(self, bpe_path: str = default_bpe()): + self.byte_encoder = bytes_to_unicode() + self.byte_decoder = {v: k for k, v in self.byte_encoder.items()} + merges = gzip.open(bpe_path).read().decode('utf-8').split('\n') + merges = merges[1:49152 - 256 - 2 + 1] + merges = [tuple(merge.split()) for merge in merges] + vocab = list(bytes_to_unicode().values()) + vocab = vocab + [v + '' for v in vocab] + for merge in merges: + vocab.append(''.join(merge)) + vocab.extend(['<|startoftext|>', '<|endoftext|>']) + self.encoder = dict(zip(vocab, range(len(vocab)))) + self.decoder = {v: k for k, v in self.encoder.items()} + self.bpe_ranks = dict(zip(merges, range(len(merges)))) + self.cache = { + '<|startoftext|>': '<|startoftext|>', + '<|endoftext|>': '<|endoftext|>' + } + self.pat = re.compile( + r"""<\|startoftext\|>|<\|endoftext\|>|'s|'t|'re|'ve|'m|\ + 'll|'d|[\p{L}]+|[\p{N}]|[^\s\p{L}\p{N}]+""", re.IGNORECASE) + + def bpe(self, token): + """Refer to bpe vocabulary dictionary.""" + if token in self.cache: + return self.cache[token] + word = tuple(token[:-1]) + (token[-1] + '', ) + pairs = get_pairs(word) + + if not pairs: + return token + '' + + while True: + bigram = min( + pairs, key=lambda pair: self.bpe_ranks.get(pair, float('inf'))) + if bigram not in self.bpe_ranks: + break + first, second = bigram + new_word = [] + i = 0 + while i < len(word): + try: + j = word.index(first, i) + new_word.extend(word[i:j]) + i = j + except ValueError: + new_word.extend(word[i:]) + break + + if word[i] == first and i < len(word) - 1 and word[ + i + 1] == second: + new_word.append(first + second) + i += 2 + else: + new_word.append(word[i]) + i += 1 + new_word = tuple(new_word) + word = new_word + if len(word) == 1: + break + else: + pairs = get_pairs(word) + word = ' '.join(word) + self.cache[token] = word + return word + + def encode(self, text): + """Encode text strings.""" + bpe_tokens = [] + text = whitespace_clean(basic_clean(text)).lower() + for token in re.findall(self.pat, text): + token = ''.join(self.byte_encoder[b] + for b in token.encode('utf-8')) + bpe_tokens.extend(self.encoder[bpe_token] + for bpe_token in self.bpe(token).split(' ')) + return bpe_tokens + + def decode(self, tokens): + """Decoder tokens to strings.""" + text = ''.join([self.decoder[token] for token in tokens]) + text = bytearray([self.byte_decoder[c] for c in text]).decode( + 'utf-8', errors='replace').replace('', ' ') + return text diff --git a/projects/CAT-Seg/configs/_base_/datasets/ade20k_384x384.py b/projects/CAT-Seg/configs/_base_/datasets/ade20k_384x384.py new file mode 100644 index 00000000000..488ba3d7f6f --- /dev/null +++ b/projects/CAT-Seg/configs/_base_/datasets/ade20k_384x384.py @@ -0,0 +1,68 @@ +# dataset settings +dataset_type = 'ADE20KDataset' +data_root = 'data/ade/ADEChallengeData2016' +crop_size = (384, 384) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', reduce_zero_label=True), + dict( + type='RandomResize', + scale=(2048, 512), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=4, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/training', seg_map_path='annotations/training'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/validation', + seg_map_path='annotations/validation'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/CAT-Seg/configs/_base_/datasets/coco-stuff164k_384x384.py b/projects/CAT-Seg/configs/_base_/datasets/coco-stuff164k_384x384.py new file mode 100644 index 00000000000..dd051761d47 --- /dev/null +++ b/projects/CAT-Seg/configs/_base_/datasets/coco-stuff164k_384x384.py @@ -0,0 +1,62 @@ +# dataset settings +dataset_type = 'COCOStuffDataset' +data_root = 'data/coco_stuff164k' +crop_size = (384, 384) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=2, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/train2017', seg_map_path='annotations/train2017'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/val2017', seg_map_path='annotations/val2017'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/CAT-Seg/configs/_base_/datasets/pascal_context_59_384x384.py b/projects/CAT-Seg/configs/_base_/datasets/pascal_context_59_384x384.py new file mode 100644 index 00000000000..250c5990f6d --- /dev/null +++ b/projects/CAT-Seg/configs/_base_/datasets/pascal_context_59_384x384.py @@ -0,0 +1,72 @@ +# dataset settings +dataset_type = 'PascalContextDataset59' +data_root = 'data/VOCdevkit/VOC2010/' + +img_scale = (520, 520) +crop_size = (384, 384) + +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', reduce_zero_label=True), + dict( + type='RandomResize', + scale=img_scale, + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=4, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='JPEGImages', seg_map_path='SegmentationClassContext'), + ann_file='ImageSets/SegmentationContext/train.txt', + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='JPEGImages', seg_map_path='SegmentationClassContext'), + ann_file='ImageSets/SegmentationContext/val.txt', + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/CAT-Seg/configs/_base_/default_runtime.py b/projects/CAT-Seg/configs/_base_/default_runtime.py new file mode 100644 index 00000000000..272b4d24679 --- /dev/null +++ b/projects/CAT-Seg/configs/_base_/default_runtime.py @@ -0,0 +1,15 @@ +default_scope = 'mmseg' +env_cfg = dict( + cudnn_benchmark=True, + mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), + dist_cfg=dict(backend='nccl'), +) +vis_backends = [dict(type='LocalVisBackend')] +visualizer = dict( + type='SegLocalVisualizer', vis_backends=vis_backends, name='visualizer') +log_processor = dict(by_epoch=False) +log_level = 'INFO' +load_from = None +resume = False + +tta_model = dict(type='SegTTAModel') diff --git a/projects/CAT-Seg/configs/_base_/schedules/schedule_80k.py b/projects/CAT-Seg/configs/_base_/schedules/schedule_80k.py new file mode 100644 index 00000000000..0dcd6c4d1bc --- /dev/null +++ b/projects/CAT-Seg/configs/_base_/schedules/schedule_80k.py @@ -0,0 +1,24 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='PolyLR', + eta_min=1e-4, + power=0.9, + begin=0, + end=80000, + by_epoch=False) +] +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=8000) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=8000), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_ade20k-384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_ade20k-384x384.py new file mode 100644 index 00000000000..bab43a6a39d --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_ade20k-384x384.py @@ -0,0 +1,103 @@ +_base_ = [ + '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py', + '../_base_/datasets/ade20k_384x384.py' +] + +custom_imports = dict(imports=['cat_seg']) + +norm_cfg = dict(type='SyncBN', requires_grad=True) +crop_size = (384, 384) +data_preprocessor = dict( + type='SegDataPreProcessor', + size=crop_size, + # due to the clip model, we do normalization in backbone forward() + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +# model_cfg +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='CLIPOVCATSeg', + feature_extractor=dict( + type='ResNet', + depth=101, + # only use the first three layers + num_stages=3, + out_indices=(0, 1, 2), + dilations=(1, 1, 1), + strides=(1, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True, + init_cfg=dict( + type='Pretrained', checkpoint='torchvision://resnet101'), + ), + train_class_json='data/ade150.json', + test_class_json='data/ade150.json', + clip_pretrained='ViT-B/16', + clip_finetune='attention', + ), + neck=dict( + type='CATSegAggregator', + appearance_guidance_dim=1024, + num_layers=2, + pooling_size=(1, 1), + ), + decode_head=dict( + type='CATSegHead', + in_channels=128, + channels=128, + num_classes=150, + embed_dims=128, + decoder_dims=(64, 32), + decoder_guidance_dims=(512, 256), + decoder_guidance_proj_dims=(32, 16), + loss_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=False, + loss_weight=1.0, + avg_non_ignore=True)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', stride=crop_size, crop_size=crop_size)) + +# dataset settings +train_dataloader = dict( + batch_size=2, + num_workers=4, +) + +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=4000) + +default_hooks = dict( + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=4000), + visualization=dict(type='SegVisualizationHook', draw=True, interval=4000)) + +# optimizer +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0002, betas=(0.9, 0.999), weight_decay=0.0001), + paramwise_cfg=dict( + custom_keys={ + 'backbone.feature_extractor': dict(lr_mult=0.01), + 'backbone.clip_model.visual': dict(lr_mult=0.01) + })) + +# learning policy +param_scheduler = [ + # Use a linear warm-up at [0, 100) iterations + dict(type='LinearLR', start_factor=0.01, by_epoch=False, begin=0, end=500), + # Use a cosine learning rate at [100, 900) iterations + dict( + type='CosineAnnealingLR', + T_max=79500, + by_epoch=False, + begin=500, + end=80000), +] diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_pascal-context-59-384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_pascal-context-59-384x384.py new file mode 100644 index 00000000000..8b412cb86fb --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb1-warmcoslr2e-4-adamw-80k_pascal-context-59-384x384.py @@ -0,0 +1,103 @@ +_base_ = [ + '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py', + '../_base_/datasets/pascal_context_59_384x384.py' +] + +custom_imports = dict(imports=['cat_seg']) + +norm_cfg = dict(type='SyncBN', requires_grad=True) +crop_size = (384, 384) +data_preprocessor = dict( + type='SegDataPreProcessor', + size=crop_size, + # due to the clip model, we do normalization in backbone forward() + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +# model_cfg +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='CLIPOVCATSeg', + feature_extractor=dict( + type='ResNet', + depth=101, + # only use the first three layers + num_stages=3, + out_indices=(0, 1, 2), + dilations=(1, 1, 1), + strides=(1, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True, + init_cfg=dict( + type='Pretrained', checkpoint='torchvision://resnet101'), + ), + train_class_json='data/pc59.json', + test_class_json='data/pc59.json', + clip_pretrained='ViT-B/16', + clip_finetune='attention', + ), + neck=dict( + type='CATSegAggregator', + appearance_guidance_dim=1024, + num_layers=2, + pooling_size=(1, 1), + ), + decode_head=dict( + type='CATSegHead', + in_channels=128, + channels=128, + num_classes=59, + embed_dims=128, + decoder_dims=(64, 32), + decoder_guidance_dims=(512, 256), + decoder_guidance_proj_dims=(32, 16), + loss_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=False, + loss_weight=1.0, + avg_non_ignore=True)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', stride=crop_size, crop_size=crop_size)) + +# dataset settings +train_dataloader = dict( + batch_size=2, + num_workers=4, +) + +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=4000) + +default_hooks = dict( + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=4000), + visualization=dict(type='SegVisualizationHook', draw=True, interval=4000)) + +# optimizer +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0002, betas=(0.9, 0.999), weight_decay=0.0001), + paramwise_cfg=dict( + custom_keys={ + 'backbone.feature_extractor': dict(lr_mult=0.01), + 'backbone.clip_model.visual': dict(lr_mult=0.01) + })) + +# learning policy +param_scheduler = [ + # Use a linear warm-up at [0, 100) iterations + dict(type='LinearLR', start_factor=0.01, by_epoch=False, begin=0, end=500), + # Use a cosine learning rate at [100, 900) iterations + dict( + type='CosineAnnealingLR', + T_max=79500, + by_epoch=False, + begin=500, + end=80000), +] diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb2-warmcoslr2e-4-adamw-80k_coco-stuff164k-384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb2-warmcoslr2e-4-adamw-80k_coco-stuff164k-384x384.py new file mode 100644 index 00000000000..52bf712feae --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vitb-r101_4xb2-warmcoslr2e-4-adamw-80k_coco-stuff164k-384x384.py @@ -0,0 +1,102 @@ +_base_ = [ + '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py', + '../_base_/datasets/coco-stuff164k_384x384.py' +] + +custom_imports = dict(imports=['cat_seg']) + +norm_cfg = dict(type='SyncBN', requires_grad=True) +crop_size = (384, 384) +data_preprocessor = dict( + type='SegDataPreProcessor', + size=crop_size, + # due to the clip model, we do normalization in backbone forward() + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) +# model_cfg +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='CLIPOVCATSeg', + feature_extractor=dict( + type='ResNet', + depth=101, + # only use the first three layers + num_stages=3, + out_indices=(0, 1, 2), + dilations=(1, 1, 1), + strides=(1, 2, 2), + norm_cfg=norm_cfg, + norm_eval=False, + style='pytorch', + contract_dilation=True, + init_cfg=dict( + type='Pretrained', checkpoint='torchvision://resnet101'), + ), + train_class_json='data/coco.json', + test_class_json='data/coco.json', + clip_pretrained='ViT-B/16', + clip_finetune='attention', + ), + neck=dict( + type='CATSegAggregator', + appearance_guidance_dim=1024, + num_layers=2, + ), + decode_head=dict( + type='CATSegHead', + in_channels=128, + channels=128, + num_classes=171, + embed_dims=128, + decoder_dims=(64, 32), + decoder_guidance_dims=(512, 256), + decoder_guidance_proj_dims=(32, 16), + loss_decode=dict( + type='CrossEntropyLoss', + use_sigmoid=False, + loss_weight=1.0, + avg_non_ignore=True)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='slide', stride=crop_size, crop_size=crop_size)) + +# dataset settings +train_dataloader = dict( + batch_size=2, + num_workers=4, +) + +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=4000) + +default_hooks = dict( + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=4000), + visualization=dict(type='SegVisualizationHook', draw=True, interval=4000)) + +# optimizer +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0002, betas=(0.9, 0.999), weight_decay=0.0001), + paramwise_cfg=dict( + custom_keys={ + 'backbone.feature_extractor': dict(lr_mult=0.01), + 'backbone.clip_model.visual': dict(lr_mult=0.01) + })) + +# learning policy +param_scheduler = [ + # Use a linear warm-up at [0, 100) iterations + dict(type='LinearLR', start_factor=0.01, by_epoch=False, begin=0, end=500), + # Use a cosine learning rate at [100, 900) iterations + dict( + type='CosineAnnealingLR', + T_max=79500, + by_epoch=False, + begin=500, + end=80000), +] diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vitg-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vitg-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py new file mode 100644 index 00000000000..345945d0284 --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vitg-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py @@ -0,0 +1,11 @@ +_base_ = './catseg_vitl-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py' # noqa + +model = dict( + backbone=dict( + type='CLIPOVCATSeg', + clip_pretrained='ViT-G', + custom_clip_weights='~/CLIP-ViT-bigG-14-laion2B-39B-b160k'), + neck=dict( + text_guidance_dim=1280, + appearance_guidance_dim=512, + )) diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vith-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vith-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py new file mode 100644 index 00000000000..2f09b8c9ca2 --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vith-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py @@ -0,0 +1,11 @@ +_base_ = './catseg_vitl-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py' # noqa + +model = dict( + backbone=dict( + type='CLIPOVCATSeg', + clip_pretrained='ViT-H', + custom_clip_weights='~/CLIP-ViT-H-14-laion2B-s32B-b79K'), + neck=dict( + text_guidance_dim=1024, + appearance_guidance_dim=512, + )) diff --git a/projects/CAT-Seg/configs/cat_seg/catseg_vitl-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py b/projects/CAT-Seg/configs/cat_seg/catseg_vitl-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py new file mode 100644 index 00000000000..bb4d57ae219 --- /dev/null +++ b/projects/CAT-Seg/configs/cat_seg/catseg_vitl-swin-b_4xb1-warmcoslr2e-4_adamw-80k_coco-stuff164k_384x384.py @@ -0,0 +1,72 @@ +_base_ = './catseg_vitb-r101_4xb2-warmcoslr2e-4-adamw-80k_coco-stuff164k-384x384.py' # noqa + +pretrained = 'https://download.openmmlab.com/mmsegmentation/v0.5/pretrain/swin/swin_base_patch4_window12_384_20220317-55b0104a.pth' # noqa +crop_size = (384, 384) +data_preprocessor = dict(size=crop_size) +model = dict( + backbone=dict( + type='CLIPOVCATSeg', + feature_extractor=dict( + _delete_=True, + type='SwinTransformer', + pretrain_img_size=384, + embed_dims=128, + depths=[2, 2, 18], + num_heads=[4, 8, 16], + window_size=12, + mlp_ratio=4, + qkv_bias=True, + qk_scale=None, + drop_rate=0., + attn_drop_rate=0., + drop_path_rate=0.3, + patch_norm=True, + out_indices=(0, 1, 2), + init_cfg=dict(type='Pretrained', checkpoint=pretrained)), + clip_pretrained='ViT-L/14@336px', + ), + neck=dict( + text_guidance_dim=768, + appearance_guidance_dim=512, + ), + decode_head=dict( + embed_dims=128, + decoder_guidance_dims=(256, 128), + )) + +# dataset settings +train_dataloader = dict( + batch_size=1, + num_workers=2, +) + +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=4000) + +default_hooks = dict( + visualization=dict(type='SegVisualizationHook', draw=True, interval=4000)) + +# optimizer +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.0002, betas=(0.9, 0.999), weight_decay=0.0001), + paramwise_cfg=dict( + custom_keys={ + 'backbone.feature_extractor': dict(lr_mult=0.01), + 'backbone.clip_model.visual': dict(lr_mult=0.01) + })) + +# learning policy +param_scheduler = [ + # Use a linear warm-up at [0, 100) iterations + dict(type='LinearLR', start_factor=0.01, by_epoch=False, begin=0, end=500), + # Use a cosine learning rate at [100, 900) iterations + dict( + type='CosineAnnealingLR', + T_max=79500, + by_epoch=False, + begin=500, + end=80000), +] diff --git a/projects/CAT-Seg/utils/__init__.py b/projects/CAT-Seg/utils/__init__.py new file mode 100644 index 00000000000..02d85f29cb1 --- /dev/null +++ b/projects/CAT-Seg/utils/__init__.py @@ -0,0 +1,7 @@ +from .clip_templates import (IMAGENET_TEMPLATES, IMAGENET_TEMPLATES_SELECT, + IMAGENET_TEMPLATES_SELECT_CLIP, ViLD_templates) + +__all__ = [ + 'IMAGENET_TEMPLATES', 'IMAGENET_TEMPLATES_SELECT', + 'IMAGENET_TEMPLATES_SELECT_CLIP', 'ViLD_templates' +] diff --git a/projects/XDecoder/README.md b/projects/XDecoder/README.md new file mode 100644 index 00000000000..3d55575c6b8 --- /dev/null +++ b/projects/XDecoder/README.md @@ -0,0 +1,17 @@ +# X-Decoder + +> [X-Decoder: Generalized Decoding for Pixel, Image, and Language](https://arxiv.org/pdf/2212.11270.pdf) + + + +## Abstract + +We present X-Decoder, a generalized decoding model that can predict pixel-level segmentation and language tokens seamlessly. X-Decodert takes as input two types of queries: (i) generic non-semantic queries and (ii) semantic queries induced from text inputs, to decode different pixel-level and token-level outputs in the same semantic space. With such a novel design, X-Decoder is the first work that provides a unified way to support all types of image segmentation and a variety of vision-language (VL) tasks. Further, our design enables seamless interactions across tasks at different granularities and brings mutual benefits by learning a common and rich pixel-level visual-semantic understanding space, without any pseudo-labeling. After pretraining on a mixed set of a limited amount of segmentation data and millions of image-text pairs, X-Decoder exhibits strong transferability to a wide range of downstream tasks in both zero-shot and finetuning settings. Notably, it achieves (1) state-of-the-art results on open-vocabulary segmentation and referring segmentation on eight datasets; (2) better or competitive finetuned performance to other generalist and specialist models on segmentation and VL tasks; and (3) flexibility for efficient finetuning and novel task composition (e.g., referring captioning and image editing). + +
+ +
+ +## Usage + +We implement it based on [mmdetection](https://github.com/open-mmlab/mmdetection/), please refer to [mmdetection/projects/XDecoder](https://github.com/open-mmlab/mmdetection/tree/main/projects/XDecoder) for more details. diff --git a/projects/bdd100k_dataset/README.md b/projects/bdd100k_dataset/README.md new file mode 100644 index 00000000000..c7745258441 --- /dev/null +++ b/projects/bdd100k_dataset/README.md @@ -0,0 +1,50 @@ +# BDD100K Dataset + +Support **`BDD100K Dataset`** + +## Description + +Author: CastleDream + +This project implements **`BDD100K Dataset`** + +### Dataset preparing + +Preparing `BDD100K Dataset` dataset following [BDD100K Dataset Preparing Guide](https://github.com/open-mmlab/mmsegmentation/tree/main/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md#bdd100k) + +```none +mmsegmentation/data +└── bdd100k + ├── images + │ └── 10k + │ ├── test [2000 entries exceeds filelimit, not opening dir] + │ ├── train [7000 entries exceeds filelimit, not opening dir] + │ └── val [1000 entries exceeds filelimit, not opening dir] + └── labels + └── sem_seg + ├── colormaps + │ ├── train [7000 entries exceeds filelimit, not opening dir] + │ └── val [1000 entries exceeds filelimit, not opening dir] + ├── masks + │ ├── train [7000 entries exceeds filelimit, not opening dir] + │ └── val [1000 entries exceeds filelimit, not opening dir] + ├── polygons + │ ├── sem_seg_train.json + │ └── sem_seg_val.json + └── rles + ├── sem_seg_train.json + └── sem_seg_val.json +``` + +### Training commands + +```bash +%cd mmsegmentation +!python tools/train.py projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py\ +--work-dir your_work_dir +``` + +## Thanks + +- [\[Datasets\] Add Mapillary Vistas Datasets to MMSeg Core Package. #2576](https://github.com/open-mmlab/mmsegmentation/pull/2576/files) +- [\[Feature\] Support CIHP dataset #1493](https://github.com/open-mmlab/mmsegmentation/pull/1493/files) diff --git a/projects/bdd100k_dataset/configs/_base_/datasets/bdd100k.py b/projects/bdd100k_dataset/configs/_base_/datasets/bdd100k.py new file mode 100644 index 00000000000..24cec69bfeb --- /dev/null +++ b/projects/bdd100k_dataset/configs/_base_/datasets/bdd100k.py @@ -0,0 +1,70 @@ +# dataset settings +dataset_type = 'BDD100KDataset' +data_root = 'data/bdd100k/' + +crop_size = (512, 1024) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict( + type='RandomResize', + scale=(2048, 1024), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 1024), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=2, + num_workers=2, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/10k/train', + seg_map_path='labels/sem_seg/masks/train'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/10k/val', + seg_map_path='labels/sem_seg/masks/val'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py b/projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py new file mode 100644 index 00000000000..456d4c79839 --- /dev/null +++ b/projects/bdd100k_dataset/configs/pspnet_r50-d8_4xb2-80k_bdd100k-512x1024.py @@ -0,0 +1,11 @@ +_base_ = [ + '../../../configs/_base_/models/pspnet_r50-d8.py', + './_base_/datasets/bdd100k.py', + '../../../configs/_base_/default_runtime.py', + '../../../configs/_base_/schedules/schedule_80k.py' +] +custom_imports = dict( + imports=['projects.bdd100k_dataset.mmseg.datasets.bdd100k']) +crop_size = (512, 1024) +data_preprocessor = dict(size=crop_size) +model = dict(data_preprocessor=data_preprocessor) diff --git a/projects/bdd100k_dataset/docs/en/user_guides/2_dataset_prepare.md b/projects/bdd100k_dataset/docs/en/user_guides/2_dataset_prepare.md new file mode 100644 index 00000000000..f2383cfcac2 --- /dev/null +++ b/projects/bdd100k_dataset/docs/en/user_guides/2_dataset_prepare.md @@ -0,0 +1,40 @@ +## BDD100K + +- You could download BDD100k datasets from [here](https://bdd-data.berkeley.edu/) after registration. + +- You can download images and masks by clicking `10K Images` button and `Segmentation` button. + +- After download, unzip by the following instructions: + + ```bash + unzip ~/bdd100k_images_10k.zip -d ~/mmsegmentation/data/ + unzip ~/bdd100k_sem_seg_labels_trainval.zip -d ~/mmsegmentation/data/ + ``` + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +``` diff --git a/projects/bdd100k_dataset/docs/zh_cn/user_guides/2_dataset_prepare.md b/projects/bdd100k_dataset/docs/zh_cn/user_guides/2_dataset_prepare.md new file mode 100644 index 00000000000..64fb763db4c --- /dev/null +++ b/projects/bdd100k_dataset/docs/zh_cn/user_guides/2_dataset_prepare.md @@ -0,0 +1,42 @@ +## BDD100K + +- 可以从[官方网站](https://bdd-data.berkeley.edu/) 下载 BDD100K数据集(语义分割任务主要是10K数据集),按照官网要求注册并登陆后,数据可以在[这里](https://bdd-data.berkeley.edu/portal.html#download)找到。 + +- 图像数据对应的名称是是`10K Images`, 语义分割标注对应的名称是`Segmentation` + +- 下载后,可以使用以下代码进行解压 + + ```bash + unzip ~/bdd100k_images_10k.zip -d ~/mmsegmentation/data/ + unzip ~/bdd100k_sem_seg_labels_trainval.zip -d ~/mmsegmentation/data/ + ``` + +就可以得到以下文件结构了: + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── bdd100k +│ │ ├── images +│ │ │ └── 10k +| │ │ │ ├── test +| │ │ │ ├── train +| │   │   │ └── val +│ │ └── labels +│ │ │ └── sem_seg +| │ │ │ ├── colormaps +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── masks +| │ │ │ │ ├──train +| │ │ │ │ └──val +| │ │ │ ├── polygons +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +| │   │   │ └── rles +| │ │ │ │ ├──sem_seg_train.json +| │ │ │ │ └──sem_seg_val.json +``` diff --git a/projects/bdd100k_dataset/mmseg/datasets/bdd100k.py b/projects/bdd100k_dataset/mmseg/datasets/bdd100k.py new file mode 100644 index 00000000000..e536de74614 --- /dev/null +++ b/projects/bdd100k_dataset/mmseg/datasets/bdd100k.py @@ -0,0 +1,31 @@ +# Copyright (c) OpenMMLab. All rights reserved. + +from mmseg.datasets.basesegdataset import BaseSegDataset + +# from mmseg.registry import DATASETS +# @DATASETS.register_module() + + +class BDD100KDataset(BaseSegDataset): + METAINFO = dict( + classes=('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', + 'traffic light', 'traffic sign', 'vegetation', 'terrain', + 'sky', 'person', 'rider', 'car', 'truck', 'bus', 'train', + 'motorcycle', 'bicycle'), + palette=[[128, 64, 128], [244, 35, 232], [70, 70, 70], [102, 102, 156], + [190, 153, 153], [153, 153, 153], [250, 170, + 30], [220, 220, 0], + [107, 142, 35], [152, 251, 152], [70, 130, 180], + [220, 20, 60], [255, 0, 0], [0, 0, 142], [0, 0, 70], + [0, 60, 100], [0, 80, 100], [0, 0, 230], [119, 11, 32]]) + + def __init__(self, + img_suffix='.jpg', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/example_project/README.md b/projects/example_project/README.md index 4338b8acac1..e4fd03cf4a4 100644 --- a/projects/example_project/README.md +++ b/projects/example_project/README.md @@ -53,7 +53,7 @@ mim train mmsegmentation configs/fcn_dummy-r50-d8_4xb2-40k_cityscapes-512x1024.p mim test mmsegmentation configs/fcn_dummy-r50-d8_4xb2-40k_cityscapes-512x1024.py --work-dir work_dirs/dummy_resnet --checkpoint ${CHECKPOINT_PATH} ``` -> List the results as usually done in other model's README. \[Example\](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/configs/fcn#results-and-models +> List the results as usually done in other model's README. \[Example\](https://github.com/open-mmlab/mmsegmentation/tree/main/configs/fcn#results-and-models > You should claim whether this is based on the pre-trained weights, which are converted from the official release; or it's a reproduced result obtained from retraining the model in this project | Method | Backbone | Crop Size | Lr schd | Mem (GB) | Inf time (fps) | mIoU | mIoU(ms+flip) | config | download | @@ -113,11 +113,11 @@ Here is a checklist illustrating a usual development workflow of a successful pr - [ ] Type hints and docstrings -> Ideally *all* the methods should have [type hints](https://www.pythontutorial.net/python-basics/python-type-hints/) and [docstrings](https://google.github.io/styleguide/pyguide.html#381-docstrings). [Example](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/mmseg/utils/io.py#L9) +> Ideally *all* the methods should have [type hints](https://www.pythontutorial.net/python-basics/python-type-hints/) and [docstrings](https://google.github.io/styleguide/pyguide.html#381-docstrings). [Example](https://github.com/open-mmlab/mmsegmentation/blob/main/mmseg/utils/io.py#L9) - [ ] Unit tests -> Unit tests for each module are required. [Example](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/tests/test_utils/test_io.py#L14) +> Unit tests for each module are required. [Example](https://github.com/open-mmlab/mmsegmentation/blob/main/tests/test_utils/test_io.py#L14) - [ ] Code polishing @@ -125,10 +125,10 @@ Here is a checklist illustrating a usual development workflow of a successful pr - [ ] Metafile.yml -> It will be parsed by MIM and Inferencer. [Example](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/fcn.yml) +> It will be parsed by MIM and Inferencer. [Example](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/fcn.yml) - [ ] Move your modules into the core package following the codebase's file hierarchy structure. -> In particular, you may have to refactor this README into a standard one. [Example](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/fcn/README.md) +> In particular, you may have to refactor this README into a standard one. [Example](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/fcn/README.md) - [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/faq.md b/projects/faq.md index 724c1cf6a5d..74b292b050c 100644 --- a/projects/faq.md +++ b/projects/faq.md @@ -1,6 +1,6 @@ Q1: Why set up `projects/` folder? -Implementing new models and features into OpenMMLab's algorithm libraries could be troublesome due to the rigorous requirements on code quality, which could hinder the fast iteration of SOTA models and might discourage our members from sharing their latest outcomes here. And that's why we have this `projects/` folder now, where some experimental features, frameworks and models are placed, only needed to satisfy the minimum requirement on the code quality, and can be used as standalone libraries. Users are welcome to use them if they [use MMSegmentation from source](https://mmsegmentation.readthedocs.io/en/dev-1.x/get_started.html#best-practices). +Implementing new models and features into OpenMMLab's algorithm libraries could be troublesome due to the rigorous requirements on code quality, which could hinder the fast iteration of SOTA models and might discourage our members from sharing their latest outcomes here. And that's why we have this `projects/` folder now, where some experimental features, frameworks and models are placed, only needed to satisfy the minimum requirement on the code quality, and can be used as standalone libraries. Users are welcome to use them if they [use MMSegmentation from source](https://mmsegmentation.readthedocs.io/en/latest/get_started.html#best-practices). Q2: Why should there be a checklist for a project? diff --git a/projects/gid_dataset/configs/_base_/datasets/gid.py b/projects/gid_dataset/configs/_base_/datasets/gid.py new file mode 100644 index 00000000000..f7218105f2f --- /dev/null +++ b/projects/gid_dataset/configs/_base_/datasets/gid.py @@ -0,0 +1,67 @@ +# dataset settings +dataset_type = 'GID_Dataset' # 注册的类名 +data_root = 'data/gid/' # 数据集根目录 +crop_size = (256, 256) # 图像裁剪大小 +train_pipeline = [ + dict(type='LoadImageFromFile'), # 从文件中加载图像 + dict(type='LoadAnnotations'), # 从文件中加载标注 + dict( + type='RandomResize', # 随机缩放 + scale=(512, 512), # 缩放尺寸 + ratio_range=(0.5, 2.0), # 缩放比例范围 + keep_ratio=True), # 是否保持长宽比 + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), # 随机裁剪 + dict(type='RandomFlip', prob=0.5), # 随机翻转 + dict(type='PhotoMetricDistortion'), # 图像增强 + dict(type='PackSegInputs') # 打包数据 +] +test_pipeline = [ + dict(type='LoadImageFromFile'), # 从文件中加载图像 + dict(type='Resize', scale=(256, 256), keep_ratio=True), # 缩放 + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations'), # 从文件中加载标注 + dict(type='PackSegInputs') # 打包数据 +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] # 多尺度预测缩放比例 +tta_pipeline = [ # 多尺度测试 + dict(type='LoadImageFromFile', file_client_args=dict(backend='disk')), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( # 训练数据加载器 + batch_size=2, # 训练时的数据批量大小 + num_workers=4, # 数据加载线程数 + persistent_workers=True, # 是否持久化线程 + sampler=dict(type='InfiniteSampler', shuffle=True), # 无限采样器 + dataset=dict( + type=dataset_type, # 数据集类名 + data_root=data_root, # 数据集根目录 + data_prefix=dict( + img_path='img_dir/train', + seg_map_path='ann_dir/train'), # 训练集图像和标注路径 + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, # 验证时的数据批量大小 + num_workers=4, # 数据加载线程数 + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path='img_dir/val', seg_map_path='ann_dir/val'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/gid_dataset/configs/deeplabv3plus_r101-d8_4xb2-240k_gid-256x256.py b/projects/gid_dataset/configs/deeplabv3plus_r101-d8_4xb2-240k_gid-256x256.py new file mode 100644 index 00000000000..70cb6005f81 --- /dev/null +++ b/projects/gid_dataset/configs/deeplabv3plus_r101-d8_4xb2-240k_gid-256x256.py @@ -0,0 +1,15 @@ +_base_ = [ + '../../../configs/_base_/models/deeplabv3plus_r50-d8.py', + './_base_/datasets/gid.py', '../../../configs/_base_/default_runtime.py', + '../../../configs/_base_/schedules/schedule_240k.py' +] +custom_imports = dict(imports=['projects.gid_dataset.mmseg.datasets.gid']) + +crop_size = (256, 256) +data_preprocessor = dict(size=crop_size) +model = dict( + data_preprocessor=data_preprocessor, + pretrained='open-mmlab://resnet101_v1c', + backbone=dict(depth=101), + decode_head=dict(num_classes=6), + auxiliary_head=dict(num_classes=6)) diff --git a/projects/gid_dataset/mmseg/datasets/gid.py b/projects/gid_dataset/mmseg/datasets/gid.py new file mode 100644 index 00000000000..a9e8c510b46 --- /dev/null +++ b/projects/gid_dataset/mmseg/datasets/gid.py @@ -0,0 +1,55 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from mmseg.datasets.basesegdataset import BaseSegDataset +from mmseg.registry import DATASETS + + +# 注册数据集类 +@DATASETS.register_module() +class GID_Dataset(BaseSegDataset): + """Gaofen Image Dataset (GID) + + Dataset paper link: + https://www.sciencedirect.com/science/article/pii/S0034425719303414 + https://x-ytong.github.io/project/GID.html + + GID 6 classes: others, built-up, farmland, forest, meadow, water + + In this example, select 15 images from GID dataset as training set, + and select 5 images as validation set. + The selected images are listed as follows: + + GF2_PMS1__L1A0000647767-MSS1 + GF2_PMS1__L1A0001064454-MSS1 + GF2_PMS1__L1A0001348919-MSS1 + GF2_PMS1__L1A0001680851-MSS1 + GF2_PMS1__L1A0001680853-MSS1 + GF2_PMS1__L1A0001680857-MSS1 + GF2_PMS1__L1A0001757429-MSS1 + GF2_PMS2__L1A0000607681-MSS2 + GF2_PMS2__L1A0000635115-MSS2 + GF2_PMS2__L1A0000658637-MSS2 + GF2_PMS2__L1A0001206072-MSS2 + GF2_PMS2__L1A0001471436-MSS2 + GF2_PMS2__L1A0001642620-MSS2 + GF2_PMS2__L1A0001787089-MSS2 + GF2_PMS2__L1A0001838560-MSS2 + + The ``img_suffix`` is fixed to '.tif' and ``seg_map_suffix`` is + fixed to '.tif' for GID. + """ + METAINFO = dict( + classes=('Others', 'Built-up', 'Farmland', 'Forest', 'Meadow', + 'Water'), + palette=[[0, 0, 0], [255, 0, 0], [0, 255, 0], [0, 255, 255], + [255, 255, 0], [0, 0, 255]]) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=None, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/gid_dataset/tools/dataset_converters/gid.py b/projects/gid_dataset/tools/dataset_converters/gid.py new file mode 100644 index 00000000000..d95654aa14b --- /dev/null +++ b/projects/gid_dataset/tools/dataset_converters/gid.py @@ -0,0 +1,181 @@ +import argparse +import glob +import math +import os +import os.path as osp + +import mmcv +import numpy as np +from mmengine.utils import ProgressBar, mkdir_or_exist + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Convert GID dataset to mmsegmentation format') + parser.add_argument('dataset_img_path', help='GID images folder path') + parser.add_argument('dataset_label_path', help='GID labels folder path') + parser.add_argument('--tmp_dir', help='path of the temporary directory') + parser.add_argument( + '-o', '--out_dir', help='output path', default='data/gid') + parser.add_argument( + '--clip_size', + type=int, + help='clipped size of image after preparation', + default=256) + parser.add_argument( + '--stride_size', + type=int, + help='stride of clipping original images', + default=256) + args = parser.parse_args() + return args + + +GID_COLORMAP = dict( + Background=(0, 0, 0), # 0-背景-黑色 + Building=(255, 0, 0), # 1-建筑-红色 + Farmland=(0, 255, 0), # 2-农田-绿色 + Forest=(0, 0, 255), # 3-森林-蓝色 + Meadow=(255, 255, 0), # 4-草地-黄色 + Water=(0, 0, 255) # 5-水-蓝色 +) +palette = list(GID_COLORMAP.values()) +classes = list(GID_COLORMAP.keys()) + + +# 用列表来存一个 RGB 和一个类别的对应 +def colormap2label(palette): + colormap2label_list = np.zeros(256**3, dtype=np.longlong) + for i, colormap in enumerate(palette): + colormap2label_list[(colormap[0] * 256 + colormap[1]) * 256 + + colormap[2]] = i + return colormap2label_list + + +# 给定那个列表,和vis_png然后生成masks_png +def label_indices(RGB_label, colormap2label_list): + RGB_label = RGB_label.astype('int32') + idx = (RGB_label[:, :, 0] * 256 + + RGB_label[:, :, 1]) * 256 + RGB_label[:, :, 2] + return colormap2label_list[idx] + + +def RGB2mask(RGB_label, colormap2label_list): + mask_label = label_indices(RGB_label, colormap2label_list) + return mask_label + + +colormap2label_list = colormap2label(palette) + + +def clip_big_image(image_path, clip_save_dir, args, to_label=False): + """Original image of GID dataset is very large, thus pre-processing of them + is adopted. + + Given fixed clip size and stride size to generate + clipped image, the intersection of width and height is determined. + For example, given one 6800 x 7200 original image, the clip size is + 256 and stride size is 256, thus it would generate 29 x 27 = 783 images + whose size are all 256 x 256. + """ + + image = mmcv.imread(image_path, channel_order='rgb') + # image = mmcv.bgr2gray(image) + + h, w, c = image.shape + clip_size = args.clip_size + stride_size = args.stride_size + + num_rows = math.ceil((h - clip_size) / stride_size) if math.ceil( + (h - clip_size) / + stride_size) * stride_size + clip_size >= h else math.ceil( + (h - clip_size) / stride_size) + 1 + num_cols = math.ceil((w - clip_size) / stride_size) if math.ceil( + (w - clip_size) / + stride_size) * stride_size + clip_size >= w else math.ceil( + (w - clip_size) / stride_size) + 1 + + x, y = np.meshgrid(np.arange(num_cols + 1), np.arange(num_rows + 1)) + xmin = x * clip_size + ymin = y * clip_size + + xmin = xmin.ravel() + ymin = ymin.ravel() + xmin_offset = np.where(xmin + clip_size > w, w - xmin - clip_size, + np.zeros_like(xmin)) + ymin_offset = np.where(ymin + clip_size > h, h - ymin - clip_size, + np.zeros_like(ymin)) + boxes = np.stack([ + xmin + xmin_offset, ymin + ymin_offset, + np.minimum(xmin + clip_size, w), + np.minimum(ymin + clip_size, h) + ], + axis=1) + + if to_label: + image = RGB2mask(image, colormap2label_list) + + for count, box in enumerate(boxes): + start_x, start_y, end_x, end_y = box + clipped_image = image[start_y:end_y, + start_x:end_x] if to_label else image[ + start_y:end_y, start_x:end_x, :] + img_name = osp.basename(image_path).replace('.tif', '') + img_name = img_name.replace('_label', '') + if count % 3 == 0: + mmcv.imwrite( + clipped_image.astype(np.uint8), + osp.join( + clip_save_dir.replace('train', 'val'), + f'{img_name}_{start_x}_{start_y}_{end_x}_{end_y}.png')) + else: + mmcv.imwrite( + clipped_image.astype(np.uint8), + osp.join( + clip_save_dir, + f'{img_name}_{start_x}_{start_y}_{end_x}_{end_y}.png')) + count += 1 + + +def main(): + args = parse_args() + """ + According to this paper: https://ieeexplore.ieee.org/document/9343296/ + select 15 images contained in GID, , which cover the whole six + categories, to generate train set and validation set. + + """ + + if args.out_dir is None: + out_dir = osp.join('data', 'gid') + else: + out_dir = args.out_dir + + print('Making directories...') + mkdir_or_exist(osp.join(out_dir, 'img_dir', 'train')) + mkdir_or_exist(osp.join(out_dir, 'img_dir', 'val')) + mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'train')) + mkdir_or_exist(osp.join(out_dir, 'ann_dir', 'val')) + + src_path_list = glob.glob(os.path.join(args.dataset_img_path, '*.tif')) + print(f'Find {len(src_path_list)} pictures') + + prog_bar = ProgressBar(len(src_path_list)) + + dst_img_dir = osp.join(out_dir, 'img_dir', 'train') + dst_label_dir = osp.join(out_dir, 'ann_dir', 'train') + + for i, img_path in enumerate(src_path_list): + label_path = osp.join( + args.dataset_label_path, + osp.basename(img_path.replace('.tif', '_label.tif'))) + + clip_big_image(img_path, dst_img_dir, args, to_label=False) + clip_big_image(label_path, dst_label_dir, args, to_label=True) + prog_bar.update() + + print('Done!') + + +if __name__ == '__main__': + main() diff --git a/projects/gid_dataset/tools/dataset_converters/gid_select15imgFromAll.py b/projects/gid_dataset/tools/dataset_converters/gid_select15imgFromAll.py new file mode 100644 index 00000000000..d3eeff26902 --- /dev/null +++ b/projects/gid_dataset/tools/dataset_converters/gid_select15imgFromAll.py @@ -0,0 +1,75 @@ +import argparse +import os +import shutil + +# select 15 images from GID dataset + +img_list = [ + 'GF2_PMS1__L1A0000647767-MSS1.tif', 'GF2_PMS1__L1A0001064454-MSS1.tif', + 'GF2_PMS1__L1A0001348919-MSS1.tif', 'GF2_PMS1__L1A0001680851-MSS1.tif', + 'GF2_PMS1__L1A0001680853-MSS1.tif', 'GF2_PMS1__L1A0001680857-MSS1.tif', + 'GF2_PMS1__L1A0001757429-MSS1.tif', 'GF2_PMS2__L1A0000607681-MSS2.tif', + 'GF2_PMS2__L1A0000635115-MSS2.tif', 'GF2_PMS2__L1A0000658637-MSS2.tif', + 'GF2_PMS2__L1A0001206072-MSS2.tif', 'GF2_PMS2__L1A0001471436-MSS2.tif', + 'GF2_PMS2__L1A0001642620-MSS2.tif', 'GF2_PMS2__L1A0001787089-MSS2.tif', + 'GF2_PMS2__L1A0001838560-MSS2.tif' +] + +labels_list = [ + 'GF2_PMS1__L1A0000647767-MSS1_label.tif', + 'GF2_PMS1__L1A0001064454-MSS1_label.tif', + 'GF2_PMS1__L1A0001348919-MSS1_label.tif', + 'GF2_PMS1__L1A0001680851-MSS1_label.tif', + 'GF2_PMS1__L1A0001680853-MSS1_label.tif', + 'GF2_PMS1__L1A0001680857-MSS1_label.tif', + 'GF2_PMS1__L1A0001757429-MSS1_label.tif', + 'GF2_PMS2__L1A0000607681-MSS2_label.tif', + 'GF2_PMS2__L1A0000635115-MSS2_label.tif', + 'GF2_PMS2__L1A0000658637-MSS2_label.tif', + 'GF2_PMS2__L1A0001206072-MSS2_label.tif', + 'GF2_PMS2__L1A0001471436-MSS2_label.tif', + 'GF2_PMS2__L1A0001642620-MSS2_label.tif', + 'GF2_PMS2__L1A0001787089-MSS2_label.tif', + 'GF2_PMS2__L1A0001838560-MSS2_label.tif' +] + + +def parse_args(): + parser = argparse.ArgumentParser( + description='From 150 images of GID dataset to select 15 images') + parser.add_argument('dataset_img_dir', help='150 GID images folder path') + parser.add_argument('dataset_label_dir', help='150 GID labels folder path') + + parser.add_argument('dest_img_dir', help='15 GID images folder path') + parser.add_argument('dest_label_dir', help='15 GID labels folder path') + + args = parser.parse_args() + + return args + + +def main(): + """This script is used to select 15 images from GID dataset, According to + paper: https://ieeexplore.ieee.org/document/9343296/""" + args = parse_args() + + img_path = args.dataset_img_dir + label_path = args.dataset_label_dir + + dest_img_dir = args.dest_img_dir + dest_label_dir = args.dest_label_dir + + # copy images of 'img_list' to 'desr_dir' + print('Copy images of img_list to desr_dir ing...') + for img in img_list: + shutil.copy(os.path.join(img_path, img), dest_img_dir) + print('Done!') + + print('copy labels of labels_list to desr_dir ing...') + for label in labels_list: + shutil.copy(os.path.join(label_path, label), dest_label_dir) + print('Done!') + + +if __name__ == '__main__': + main() diff --git a/projects/gid_dataset/user_guides/2_dataset_prepare.md b/projects/gid_dataset/user_guides/2_dataset_prepare.md new file mode 100644 index 00000000000..63bd4d46fc5 --- /dev/null +++ b/projects/gid_dataset/user_guides/2_dataset_prepare.md @@ -0,0 +1,53 @@ +## Gaofen Image Dataset (GID) + +- GID 数据集可在[此处](https://x-ytong.github.io/project/GID.html)进行下载。 +- GID 数据集包含 150 张 6800x7200 的大尺寸图像,标签为 RGB 标签。 +- 根据[文献](https://ieeexplore.ieee.org/document/9343296/),此处选择 15 张图像生成训练集和验证集,该 15 张图像包含了所有六类信息。所选的图像名称如下: + +```None + GF2_PMS1__L1A0000647767-MSS1 + GF2_PMS1__L1A0001064454-MSS1 + GF2_PMS1__L1A0001348919-MSS1 + GF2_PMS1__L1A0001680851-MSS1 + GF2_PMS1__L1A0001680853-MSS1 + GF2_PMS1__L1A0001680857-MSS1 + GF2_PMS1__L1A0001757429-MSS1 + GF2_PMS2__L1A0000607681-MSS2 + GF2_PMS2__L1A0000635115-MSS2 + GF2_PMS2__L1A0000658637-MSS2 + GF2_PMS2__L1A0001206072-MSS2 + GF2_PMS2__L1A0001471436-MSS2 + GF2_PMS2__L1A0001642620-MSS2 + GF2_PMS2__L1A0001787089-MSS2 + GF2_PMS2__L1A0001838560-MSS2 +``` + +这里也提供了一个脚本来方便的筛选出15张图像, + +``` +python projects/gid_dataset/tools/dataset_converters/gid_select15imgFromAll.py {150 张图像的路径} {150 张标签的路径} {15 张图像的路径} {15 张标签的路径} +``` + +在选择出 15 张图像后,执行以下命令进行裁切及标签的转换,需要修改为您所存储 15 张图像及标签的路径。 + +``` +python projects/gid_dataset/tools/dataset_converters/gid.py {15 张图像的路径} {15 张标签的路径} +``` + +完成裁切后的 GID 数据结构如下: + +```none +mmsegmentation +├── mmseg +├── tools +├── configs +├── data +│ ├── gid +│ │ ├── ann_dir +| │ │ │ ├── train +| │ │ │ ├── val +│ │ ├── img_dir +| │ │ │ ├── train +| │ │ │ ├── val + +``` diff --git a/projects/hssn/README.md b/projects/hssn/README.md index c2a74c69f9a..9dcbf37de0c 100644 --- a/projects/hssn/README.md +++ b/projects/hssn/README.md @@ -41,9 +41,9 @@ bash tools/dist_test.sh projects/hssn/configs/hssn/hieraseg_deeplabv3plus_r101-d ### Cityscapes -| Method | Backbone | Crop Size | mIoU | mIoU (ms+flip) | config | model | -| :--------: | :------: | :-------: | :---: | :------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------: | -| DeeplabV3+ | R-101-D8 | 512x1024 | 81.61 | 82.71 | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/HieraSeg/configs/hieraseg/hieraseg_deeplabv3plus_r101-d8_4xb2-80l_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hieraseg/hieraseg_deeplabv3plus_r101-d8_4xb2-80k_cityscapes-512x1024_20230112_125023-bc59a3d1.pth) | +| Method | Backbone | Crop Size | mIoU | mIoU (ms+flip) | config | model | +| :--------: | :------: | :-------: | :---: | :------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------: | +| DeeplabV3+ | R-101-D8 | 512x1024 | 81.61 | 82.71 | [config](https://github.com/open-mmlab/mmsegmentation/tree/main/projects/HieraSeg/configs/hieraseg/hieraseg_deeplabv3plus_r101-d8_4xb2-80l_cityscapes-512x1024.py) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/hieraseg/hieraseg_deeplabv3plus_r101-d8_4xb2-80k_cityscapes-512x1024_20230112_125023-bc59a3d1.pth) | diff --git a/projects/isnet/README.md b/projects/isnet/README.md index 3a3172a9d99..0a79ad6a4fa 100644 --- a/projects/isnet/README.md +++ b/projects/isnet/README.md @@ -96,11 +96,11 @@ A project does not necessarily have to be finished in a single PR, but it's esse - [ ] Type hints and docstrings - + - [ ] Unit tests - + - [ ] Code polishing @@ -108,10 +108,10 @@ A project does not necessarily have to be finished in a single PR, but it's esse - [ ] Metafile.yml - + - [ ] Move your modules into the core package following the codebase's file hierarchy structure. - + - [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/mapillary_dataset/README.md b/projects/mapillary_dataset/README.md index cdc61d53a93..44a1e33ef93 100644 --- a/projects/mapillary_dataset/README.md +++ b/projects/mapillary_dataset/README.md @@ -10,7 +10,7 @@ This project implements **`Mapillary Vistas Dataset`** ### Dataset preparing -Preparing `Mapillary Vistas Dataset` dataset following [Mapillary Vistas Dataset Preparing Guide](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md) +Preparing `Mapillary Vistas Dataset` dataset following [Mapillary Vistas Dataset Preparing Guide](https://github.com/open-mmlab/mmsegmentation/tree/main/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md) ```none mmsegmentation diff --git a/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md b/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md index fa074543300..c5cbc0f9b80 100644 --- a/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md +++ b/projects/mapillary_dataset/docs/en/user_guides/2_dataset_prepare.md @@ -47,7 +47,7 @@ ``` - You could set Datasets version with `MapillaryDataset_v1` and `MapillaryDataset_v2` in your configs. - View the Mapillary Vistas Datasets config file here [V1.2](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/datasets/mapillary_v1.py) and [V2.0](https://github.com/open-mmlab/mmsegmentation/blob/dev-1.x/configs/_base_/datasets/mapillary_v2.py) + View the Mapillary Vistas Datasets config file here [V1.2](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v1.py) and [V2.0](https://github.com/open-mmlab/mmsegmentation/blob/main/configs/_base_/datasets/mapillary_v2.py) - **View datasets labels index and palette** diff --git a/projects/medical/2d_image/ct/cranium/README.md b/projects/medical/2d_image/ct/cranium/README.md new file mode 100644 index 00000000000..d3fa64ea406 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/README.md @@ -0,0 +1,142 @@ +# Brain CT Images with Intracranial Hemorrhage Masks (Cranium) + +## Description + +This project supports **`Brain CT Images with Intracranial Hemorrhage Masks (Cranium)`**, which can be downloaded from [here](https://www.kaggle.com/datasets/vbookshelf/computed-tomography-ct-images). + +### Dataset Overview + +This dataset consists of head CT (Computed Thomography) images in jpg format. There are 2500 brain window images and 2500 bone window images, for 82 patients. There are approximately 30 image slices per patient. 318 images have associated intracranial image masks. Also included are csv files containing hemorrhage diagnosis data and patient data. +This is version 1.0.0 of this dataset. A full description of this dataset as well as updated versions can be found here: +https://physionet.org/content/ct-ich/1.0.0/ + +### Statistic Information + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ----------------------------------------------------------------------------------- | ----------------- | ------------ | -------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------- | +| [Cranium](https://www.kaggle.com/datasets/vbookshelf/computed-tomography-ct-images) | head_and_neck | segmentation | ct | 2 | 2501/-/- | yes/-/- | 2020 | [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 2501 | 99.93 | - | - | - | - | +| hemorrhage | 318 | 0.07 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![cranium](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/ct/cranium/cranium_dataset.png?raw=true) + +## Dataset Citation + +``` +@article{hssayeni2020computed, + title={Computed tomography images for intracranial hemorrhage detection and segmentation}, + author={Hssayeni, Murtadha and Croock, MS and Salman, AD and Al-khafaji, HF and Yahya, ZA and Ghoraani, B}, + journal={Intracranial Hemorrhage Segmentation Using A Deep Convolutional Model. Data}, + volume={5}, + number={1}, + pages={179}, + year={2020} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 9.3.0 +- scikit-learn(sklearn) v1.2.0 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `cranium/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://www.kaggle.com/datasets/vbookshelf/computed-tomography-ct-images) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── ct + │ │ │ │ ├── cranium + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 2000 | 99.93 | 501 | 99.92 | - | - | +| hemorrhage | 260 | 0.07 | 260 | 0.08 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/ct/cranium/configs/cranium_512x512.py b/projects/medical/2d_image/ct/cranium/configs/cranium_512x512.py new file mode 100644 index 00000000000..d9b44362a5c --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/configs/cranium_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'CraniumDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_cranium-512x512.py b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_cranium-512x512.py new file mode 100644 index 00000000000..ac013a215ae --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_cranium-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './cranium_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.cranium_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_cranium-512x512.py b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_cranium-512x512.py new file mode 100644 index 00000000000..c71110a21f7 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_cranium-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './cranium_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.cranium_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_cranium-512x512.py b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_cranium-512x512.py new file mode 100644 index 00000000000..abbdac285b2 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_cranium-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './cranium_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.cranium_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_cranium-512x512.py b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_cranium-512x512.py new file mode 100644 index 00000000000..418595268f9 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_cranium-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './cranium_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.cranium_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/ct/cranium/datasets/cranium_dataset.py b/projects/medical/2d_image/ct/cranium/datasets/cranium_dataset.py new file mode 100644 index 00000000000..d65f1cbfc68 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/datasets/cranium_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class CraniumDataset(BaseSegDataset): + """CraniumDataset dataset. + + In segmentation map annotation for CraniumDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'hemorrhage')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/ct/cranium/tools/prepare_dataset.py b/projects/medical/2d_image/ct/cranium/tools/prepare_dataset.py new file mode 100644 index 00000000000..1aa4e435614 --- /dev/null +++ b/projects/medical/2d_image/ct/cranium/tools/prepare_dataset.py @@ -0,0 +1,66 @@ +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +tgt_img_dir = os.path.join(root_path, 'images/train/') +tgt_mask_dir = os.path.join(root_path, 'masks/train/') +os.system('mkdir -p ' + tgt_img_dir) +os.system('mkdir -p ' + tgt_mask_dir) + + +def read_single_array_from_pil(path): + return np.asarray(Image.open(path)) + + +def save_png_from_array(arr, save_path, mode=None): + Image.fromarray(arr, mode=mode).save(save_path) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +patients_dir = os.path.join( + root_path, 'Cranium/computed-tomography-images-for-' + + 'intracranial-hemorrhage-detection-and-segmentation-1.0.0' + + '/Patients_CT') + +patients = sorted(os.listdir(patients_dir)) +for p in patients: + data_dir = os.path.join(patients_dir, p, 'brain') + file_names = os.listdir(data_dir) + img_w_mask_names = [ + _.replace('_HGE_Seg', '') for _ in file_names if 'Seg' in _ + ] + img_wo_mask_names = [ + _ for _ in file_names if _ not in img_w_mask_names and 'Seg' not in _ + ] + + for file_name in file_names: + path = os.path.join(data_dir, file_name) + img = read_single_array_from_pil(path) + tgt_name = file_name.replace('.jpg', img_suffix) + tgt_name = p + '_' + tgt_name + if 'Seg' in file_name: # is a mask + tgt_name = tgt_name.replace('_HGE_Seg', '') + mask_path = os.path.join(tgt_mask_dir, tgt_name) + mask = convert_label(img, convert_dict={0: 0, 255: 1}) + save_png_from_array(mask, mask_path) + else: + img_path = os.path.join(tgt_img_dir, tgt_name) + pil = Image.fromarray(img).convert('RGB') + pil.save(img_path) + + if file_name in img_wo_mask_names: + mask = np.zeros_like(img, dtype=np.uint8) + mask_path = os.path.join(tgt_mask_dir, tgt_name) + save_png_from_array(mask, mask_path) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/README.md b/projects/medical/2d_image/dermoscopy/isic2016_task1/README.md new file mode 100644 index 00000000000..6e44e415ed6 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/README.md @@ -0,0 +1,149 @@ +# ISIC-2016 Task1 + +## Description + +This project support **`ISIC-2016 Task1 `**, and the dataset used in this project can be downloaded from [here](https://challenge.isic-archive.com/data/#2016). + +### Dataset Overview + +The overarching goal of the challenge is to develop image analysis tools to enable the automated diagnosis of melanoma from dermoscopic images. + +This challenge provides training data (~900 images) for participants to engage in all 3 components of lesion image analysis. A separate test dataset (~350 images) will be provided for participants to generate and submit automated results. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ---------------------------------------------------------------- | ----------------- | ------------ | ---------- | ------------ | --------------------- | ---------------------- | ------------ | ---------------------------------------------------------------------- | +| [ISIC-2016 Task1](https://challenge.isic-archive.com/data/#2016) | full body | segmentation | dermoscopy | 2 | 900/-/379- | yes/-/yes | 2016 | [CC-0](https://creativecommons.org/share-your-work/public-domain/cc0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 900 | 82.08 | - | - | 379 | 81.98 | +| skin lesion | 900 | 17.92 | - | - | 379 | 18.02 | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/dermoscopy/isic2016_task1/isic2016_task1.png) + +### Prerequisites + +- Python 3.8 +- PyTorch 1.10.0 +- pillow(PIL) 9.3.0 +- scikit-learn(sklearn) 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of PYTHONPATH, which should point to the project's directory so that Python can locate the module files. In isic2016_task1/ root directory, run the following line to add the current directory to PYTHONPATH: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://challenge.isic-archive.com/data/#2016) and decompression data to path 'data/'. +- run script `"python tools/prepare_dataset.py"` to split dataset and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── dermoscopy + │ │ │ │ ├── isic2016_task1 + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── test.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── xxx.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── xxx.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png +``` + +### Training commands + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +To train on multiple GPUs, e.g. 8 GPUs, run the following command: + +```shell +mim train mmseg ./configs/${CONFIG_PATH} --launcher pytorch --gpus 8 +``` + +### Testing commands + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Results + +### ISIC-2016 Task1 + +| Method | Backbone | Crop Size | lr | mIoU | mDice | config | +| :-------------: | :------: | :-------: | :----: | :--: | :---: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| fcn_unet_s5-d16 | unet | 512x512 | 0.01 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2016-task1-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.001 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2016-task1-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.0001 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2016-task1-512x512.py) | + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2016-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2016-task1-512x512.py new file mode 100644 index 00000000000..5638de4d560 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2016-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2016-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2016-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2016-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2016-task1-512x512.py new file mode 100644 index 00000000000..bf17faa5380 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2016-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2016-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2016-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2016-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2016-task1-512x512.py new file mode 100644 index 00000000000..f7bfcf6158f --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2016-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2016-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2016-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/isic2016-task1_512x512.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/isic2016-task1_512x512.py new file mode 100644 index 00000000000..029f5d4d7ec --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/configs/isic2016-task1_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'ISIC2017Task1' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='test.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/datasets/isic2016-task1_dataset.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/datasets/isic2016-task1_dataset.py new file mode 100644 index 00000000000..8f11bdd0ba9 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/datasets/isic2016-task1_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ISIC2017Task1(BaseSegDataset): + """ISIC2017Task1 dataset. + + In segmentation map annotation for ISIC2017Task1, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('normal', 'skin lesion')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/dermoscopy/isic2016_task1/tools/prepare_dataset.py b/projects/medical/2d_image/dermoscopy/isic2016_task1/tools/prepare_dataset.py new file mode 100755 index 00000000000..ef4dad54086 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2016_task1/tools/prepare_dataset.py @@ -0,0 +1,120 @@ +import glob +import os +import shutil + +import numpy as np +from PIL import Image + + +def check_maskid(train_imgs): + for i in train_masks: + img = Image.open(i) + print(np.unique(np.array(img))) + + +def reformulate_file(image_list, mask_list): + file_list = [] + for idx, (imgp, + maskp) in enumerate(zip(sorted(image_list), sorted(mask_list))): + item = {'image': imgp, 'label': maskp} + file_list.append(item) + return file_list + + +def check_file_exist(pair_list): + rel_path = os.getcwd() + for idx, sample in enumerate(pair_list): + image_path = sample['image'] + assert os.path.exists(os.path.join(rel_path, image_path)) + if 'label' in sample: + mask_path = sample['label'] + assert os.path.exists(os.path.join(rel_path, mask_path)) + print('all file path ok!') + + +def convert_maskid(mask): + # add mask id conversion + arr_mask = np.array(mask).astype(np.uint8) + arr_mask[arr_mask == 255] = 1 + return Image.fromarray(arr_mask) + + +def process_dataset(file_lists, part_dir_dict): + for ith, part in enumerate(file_lists): + part_dir = part_dir_dict[ith] + for sample in part: + # read image and mask + image_path = sample['image'] + if 'label' in sample: + mask_path = sample['label'] + + basename = os.path.basename(image_path) + targetname = basename.split('.')[0] # from image name + + # check image file + img_save_path = os.path.join(root_path, 'images', part_dir, + targetname + save_img_suffix) + if not os.path.exists(img_save_path): + if not image_path.endswith('.png'): + src = Image.open(image_path) + src.save(img_save_path) + else: + shutil.copy(image_path, img_save_path) + + if mask_path is not None: + mask_save_path = os.path.join(root_path, 'masks', part_dir, + targetname + save_seg_map_suffix) + if not os.path.exists(mask_save_path): + # check mask file + mask = Image.open(mask_path).convert('L') + # convert mask id + mask = convert_maskid(mask) + if not mask_path.endswith('.png'): + mask.save(mask_save_path) + else: + mask.save(mask_save_path) + + # print image num + part_dir_folder = os.path.join(root_path, 'images', part_dir) + print( + f'{part_dir} has {len(os.listdir(part_dir_folder))} images completed!' # noqa + ) + + +if __name__ == '__main__': + + root_path = 'data/' # original file + img_suffix = '.jpg' + seg_map_suffix = '.png' + save_img_suffix = '.png' + save_seg_map_suffix = '.png' + + train_imgs = glob.glob('data/ISBI2016_ISIC_Part1_Training_Data/*' # noqa + + img_suffix) + train_masks = glob.glob( + 'data/ISBI2016_ISIC_Part1_Training_GroundTruth/*' # noqa + + seg_map_suffix) + + test_imgs = glob.glob('data/ISBI2016_ISIC_Part1_Test_Data/*' + img_suffix) + test_masks = glob.glob( + 'data/ISBI2016_ISIC_Part1_Test_GroundTruth/*' # noqa + + seg_map_suffix) + + assert len(train_imgs) == len(train_masks) + assert len(test_imgs) == len(test_masks) + + print(f'training images: {len(train_imgs)}, test images: {len(test_imgs)}') + + os.system('mkdir -p ' + root_path + 'images/train/') + os.system('mkdir -p ' + root_path + 'images/test/') + os.system('mkdir -p ' + root_path + 'masks/train/') + os.system('mkdir -p ' + root_path + 'masks/test/') + + train_pair_list = reformulate_file(train_imgs, train_masks) + test_pair_list = reformulate_file(test_imgs, test_masks) + + check_file_exist(train_pair_list) + check_file_exist(test_pair_list) + + part_dir_dict = {0: 'train/', 1: 'test/'} + process_dataset([train_pair_list, test_pair_list], part_dir_dict) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/README.md b/projects/medical/2d_image/dermoscopy/isic2017_task1/README.md new file mode 100644 index 00000000000..c7cc27096be --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/README.md @@ -0,0 +1,158 @@ +# ISIC-2017 Task1 + +## Description + +This project support **`ISIC-2017 Task1 `**, and the dataset used in this project can be downloaded from [here](https://challenge.isic-archive.com/data/#2017). + +### Dataset Overview + +The goal of the challenge is to help participants develop image analysis tools to enable the automated diagnosis of melanoma from dermoscopic images. + +This challenge provides training data (~2000 images) for participants to engage in all 3 components of lesion image analysis. A separate public validation dataset (~150 images) and blind held-out test dataset (~600 images) will be provided for participants to generate and submit automated results. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ---------------------------------------------------------------- | ----------------- | ------------ | ---------- | ------------ | --------------------- | ---------------------- | ------------ | ---------------------------------------------------------------------- | +| [ISIC-2017 Task1](https://challenge.isic-archive.com/data/#2017) | full body | segmentation | dermoscopy | 2 | 2000/150/600 | yes/yes/yes | 2017 | [CC-0](https://creativecommons.org/share-your-work/public-domain/cc0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| normal | 2000 | 82.86 | 150 | 73.88 | 600 | 70.62 | +| skin lesion | 2000 | 17.14 | 150 | 26.12 | 600 | 29.38 | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/dermoscopy/isic2017_task1/isic2017_task1.png) + +### Prerequisites + +- Python 3.8 +- PyTorch 1.10.0 +- pillow(PIL) 9.3.0 +- scikit-learn(sklearn) 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of PYTHONPATH, which should point to the project's directory so that Python can locate the module files. In isic2017_task1/ root directory, run the following line to add the current directory to PYTHONPATH: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://challenge.isic-archive.com/data/#2017) and decompression data to path 'data/'. +- run script `"python tools/prepare_dataset.py"` to split dataset and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── dermoscopy + │ │ │ │ ├── isic2017_task1 + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── test.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── xxx.png + │ │ │ │ │ │ │ ├── val + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── xxx.png + │ │ │ │ │ │ │ ├── val + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │   │   │ └── yyy.png +``` + +### Training commands + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +To train on multiple GPUs, e.g. 8 GPUs, run the following command: + +```shell +mim train mmseg ./configs/${CONFIG_PATH} --launcher pytorch --gpus 8 +``` + +### Testing commands + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Results + +### ISIC-2017 Task1 + +| Method | Backbone | Crop Size | lr | mIoU | mDice | config | +| :-------------: | :------: | :-------: | :----: | :--: | :---: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| fcn_unet_s5-d16 | unet | 512x512 | 0.01 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2017-task1-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.001 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2017-task1-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.0001 | - | - | [config](https://github.com/open-mmlab/mmsegmentation/tree/dev-1.x/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2017-task1-512x512.py) | + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [ ] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2017-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2017-task1-512x512.py new file mode 100644 index 00000000000..58d0a125d33 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_isic2017-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2017-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2017-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2017-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2017-task1-512x512.py new file mode 100644 index 00000000000..3becacf64fb --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_isic2017-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2017-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2017-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2017-task1-512x512.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2017-task1-512x512.py new file mode 100644 index 00000000000..654ef4dc3d5 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_isic2017-task1-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './isic2017-task1_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.isic2017-task1_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/isic2017-task1_512x512.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/isic2017-task1_512x512.py new file mode 100644 index 00000000000..95997a10997 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/configs/isic2017-task1_512x512.py @@ -0,0 +1,41 @@ +dataset_type = 'ISIC2017Task1' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/train/', seg_map_path='masks/train/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict(img_path='images/val/', seg_map_path='masks/val/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/datasets/isic2017-task1_dataset.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/datasets/isic2017-task1_dataset.py new file mode 100644 index 00000000000..8f11bdd0ba9 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/datasets/isic2017-task1_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ISIC2017Task1(BaseSegDataset): + """ISIC2017Task1 dataset. + + In segmentation map annotation for ISIC2017Task1, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('normal', 'skin lesion')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/dermoscopy/isic2017_task1/tools/prepare_dataset.py b/projects/medical/2d_image/dermoscopy/isic2017_task1/tools/prepare_dataset.py new file mode 100755 index 00000000000..b3643c93590 --- /dev/null +++ b/projects/medical/2d_image/dermoscopy/isic2017_task1/tools/prepare_dataset.py @@ -0,0 +1,127 @@ +import glob +import os +import shutil + +import numpy as np +from PIL import Image + + +def check_maskid(train_imgs): + for i in train_masks: + img = Image.open(i) + print(np.unique(np.array(img))) + + +def reformulate_file(image_list, mask_list): + file_list = [] + for idx, (imgp, + maskp) in enumerate(zip(sorted(image_list), sorted(mask_list))): + item = {'image': imgp, 'label': maskp} + file_list.append(item) + return file_list + + +def convert_maskid(mask): + # add mask id conversion + arr_mask = np.array(mask).astype(np.uint8) + arr_mask[arr_mask == 255] = 1 + return Image.fromarray(arr_mask) + + +def check_file_exist(pair_list): + rel_path = os.getcwd() + for idx, sample in enumerate(pair_list): + image_path = sample['image'] + assert os.path.exists(os.path.join(rel_path, image_path)) + if 'label' in sample: + mask_path = sample['label'] + assert os.path.exists(os.path.join(rel_path, mask_path)) + print('all file path ok!') + + +def process_dataset(file_lists, part_dir_dict): + for ith, part in enumerate(file_lists): + part_dir = part_dir_dict[ith] + for sample in part: + # read image and mask + image_path = sample['image'] + if 'label' in sample: + mask_path = sample['label'] + + basename = os.path.basename(image_path) + targetname = basename.split('.')[0] # from image name + + # check image file + img_save_path = os.path.join(root_path, 'images', part_dir, + targetname + save_img_suffix) + if not os.path.exists(img_save_path): + if not image_path.endswith('.png'): + src = Image.open(image_path) + src.save(img_save_path) + else: + shutil.copy(image_path, img_save_path) + + if mask_path is not None: + mask_save_path = os.path.join(root_path, 'masks', part_dir, + targetname + save_seg_map_suffix) + if not os.path.exists(mask_save_path): + # check mask file + mask = Image.open(mask_path).convert('L') + # convert mask id + mask = convert_maskid(mask) + if not mask_path.endswith('.png'): + mask.save(mask_save_path) + else: + mask.save(mask_save_path) + + # print image num + part_dir_folder = os.path.join(root_path, 'images', part_dir) + print( + f'{part_dir} has {len(os.listdir(part_dir_folder))} images completed!' # noqa + ) + + +if __name__ == '__main__': + + root_path = 'data/' # original file + img_suffix = '.jpg' + seg_map_suffix = '.png' + save_img_suffix = '.png' + save_seg_map_suffix = '.png' + + train_imgs = glob.glob('data/ISIC-2017_Training_Data/*' + img_suffix) + train_masks = glob.glob('data/ISIC-2017_Training_Part1_GroundTruth/*' + + seg_map_suffix) + + val_imgs = glob.glob('data/ISIC-2017_Validation_Data/*' + img_suffix) + val_masks = glob.glob('data/ISIC-2017_Validation_Part1_GroundTruth/*' + + seg_map_suffix) + + test_imgs = glob.glob('data/ISIC-2017_Test_v2_Data/*' + img_suffix) + test_masks = glob.glob('data/ISIC-2017_Test_v2_Part1_GroundTruth/*' + + seg_map_suffix) + + assert len(train_imgs) == len(train_masks) + assert len(val_imgs) == len(val_masks) + assert len(test_imgs) == len(test_masks) + + os.system('mkdir -p ' + root_path + 'images/train/') + os.system('mkdir -p ' + root_path + 'images/val/') + os.system('mkdir -p ' + root_path + 'images/test/') + os.system('mkdir -p ' + root_path + 'masks/train/') + os.system('mkdir -p ' + root_path + 'masks/val/') + os.system('mkdir -p ' + root_path + 'masks/test/') + + part_dir_dict = {0: 'train/', 1: 'val/', 2: 'test/'} + + train_pair_list = reformulate_file(train_imgs, train_masks) + val_pair_list = reformulate_file(val_imgs, val_masks) + test_pair_list = reformulate_file(test_imgs, test_masks) + + check_file_exist(train_pair_list) + check_file_exist(val_pair_list) + check_file_exist(test_pair_list) + + part_dir_dict = {0: 'train/', 1: 'val/', 2: 'test/'} + process_dataset([train_pair_list, val_pair_list, test_pair_list], + part_dir_dict) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/README.md b/projects/medical/2d_image/endoscopy/kvasir_seg/README.md new file mode 100644 index 00000000000..ea597bc4401 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/README.md @@ -0,0 +1,145 @@ +# Kvasir-Sessile Dataset (Kvasir SEG) + +## Description + +This project supports **`Kvasir-Sessile Dataset (Kvasir SEG) `**, which can be downloaded from [here](https://opendatalab.com/Kvasir-Sessile_dataset). + +## Dataset Overview + +The Kvasir-SEG dataset contains polyp images and their corresponding ground truth from the Kvasir Dataset v2. The resolution of the images contained in Kvasir-SEG varies from 332x487 to 1920x1072 pixels. + + + +### Information Statistics + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------------------------- | ----------------- | ------------ | --------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------- | +| [Kvarsir-SEG](https://opendatalab.com/Kvasir-Sessile_dataset) | abdomen | segmentation | endoscopy | 2 | 196/-/- | yes/-/- | 2020 | [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 196 | 92.31 | - | - | - | - | +| polyp | 196 | 7.69 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![kvasir-seg](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/endoscopy_images/kvasir_seg/kvasir_seg_dataset.png?raw=true) + +### Dataset Citation + +``` +@inproceedings{jha2020kvasir, + title={Kvasir-seg: A segmented polyp dataset}, + author={Jha, Debesh and Smedsrud, Pia H and Riegler, Michael A and Halvorsen, P{\aa}l and Lange, Thomas de and Johansen, Dag and Johansen, H{\aa}vard D}, + booktitle={International Conference on Multimedia Modeling}, + pages={451--462}, + year={2020}, + organization={Springer} + } +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `kvasir_seg/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://opendatalab.com/Kvasir-Sessile_dataset) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── endoscopy + │ │ │ │ ├── kvasir_seg + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 156 | 92.28 | 40 | 92.41 | - | - | +| polyp | 156 | 7.72 | 40 | 7.59 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg .configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_kvasir-seg-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_kvasir-seg-512x512.py new file mode 100644 index 00000000000..145d5a7a172 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_kvasir-seg-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './kvasir-seg_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-512x512.py new file mode 100644 index 00000000000..3ea05c51090 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './kvasir-seg_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-512x512.py new file mode 100644 index 00000000000..7e064a716aa --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './kvasir-seg_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-512x512.py new file mode 100644 index 00000000000..0fc1d6e99d7 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './kvasir-seg_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/configs/kvasir-seg_512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/kvasir-seg_512x512.py new file mode 100644 index 00000000000..e8b2467f8cf --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/configs/kvasir-seg_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'KvasirSEGDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/datasets/kvasir-seg_dataset.py b/projects/medical/2d_image/endoscopy/kvasir_seg/datasets/kvasir-seg_dataset.py new file mode 100644 index 00000000000..9d601328eb6 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/datasets/kvasir-seg_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class KvasirSEGDataset(BaseSegDataset): + """KvasirSEGDataset dataset. + + In segmentation map annotation for KvasirSEGDataset, 0 stands for + background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` is + fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False.. + """ + METAINFO = dict(classes=('background', 'polyp')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg/tools/prepare_dataset.py b/projects/medical/2d_image/endoscopy/kvasir_seg/tools/prepare_dataset.py new file mode 100644 index 00000000000..74c43e96351 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg/tools/prepare_dataset.py @@ -0,0 +1,87 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.jpg' +seg_map_suffix = '.jpg' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +tgt_img_dir = os.path.join(root_path, 'images/train/') +tgt_mask_dir = os.path.join(root_path, 'masks/train/') +os.system('mkdir -p ' + tgt_img_dir) +os.system('mkdir -p ' + tgt_mask_dir) + + +def filter_suffix_recursive(src_dir, suffix): + # filter out file names and paths in source directory + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob.glob( + os.path.join(src_dir, '**', '*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +def convert_pics_into_pngs(src_dir, tgt_dir, suffix, convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_img_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + num = len(src_paths) + img = np.array(Image.open(src_path)) + if len(img.shape) == 2: + pil = Image.fromarray(img).convert(convert) + elif len(img.shape) == 3: + pil = Image.fromarray(img) + else: + raise ValueError('Input image not 2D/3D: ', img.shape) + + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +def convert_label_pics_into_pngs(src_dir, + tgt_dir, + suffix, + convert_dict={ + 0: 0, + 255: 1 + }): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_seg_map_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = np.array(Image.open(src_path)) + img = convert_label(img, convert_dict) + Image.fromarray(img).save(tgt_path) + print(f'processed {i+1}/{num}.') + + +if __name__ == '__main__': + + convert_pics_into_pngs( + os.path.join(root_path, 'sessile-main-Kvasir-SEG/images'), + tgt_img_dir, + suffix=img_suffix) + + convert_label_pics_into_pngs( + os.path.join(root_path, 'sessile-main-Kvasir-SEG/masks'), + tgt_mask_dir, + suffix=seg_map_suffix) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/README.md b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/README.md new file mode 100644 index 00000000000..80eb00f51bd --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/README.md @@ -0,0 +1,145 @@ +# Kvasir-SEG Segmented Polyp Dataset from Aliyun (Kvasir SEG Aliyun) + +## Description + +This project supports **`Kvasir-SEG Segmented Polyp Dataset from Aliyun (Kvasir SEG Aliyun) `**, which can be downloaded from [here](https://tianchi.aliyun.com/dataset/84385). + +### Dataset Overview + +Colorectal cancer is the second most common cancer type among women and third most common among men. Polyps are precursors to colorectal cancer and therefore important to detect and remove at an early stage. Polyps are found in nearly half of the individuals at age 50 that undergo a colonoscopy screening, and their frequency increase with age.Polyps are abnormal tissue growth from the mucous membrane, which is lining the inside of the GI tract, and can sometimes be cancerous. Colonoscopy is the gold standard for detection and assessment of these polyps with subsequent biopsy and removal of the polyps. Early disease detection has a huge impact on survival from colorectal cancer. Increasing the detection of polyps has been shown to decrease risk of colorectal cancer. Thus, automatic detection of more polyps at an early stage can play a crucial role in prevention and survival from colorectal cancer. + +The Kvasir-SEG dataset is based on the previous Kvasir dataset, which is the first multi-class dataset for gastrointestinal (GI) tract disease detection and classification. It contains annotated polyp images and their corresponding masks. The pixels depicting polyp tissue, the ROI, are represented by the foreground (white mask), while the background (in black) does not contain positive pixels. These images were collected and verified by experienced gastroenterologists from Vestre Viken Health Trust in Norway. The classes include anatomical landmarks, pathological findings and endoscopic procedures. + +### Information Statistics + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------------------ | ----------------- | ------------ | --------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------- | +| [kvasir-seg](https://tianchi.aliyun.com/dataset/84385) | abdomen | segmentation | endoscopy | 2 | 1000/-/- | yes/-/- | 2020 | [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 1000 | 84.72 | - | - | - | - | +| polyp | 1000 | 15.28 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![kvasir_seg_aliyun](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/endoscopy_images/kvasir_seg_aliyun/kvasir_seg_aliyun_dataset.png?raw=true) + +### Dataset Citation + +``` +@inproceedings{jha2020kvasir, + title={Kvasir-seg: A segmented polyp dataset}, + author={Jha, Debesh and Smedsrud, Pia H and Riegler, Michael A and Halvorsen, P{\aa}l and Lange, Thomas de and Johansen, Dag and Johansen, H{\aa}vard D}, + booktitle={International Conference on Multimedia Modeling}, + pages={451--462}, + year={2020}, + organization={Springer} + } +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `kvasir_seg_aliyun/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://tianchi.aliyun.com/dataset/84385) and decompression data to path 'data/.'. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── endoscopy + │ │ │ │ ├── kvasir_seg_aliyun + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 800 | 84.66 | 200 | 84.94 | - | - | +| polyp | 800 | 15.34 | 200 | 15.06 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-aliyun-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-aliyun-512x512.py new file mode 100644 index 00000000000..b59db95232b --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_kvasir-seg-aliyun-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './kvasir-seg-aliyun_512x512.py', 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg-aliyun_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-aliyun-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-aliyun-512x512.py new file mode 100644 index 00000000000..6c526680cd4 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_kvasir-seg-aliyun-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './kvasir-seg-aliyun_512x512.py', 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg-aliyun_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-aliyun-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-aliyun-512x512.py new file mode 100644 index 00000000000..a192a5bd240 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_kvasir-seg-aliyun-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './kvasir-seg-aliyun_512x512.py', 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg-aliyun_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_kvasir-seg-aliyun-512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_kvasir-seg-aliyun-512x512.py new file mode 100644 index 00000000000..5325e1f0807 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_kvasir-seg-aliyun-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './kvasir-seg-aliyun_512x512.py', 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.kvasir-seg-aliyun_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/kvasir-seg-aliyun_512x512.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/kvasir-seg-aliyun_512x512.py new file mode 100644 index 00000000000..5f868804679 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/configs/kvasir-seg-aliyun_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'KvasirSEGAliyunDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/datasets/kvasir-seg-aliyun_dataset.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/datasets/kvasir-seg-aliyun_dataset.py new file mode 100644 index 00000000000..198caf07bcd --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/datasets/kvasir-seg-aliyun_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class KvasirSEGAliyunDataset(BaseSegDataset): + """KvasirSEGAliyunDataset dataset. + + In segmentation map annotation for KvasirSEGAliyunDataset, + 0 stands for background,which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False.. + """ + METAINFO = dict(classes=('background', 'polyp')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/tools/prepare_dataset.py b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/tools/prepare_dataset.py new file mode 100644 index 00000000000..b230e7fef58 --- /dev/null +++ b/projects/medical/2d_image/endoscopy/kvasir_seg_aliyun/tools/prepare_dataset.py @@ -0,0 +1,86 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.jpg' +seg_map_suffix = '.jpg' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +tgt_img_dir = os.path.join(root_path, 'images/train/') +tgt_mask_dir = os.path.join(root_path, 'masks/train/') +os.system('mkdir -p ' + tgt_img_dir) +os.system('mkdir -p ' + tgt_mask_dir) + + +def filter_suffix_recursive(src_dir, suffix): + # filter out file names and paths in source directory + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob.glob( + os.path.join(src_dir, '**', '*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +def convert_pics_into_pngs(src_dir, tgt_dir, suffix, convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_img_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + num = len(src_paths) + img = np.array(Image.open(src_path)) + if len(img.shape) == 2: + pil = Image.fromarray(img).convert(convert) + elif len(img.shape) == 3: + pil = Image.fromarray(img) + else: + raise ValueError('Input image not 2D/3D: ', img.shape) + + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +def convert_label_pics_into_pngs(src_dir, + tgt_dir, + suffix, + convert_dict={ + 0: 0, + 255: 1 + }): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_seg_map_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = np.array(Image.open(src_path).convert('L')) + img = convert_label(img, convert_dict) + Image.fromarray(img).save(tgt_path) + print(f'processed {i+1}/{num}.') + + +if __name__ == '__main__': + convert_pics_into_pngs( + os.path.join(root_path, 'Kvasir-SEG/images'), + tgt_img_dir, + suffix=img_suffix) + + convert_label_pics_into_pngs( + os.path.join(root_path, 'Kvasir-SEG/masks'), + tgt_mask_dir, + suffix=seg_map_suffix) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/README.md b/projects/medical/2d_image/fluorescein_angriogram/vampire/README.md new file mode 100644 index 00000000000..c2c61c46a0b --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/README.md @@ -0,0 +1,158 @@ +# Vessel Assessment and Measurement Platform for Images of the REtina + +## Description + +This project support **`Vessel Assessment and Measurement Platform for Images of the REtina`**, and the dataset used in this project can be downloaded from [here](https://vampire.computing.dundee.ac.uk/vesselseg.html). + +### Dataset Overview + +In order to promote evaluation of vessel segmentation on ultra-wide field-of-view (UWFV) fluorescein angriogram (FA) frames, we make public 8 frames from two different sequences, the manually annotated images and the result of our automatic vessel segmentation algorithm. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ---------------------------------------------------------------- | ----------------- | ------------ | ---------------------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Vampire](https://vampire.computing.dundee.ac.uk/vesselseg.html) | vessel | segmentation | fluorescein angriogram | 2 | 8/-/- | yes/-/- | 2017 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 8 | 96.75 | - | - | - | - | +| vessel | 8 | 3.25 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/fluorescein_angriogram/vampire/vampire_dataset.png) + +## Dataset Citation + +```bibtex + +@inproceedings{perez2011improving, + title={Improving vessel segmentation in ultra-wide field-of-view retinal fluorescein angiograms}, + author={Perez-Rovira, Adria and Zutis, K and Hubschman, Jean Pierre and Trucco, Emanuele}, + booktitle={2011 Annual International Conference of the IEEE Engineering in Medicine and Biology Society}, + pages={2614--2617}, + year={2011}, + organization={IEEE} +} + +@article{perez2011rerbee, + title={RERBEE: robust efficient registration via bifurcations and elongated elements applied to retinal fluorescein angiogram sequences}, + author={Perez-Rovira, Adria and Cabido, Raul and Trucco, Emanuele and McKenna, Stephen J and Hubschman, Jean Pierre}, + journal={IEEE Transactions on Medical Imaging}, + volume={31}, + number={1}, + pages={140--150}, + year={2011}, + publisher={IEEE} +} + +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `vampire/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://vampire.computing.dundee.ac.uk/vesselseg.html) and decompression data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to split dataset and change folder structure as below. +- run script `python ../../tools/split_seg_dataset.py` to split dataset. For the Bacteria_detection dataset, as there is no test or validation dataset, we sample 20% samples from the whole dataset as the validation dataset and 80% samples for training data and make two filename lists `train.txt` and `val.txt`. As we set the random seed as the hard code, we eliminated the randomness, the dataset split actually can be reproducible. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── fluorescein_angriogram + │ │ │ │ ├── vampire + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 6 | 97.48 | 2 | 94.54 | - | - | +| vessel | 6 | 2.52 | 2 | 5.46 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [ ] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_vampire-512x512.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_vampire-512x512.py new file mode 100755 index 00000000000..7f5273aaff9 --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_vampire-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './vampire_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.vampire_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + pretrained=None, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_vampire-512x512.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_vampire-512x512.py new file mode 100755 index 00000000000..4382229989b --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_vampire-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './vampire_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.vampire_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=dict(size=img_scale), + pretrained=None, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_vampire-512x512.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_vampire-512x512.py new file mode 100755 index 00000000000..8d93e17627f --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_vampire-512x512.py @@ -0,0 +1,22 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './vampire_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.vampire_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + pretrained=None, + decode_head=dict( + num_classes=2, + loss_decode=dict(type='CrossEntropyLoss', use_sigmoid=True), + out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/vampire_512x512.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/vampire_512x512.py new file mode 100755 index 00000000000..4eda92f9f22 --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/configs/vampire_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'VampireDataset' +data_root = 'data' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/__init__.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/__init__.py new file mode 100755 index 00000000000..93f9cbf0506 --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/__init__.py @@ -0,0 +1,3 @@ +from .vampire_dataset import VampireDataset + +__all__ = ['VampireDataset'] diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/vampire_dataset.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/vampire_dataset.py new file mode 100755 index 00000000000..4d38040f7f1 --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/datasets/vampire_dataset.py @@ -0,0 +1,28 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class VampireDataset(BaseSegDataset): + """VampireDataset dataset. + + In segmentation map annotation for VampireDataset, 0 stands for background, + which is included in 2 categories. ``reduce_zero_label`` is fixed to + False. The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is + fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('background', 'vessel')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/fluorescein_angriogram/vampire/tools/prepare_dataset.py b/projects/medical/2d_image/fluorescein_angriogram/vampire/tools/prepare_dataset.py new file mode 100644 index 00000000000..2755b5d28bd --- /dev/null +++ b/projects/medical/2d_image/fluorescein_angriogram/vampire/tools/prepare_dataset.py @@ -0,0 +1,44 @@ +import os +import shutil + +from PIL import Image + +path = 'data' + +if not os.path.exists(os.path.join(path, 'images', 'train')): + os.system(f'mkdir -p {os.path.join(path, "images", "train")}') + +if not os.path.exists(os.path.join(path, 'masks', 'train')): + os.system(f'mkdir -p {os.path.join(path, "masks", "train")}') + +origin_data_path = os.path.join(path, 'vesselSegmentation') + +imgs_amd14 = os.listdir(os.path.join(origin_data_path, 'AMD14')) +imgs_ger7 = os.listdir(os.path.join(origin_data_path, 'GER7')) + +for img in imgs_amd14: + shutil.copy( + os.path.join(origin_data_path, 'AMD14', img), + os.path.join(path, 'images', 'train', img)) + # copy GT + img_gt = img.replace('.png', '-GT.png') + shutil.copy( + os.path.join(origin_data_path, 'AMD14-GT', f'{img_gt}'), + os.path.join(path, 'masks', 'train', img)) + +for img in imgs_ger7: + shutil.copy( + os.path.join(origin_data_path, 'GER7', img), + os.path.join(path, 'images', 'train', img)) + # copy GT + img_gt = img.replace('.bmp', '-GT.png') + img = img.replace('bmp', 'png') + shutil.copy( + os.path.join(origin_data_path, 'GER7-GT', img_gt), + os.path.join(path, 'masks', 'train', img)) + +imgs = os.listdir(os.path.join(path, 'images', 'train')) +for img in imgs: + if not img.endswith('.png'): + im = Image.open(os.path.join(path, 'images', 'train', img)) + im.save(os.path.join(path, 'images', 'train', img[:-4] + '.png')) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/README.md b/projects/medical/2d_image/fundus_photography/dr_hagis/README.md new file mode 100644 index 00000000000..85d8a3e271c --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/README.md @@ -0,0 +1,155 @@ +# DR HAGIS: Diabetic Retinopathy, Hypertension, Age-related macular degeneration and Glacuoma ImageS + +## Description + +This project supports **`DR HAGIS: Diabetic Retinopathy, Hypertension, Age-related macular degeneration and Glacuoma ImageS`**, which can be downloaded from [here](https://paperswithcode.com/dataset/dr-hagis). + +### Dataset Overview + +The DR HAGIS database has been created to aid the development of vessel extraction algorithms suitable for retinal screening programmes. Researchers are encouraged to test their segmentation algorithms using this database. All thirty-nine fundus images were obtained from a diabetic retinopathy screening programme in the UK. Hence, all images were taken from diabetic patients. + +Besides the fundus images, the manual segmentation of the retinal surface vessels is provided by an expert grader. These manually segmented images can be used as the ground truth to compare and assess the automatic vessel extraction algorithms. Masks of the FOV are provided as well to quantify the accuracy of vessel extraction within the FOV only. The images were acquired in different screening centers, therefore reflecting the range of image resolutions, digital cameras and fundus cameras used in the clinic. The fundus images were captured using a Topcon TRC-NW6s, Topcon TRC-NW8 or a Canon CR DGi fundus camera with a horizontal 45 degree field-of-view (FOV). The images are 4752x3168 pixels, 3456x2304 pixels, 3126x2136 pixels, 2896x1944 pixels or 2816x1880 pixels in size. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------------------- | ----------------- | ------------ | ------------------ | ------------ | --------------------- | ---------------------- | ------------ | ------- | +| [DR HAGIS](https://paperswithcode.com/dataset/dr-hagis) | head and neck | segmentation | fundus photography | 2 | 40/-/- | yes/-/- | 2017 | - | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 40 | 96.38 | - | - | - | - | +| vessel | 40 | 3.62 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/fundus_photography/dr_hagis/dr_hagis_dataset.png) + +## Usage + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `dr_hagis/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://paperswithcode.com/dataset/dr-hagis) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── fundus_photography + │ │ │ │ ├── dr_hagis + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 32 | 96.21 | 8 | 97.12 | - | - | +| vessel | 32 | 3.79 | 8 | 2.88 | - | - | + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Dataset Citation + +If this work is helpful for your research, please consider citing the below paper. + +``` +@article{holm2017dr, + title={DR HAGIS—a fundus image database for the automatic extraction of retinal surface vessels from diabetic patients}, + author={Holm, Sven and Russell, Greg and Nourrit, Vincent and McLoughlin, Niall}, + journal={Journal of Medical Imaging}, + volume={4}, + number={1}, + pages={014503--014503}, + year={2017}, + publisher={Society of Photo-Optical Instrumentation Engineers} +} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [ ] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/configs/dr-hagis_512x512.py b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/dr-hagis_512x512.py new file mode 100644 index 00000000000..93b96384109 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/dr-hagis_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'DRHAGISDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_dr-hagis-512x512.py b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_dr-hagis-512x512.py new file mode 100644 index 00000000000..9d14427c45f --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_dr-hagis-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './dr-hagis_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.dr-hagis_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py new file mode 100644 index 00000000000..507ec748bf5 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_dr-hagis-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './dr-hagis_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.dr-hagis_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_dr-hagis-512x512.py b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_dr-hagis-512x512.py new file mode 100644 index 00000000000..092ae00a7d3 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_dr-hagis-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './dr-hagis_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.dr-hagis_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/datasets/dr-hagis_dataset.py b/projects/medical/2d_image/fundus_photography/dr_hagis/datasets/dr-hagis_dataset.py new file mode 100644 index 00000000000..9659f0b8d77 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/datasets/dr-hagis_dataset.py @@ -0,0 +1,27 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class DRHAGISDataset(BaseSegDataset): + """DRHAGISDataset dataset. + + In segmentation map annotation for DRHAGISDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('background', 'vessel')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/fundus_photography/dr_hagis/tools/prepare_dataset.py b/projects/medical/2d_image/fundus_photography/dr_hagis/tools/prepare_dataset.py new file mode 100755 index 00000000000..51f4df7dac2 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/dr_hagis/tools/prepare_dataset.py @@ -0,0 +1,41 @@ +import glob +import os +import shutil + +import mmengine +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.jpg' +seg_map_suffix = '_manual_orig.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = glob.glob(os.path.join('data/DRHAGIS/**/*' + img_suffix)) + +mmengine.mkdir_or_exist(root_path + 'images/train/') +mmengine.mkdir_or_exist(root_path + 'masks/train/') + +D3_palette = {0: (0, 0, 0), 1: (1, 1, 1)} +D3_invert_palette = {v: k for k, v in D3_palette.items()} +D2_255_convert_dict = {0: 0, 255: 1} + +part_dir_dict = {0: 'train/', 1: 'val/'} +for ith, part in enumerate([x_train]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + shutil.copy( + img, root_path + 'images/' + part_dir + basename.split('.')[0] + + save_img_suffix) + mask_path = root_path + 'DRHAGIS/Manual_Segmentations/' + basename.split( # noqa + '.')[0] + seg_map_suffix + label = np.array(Image.open(mask_path)) + + save_mask_path = root_path + 'masks/' + part_dir + basename.split( + '.')[0] + save_seg_map_suffix # noqa + mask = np.array(Image.open(mask_path)).astype(np.uint8) + mask[mask == 255] = 1 + mask = Image.fromarray(mask) + mask.save(save_mask_path) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/README.md b/projects/medical/2d_image/fundus_photography/gamma3/README.md new file mode 100644 index 00000000000..e834508fcb5 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/README.md @@ -0,0 +1,167 @@ +# Glaucoma grAding from Multi-Modality imAges Task3 + +## Description + +This project support **`Glaucoma grAding from Multi-Modality imAges Task3`**, and the dataset used in this project can be downloaded from [here](https://aistudio.baidu.com/aistudio/competition/detail/121/0/datasets). + +### Dataset Overview + +This regular-challenge dataset was provided by Sun Yat-sen Ophthalmic Center, Sun Yat-sen University, Guangzhou, China. The dataset contains 200 fundus color images: 100 pairs in the training set and 100 pairs in the test set. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ----------------------------------------------------------------------------------- | ----------------- | ------------ | --------------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [GammaTask3](https://aistudio.baidu.com/aistudio/competition/detail/121/0/datasets) | eye | segmentation | fundus photophy | 3 | 100/-/100 | yes/-/- | 2021 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 100 | 99.02 | - | - | - | - | +| optic disc | 100 | 0.67 | - | - | - | - | +| optic cup | 100 | 0.31 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/fundus_photography/gamma3/gamma3_dataset.png) + +## Dataset Citation + +```bibtex +@article{fu2018joint, + title={Joint optic disc and cup segmentation based on multi-label deep network and polar transformation}, + author={Fu, Huazhu and Cheng, Jun and Xu, Yanwu and Wong, Damon Wing Kee and Liu, Jiang and Cao, Xiaochun}, + journal={IEEE transactions on medical imaging}, + volume={37}, + number={7}, + pages={1597--1605}, + year={2018}, + publisher={IEEE} +} + +@article{sevastopolsky2017optic, + title={Optic disc and cup segmentation methods for glaucoma detection with modification of U-Net convolutional neural network}, + author={Sevastopolsky, Artem}, + journal={Pattern Recognition and Image Analysis}, + volume={27}, + pages={618--624}, + year={2017}, + publisher={Springer} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `gammm3/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://aistudio.baidu.com/aistudio/competition/detail/121/0/datasets) and decompression data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to split dataset and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── fundus_photography + │ │ │ │ ├── gamma3 + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── yyy.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 80 | 99.01 | 20 | 99.07 | - | - | +| optic disc | 80 | 0.68 | 20 | 0.63 | - | - | +| optic cup | 80 | 0.32 | 20 | 0.31 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [ ] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_gamma3-512x512.py b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_gamma3-512x512.py new file mode 100644 index 00000000000..0daac51e10f --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_gamma3-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './gamma3_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.gamma3_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py new file mode 100644 index 00000000000..8a25cd0d266 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_gamma3-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './gamma3_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.gamma3_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_gamma3-512x512.py b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_gamma3-512x512.py new file mode 100644 index 00000000000..ea648438672 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_gamma3-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './gamma3_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.gamma3_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/configs/gamma3_512x512.py b/projects/medical/2d_image/fundus_photography/gamma3/configs/gamma3_512x512.py new file mode 100644 index 00000000000..d23ab55ca71 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/configs/gamma3_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'Gamma3Dataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/datasets/gamma3_dataset.py b/projects/medical/2d_image/fundus_photography/gamma3/datasets/gamma3_dataset.py new file mode 100644 index 00000000000..56cbdd63e61 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/datasets/gamma3_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class Gamma3Dataset(BaseSegDataset): + """Gamma3Dataset dataset. + + In segmentation map annotation for Gamma3Dataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'disc', 'cup')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/fundus_photography/gamma3/tools/prepare_dataset.py b/projects/medical/2d_image/fundus_photography/gamma3/tools/prepare_dataset.py new file mode 100644 index 00000000000..eb820b6b740 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/gamma3/tools/prepare_dataset.py @@ -0,0 +1,107 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.jpg' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_img_test_dir) + + +def filter_suffix_recursive(src_dir, suffix): + # filter out file names and paths in source directory + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob.glob( + os.path.join(src_dir, '**/*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +def convert_pics_into_pngs(src_dir, tgt_dir, suffix, convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_img_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + num = len(src_paths) + img = np.array(Image.open(src_path)) + if len(img.shape) == 2: + pil = Image.fromarray(img).convert(convert) + elif len(img.shape) == 3: + pil = Image.fromarray(img) + else: + raise ValueError('Input image not 2D/3D: ', img.shape) + + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +def convert_label_pics_into_pngs(src_dir, + tgt_dir, + suffix, + convert_dict={ + 0: 2, + 128: 1, + 255: 0 + }): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_seg_map_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = np.array(Image.open(src_path)) + img = convert_label(img, convert_dict) + Image.fromarray(img).save(tgt_path) + print(f'processed {i+1}/{num}.') + + +if __name__ == '__main__': + + convert_pics_into_pngs( + os.path.join( + root_path, + 'task3_disc_cup_segmentation/training/fundus color images/'), + tgt_img_train_dir, + suffix=img_suffix) + + convert_pics_into_pngs( + os.path.join( + root_path, + 'task3_disc_cup_segmentation/testing/fundus color images/'), + tgt_img_test_dir, + suffix=img_suffix) + + convert_label_pics_into_pngs( + os.path.join(root_path, + 'task3_disc_cup_segmentation/training/Disc_Cup_Mask/'), + tgt_mask_train_dir, + suffix=seg_map_suffix, + convert_dict={ + 0: 2, + 128: 1, + 255: 0 + }) + # original: [0, 128, 255] for ['optic cup', 'optic disc', 'background'] + # converted: [0, 1, 2] for ['background', 'optic disc', 'optic cup'] diff --git a/projects/medical/2d_image/fundus_photography/orvs/README.md b/projects/medical/2d_image/fundus_photography/orvs/README.md new file mode 100644 index 00000000000..6f09203ac4d --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/README.md @@ -0,0 +1,140 @@ +# ORVS (Online Retinal image for Vessel Segmentation (ORVS)) + +## Description + +This project supports **`ORVS (Online Retinal image for Vessel Segmentation (ORVS))`**, which can be downloaded from [here](https://opendatalab.org.cn/ORVS). + +### Dataset Overview + +The ORVS dataset is a newly established collaboration between the Department of Computer Science and the Department of Vision Science at the University of Calgary. The dataset contains 49 images collected from a clinic in Calgary, Canada, consisting of 42 training images and 7 testing images. All images were obtained using a Zeiss Visucam 200 with a 30-degree field of view (FOV). The image size is 1444×1444 pixels with 24 bits per pixel. The images are stored in JPEG format with low compression, which is common in ophthalmic practice. All images were manually traced by an expert who has been working in the field of retinal image analysis and has been trained to mark all pixels belonging to retinal vessels. The Windows Paint 3D tool was used for manual image annotation. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------------------ | ----------------- | ------------ | ------------------ | ------------ | --------------------- | ---------------------- | ------------ | ------- | +| [Bactteria detection](https://opendatalab.org.cn/ORVS) | bacteria | segmentation | fundus photography | 2 | 130/-/72 | yes/-/yes | 2020 | - | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 130 | 94.83 | - | - | 72 | 94.25 | +| vessel | 130 | 5.17 | - | - | 72 | 5.75 | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/fundus_photography/orvs/ORVS_dataset.png) + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `orvs/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- Clone this [repository](https://github.com/AbdullahSarhan/ICPRVessels), then move `Vessels-Datasets` to `data/`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── fundus_photography + │ │ │ │ ├── orvs + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── test.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Dataset Citation + +If this work is helpful for your research, please consider citing the below paper. + +``` +@inproceedings{sarhan2021transfer, + title={Transfer learning through weighted loss function and group normalization for vessel segmentation from retinal images}, + author={Sarhan, Abdullah and Rokne, Jon and Alhajj, Reda and Crichton, Andrew}, + booktitle={2020 25th International Conference on Pattern Recognition (ICPR)}, + pages={9211--9218}, + year={2021}, + organization={IEEE} +} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [ ] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_orvs-512x512.py b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_orvs-512x512.py new file mode 100644 index 00000000000..662f837158a --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_orvs-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './orvs_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.orvs_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_orvs-512x512.py b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_orvs-512x512.py new file mode 100644 index 00000000000..c47cdb6b24d --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_orvs-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './orvs_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.orvs_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_orvs-512x512.py b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_orvs-512x512.py new file mode 100644 index 00000000000..1097aade286 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_orvs-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './orvs_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.orvs_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/orvs/configs/orvs_512x512.py b/projects/medical/2d_image/fundus_photography/orvs/configs/orvs_512x512.py new file mode 100644 index 00000000000..a5594dec388 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/configs/orvs_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'ORVSDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='test.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/fundus_photography/orvs/datasets/orvs_dataset.py b/projects/medical/2d_image/fundus_photography/orvs/datasets/orvs_dataset.py new file mode 100644 index 00000000000..e915ae4cd2b --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/datasets/orvs_dataset.py @@ -0,0 +1,27 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ORVSDataset(BaseSegDataset): + """ORVSDataset dataset. + + In segmentation map annotation for ORVSDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('background', 'vessel')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/fundus_photography/orvs/tools/prepare_dataset.py b/projects/medical/2d_image/fundus_photography/orvs/tools/prepare_dataset.py new file mode 100755 index 00000000000..f902d871010 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/orvs/tools/prepare_dataset.py @@ -0,0 +1,55 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.jpg' +seg_map_suffix_list = ['.jpg', '.png', '.tif'] +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = glob.glob( + os.path.join('data/Vessels-Datasets/*/Train/Original/Images/*' + + img_suffix)) +x_test = glob.glob( + os.path.join('data/Vessels-Datasets/*/Test/Original/Images/*' + + img_suffix)) + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'images/test/') +os.system('mkdir -p ' + root_path + 'masks/train/') +os.system('mkdir -p ' + root_path + 'masks/test/') + +part_dir_dict = {0: 'train/', 1: 'test/'} +for ith, part in enumerate([x_train, x_test]): + part_dir = part_dir_dict[ith] + for img in part: + type_name = img.split('/')[-5] + basename = type_name + '_' + os.path.basename(img) + save_img_path = root_path + 'images/' + part_dir + basename.split( + '.')[0] + save_img_suffix + Image.open(img).save(save_img_path) + + for seg_map_suffix in seg_map_suffix_list: + if os.path.exists('/'.join(img.split('/')[:-1]).replace( + 'Images', 'Labels')): + mask_path = img.replace('Images', 'Labels').replace( + img_suffix, seg_map_suffix) + else: + mask_path = img.replace('Images', 'labels').replace( + img_suffix, seg_map_suffix) + if os.path.exists(mask_path): + break + save_mask_path = root_path + 'masks/' + part_dir + basename.split( + '.')[0] + save_seg_map_suffix + masks = np.array(Image.open(mask_path).convert('L')).astype(np.uint8) + if len(np.unique(masks)) == 2 and 1 in np.unique(masks): + print(np.unique(masks)) + pass + else: + masks[masks < 128] = 0 + masks[masks >= 128] = 1 + masks = Image.fromarray(masks) + masks.save(save_mask_path) diff --git a/projects/medical/2d_image/fundus_photography/rite/README.md b/projects/medical/2d_image/fundus_photography/rite/README.md new file mode 100644 index 00000000000..0aea9b00d17 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/README.md @@ -0,0 +1,135 @@ +# Retinal Images vessel Tree Extraction (RITE) + +## Description + +This project supports **`Retinal Images vessel Tree Extraction (RITE) `**, which can be downloaded from [here](https://opendatalab.com/RITE). + +### Dataset Overview + +The RITE (Retinal Images vessel Tree Extraction) is a database that enables comparative studies on segmentation or classification of arteries and veins on retinal fundus images, which is established based on the public available DRIVE database (Digital Retinal Images for Vessel Extraction). RITE contains 40 sets of images, equally separated into a training subset and a test subset, the same as DRIVE. The two subsets are built from the corresponding two subsets in DRIVE. For each set, there is a fundus photograph, a vessel reference standard. The fundus photograph is inherited from DRIVE. For the training set, the vessel reference standard is a modified version of 1st_manual from DRIVE. For the test set, the vessel reference standard is 2nd_manual from DRIVE. + +### Statistic Information + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------ | ----------------- | ------------ | ------------------ | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Rite](https://opendatalab.com/RITE) | head_and_neck | segmentation | fundus_photography | 2 | 20/-/20 | yes/-/yes | 2013 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 20 | 91.61 | - | - | 20 | 91.58 | +| vessel | 20 | 8.39 | - | - | 20 | 8.42 | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![rite](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/fundus_photography/rite/rite_dataset.png?raw=true) + +### Dataset Citation + +``` +@InProceedings{10.1007/978-3-642-40763-5_54, + author={Hu, Qiao and Abr{\`a}moff, Michael D. and Garvin, Mona K.}, + title={Automated Separation of Binary Overlapping Trees in Low-Contrast Color Retinal Images}, + booktitle={Medical Image Computing and Computer-Assisted Intervention -- MICCAI 2013}, + year={2013}, + pages={436--443}, +} + + +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 9.3.0 +- scikit-learn(sklearn) v1.2.0 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `rite/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://opendatalab.com/RITE) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── fundus_photography + │ │ │ │ ├── rite + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_rite-512x512.py b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_rite-512x512.py new file mode 100644 index 00000000000..27dd4363b16 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_rite-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './rite_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.rite_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_rite-512x512.py b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_rite-512x512.py new file mode 100644 index 00000000000..48f6f973a1a --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_rite-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './rite_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.rite_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_rite-512x512.py b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_rite-512x512.py new file mode 100644 index 00000000000..5f5b24ba6a4 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_rite-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './rite_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.rite_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_rite-512x512.py b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_rite-512x512.py new file mode 100644 index 00000000000..bf66b6f320c --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_rite-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './rite_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.rite_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/fundus_photography/rite/configs/rite_512x512.py b/projects/medical/2d_image/fundus_photography/rite/configs/rite_512x512.py new file mode 100644 index 00000000000..02f620c665f --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/configs/rite_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'RITEDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='test.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/fundus_photography/rite/datasets/rite_dataset.py b/projects/medical/2d_image/fundus_photography/rite/datasets/rite_dataset.py new file mode 100644 index 00000000000..99f688de949 --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/datasets/rite_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class RITEDataset(BaseSegDataset): + """RITEDataset dataset. + + In segmentation map annotation for RITEDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'vessel')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/fundus_photography/rite/tools/prepare_dataset.py b/projects/medical/2d_image/fundus_photography/rite/tools/prepare_dataset.py new file mode 100644 index 00000000000..ca7e996961f --- /dev/null +++ b/projects/medical/2d_image/fundus_photography/rite/tools/prepare_dataset.py @@ -0,0 +1,98 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.tif' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +src_img_train_dir = os.path.join(root_path, 'AV_groundTruth/training/images/') +src_img_test_dir = os.path.join(root_path, 'AV_groundTruth/test/images/') +src_mask_train_dir = os.path.join(root_path, 'AV_groundTruth/training/vessel/') +src_mask_test_dir = os.path.join(root_path, 'AV_groundTruth/test/vessel/') + +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') +tgt_mask_test_dir = os.path.join(root_path, 'masks/test/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_img_test_dir) +os.system('mkdir -p ' + tgt_mask_test_dir) + + +def filter_suffix_recursive(src_dir, suffix): + # filter out file names and paths in source directory + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob.glob( + os.path.join(src_dir, '**', '*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +def convert_pics_into_pngs(src_dir, tgt_dir, suffix, convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_img_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + num = len(src_paths) + img = np.array(Image.open(src_path)) + if len(img.shape) == 2: + pil = Image.fromarray(img).convert(convert) + elif len(img.shape) == 3: + pil = Image.fromarray(img) + else: + raise ValueError('Input image not 2D/3D: ', img.shape) + + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +def convert_label_pics_into_pngs(src_dir, + tgt_dir, + suffix, + convert_dict={ + 0: 0, + 255: 1 + }): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_seg_map_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = np.array(Image.open(src_path)) + img = convert_label(img, convert_dict) + Image.fromarray(img).save(tgt_path) + print(f'processed {i+1}/{num}.') + + +if __name__ == '__main__': + + convert_pics_into_pngs( + src_img_train_dir, tgt_img_train_dir, suffix=img_suffix) + + convert_pics_into_pngs( + src_img_test_dir, tgt_img_test_dir, suffix=img_suffix) + + convert_label_pics_into_pngs( + src_mask_train_dir, tgt_mask_train_dir, suffix=seg_map_suffix) + + convert_label_pics_into_pngs( + src_mask_test_dir, tgt_mask_test_dir, suffix=seg_map_suffix) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/README.md b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/README.md new file mode 100644 index 00000000000..97c4a0f0e55 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/README.md @@ -0,0 +1,123 @@ +# breastCancerCellSegmentation + +## Description + +This project supports **`breastCancerCellSegmentation`**, which can be downloaded from [here](https://www.heywhale.com/mw/dataset/5e9e9b35ebb37f002c625423). + +### Dataset Overview + +This dataset, with 58 H&E-stained histopathology images was used for breast cancer cell detection and associated real-world data. +Conventional histology uses a combination of hematoxylin and eosin stains, commonly referred to as H&E. These images are stained because most cells are inherently transparent with little or no intrinsic pigment. +Certain special stains selectively bind to specific components and can be used to identify biological structures such as cells. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| -------------------------------------------------------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [breastCancerCellSegmentation](https://www.heywhale.com/mw/dataset/5e9e9b35ebb37f002c625423) | cell | segmentation | histopathology | 2 | 58/-/- | yes/-/- | 2020 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 58 | 98.37 | - | - | - | - | +| breastCancerCell | 58 | 1.63 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/breastCancerCellSegmentation/breastCancerCellSegmentation_dataset.png) + +## Usage + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow (PIL) v9.3.0 +- scikit-learn (sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `breastCancerCellSegmentation/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- Download dataset from [here](https://www.heywhale.com/mw/dataset/5e9e9b35ebb37f002c625423) and save it to the `data/` directory . +- Decompress data to path `data/`. This will create a new folder named `data/breastCancerCellSegmentation/`, which contains the original image data. +- run script `python tools/prepare_dataset.py` to format data and change folder structure as below. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── breastCancerCellSegmentation + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── breastCancerCellSegmentation + | │ │ │ │ │ │ ├── train.txt + | │ │ │ │ │ │ ├── val.txt + | │ │ │ │ │ │ ├── images + | │ │ │ │ │ │ | ├── xxx.tif + | │ │ │ │ │ │ ├── masks + | │ │ │ │ │ │ | ├── xxx.TIF + +``` + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/breastCancerCellSegmentation_512x512.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/breastCancerCellSegmentation_512x512.py new file mode 100644 index 00000000000..1cf0fccf5be --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/breastCancerCellSegmentation_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'breastCancerCellSegmentationDataset' +data_root = 'data/breastCancerCellSegmentation' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile', imdecode_backend='tifffile'), + dict(type='LoadAnnotations', imdecode_backend='tifffile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile', imdecode_backend='tifffile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations', imdecode_backend='tifffile'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images', seg_map_path='masks'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images', seg_map_path='masks'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breastCancerCellSegmentation-512x512.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breastCancerCellSegmentation-512x512.py new file mode 100644 index 00000000000..55d17089686 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breastCancerCellSegmentation-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './breastCancerCellSegmentation_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breastCancerCellSegmentation_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breastCancerCellSegmentation-512x512.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breastCancerCellSegmentation-512x512.py new file mode 100644 index 00000000000..cf28aad739f --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breastCancerCellSegmentation-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './breastCancerCellSegmentation_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breastCancerCellSegmentation_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breastCancerCellSegmentation-512x512.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breastCancerCellSegmentation-512x512.py new file mode 100644 index 00000000000..29aaff38941 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breastCancerCellSegmentation-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './breastCancerCellSegmentation_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breastCancerCellSegmentation_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/datasets/breastCancerCellSegmentation_dataset.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/datasets/breastCancerCellSegmentation_dataset.py new file mode 100644 index 00000000000..eeceb6318c0 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/datasets/breastCancerCellSegmentation_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class breastCancerCellSegmentationDataset(BaseSegDataset): + """breastCancerCellSegmentationDataset dataset. + + In segmentation map annotation for breastCancerCellSegmentationDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'breastCancerCell')) + + def __init__(self, + img_suffix='_ccd.tif', + seg_map_suffix='.TIF', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/tools/prepare_dataset.py new file mode 100644 index 00000000000..09cc689c862 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breastCancerCellSegmentation/tools/prepare_dataset.py @@ -0,0 +1,36 @@ +import argparse +import glob +import os + +from sklearn.model_selection import train_test_split + + +def save_anno(img_list, file_path, suffix): + # 只保留文件名,不保留后缀 + img_list = [x.split('/')[-1][:-len(suffix)] for x in img_list] + + with open(file_path, 'w') as file_: + for x in list(img_list): + file_.write(x + '\n') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument( + '--data_root', default='data/breastCancerCellSegmentation/') + args = parser.parse_args() + data_root = args.data_root + + # 1. 划分训练集、验证集 + # 1.1 获取所有图片路径 + img_list = glob.glob(os.path.join(data_root, 'images', '*.tif')) + img_list.sort() + mask_list = glob.glob(os.path.join(data_root, 'masks', '*.TIF')) + mask_list.sort() + assert len(img_list) == len(mask_list) + # 1.2 划分训练集、验证集、测试集 + train_img_list, val_img_list, train_mask_list, val_mask_list = train_test_split( # noqa + img_list, mask_list, test_size=0.2, random_state=42) + # 1.3 保存划分结果 + save_anno(train_img_list, os.path.join(data_root, 'train.txt'), '_ccd.tif') + save_anno(val_img_list, os.path.join(data_root, 'val.txt'), '_ccd.tif') diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/README.md b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/README.md new file mode 100644 index 00000000000..b6f1ca63419 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/README.md @@ -0,0 +1,147 @@ +# Breast Cancer Cell Segmentation + +## Description + +This project support **`Breast Cancer Cell Segmentation`**, and the dataset used in this project can be downloaded from [here](https://tianchi.aliyun.com/dataset/dataDetail?dataId=90152). + +### Dataset Overview + +In this dataset, there are 58 H&E stained histopathology images used in breast cancer cell detection with associated ground truth data available. Routine histology uses the stain combination of hematoxylin and eosin, commonly referred to as H&E. These images are stained since most cells are essentially transparent, with little or no intrinsic pigment. Certain special stains, which bind selectively to particular components, are be used to identify biological structures such as cells. In those images, the challenging problem is cell segmentation for subsequent classification in benign and malignant cells. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| --------------------------------------------------------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------------------------------------------------ | +| [Breast Cancer Cell Segmentation](https://tianchi.aliyun.com/dataset/dataDetail?dataId=90152) | thorax | segmentation | histopathology | 2 | 58/-/- | yes/-/- | 2021 | [CC-BY-SA-NC 4.0](http://creativecommons.org/licenses/by-sa/4.0/?spm=5176.12282016.0.0.3f5b5291ypBxb2) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :----------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| normal | 58 | 98.37 | - | - | - | - | +| breast cancer cell | 58 | 1.63 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/breast_cancer_cell_seg/breast_cancer_cell_seg_dataset.png) + +## Dataset Citation + +``` +@inproceedings{gelasca2008evaluation, + title={Evaluation and benchmark for biological image segmentation}, + author={Gelasca, Elisa Drelie and Byun, Jiyun and Obara, Boguslaw and Manjunath, BS}, + booktitle={2008 15th IEEE international conference on image processing}, + pages={1816--1819}, + year={2008}, + organization={IEEE} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `breast_cancer_cell_seg/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://tianchi.aliyun.com/dataset/dataDetail?dataId=90152) and decompression data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── breast_cancer_cell_seg + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :----------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 46 | 98.36 | 12 | 98.41 | - | - | +| erythrocytes | 46 | 1.64 | 12 | 1.59 | - | - | + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/breast-cancer-cell-seg_512x512.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/breast-cancer-cell-seg_512x512.py new file mode 100644 index 00000000000..ead40e4345c --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/breast-cancer-cell-seg_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'BreastCancerCellSegDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breast-cancer-cell-seg-512x512.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breast-cancer-cell-seg-512x512.py new file mode 100644 index 00000000000..691a0ff613d --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_breast-cancer-cell-seg-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './breast-cancer-cell-seg_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breast-cancer-cell-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breast-cancer-cell-seg-512x512.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breast-cancer-cell-seg-512x512.py new file mode 100644 index 00000000000..719b767ab1f --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_breast-cancer-cell-seg-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './breast-cancer-cell-seg_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breast-cancer-cell-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breast-cancer-cell-seg-512x512.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breast-cancer-cell-seg-512x512.py new file mode 100644 index 00000000000..9dfe70f761f --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_breast-cancer-cell-seg-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './breast-cancer-cell-seg_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.breast-cancer-cell-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/datasets/breast-cancer-cell-seg_dataset.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/datasets/breast-cancer-cell-seg_dataset.py new file mode 100644 index 00000000000..6f27029d396 --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/datasets/breast-cancer-cell-seg_dataset.py @@ -0,0 +1,29 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class BreastCancerCellSegDataset(BaseSegDataset): + """BreastCancerCellSegDataset dataset. + + In segmentation map annotation for BreastCancerCellSegDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('normal', 'breast cancer cell')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/tools/prepare_dataset.py new file mode 100755 index 00000000000..775f2eed18a --- /dev/null +++ b/projects/medical/2d_image/histopathology/breast_cancer_cell_seg/tools/prepare_dataset.py @@ -0,0 +1,47 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.tif' +seg_map_suffix = '.TIF' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = glob.glob( + os.path.join('data/Breast Cancer Cell Segmentation_datasets/Images/*' + + img_suffix)) + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'masks/train/') + +D2_255_convert_dict = {0: 0, 255: 1} + + +def convert_2d(img, convert_dict=D2_255_convert_dict): + arr_2d = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) + for c, i in convert_dict.items(): + arr_2d[img == c] = i + return arr_2d + + +part_dir_dict = {0: 'train/'} +for ith, part in enumerate([x_train]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + img_save_path = root_path + 'images/' + part_dir + basename.split( + '.')[0] + save_img_suffix + Image.open(img).save(img_save_path) + mask_path = root_path + 'Breast Cancer Cell Segmentation_datasets/Masks/' + '_'.join( # noqa + basename.split('_')[:-1]) + seg_map_suffix + label = np.array(Image.open(mask_path)) + + save_mask_path = root_path + 'masks/' + part_dir + basename.split( + '.')[0] + save_seg_map_suffix + assert len(label.shape) == 2 and 255 in label and 1 not in label + mask = convert_2d(label) + mask = Image.fromarray(mask.astype(np.uint8)) + mask.save(save_mask_path) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/README.md b/projects/medical/2d_image/histopathology/conic2022_seg/README.md new file mode 100644 index 00000000000..1f55b44ed6d --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/README.md @@ -0,0 +1,207 @@ +# CoNIC: Colon Nuclei Identification and Counting Challenge + +## Description + +This project supports **`CoNIC: Colon Nuclei Identification and Counting Challenge`**, which can be downloaded from [here](https://drive.google.com/drive/folders/1il9jG7uA4-ebQ_lNmXbbF2eOK9uNwheb). + +### Dataset Overview + +Nuclear segmentation, classification and quantification within Haematoxylin & Eosin stained histology images enables the extraction of interpretable cell-based features that can be used in downstream explainable models in computational pathology (CPath). To help drive forward research and innovation for automatic nuclei recognition in CPath, we organise the Colon Nuclei Identification and Counting (CoNIC) Challenge. The challenge requires researchers to develop algorithms that perform segmentation, classification and counting of 6 different types of nuclei within the current largest known publicly available nuclei-level dataset in CPath, containing around half a million labelled nuclei. + +### Task Information + +The CONIC challenge has 2 tasks: + +- Task 1: Nuclear segmentation and classification. + +The first task requires participants to segment nuclei within the tissue, while also classifying each nucleus into one of the following categories: epithelial, lymphocyte, plasma, eosinophil, neutrophil or connective tissue. + +- Task 2: Prediction of cellular composition. + +For the second task, we ask participants to predict how many nuclei of each class are present in each input image. + +The output of Task 1 can be directly used to perform Task 2, but these can be treated as independent tasks. Therefore, if it is preferred, prediction of cellular composition can be treated as a stand alone regression task. + +***NOTE:We only consider `Task 1` in the following sections.*** + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| -------------------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------------------------------------------------------ | +| [CoNIC202](https://conic-challenge.grand-challenge.org/) | abdomen | segmentation | histopathology | 7 | 4981/-/- | yes/-/- | 2022 | [Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 4981 | 83.97 | - | - | - | - | +| neutrophil | 1218 | 0.13 | - | - | - | - | +| epithelial | 4256 | 10.31 | - | - | - | - | +| lymphocyte | 4473 | 1.85 | - | - | - | - | +| plasma | 3316 | 0.55 | - | - | - | - | +| eosinophil | 1456 | 0.1 | - | - | - | - | +| connective | 4613 | 3.08 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/conic2022_seg/conic2022_seg_dataset.png) + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `conic2022_seg/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://drive.google.com/drive/folders/1il9jG7uA4-ebQ_lNmXbbF2eOK9uNwheb/) and move data to path `'data/CoNIC_Challenge'`. The directory should be like: + ```shell + data/CoNIC_Challenge + ├── README.txt + ├── by-nc-sa.md + ├── counts.csv + ├── images.npy + ├── labels.npy + └── patch_info.csv + ``` +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── conic2022_seg + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 3984 | 84.06 | 997 | 83.65 | - | - | +| neutrophil | 956 | 0.12 | 262 | 0.13 | - | - | +| epithelial | 3400 | 10.26 | 856 | 10.52 | - | - | +| lymphocyte | 3567 | 1.83 | 906 | 1.96 | - | - | +| plasma | 2645 | 0.55 | 671 | 0.56 | - | - | +| eosinophil | 1154 | 0.1 | 302 | 0.1 | - | - | +| connective | 3680 | 3.08 | 933 | 3.08 | - | - | + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Organizers + +- Simon Graham (TIA, PathLAKE) +- Mostafa Jahanifar (TIA, PathLAKE) +- Dang Vu (TIA) +- Giorgos Hadjigeorghiou (TIA, PathLAKE) +- Thomas Leech (TIA, PathLAKE) +- David Snead (UHCW, PathLAKE) +- Shan Raza (TIA, PathLAKE) +- Fayyaz Minhas (TIA, PathLAKE) +- Nasir Rajpoot (TIA, PathLAKE) + +TIA: Tissue Image Analytics Centre, Department of Computer Science, University of Warwick, United Kingdom + +UHCW: Department of Pathology, University Hospitals Coventry and Warwickshire, United Kingdom + +PathLAKE: Pathology Image Data Lake for Analytics Knowledge & Education, , University Hospitals Coventry and Warwickshire, United Kingdom + +## Dataset Citation + +If this work is helpful for your research, please consider citing the below paper. + +``` +@inproceedings{graham2021lizard, + title={Lizard: A large-scale dataset for colonic nuclear instance segmentation and classification}, + author={Graham, Simon and Jahanifar, Mostafa and Azam, Ayesha and Nimir, Mohammed and Tsang, Yee-Wah and Dodd, Katherine and Hero, Emily and Sahota, Harvir and Tank, Atisha and Benes, Ksenija and others}, + booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, + pages={684--693}, + year={2021} +} +@article{graham2021conic, + title={Conic: Colon nuclei identification and counting challenge 2022}, + author={Graham, Simon and Jahanifar, Mostafa and Vu, Quoc Dang and Hadjigeorghiou, Giorgos and Leech, Thomas and Snead, David and Raza, Shan E Ahmed and Minhas, Fayyaz and Rajpoot, Nasir}, + journal={arXiv preprint arXiv:2111.14485}, + year={2021} +} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/configs/conic2022-seg_512x512.py b/projects/medical/2d_image/histopathology/conic2022_seg/configs/conic2022-seg_512x512.py new file mode 100644 index 00000000000..51b4e5782ab --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/configs/conic2022-seg_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'Conic2022SegDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_conic2022-512x512.py b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_conic2022-512x512.py new file mode 100644 index 00000000000..3e0248c78ce --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_conic2022-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './conic2022-seg_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.conic2022-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=7), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_conic2022-512x512.py b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_conic2022-512x512.py new file mode 100644 index 00000000000..fd0e9d8d28b --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_conic2022-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './conic2022-seg_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.conic2022-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=7), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_conic2022-512x512.py b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_conic2022-512x512.py new file mode 100644 index 00000000000..bb667f14fd4 --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_conic2022-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './conic2022-seg_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.conic2022-seg_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=7), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/conic2022_seg_dataset.png b/projects/medical/2d_image/histopathology/conic2022_seg/conic2022_seg_dataset.png new file mode 100644 index 00000000000..65bb0bbe0a5 Binary files /dev/null and b/projects/medical/2d_image/histopathology/conic2022_seg/conic2022_seg_dataset.png differ diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/datasets/conic2022-seg_dataset.py b/projects/medical/2d_image/histopathology/conic2022_seg/datasets/conic2022-seg_dataset.py new file mode 100644 index 00000000000..9af0958ab34 --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/datasets/conic2022-seg_dataset.py @@ -0,0 +1,29 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class Conic2022SegDataset(BaseSegDataset): + """Conic2022SegDataset dataset. + + In segmentation map annotation for Conic2022SegDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict( + classes=('background', 'neutrophil', 'epithelial', 'lymphocyte', + 'plasma', 'eosinophil', 'connective')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/conic2022_seg/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/conic2022_seg/tools/prepare_dataset.py new file mode 100755 index 00000000000..89cfb4aae24 --- /dev/null +++ b/projects/medical/2d_image/histopathology/conic2022_seg/tools/prepare_dataset.py @@ -0,0 +1,65 @@ +import glob +import os +import shutil + +import numpy as np +from PIL import Image + +img_save_root = 'data/' +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +label_set = set() + + +def save_masks_from_npz(data, save_root, part='masks/'): + global label_set + num = data.shape[0] + for i in range(num): + # np_img = data[i, :, :, :] + np_mask = data[i, :, :, 1] + label_set = set.union(label_set, set(np.unique(np_mask))) + img = Image.fromarray(np_mask) + save_path = os.path.join(save_root, part, str(i) + save_seg_map_suffix) + img.save(save_path) + + +def save_images_from_npz(data, save_root, part='images/'): + num = data.shape[0] + for i in range(num): + np_img = data[i, :, :, :] + img = Image.fromarray(np_img) + save_path = os.path.join(save_root, part, str(i) + save_img_suffix) + img.save(save_path) + + +images_npy = np.load('data/CoNIC_Challenge/images.npy') +labels_npy = np.load('data/CoNIC_Challenge/labels.npy') + +os.system('mkdir -p ' + img_save_root + 'images_ori') +os.system('mkdir -p ' + img_save_root + 'labels') +save_images_from_npz(images_npy, img_save_root, 'images_ori') +save_masks_from_npz(labels_npy, img_save_root, 'labels') +print(label_set) + +x_train = glob.glob(os.path.join('data/images_ori/*' + img_suffix)) + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'masks/train/') + +part_dir_dict = {0: 'train/', 1: 'val/'} +for ith, part in enumerate([x_train]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + shutil.copy( + img, root_path + 'images/' + part_dir + basename.split('.')[0] + + save_img_suffix) + mask_path = root_path + 'labels/' + basename.split( + '.')[0] + seg_map_suffix + save_mask_path = root_path + 'masks/' + part_dir + basename.split( + '.')[0] + save_seg_map_suffix + shutil.copy(mask_path, save_mask_path) diff --git a/projects/medical/2d_image/histopathology/consep/README.md b/projects/medical/2d_image/histopathology/consep/README.md new file mode 100644 index 00000000000..ca3d7aa1089 --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/README.md @@ -0,0 +1,147 @@ +# Colorectal Nuclear Segmentation and Phenotypes (CoNSeP) Dataset + +## Description + +This project supports **`Colorectal Nuclear Segmentation and Phenotypes (CoNSeP) Dataset`**, which can be downloaded from [here](https://warwick.ac.uk/fac/cross_fac/tia/data/hovernet/). + +### Dataset Overview + +The CoNSeP (Colon Segmentation and Phenotyping) dataset consists of 41 H&E stained image tiles, each with a size of 1,000×1,000 pixels and a magnification of 40x. These images were extracted from 16 colorectal adenocarcinoma (CRA) whole slide images (WSI), each of which belonged to a separate patient and was scanned using an Omnyx VL120 scanner at the Pathology Department of the University Hospitals Coventry and Warwickshire NHS Trust, UK. This dataset was first used in paper named, "HoVer-Net: Simultaneous Segmentation and Classification of Nuclei in Multi-Tissue Histology Images". + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| -------------------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | ------- | +| [CoNIC202](https://conic-challenge.grand-challenge.org/) | abdomen | segmentation | histopathology | 7 | 4981/-/- | yes/-/- | 2022 | - | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :-----------------------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 27 | 83.61 | 14 | 80.4 | - | - | +| other | 17 | 0.17 | 9 | 0.52 | - | - | +| inflammatory | 25 | 2.66 | 14 | 2.14 | - | - | +| healthy epithelial | 3 | 1.47 | 2 | 1.58 | - | - | +| dysplastic/malignant epithelial | 10 | 7.17 | 8 | 9.16 | - | - | +| fibroblast | 23 | 3.84 | 14 | 4.63 | - | - | +| muscle | 8 | 1.05 | 3 | 1.42 | - | - | +| endothelial | 7 | 0.02 | 4 | 0.15 | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/consep/consep_dataset.png) + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `conic2022_seg/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://opendatalab.com/CoNSeP) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── consep + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Dataset Citation + +If this work is helpful for your research, please consider citing the below paper. + +``` +@article{graham2019hover, + title={Hover-net: Simultaneous segmentation and classification of nuclei in multi-tissue histology images}, + author={Graham, Simon and Vu, Quoc Dang and Raza, Shan E Ahmed and Azam, Ayesha and Tsang, Yee Wah and Kwak, Jin Tae and Rajpoot, Nasir}, + journal={Medical Image Analysis}, + volume={58}, + pages={101563}, + year={2019}, + publisher={Elsevier} +} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/consep/configs/consep_512x512.py b/projects/medical/2d_image/histopathology/consep/configs/consep_512x512.py new file mode 100644 index 00000000000..0d9b8948b01 --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/configs/consep_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'ConsepDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_consep-512x512.py b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_consep-512x512.py new file mode 100644 index 00000000000..cbcf5db775b --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_consep-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './consep_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.consep_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=8), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_consep-512x512.py b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_consep-512x512.py new file mode 100644 index 00000000000..b374566e6ef --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_consep-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './consep_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.consep_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=8), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_consep-512x512.py b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_consep-512x512.py new file mode 100644 index 00000000000..35bdaa34c84 --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_consep-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + './consep_512x512.py', 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.consep_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=8), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/consep/datasets/consep_dataset.py b/projects/medical/2d_image/histopathology/consep/datasets/consep_dataset.py new file mode 100644 index 00000000000..ceb2b3ab25b --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/datasets/consep_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ConsepDataset(BaseSegDataset): + """ConsepDataset dataset. + + In segmentation map annotation for ConsepDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict( + classes=('background', 'other', 'inflammatory', 'healthy epithelial', + 'dysplastic/malignant epithelial', 'fibroblast', 'muscle', + 'endothelial')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/consep/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/consep/tools/prepare_dataset.py new file mode 100755 index 00000000000..83a2e18ce10 --- /dev/null +++ b/projects/medical/2d_image/histopathology/consep/tools/prepare_dataset.py @@ -0,0 +1,54 @@ +import glob +import os +import shutil + +import numpy as np +from PIL import Image +from scipy.io import loadmat + +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.mat' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = glob.glob(os.path.join('data/CoNSeP/Train/Images/*' + img_suffix)) +x_test = glob.glob(os.path.join('data/CoNSeP/Test/Images/*' + img_suffix)) + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'images/val/') +os.system('mkdir -p ' + root_path + 'masks/train/') +os.system('mkdir -p ' + root_path + 'masks/val/') +D2_255_convert_dict = {0: 0, 255: 1} + + +def convert_2d(img, convert_dict=D2_255_convert_dict): + arr_2d = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) + for c, i in convert_dict.items(): + arr_2d[img == c] = i + return arr_2d + + +part_dir_dict = {0: 'CoNSeP/Train/', 1: 'CoNSeP/Test/'} +save_dir_dict = {0: 'train/', 1: 'val/'} +for ith, part in enumerate([x_train, x_test]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + shutil.copy( + img, root_path + 'images/' + save_dir_dict[ith] + + basename.split('.')[0] + save_img_suffix) + + mask_path = root_path + part_dir + 'Labels/' + basename.split( + '.')[0] + seg_map_suffix + label_ = loadmat(mask_path) + label = label_['inst_map'] + label_type = label_['inst_type'] + label_dict = {i + 1: int(val) for i, val in enumerate(label_type)} + + save_mask_path = root_path + 'masks/' + save_dir_dict[ + ith] + basename.split('.')[0] + save_seg_map_suffix + + res = convert_2d(label, convert_dict=label_dict) + res = Image.fromarray(res.astype(np.uint8)) + res.save(save_mask_path) diff --git a/projects/medical/2d_image/histopathology/fusc2021/README.md b/projects/medical/2d_image/histopathology/fusc2021/README.md new file mode 100644 index 00000000000..8130d593503 --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/README.md @@ -0,0 +1,136 @@ +# Foot Ulcer Segmentation Challenge 2021 (FUSC 2021) + +## Description + +This project supports **`Foot Ulcer Segmentation Challenge 2021 (FUSC 2021) `**, which can be downloaded from [here](https://fusc.grand-challenge.org/). + +### Dataset Overview + +This chronic wound dataset was collected over 2 years from October 2019 to April 2021 at the center and contains 1,210 foot ulcer images taken from 889 patients during multiple clinical visits. The raw images were taken by Canon SX 620 HS digital camera and iPad Pro under uncontrolled illumination conditions, +with various backgrounds. The images (shown in Figure 1) are randomly split into 3 subsets: a training set with 810 images, a validation set with 200 images, and a testing set with 200 images. Of course, the annotations of the testing set are kept private. The data collected were de-identified and in accordance with relevant guidelines and regulations and the patient’s informed consent is waived by the institutional review board of the University of Wisconsin-Milwaukee. + +### Information Statistics + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| --------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------- | +| [fusc2021](https://fusc.grand-challenge.org/) | lower limb | segmentation | histopathology | 2 | 810/200/200 | yes/yes/no | 2021 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 810 | 98.71 | 200 | 98.78 | - | - | +| wound | 791 | 1.29 | 195 | 1.22 | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![fusc2021](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/fusc2021/fusc2021_dataset.png?raw=true) + +### Dataset Citation + +``` +@article{s41598-020-78799-w, + title={Fully automatic wound segmentation with deep convolutional neural networks}, + author={Chuanbo Wang and D. M. Anisuzzaman and Victor Williamson and Mrinal Kanti Dhar and Behrouz Rostami and Jeffrey Niezgoda and Sandeep Gopalakrishnan and Zeyun Yu}, + journal={Scientific Reports}, + volume={10}, + number={1}, + pages={21897}, + year={2020} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `fusc2021/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://fusc.grand-challenge.org/) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── fusc2021 + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_fusc2021-512x512.py b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_fusc2021-512x512.py new file mode 100644 index 00000000000..c3f42751124 --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_fusc2021-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './fusc2021_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.fusc2021_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_fusc2021-512x512.py b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_fusc2021-512x512.py new file mode 100644 index 00000000000..ed870303fff --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_fusc2021-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './fusc2021_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.fusc2021_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_fusc2021-512x512.py b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_fusc2021-512x512.py new file mode 100644 index 00000000000..cbc09ae6cdd --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_fusc2021-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './fusc2021_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.fusc2021_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_fusc2021-512x512.py b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_fusc2021-512x512.py new file mode 100644 index 00000000000..f1477ee725e --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_fusc2021-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './fusc2021_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.fusc2021_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/fusc2021/configs/fusc2021_512x512.py b/projects/medical/2d_image/histopathology/fusc2021/configs/fusc2021_512x512.py new file mode 100644 index 00000000000..e650474cea8 --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/configs/fusc2021_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'FUSC2021Dataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/fusc2021/datasets/fusc2021_dataset.py b/projects/medical/2d_image/histopathology/fusc2021/datasets/fusc2021_dataset.py new file mode 100644 index 00000000000..d331ac8c3a2 --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/datasets/fusc2021_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class FUSC2021Dataset(BaseSegDataset): + """FUSC2021Dataset dataset. + + In segmentation map annotation for FUSC2021Dataset, 0 stands for background + , which is included in 2 categories. ``reduce_zero_label`` + is fixed to False. The ``img_suffix`` is fixed to '.png' and + ``seg_map_suffix`` is fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False.. + """ + METAINFO = dict(classes=('background', 'wound')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/fusc2021/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/fusc2021/tools/prepare_dataset.py new file mode 100644 index 00000000000..8f2de3daa95 --- /dev/null +++ b/projects/medical/2d_image/histopathology/fusc2021/tools/prepare_dataset.py @@ -0,0 +1,114 @@ +import glob +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' +src_img_train_dir = os.path.join( + root_path, 'wound-segmentation/data/' + + 'Foot Ulcer Segmentation Challenge/train/images') +src_img_val_dir = os.path.join( + root_path, 'wound-segmentation/data/' + + 'Foot Ulcer Segmentation Challenge/validation/images') +src_img_test_dir = os.path.join( + root_path, 'wound-segmentation/data/' + + 'Foot Ulcer Segmentation Challenge/test/images') +src_mask_train_dir = os.path.join( + root_path, 'wound-segmentation/data/' + + 'Foot Ulcer Segmentation Challenge/train/labels') +src_mask_val_dir = os.path.join( + root_path, 'wound-segmentation/data/' + + 'Foot Ulcer Segmentation Challenge/validation/labels') + +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_val_dir = os.path.join(root_path, 'images/val/') +tgt_mask_val_dir = os.path.join(root_path, 'masks/val/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_img_val_dir) +os.system('mkdir -p ' + tgt_img_test_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_mask_val_dir) + + +def filter_suffix_recursive(src_dir, suffix): + # filter out file names and paths in source directory + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob.glob( + os.path.join(src_dir, '**', '*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +def convert_pics_into_pngs(src_dir, tgt_dir, suffix, convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_img_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + num = len(src_paths) + img = np.array(Image.open(src_path)) + if len(img.shape) == 2: + pil = Image.fromarray(img).convert(convert) + elif len(img.shape) == 3: + pil = Image.fromarray(img) + else: + raise ValueError('Input image not 2D/3D: ', img.shape) + + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +def convert_label_pics_into_pngs(src_dir, + tgt_dir, + suffix, + convert_dict={ + 0: 0, + 255: 1 + }): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, save_seg_map_suffix) + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = np.array(Image.open(src_path).convert('L')) + img = convert_label(img, convert_dict) + Image.fromarray(img).save(tgt_path) + print(f'processed {i+1}/{num}.') + + +if __name__ == '__main__': + + convert_pics_into_pngs( + src_img_train_dir, tgt_img_train_dir, suffix=img_suffix) + + convert_pics_into_pngs(src_img_val_dir, tgt_img_val_dir, suffix=img_suffix) + + convert_pics_into_pngs( + src_img_test_dir, tgt_img_test_dir, suffix=img_suffix) + + convert_label_pics_into_pngs( + src_mask_train_dir, tgt_mask_train_dir, suffix=seg_map_suffix) + + convert_label_pics_into_pngs( + src_mask_val_dir, tgt_mask_val_dir, suffix=seg_map_suffix) diff --git a/projects/medical/2d_image/histopathology/pannuke/README.md b/projects/medical/2d_image/histopathology/pannuke/README.md new file mode 100644 index 00000000000..e0cade7536d --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/README.md @@ -0,0 +1,146 @@ +# Pan-Cancer Histology Dataset for Nuclei Instance Segmentation and Classification (PanNuke) + +## Description + +This project supports **`Pan-Cancer Histology Dataset for Nuclei Instance Segmentation and Classification (PanNuke)`**, which can be downloaded from [here](https://academictorrents.com/details/99f2c7b57b95500711e33f2ee4d14c9fd7c7366c). + +### Dataset Overview + +Semi automatically generated nuclei instance segmentation and classification dataset with exhaustive nuclei labels across 19 different tissue types. The dataset consists of 481 visual fields, of which 312 are randomly sampled from more than 20K whole slide images at different magnifications, from multiple data sources. In total the dataset contains 205,343 labeled nuclei, each with an instance segmentation mask. Models trained on pannuke can aid in whole slide image tissue type segmentation, and generalise to new tissues. PanNuke demonstrates one of the first successfully semi-automatically generated datasets. + +### Statistic Information + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ---------------------------------------------------------------------------------------- | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Pannuke](https://academictorrents.com/details/99f2c7b57b95500711e33f2ee4d14c9fd7c7366c) | full_body | segmentation | histopathology | 6 | 7901/-/- | yes/-/- | 2019 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :-----------------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 7901 | 83.32 | - | - | - | - | +| neoplastic | 4190 | 8.64 | - | - | - | - | +| non-neoplastic epithelial | 4126 | 1.77 | - | - | - | - | +| inflammatory | 6137 | 3.73 | - | - | - | - | +| connective | 232 | 0.07 | - | - | - | - | +| dead | 1528 | 2.47 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![pannuke](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/pannuke/pannuke_dataset.png?raw=true) + +### Dataset Citation + +``` +@inproceedings{gamper2019pannuke, + title={PanNuke: an open pan-cancer histology dataset for nuclei instance segmentation and classification}, + author={Gamper, Jevgenij and Koohbanani, Navid Alemi and Benet, Ksenija and Khuram, Ali and Rajpoot, Nasir}, + booktitle={European Congress on Digital Pathology}, + pages={11--19}, + year={2019}, +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 9.3.0 +- scikit-learn(sklearn) v1.2.0 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `pannuke/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://academictorrents.com/details/99f2c7b57b95500711e33f2ee4d14c9fd7c7366c) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── pannuke + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :-----------------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 6320 | 83.38 | 1581 | 83.1 | - | - | +| neoplastic | 3339 | 8.55 | 851 | 9.0 | - | - | +| non-neoplastic epithelial | 3293 | 1.77 | 833 | 1.76 | - | - | +| inflammatory | 4914 | 3.72 | 1223 | 3.76 | - | - | +| connective | 170 | 0.06 | 62 | 0.09 | - | - | +| dead | 1235 | 2.51 | 293 | 2.29 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_bactteria-detection-512x512.py b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_bactteria-detection-512x512.py new file mode 100644 index 00000000000..92584e9a684 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_bactteria-detection-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './bactteria-detection_512x512.py', 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.bactteria-detection_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pannuke-512x512.py b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pannuke-512x512.py new file mode 100644 index 00000000000..042a08ce008 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pannuke-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pannuke_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pannuke_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=6), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pannuke-512x512.py b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pannuke-512x512.py new file mode 100644 index 00000000000..e92514c9132 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pannuke-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pannuke_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pannuke_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=6), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pannuke-512x512.py b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pannuke-512x512.py new file mode 100644 index 00000000000..a9403c849fa --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pannuke-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pannuke_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pannuke_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=6), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pannuke/configs/pannuke_512x512.py b/projects/medical/2d_image/histopathology/pannuke/configs/pannuke_512x512.py new file mode 100644 index 00000000000..316ac1ac443 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/configs/pannuke_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'PanNukeDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/pannuke/datasets/pannuke_dataset.py b/projects/medical/2d_image/histopathology/pannuke/datasets/pannuke_dataset.py new file mode 100644 index 00000000000..4d3c687ff31 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/datasets/pannuke_dataset.py @@ -0,0 +1,33 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class PanNukeDataset(BaseSegDataset): + """PanNukeDataset dataset. + + In segmentation map annotation for PanNukeDataset, + 0 stands for background, which is included in 6 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict( + classes=('background', 'neoplastic', 'non-neoplastic epithelial', + 'inflammatory', 'connective', 'dead')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/pannuke/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/pannuke/tools/prepare_dataset.py new file mode 100644 index 00000000000..7213b181f40 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pannuke/tools/prepare_dataset.py @@ -0,0 +1,49 @@ +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' + +tgt_img_dir = os.path.join(root_path, 'images/train') +tgt_mask_dir = os.path.join(root_path, 'masks/train') +os.system('mkdir -p ' + tgt_img_dir) +os.system('mkdir -p ' + tgt_mask_dir) + +fold_img_paths = sorted([ + os.path.join(root_path, 'pannuke/Fold 1/images/fold1/images.npy'), + os.path.join(root_path, 'pannuke/Fold 2/images/fold2/images.npy'), + os.path.join(root_path, 'pannuke/Fold 3/images/fold3/images.npy') +]) + +fold_mask_paths = sorted([ + os.path.join(root_path, 'pannuke/Fold 1/masks/fold1/masks.npy'), + os.path.join(root_path, 'pannuke/Fold 2/masks/fold2/masks.npy'), + os.path.join(root_path, 'pannuke/Fold 3/masks/fold3/masks.npy') +]) + +for n, (img_path, + mask_path) in enumerate(zip(fold_img_paths, fold_mask_paths)): + fold_name = str(n + 1) + imgs = np.load(img_path) + masks = np.load(mask_path) + + for i in range(imgs.shape[0]): + img = np.uint8(imgs[i]) + mask_multichannel = np.minimum(np.uint8(masks[i]), 1) + mask = np.zeros((img.shape[0], img.shape[1]), dtype=np.uint8) + for j in range(mask_multichannel.shape[-1]): + factor = (j + 1) % mask_multichannel.shape[-1] + # convert [0,1,2,3,4,5] to [1,2,3,4,5,0], + # with the last label being background + mask[mask_multichannel[..., j] == 1] = factor + + file_name = 'fold' + fold_name + '_' + str(i).rjust(4, '0') + '.png' + print('Processing: ', file_name) + tgt_img_path = os.path.join(tgt_img_dir, file_name) + tgt_mask_path = os.path.join(tgt_mask_dir, file_name) + Image.fromarray(img).save(tgt_img_path) + Image.fromarray(mask).save(tgt_mask_path) + + del imgs + del masks diff --git a/projects/medical/2d_image/histopathology/pcam/README.md b/projects/medical/2d_image/histopathology/pcam/README.md new file mode 100644 index 00000000000..5a8094950c5 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/README.md @@ -0,0 +1,153 @@ +# PCam (PatchCamelyon) + +## Description + +This project supports **`Patch Camelyon (PCam) `**, which can be downloaded from [here](https://opendatalab.com/PCam). + +### Dataset Overview + +PatchCamelyon is an image classification dataset. It consists of 327680 color images (96 x 96px) extracted from histopathologic scans of lymph node sections. Each image is annotated with a binary label indicating presence of metastatic tissue. PCam provides a new benchmark for machine learning models: bigger than CIFAR10, smaller than ImageNet, trainable on a single GPU. + +### Statistic Information + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------ | ----------------- | ------------ | -------------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------- | +| [Pcam](https://opendatalab.com/PCam) | throax | segmentation | histopathology | 2 | 327680/-/- | yes/-/- | 2018 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 214849 | 63.77 | - | - | - | - | +| metastatic tissue | 131832 | 36.22 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![pcam](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/pcam/pcam_dataset.png?raw=true) + +### Dataset Citation + +``` +@inproceedings{veeling2018rotation, + title={Rotation equivariant CNNs for digital pathology}, + author={Veeling, Bastiaan S and Linmans, Jasper and Winkens, Jim and Cohen, Taco and Welling, Max}, + booktitle={International Conference on Medical image computing and computer-assisted intervention}, + pages={210--218}, + year={2018}, +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 9.3.0 +- scikit-learn(sklearn) v1.2.0 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `pcam/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://opendatalab.com/PCam) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```shell +mkdir data & cd data +pip install opendatalab +odl get PCam +mv ./PCam/raw/pcamv1 ./ +rm -rf PCam +cd .. +python tools/prepare_dataset.py +python ../../tools/split_seg_dataset.py +``` + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── histopathology + │ │ │ │ ├── pcam + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 171948 | 63.82 | 42901 | 63.6 | - | - | +| metastatic tissue | 105371 | 36.18 | 26461 | 36.4 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pcam-512x512.py b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pcam-512x512.py new file mode 100644 index 00000000000..20601f1ea56 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_pcam-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pcam_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pcam_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pcam-512x512.py b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pcam-512x512.py new file mode 100644 index 00000000000..c057535409f --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_pcam-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pcam_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pcam_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pcam-512x512.py b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pcam-512x512.py new file mode 100644 index 00000000000..4c1d5fe421c --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_pcam-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pcam_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pcam_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_pcam-512x512.py b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_pcam-512x512.py new file mode 100644 index 00000000000..25e3734795c --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_pcam-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './pcam_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.pcam_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/histopathology/pcam/configs/pcam_512x512.py b/projects/medical/2d_image/histopathology/pcam/configs/pcam_512x512.py new file mode 100644 index 00000000000..04efc23eb51 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/configs/pcam_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'PCamDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/histopathology/pcam/datasets/pcam_dataset.py b/projects/medical/2d_image/histopathology/pcam/datasets/pcam_dataset.py new file mode 100644 index 00000000000..1c27de543ab --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/datasets/pcam_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class PCamDataset(BaseSegDataset): + """PCamDataset dataset. + + In segmentation map annotation for PCamDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'metastatic tissue')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/histopathology/pcam/tools/prepare_dataset.py b/projects/medical/2d_image/histopathology/pcam/tools/prepare_dataset.py new file mode 100644 index 00000000000..75038e6fb49 --- /dev/null +++ b/projects/medical/2d_image/histopathology/pcam/tools/prepare_dataset.py @@ -0,0 +1,49 @@ +import os + +import h5py +import numpy as np +from PIL import Image + +root_path = 'data/' + +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_val_dir = os.path.join(root_path, 'images/val/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') + +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_img_val_dir) +os.system('mkdir -p ' + tgt_img_test_dir) + + +def extract_pics_from_h5(h5_path, h5_key, save_dir): + f = h5py.File(h5_path, 'r') + for i, img in enumerate(f[h5_key]): + img = img.astype(np.uint8).squeeze() + img = Image.fromarray(img) + save_image_path = os.path.join(save_dir, str(i).zfill(8) + '.png') + img.save(save_image_path) + + +if __name__ == '__main__': + + extract_pics_from_h5( + 'data/pcamv1/camelyonpatch_level_2_split_train_x.h5', + h5_key='x', + save_dir=tgt_img_train_dir) + + extract_pics_from_h5( + 'data/pcamv1/camelyonpatch_level_2_split_valid_x.h5', + h5_key='x', + save_dir=tgt_img_val_dir) + + extract_pics_from_h5( + 'data/pcamv1/camelyonpatch_level_2_split_test_x.h5', + h5_key='x', + save_dir=tgt_img_test_dir) + + extract_pics_from_h5( + 'data/pcamv1/camelyonpatch_level_2_split_train_mask.h5', + h5_key='mask', + save_dir=tgt_mask_train_dir) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/README.md b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/README.md new file mode 100644 index 00000000000..ca95921ba36 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/README.md @@ -0,0 +1,167 @@ +# RAVIR: A Dataset and Methodology for the Semantic Segmentation and Quantitative Analysis of Retinal Arteries and Veins in Infrared Reflectance Imaging + +## Description + +This project support **`RAVIR: A Dataset and Methodology for the Semantic Segmentation and Quantitative Analysis of Retinal Arteries and Veins in Infrared Reflectance Imaging`**, and the dataset used in this project can be downloaded from [here](https://ravir.grand-challenge.org/). + +### Dataset Overview + +The retinal vasculature provides important clues in the diagnosis and monitoring of systemic diseases including hypertension and diabetes. The microvascular system is of primary involvement in such conditions, and the retina is the only anatomical site where the microvasculature can be directly observed. The objective assessment of retinal vessels has long been considered a surrogate biomarker for systemic vascular diseases, and with recent advancements in retinal imaging and computer vision technologies, this topic has become the subject of renewed attention. In this paper, we present a novel dataset, dubbed RAVIR, for the semantic segmentation of Retinal Arteries and Veins in Infrared Reflectance (IR) imaging. It enables the creation of deep learning-based models that distinguish extracted vessel type without extensive post-processing. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------- | ----------------- | ------------ | ---------------------------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Ravir](https://ravir.grand-challenge.org/) | eye | segmentation | infrared reflectance imaging | 3 | 23/-/19 | yes/-/- | 2022 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 23 | 87.22 | - | - | - | - | +| artery | 23 | 5.45 | - | - | - | - | +| vein | 23 | 7.33 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/infrared_reflectance_imaging/ravir/ravir_dataset.png) + +## Dataset Citation + +```bibtex +@article{hatamizadeh2022ravir, + title={RAVIR: A dataset and methodology for the semantic segmentation and quantitative analysis of retinal arteries and veins in infrared reflectance imaging}, + author={Hatamizadeh, Ali and Hosseini, Hamid and Patel, Niraj and Choi, Jinseo and Pole, Cameron C and Hoeferlin, Cory M and Schwartz, Steven D and Terzopoulos, Demetri}, + journal={IEEE Journal of Biomedical and Health Informatics}, + volume={26}, + number={7}, + pages={3272--3283}, + year={2022}, + publisher={IEEE} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `ravir/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://ravir.grand-challenge.org/) and decompression data to path `'data/ravir/'`. +- run script `"python tools/prepare_dataset.py"` to split dataset and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py --data_root data/ravir"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── infrared_reflectance_imaging + │ │ │ │ ├── ravir + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ │ ├── test + │ │ │ │ | │ │ │ ├── yyy.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── yyy.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 18 | 87.41 | 5 | 86.53 | - | - | +| artery | 18 | 5.44 | 5 | 5.50 | - | - | +| vein | 18 | 7.15 | 5 | 7.97 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +### Testing commands + +To train models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Results + +### Ravir + +| Method | Backbone | Crop Size | lr | config | +| :-------------: | :------: | :-------: | :----: | :------------------------------------------------------------------------: | +| fcn_unet_s5-d16 | unet | 512x512 | 0.01 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_ravir-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.001 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_ravir-512x512.py) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.0001 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_ravir-512x512.py) | + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_ravir-512x512.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_ravir-512x512.py new file mode 100755 index 00000000000..375ad5abf27 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_ravir-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './ravir_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.ravir_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + pretrained=None, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_ravir-512x512.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_ravir-512x512.py new file mode 100755 index 00000000000..a7ecf6dd453 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_ravir-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './ravir_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.ravir_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=dict(size=img_scale), + pretrained=None, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_ravir-512x512.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_ravir-512x512.py new file mode 100755 index 00000000000..28556df53d1 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_ravir-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './ravir_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.ravir_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + pretrained=None, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/ravir_512x512.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/ravir_512x512.py new file mode 100755 index 00000000000..cb4c292d1f7 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/configs/ravir_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'RAVIRDataset' +data_root = 'data/ravir' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/__init__.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/__init__.py new file mode 100755 index 00000000000..6f1d051bcff --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/__init__.py @@ -0,0 +1,3 @@ +from .ravir_dataset import RAVIRDataset + +__all__ = ['RAVIRDataset'] diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/ravir_dataset.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/ravir_dataset.py new file mode 100755 index 00000000000..c9e0a8ed21e --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/datasets/ravir_dataset.py @@ -0,0 +1,28 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class RAVIRDataset(BaseSegDataset): + """RAVIRDataset dataset. + + In segmentation map annotation for RAVIRDataset, 0 stands for background, + which is included in 3 categories. ``reduce_zero_label`` is fixed to + False. The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is + fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('background', 'artery', 'vein')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/infrared_reflectance_imaging/ravir/tools/prepare_dataset.py b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/tools/prepare_dataset.py new file mode 100644 index 00000000000..068dcad8145 --- /dev/null +++ b/projects/medical/2d_image/infrared_reflectance_imaging/ravir/tools/prepare_dataset.py @@ -0,0 +1,33 @@ +import glob +import os + +import numpy as np +from PIL import Image +from tqdm import tqdm + +# map = {255:2, 128:1, 0:0} + +os.makedirs('data/ravir/images/train', exist_ok=True) +os.makedirs('data/ravir/images/test', exist_ok=True) +os.makedirs('data/ravir/masks/train', exist_ok=True) + +os.system( + r'cp data/ravir/RAVIR\ Dataset/train/training_images/* data/ravir/images/train' # noqa +) +os.system( + r'cp data/ravir/RAVIR\ Dataset/train/training_masks/* data/ravir/masks/train' # noqa +) +os.system(r'cp data/ravir/RAVIR\ Dataset/test/* data/ravir/images/test') + +os.system(r'rm -rf data/ravir/RAVIR\ Dataset') + +imgs = glob.glob(os.path.join('data/ravir/masks/train', '*.png')) + +for im_path in tqdm(imgs): + im = Image.open(im_path) + imn = np.array(im) + imn[imn == 255] = 2 + imn[imn == 128] = 1 + imn[imn == 0] = 0 + new_im = Image.fromarray(imn) + new_im.save(im_path) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/README.md b/projects/medical/2d_image/microscopy_images/2pm_vessel/README.md new file mode 100644 index 00000000000..1feb433a319 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/README.md @@ -0,0 +1,153 @@ +# 2-PM Vessel Dataset + +## Description + +This project supports **`2-PM Vessel Dataset`**, which can be downloaded from [here](https://opendatalab.org.cn/2-PM_Vessel_Dataset). + +### Dataset Overview + +An open-source volumetric brain vasculature dataset obtained with two-photon microscopy at Focused Ultrasound Lab, at Sunnybrook Research Institute (affiliated with University of Toronto by Dr. Alison Burgess, Charissa Poon and Marc Santos). + +The dataset contains a total of 12 volumetric stacks consisting images of mouse brain vasculature and tumor vasculature. + +### Information Statistics + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------------------------ | ----------------- | ------------ | ----------------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------- | +| [2pm_vessel](https://opendatalab.org.cn/2-PM_Vessel_Dataset) | vessel | segmentation | microscopy_images | 2 | 216/-/- | yes/-/- | 2021 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 216 | 85.78 | - | - | - | - | +| vessel | 180 | 14.22 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![2pmv](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/histopathology/2pm_vessel/2pm_vessel_dataset.png?raw=true) + +### Dataset Citation + +``` +@article{teikari2016deep, + title={Deep learning convolutional networks for multiphoton microscopy vasculature segmentation}, + author={Teikari, Petteri and Santos, Marc and Poon, Charissa and Hynynen, Kullervo}, + journal={arXiv preprint arXiv:1606.02382}, + year={2016} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `2pm_vessel/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://opendatalab.org.cn/2-PM_Vessel_Dataset) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```shell +mkdir data & cd data +pip install opendatalab +odl get 2-PM_Vessel_Dataset +cd .. +python tools/prepare_dataset.py +python ../../tools/split_seg_dataset.py +``` + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── microscopy_images + │ │ │ │ ├── 2pm_vessel + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 172 | 85.88 | 44 | 85.4 | - | - | +| vessel | 142 | 14.12 | 38 | 14.6 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [ ] Milestone 2: Indicates a successful model implementation. + + - [ ] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/2pm-vessel_512x512.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/2pm-vessel_512x512.py new file mode 100644 index 00000000000..124403fa973 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/2pm-vessel_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'TwoPMVesselDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_2pm-vessel-512x512.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_2pm-vessel-512x512.py new file mode 100644 index 00000000000..2a429e9068e --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_2pm-vessel-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './2pm-vessel_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.2pm-vessel_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_2pm-vessel-512x512.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_2pm-vessel-512x512.py new file mode 100644 index 00000000000..10d9bb82f25 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_2pm-vessel-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './2pm-vessel_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.2pm-vessel_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_2pm-vessel-512x512.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_2pm-vessel-512x512.py new file mode 100644 index 00000000000..65c1579ec71 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_2pm-vessel-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './2pm-vessel_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.2pm-vessel_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_bactteria-detection-512x512.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_bactteria-detection-512x512.py new file mode 100644 index 00000000000..91ed6ada3f2 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/configs/fcn-unet-s5-d16_unet_1xb16-0.01lr-sigmoid-20k_bactteria-detection-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './2pm-vessel_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.2pm-vessel_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/datasets/2pm-vessel_dataset.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/datasets/2pm-vessel_dataset.py new file mode 100644 index 00000000000..984b5a1361d --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/datasets/2pm-vessel_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class TwoPMVesselDataset(BaseSegDataset): + """TwoPMVesselDataset dataset. + + In segmentation map annotation for TwoPMVesselDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'vessel')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/microscopy_images/2pm_vessel/tools/prepare_dataset.py b/projects/medical/2d_image/microscopy_images/2pm_vessel/tools/prepare_dataset.py new file mode 100644 index 00000000000..1b46af2cad0 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/2pm_vessel/tools/prepare_dataset.py @@ -0,0 +1,46 @@ +import os + +import tifffile as tiff +from PIL import Image + +root_path = 'data/' + +image_dir = os.path.join(root_path, + '2-PM_Vessel_Dataset/raw/vesselNN_dataset/denoised') +label_dir = os.path.join(root_path, + '2-PM_Vessel_Dataset/raw/vesselNN_dataset/labels') +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) + + +def filter_suffix(src_dir, suffix): + suffix = '.' + suffix if '.' not in suffix else suffix + file_names = [_ for _ in os.listdir(src_dir) if _.endswith(suffix)] + file_paths = [os.path.join(src_dir, _) for _ in file_names] + return sorted(file_paths), sorted(file_names) + + +if __name__ == '__main__': + + image_path_list, _ = filter_suffix(image_dir, suffix='tif') + label_path_list, _ = filter_suffix(label_dir, suffix='.tif') + + for img_path, label_path in zip(image_path_list, label_path_list): + labels = tiff.imread(label_path) + images = tiff.imread(img_path) + assert labels.ndim == 3 + assert images.shape == labels.shape + name = img_path.split('/')[-1].replace('.tif', '') + # a single .tif file contains multiple slices + # as long as it is read by tifffile package. + for i in range(labels.shape[0]): + slice_name = name + '_' + str(i).rjust(3, '0') + '.png' + image = images[i] + label = labels[i] // 255 + + save_path_label = os.path.join(tgt_mask_train_dir, slice_name) + Image.fromarray(label).save(save_path_label) + save_path_image = os.path.join(tgt_img_train_dir, slice_name) + Image.fromarray(image).convert('RGB').save(save_path_image) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/README.md b/projects/medical/2d_image/microscopy_images/bactteria_detection/README.md new file mode 100644 index 00000000000..1cedda715a7 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/README.md @@ -0,0 +1,160 @@ +# Bactteria detection with darkfield microscopy + +## Description + +This project supports **`Bactteria detection with darkfield microscopy`**, which can be downloaded from [here](https://tianchi.aliyun.com/dataset/94411). + +### Dataset Overview + +Spirochaeta is a genus of bacteria classified within the phylum Spirochaetes. Included in this dataset are 366 darkfield microscopy images and manually annotated masks which can be used for classification and segmentation purposes. Detecting bacteria in blood could have a huge significance for research in both the medical and computer science field. + +It was gathered and annotated by students (hand-on experience) +It has more than just one targeted class (blood cell and bacteria were annotated) +It is highly imbalanced, so naive loss functions would work less properly + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| --------------------------------------------------------------- | ----------------- | ------------ | ---------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Bactteria detection](https://tianchi.aliyun.com/dataset/94411) | bacteria | segmentation | microscopy | 3 | 366/-/- | yes/-/- | 2017 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :----------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 366 | 85.9 | - | - | - | - | +| erythrocytes | 345 | 13.03 | - | - | - | - | +| spirochaete | 288 | 1.07 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/microscopy_images/bactteria_detection/bactteria_detection_dataset.png) + +## Usage + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow (PIL) v9.3.0 +- scikit-learn (sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `bactteria_detection/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- Download dataset from [here](https://tianchi.aliyun.com/dataset/94411) and save it to the `data/` directory . +- Decompress data to path `data/`. This will create a new folder named `data/Bacteria_detection_with_darkfield_microscopy_datasets/`, which contains the original image data. +- run script `python tools/prepare_dataset.py` to format data and change folder structure as below. +- run script `python ../../tools/split_seg_dataset.py` to split dataset. For the Bacteria_detection dataset, as there is no test or validation dataset, we sample 20% samples from the whole dataset as the validation dataset and 80% samples for training data and make two filename lists `train.txt` and `val.txt`. As we set the random seed as the hard code, we eliminated the randomness, the dataset split actually can be reproducible. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── microscopy_images + │ │ │ │ ├── bactteria_detection + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── Bacteria_detection_with_darkfield_microscopy_datasets + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :----------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 292 | 85.66 | 74 | 86.7 | - | - | +| erythrocytes | 274 | 13.25 | 71 | 12.29 | - | - | +| spirochaete | 231 | 1.09 | 57 | 1.01 | - | - | + +### Training commands + +Train models on a single server with one GPU. + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Results + +### Bactteria detection with darkfield microscopy + +***Note: The following experimental results are based on the data randomly partitioned according to the above method described in the dataset preparing section.*** + +| Method | Backbone | Crop Size | lr | mIoU | mDice | config | download | +| :-------------: | :------: | :-------: | :----: | :---: | :---: | :--------------------------------------------------------------------------------------: | :----------------------: | +| fcn_unet_s5-d16 | unet | 512x512 | 0.01 | 76.48 | 84.68 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_bactteria-detection-512x512.py) | [model](<>) \| [log](<>) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.001 | 61.06 | 63.69 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_bactteria-detection-512x512.py) | [model](<>) \| [log](<>) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.0001 | 58.87 | 62.42 | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_bactteria-detection-512x512.py) | [model](<>) \| [log](<>) | + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/bactteria-detection_512x512.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/bactteria-detection_512x512.py new file mode 100644 index 00000000000..e3eab4e3868 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/bactteria-detection_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'BactteriaDetectionDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_bactteria-detection-512x512.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_bactteria-detection-512x512.py new file mode 100644 index 00000000000..ede58d785c1 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_bactteria-detection-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './bactteria-detection_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.bactteria-detection_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_bactteria-detection-512x512.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_bactteria-detection-512x512.py new file mode 100644 index 00000000000..bde3fa14acd --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_bactteria-detection-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './bactteria-detection_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.bactteria-detection_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_bactteria-detection-512x512.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_bactteria-detection-512x512.py new file mode 100644 index 00000000000..08e204f3809 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_bactteria-detection-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './bactteria-detection_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.bactteria-detection_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=3), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/datasets/bactteria-detection_dataset.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/datasets/bactteria-detection_dataset.py new file mode 100644 index 00000000000..c95097b1acd --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/datasets/bactteria-detection_dataset.py @@ -0,0 +1,27 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class BactteriaDetectionDataset(BaseSegDataset): + """BactteriaDetectionDataset dataset. + + In segmentation map annotation for BactteriaDetectionDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('background', 'erythrocytes', 'spirochaete')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/microscopy_images/bactteria_detection/tools/prepare_dataset.py b/projects/medical/2d_image/microscopy_images/bactteria_detection/tools/prepare_dataset.py new file mode 100755 index 00000000000..8dcc719e262 --- /dev/null +++ b/projects/medical/2d_image/microscopy_images/bactteria_detection/tools/prepare_dataset.py @@ -0,0 +1,33 @@ +import glob +import os +import shutil + +from PIL import Image + +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = glob.glob( + 'data/Bacteria_detection_with_darkfield_microscopy_datasets/images/*' + + img_suffix) # noqa + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'masks/train/') + +part_dir_dict = {0: 'train/'} +for ith, part in enumerate([x_train]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + img_save_path = os.path.join(root_path, 'images', part_dir, + basename.split('.')[0] + save_img_suffix) + shutil.copy(img, img_save_path) + mask_path = 'data/Bacteria_detection_with_darkfield_microscopy_datasets/masks/' + basename # noqa + mask = Image.open(mask_path).convert('L') + mask_save_path = os.path.join( + root_path, 'masks', part_dir, + basename.split('.')[0] + save_seg_map_suffix) + mask.save(mask_save_path) diff --git a/projects/medical/2d_image/tools/split_seg_dataset.py b/projects/medical/2d_image/tools/split_seg_dataset.py new file mode 100644 index 00000000000..9ab2e9282fa --- /dev/null +++ b/projects/medical/2d_image/tools/split_seg_dataset.py @@ -0,0 +1,42 @@ +import argparse +import glob +import os + +from sklearn.model_selection import train_test_split + + +def save_anno(img_list, file_path, remove_suffix=True): + if remove_suffix: + img_list = [ + '/'.join(img_path.split('/')[-2:]) for img_path in img_list + ] + img_list = [ + '.'.join(img_path.split('.')[:-1]) for img_path in img_list + ] + with open(file_path, 'w') as file_: + for x in list(img_list): + file_.write(x + '\n') + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--data_root', default='data/') + args = parser.parse_args() + data_root = args.data_root + if os.path.exists(os.path.join(data_root, 'masks/val')): + x_val = sorted(glob.glob(data_root + '/images/val/*.png')) + save_anno(x_val, data_root + '/val.txt') + if os.path.exists(os.path.join(data_root, 'masks/test')): + x_test = sorted(glob.glob(data_root + '/images/test/*.png')) + save_anno(x_test, data_root + '/test.txt') + if not os.path.exists(os.path.join( + data_root, 'masks/val')) and not os.path.exists( + os.path.join(data_root, 'masks/test')): + all_imgs = sorted(glob.glob(data_root + '/images/train/*.png')) + x_train, x_val = train_test_split( + all_imgs, test_size=0.2, random_state=0) + save_anno(x_train, data_root + '/train.txt') + save_anno(x_val, data_root + '/val.txt') + else: + x_train = sorted(glob.glob(data_root + '/images/train/*.png')) + save_anno(x_train, data_root + '/train.txt') diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/README.md b/projects/medical/2d_image/x_ray/chest_image_pneum/README.md new file mode 100644 index 00000000000..a1cd27ba455 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/README.md @@ -0,0 +1,147 @@ +# Chest Image Dataset for Pneumothorax Segmentation + +## Description + +This project supports **`Chest Image Dataset for Pneumothorax Segmentation`**, which can be downloaded from [here](https://tianchi.aliyun.com/dataset/83075). + +### Dataset Overview + +Pneumothorax can be caused by a blunt chest injury, damage from underlying lung disease, or most horrifying—it may occur for no obvious reason at all. On some occasions, a collapsed lung can be a life-threatening event. +Pneumothorax is usually diagnosed by a radiologist on a chest x-ray, and can sometimes be very difficult to confirm. An accurate AI algorithm to detect pneumothorax would be useful in a lot of clinical scenarios. AI could be used to triage chest radiographs for priority interpretation, or to provide a more confident diagnosis for non-radiologists. + +The dataset is provided by the Society for Imaging Informatics in Medicine(SIIM), American College of Radiology (ACR),Society of Thoracic Radiology (STR) and MD.ai. You can develop a model to classify (and if present, segment) pneumothorax from a set of chest radiographic images. If successful, you could aid in the early recognition of pneumothoraces and save lives. + +### Original Statistic Information + +| Dataset name | Anatomical region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| --------------------------------------------------------------------- | ----------------- | ------------ | -------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------------ | +| [pneumothorax segmentation](https://tianchi.aliyun.com/dataset/83075) | thorax | segmentation | x_ray | 2 | 12089/-/3205 | yes/-/no | - | [CC-BY-SA-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| normal | 12089 | 99.75 | - | - | - | - | +| pneumothorax area | 2669 | 0.25 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![bac](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/x_ray/chest_image_pneum/chest_image_pneum_dataset.png) + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `chest_image_pneum/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://tianchi.aliyun.com/dataset/83075) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set can't be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── x_ray + │ │ │ │ ├── chest_image_pneum + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── test.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :---------------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| normal | 9637 | 99.75 | 2410 | 99.74 | - | - | +| pneumothorax area | 2137 | 0.25 | 532 | 0.26 | - | - | + +### Training commands + +Train models on a single server with one GPU. + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +Test models on a single server with one GPU. + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Results + +### Bactteria detection with darkfield microscopy + +| Method | Backbone | Crop Size | lr | mIoU | mDice | config | download | +| :-------------: | :------: | :-------: | :----: | :--: | :---: | :------------------------------------------------------------------------------------: | :----------------------: | +| fcn_unet_s5-d16 | unet | 512x512 | 0.01 | - | - | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-image-pneum-512x512.py) | [model](<>) \| [log](<>) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.001 | - | - | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-image-pneum-512x512.py) | [model](<>) \| [log](<>) | +| fcn_unet_s5-d16 | unet | 512x512 | 0.0001 | - | - | [config](./configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-image-pneum-512x512.py) | [model](<>) \| [log](<>) | + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + + - [x] Basic docstrings & proper citation + + - [x] Test-time correctness + + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + + - [ ] Unit tests + + - [ ] Code polishing + + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/configs/chest-image-pneum_512x512.py b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/chest-image-pneum_512x512.py new file mode 100644 index 00000000000..411229bd413 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/chest-image-pneum_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'ChestImagePneumDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-image-pneum-512x512.py b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-image-pneum-512x512.py new file mode 100644 index 00000000000..0f26459467c --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-image-pneum-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './chest-image-pneum_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.chest-image-pneum_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-image-pneum-512x512.py b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-image-pneum-512x512.py new file mode 100644 index 00000000000..37b91889d8a --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-image-pneum-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './chest-image-pneum_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.chest-image-pneum_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-image-pneum-512x512.py b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-image-pneum-512x512.py new file mode 100644 index 00000000000..379e8181f3d --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-image-pneum-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + './chest-image-pneum_512x512.py', + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.chest-image-pneum_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/datasets/chest-image-pneum_dataset.py b/projects/medical/2d_image/x_ray/chest_image_pneum/datasets/chest-image-pneum_dataset.py new file mode 100644 index 00000000000..aeee60ae92e --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/datasets/chest-image-pneum_dataset.py @@ -0,0 +1,27 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ChestImagePneumDataset(BaseSegDataset): + """ChestImagePneumDataset dataset. + + In segmentation map annotation for ChestImagePneumDataset, + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + """ + METAINFO = dict(classes=('normal', 'pneumothorax area')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=False, + **kwargs) diff --git a/projects/medical/2d_image/x_ray/chest_image_pneum/tools/prepare_dataset.py b/projects/medical/2d_image/x_ray/chest_image_pneum/tools/prepare_dataset.py new file mode 100755 index 00000000000..47eddc96dc5 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_image_pneum/tools/prepare_dataset.py @@ -0,0 +1,73 @@ +import os + +import numpy as np +import pandas as pd +import pydicom +from PIL import Image + +root_path = 'data/' +img_suffix = '.dcm' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +x_train = [] +for fpath, dirname, fnames in os.walk('data/chestimage_train_datasets'): + for fname in fnames: + if fname.endswith('.dcm'): + x_train.append(os.path.join(fpath, fname)) +x_test = [] +for fpath, dirname, fnames in os.walk('data/chestimage_test_datasets/'): + for fname in fnames: + if fname.endswith('.dcm'): + x_test.append(os.path.join(fpath, fname)) + +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'images/test/') +os.system('mkdir -p ' + root_path + 'masks/train/') + + +def rle_decode(rle, width, height): + mask = np.zeros(width * height, dtype=np.uint8) + array = np.asarray([int(x) for x in rle.split()]) + starts = array[0::2] + lengths = array[1::2] + + current_position = 0 + for index, start in enumerate(starts): + current_position += start + mask[current_position:current_position + lengths[index]] = 1 + current_position += lengths[index] + + return mask.reshape(width, height, order='F') + + +part_dir_dict = {0: 'train/', 1: 'test/'} +dict_from_csv = pd.read_csv( + root_path + 'chestimage_train-rle_datasets.csv', sep=',', + index_col=0).to_dict()[' EncodedPixels'] + +for ith, part in enumerate([x_train, x_test]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + img_id = '.'.join(basename.split('.')[:-1]) + if ith == 0 and (img_id not in dict_from_csv.keys()): + continue + image = pydicom.read_file(img).pixel_array + save_img_path = root_path + 'images/' + part_dir + '.'.join( + basename.split('.')[:-1]) + save_img_suffix + print(save_img_path) + img_h, img_w = image.shape[:2] + image = Image.fromarray(image) + image.save(save_img_path) + if ith == 1: + continue + if dict_from_csv[img_id] == '-1': + mask = np.zeros((img_h, img_w), dtype=np.uint8) + else: + mask = rle_decode(dict_from_csv[img_id], img_h, img_w) + save_mask_path = root_path + 'masks/' + part_dir + '.'.join( + basename.split('.')[:-1]) + save_seg_map_suffix + mask = Image.fromarray(mask) + mask.save(save_mask_path) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/README.md b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/README.md new file mode 100644 index 00000000000..7cb099c8a43 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/README.md @@ -0,0 +1,119 @@ +# Chest X-ray Images with Pneumothorax Masks + +## Description + +This project support **`Chest X-ray Images with Pneumothorax Masks `**, and the dataset used in this project can be downloaded from [here](https://www.kaggle.com/datasets/vbookshelf/pneumothorax-chest-xray-images-and-masks). + +### Dataset Overview + +A pneumothorax (noo-moe-THOR-aks) is a collapsed lung. A pneumothorax occurs when air leaks into the space between your lung and chest wall. This air pushes on the outside of your lung and makes it collapse. Pneumothorax can be a complete lung collapse or a collapse of only a portion of the lung. + +A pneumothorax can be caused by a blunt or penetrating chest injury, certain medical procedures, or damage from underlying lung disease. Or it may occur for no obvious reason. Symptoms usually include sudden chest pain and shortness of breath. On some occasions, a collapsed lung can be a life-threatening event. + +Treatment for a pneumothorax usually involves inserting a needle or chest tube between the ribs to remove the excess air. However, a small pneumothorax may heal on its own. + +### Statistic Information + +| Dataset Name | Anatomical Region | Task type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release date | License | +| --------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ | -------- | ------------ | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------- | +| [Chest-x-ray-images-with-pneumothorax-masks](https://www.kaggle.com/datasets/vbookshelf/pneumothorax-chest-xray-images-and-masks) | throax | segmentation | x_ray | 2 | 10675/-/1372 | yes/-/yes | 2020 | [CC-BY-NC 4.0](https://creativecommons.org/licenses/by-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :----------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 10675 | 99.7 | - | - | 1372 | 99.71 | +| pneumothroax | 2379 | 0.3 | - | - | 290 | 0.29 | + +### Visualization + +![chest_x_ray_images_with_pneumothorax_masks](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/x_ray/chest_x_ray_images_with_pneumothorax_masks/chest_x_ray_images_with_pneumothorax_masks_dataset.png?raw=true) + +### Prerequisites + +- Python 3.8 +- PyTorch 1.10.0 +- pillow(PIL) 9.3.0 +- scikit-learn(sklearn) 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of PYTHONPATH, which should point to the project's directory so that Python can locate the module files. In chest_x_ray_images_with_pneumothorax_masks/ root directory, run the following line to add the current directory to PYTHONPATH: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset preparing + +- download dataset from [here](https://www.kaggle.com/datasets/vbookshelf/pneumothorax-chest-xray-images-and-masks) and decompression data to path 'data/'. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── x_ray + │ │ │ │ ├── chest_x_ray_images_with_pneumothorax_masks + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Training commands + +```shell +mim train mmseg ./configs/${CONFIG_PATH} +``` + +To train on multiple GPUs, e.g. 8 GPUs, run the following command: + +```shell +mim train mmseg ./configs/${CONFIG_PATH} --launcher pytorch --gpus 8 +``` + +### Testing commands + +```shell +mim test mmseg ./configs/${CONFIG_PATH} --checkpoint ${CHECKPOINT_PATH} +``` + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [x] Test-time correctness + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/chest-x-ray-images-with-pneumothorax-masks_512x512.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/chest-x-ray-images-with-pneumothorax-masks_512x512.py new file mode 100644 index 00000000000..96676de8616 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/chest-x-ray-images-with-pneumothorax-masks_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'ChestPenumoMaskDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py new file mode 100644 index 00000000000..76c214d04cb --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py @@ -0,0 +1,20 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './chest-x-ray-images-with-pneumothorax-masks_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict( + imports='datasets.chest-x-ray-images-with-pneumothorax-masks_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py new file mode 100644 index 00000000000..066996dda94 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './chest-x-ray-images-with-pneumothorax-masks_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict( + imports='datasets.chest-x-ray-images-with-pneumothorax-masks_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py new file mode 100644 index 00000000000..a7065b82315 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './chest-x-ray-images-with-pneumothorax-masks_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict( + imports='datasets.chest-x-ray-images-with-pneumothorax-masks_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py new file mode 100644 index 00000000000..e5682ee76b7 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_chest-x-ray-images-with-pneumothorax-masks-512x512.py @@ -0,0 +1,19 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', + './chest-x-ray-images-with-pneumothorax-masks_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict( + imports='datasets.chest-x-ray-images-with-pneumothorax-masks_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/datasets/chest-x-ray-images-with-pneumothorax-masks_dataset.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/datasets/chest-x-ray-images-with-pneumothorax-masks_dataset.py new file mode 100644 index 00000000000..d32f597a5a0 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/datasets/chest-x-ray-images-with-pneumothorax-masks_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class ChestPenumoMaskDataset(BaseSegDataset): + """ChestPenumoMaskDataset dataset. + + In segmentation map annotation for ChestPenumoMaskDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'penumothroax')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/tools/prepare_dataset.py b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/tools/prepare_dataset.py new file mode 100644 index 00000000000..c7de1f19042 --- /dev/null +++ b/projects/medical/2d_image/x_ray/chest_x_ray_images_with_pneumothorax_masks/tools/prepare_dataset.py @@ -0,0 +1,36 @@ +import glob +import os +import shutil + +from PIL import Image +from sklearn.model_selection import train_test_split + +root_path = 'data/' +img_suffix = '.png' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +all_imgs = glob.glob('data/siim-acr-pneumothorax/png_images/*' + img_suffix) +x_train, x_test = train_test_split(all_imgs, test_size=0.2, random_state=0) + +print(len(x_train), len(x_test)) +os.system('mkdir -p ' + root_path + 'images/train/') +os.system('mkdir -p ' + root_path + 'images/val/') +os.system('mkdir -p ' + root_path + 'masks/train/') +os.system('mkdir -p ' + root_path + 'masks/val/') + +part_dir_dict = {0: 'train/', 1: 'val/'} +for ith, part in enumerate([x_train, x_test]): + part_dir = part_dir_dict[ith] + for img in part: + basename = os.path.basename(img) + img_save_path = os.path.join(root_path, 'images', part_dir, + basename.split('.')[0] + save_img_suffix) + shutil.copy(img, img_save_path) + mask_path = 'data/siim-acr-pneumothorax/png_masks/' + basename + mask = Image.open(mask_path).convert('L') + mask_save_path = os.path.join( + root_path, 'masks', part_dir, + basename.split('.')[0] + save_seg_map_suffix) + mask.save(mask_save_path) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/README.md b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/README.md new file mode 100644 index 00000000000..8469219effa --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/README.md @@ -0,0 +1,158 @@ +# Covid-19 CT Chest X-ray Dataset + +## Description + +This project supports **`Covid-19 CT Chest X-ray Dataset`**, which can be downloaded from [here](https://github.com/ieee8023/covid-chestxray-dataset). + +### Dataset Overview + +In the context of a COVID-19 pandemic, we want to improve prognostic predictions to triage and manage patient care. Data is the first step to developing any diagnostic/prognostic tool. While there exist large public datasets of more typical chest X-rays from the NIH \[Wang 2017\], Spain \[Bustos 2019\], Stanford \[Irvin 2019\], MIT \[Johnson 2019\] and Indiana University \[Demner-Fushman 2016\], there is no collection of COVID-19 chest X-rays or CT scans designed to be used for computational analysis. + +The 2019 novel coronavirus (COVID-19) presents several unique features [Fang, 2020](https://pubs.rsna.org/doi/10.1148/radiol.2020200432) and [Ai 2020](https://pubs.rsna.org/doi/10.1148/radiol.2020200642). While the diagnosis is confirmed using polymerase chain reaction (PCR), infected patients with pneumonia may present on chest X-ray and computed tomography (CT) images with a pattern that is only moderately characteristic for the human eye [Ng, 2020](https://pubs.rsna.org/doi/10.1148/ryct.2020200034). In late January, a Chinese team published a paper detailing the clinical and paraclinical features of COVID-19. They reported that patients present abnormalities in chest CT images with most having bilateral involvement [Huang 2020](). Bilateral multiple lobular and subsegmental areas of consolidation constitute the typical findings in chest CT images of intensive care unit (ICU) patients on admission [Huang 2020](). In comparison, non-ICU patients show bilateral ground-glass opacity and subsegmental areas of consolidation in their chest CT images [Huang 2020](). In these patients, later chest CT images display bilateral ground-glass opacity with resolved consolidation [Huang 2020](). + +### Statistic Information + +| Dataset Name | Anatomical Region | Task Type | Modality | Nnum. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release date | License | +| ---------------------------------------------------------------------- | ----------------- | ------------ | -------- | ------------- | --------------------- | ---------------------- | ------------ | --------------------------------------------------------------------- | +| [Covid-19-ct-cxr](https://github.com/ieee8023/covid-chestxray-dataset) | thorax | segmentation | x_ray | 2 | 205/-/714 | yes/-/no | 2021 | [CC-BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 205 | 72.84 | - | - | - | - | +| lung | 205 | 27.16 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![cov19ctcxr](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/x_ray/covid_19_ct_cxr/covid_19_ct_cxr_dataset.png?raw=true) + +### Dataset Citation + +``` +@article{cohen2020covidProspective, + title={{COVID-19} Image Data Collection: Prospective Predictions Are the Future}, + author={Joseph Paul Cohen and Paul Morrison and Lan Dao and Karsten Roth and Tim Q Duong and Marzyeh Ghassemi}, + journal={arXiv 2006.11988}, + year={2020} +} + +@article{cohen2020covid, + title={COVID-19 image data collection}, + author={Joseph Paul Cohen and Paul Morrison and Lan Dao}, + journal={arXiv 2003.11597}, + year={2020} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 9.3.0 +- scikit-learn(sklearn) v1.2.0 1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `covid_19_ct_cxr/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://github.com/ieee8023/covid-chestxray-dataset) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```shell +mkdir data && cd data +git clone git@github.com:ieee8023/covid-chestxray-dataset.git +cd .. +python tools/prepare_dataset.py +python ../../tools/split_seg_dataset.py +``` + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── x_ray + │ │ │ │ ├── covid_19_ct_cxr + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 164 | 72.88 | 41 | 72.69 | - | - | +| lung | 164 | 27.12 | 41 | 27.31 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [x] Test-time correctness + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/covid-19-ct-cxr_512x512.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/covid-19-ct-cxr_512x512.py new file mode 100644 index 00000000000..5242d06c374 --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/covid-19-ct-cxr_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'Covid19CXRDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='val.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py new file mode 100644 index 00000000000..59a7bedaa06 --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet-{use-sigmoid}_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './covid-19-ct-cxr_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.covid-19-ct-cxr_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_covid-19-ct-cxr-512x512.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_covid-19-ct-cxr-512x512.py new file mode 100644 index 00000000000..83b8527d46d --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_covid-19-ct-cxr-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './covid-19-ct-cxr_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.covid-19-ct-cxr_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_covid-19-ct-cxr-512x512.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_covid-19-ct-cxr-512x512.py new file mode 100644 index 00000000000..10cfcbda6ec --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_covid-19-ct-cxr-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './covid-19-ct-cxr_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.covid-19-ct-cxr_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py new file mode 100644 index 00000000000..aaccc8fd8dd --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_covid-19-ct-cxr-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './covid-19-ct-cxr_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.covid-19-ct-cxr_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/datasets/covid-19-ct-cxr_dataset.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/datasets/covid-19-ct-cxr_dataset.py new file mode 100644 index 00000000000..68a1bb331f7 --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/datasets/covid-19-ct-cxr_dataset.py @@ -0,0 +1,31 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class Covid19CXRDataset(BaseSegDataset): + """Covid19CXRDataset dataset. + + In segmentation map annotation for Covid19CXRDataset, + 0 stands for background, which is included in 2 categories. + ``reduce_zero_label`` is fixed to False. The ``img_suffix`` + is fixed to '.png' and ``seg_map_suffix`` is fixed to '.png'. + + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False. + """ + METAINFO = dict(classes=('background', 'lung')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/x_ray/covid_19_ct_cxr/tools/prepare_dataset.py b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/tools/prepare_dataset.py new file mode 100644 index 00000000000..72f6435389d --- /dev/null +++ b/projects/medical/2d_image/x_ray/covid_19_ct_cxr/tools/prepare_dataset.py @@ -0,0 +1,52 @@ +import os + +import numpy as np +from PIL import Image + +root_path = 'data/' +src_img_dir = os.path.join(root_path, 'covid-chestxray-dataset', 'images') +src_mask_dir = os.path.join(root_path, 'covid-chestxray-dataset', + 'annotations/lungVAE-masks') +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_img_test_dir) + + +def convert_label(img, convert_dict): + arr = np.zeros_like(img, dtype=np.uint8) + for c, i in convert_dict.items(): + arr[img == c] = i + return arr + + +if __name__ == '__main__': + + all_img_names = os.listdir(src_img_dir) + all_mask_names = os.listdir(src_mask_dir) + + for img_name in all_img_names: + base_name = img_name.replace('.png', '') + base_name = base_name.replace('.jpg', '') + base_name = base_name.replace('.jpeg', '') + mask_name_orig = base_name + '_mask.png' + if mask_name_orig in all_mask_names: + mask_name = base_name + '.png' + src_img_path = os.path.join(src_img_dir, img_name) + src_mask_path = os.path.join(src_mask_dir, mask_name_orig) + tgt_img_path = os.path.join(tgt_img_train_dir, img_name) + tgt_mask_path = os.path.join(tgt_mask_train_dir, mask_name) + + img = Image.open(src_img_path).convert('RGB') + img.save(tgt_img_path) + mask = np.array(Image.open(src_mask_path)) + mask = convert_label(mask, {0: 0, 255: 1}) + mask = Image.fromarray(mask) + mask.save(tgt_mask_path) + else: + src_img_path = os.path.join(src_img_dir, img_name) + tgt_img_path = os.path.join(tgt_img_test_dir, img_name) + img = Image.open(src_img_path).convert('RGB') + img.save(tgt_img_path) diff --git a/projects/medical/2d_image/x_ray/crass/README.md b/projects/medical/2d_image/x_ray/crass/README.md new file mode 100644 index 00000000000..0621205be81 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/README.md @@ -0,0 +1,144 @@ +# Chest Radiograph Anatomical Structure Segmentation (CRASS) + +## Description + +This project supports **`Chest Radiograph Anatomical Structure Segmentation (CRASS) `**, which can be downloaded from [here](https://crass.grand-challenge.org/). + +### Dataset Overview + +A set of consecutively obtained posterior-anterior chest radiograph were selected from a database containing images acquired at two sites in sub Saharan Africa with a high tuberculosis incidence. All subjects were 15 years or older. Images from digital chest radiography units were used (Delft Imaging Systems, The Netherlands) of varying resolutions, with a typical resolution of 1800--2000 pixels, the pixel size was 250 lm isotropic. From the total set of images, 225 were considered to be normal by an expert radiologist, while 333 of the images contained abnormalities. Of the abnormal images, 220 contained abnormalities in the upper area of the lung where the clavicle is located. The data was divided into a training and a test set. The training set consisted of 299 images, the test set of 249 images. +The current data is still incomplete and to be added later. + +### Information Statistics + +| Dataset Name | Anatomical Region | Task Type | Modality | Num. Classes | Train/Val/Test Images | Train/Val/Test Labeled | Release Date | License | +| ------------------------------------------- | ----------------- | ------------ | -------- | ------------ | --------------------- | ---------------------- | ------------ | ------------------------------------------------------------- | +| [crass](https://crass.grand-challenge.org/) | pulmonary | segmentation | x_ray | 2 | 299/-/234 | yes/-/no | 2021 | [CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/) | + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 299 | 98.38 | - | - | - | - | +| clavicles | 299 | 1.62 | - | - | - | - | + +Note: + +- `Pct` means percentage of pixels in this category in all pixels. + +### Visualization + +![crass](https://raw.githubusercontent.com/uni-medical/medical-datasets-visualization/main/2d/semantic_seg/x_ray/crass/crass_dataset.png?raw=true) + +### Dataset Citation + +``` +@article{HOGEWEG20121490, + title={Clavicle segmentation in chest radiographs}, + journal={Medical Image Analysis}, + volume={16}, + number={8}, + pages={1490-1502}, + year={2012} +} +``` + +### Prerequisites + +- Python v3.8 +- PyTorch v1.10.0 +- pillow(PIL) v9.3.0 +- scikit-learn(sklearn) v1.2.0 +- [MIM](https://github.com/open-mmlab/mim) v0.3.4 +- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 +- [MMEngine](https://github.com/open-mmlab/mmengine) v0.2.0 or higher +- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation) v1.0.0rc5 + +All the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `crass/` root directory, run the following line to add the current directory to `PYTHONPATH`: + +```shell +export PYTHONPATH=`pwd`:$PYTHONPATH +``` + +### Dataset Preparing + +- download dataset from [here](https://crass.grand-challenge.org/) and decompress data to path `'data/'`. +- run script `"python tools/prepare_dataset.py"` to format data and change folder structure as below. +- run script `"python ../../tools/split_seg_dataset.py"` to split dataset and generate `train.txt`, `val.txt` and `test.txt`. If the label of official validation set and test set cannot be obtained, we generate `train.txt` and `val.txt` from the training set randomly. + +```none + mmsegmentation + ├── mmseg + ├── projects + │ ├── medical + │ │ ├── 2d_image + │ │ │ ├── x_ray + │ │ │ │ ├── crass + │ │ │ │ │ ├── configs + │ │ │ │ │ ├── datasets + │ │ │ │ │ ├── tools + │ │ │ │ │ ├── data + │ │ │ │ │ │ ├── train.txt + │ │ │ │ │ │ ├── val.txt + │ │ │ │ │ │ ├── images + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png + │ │ │ │ │ │ ├── masks + │ │ │ │ │ │ │ ├── train + │ │ │ │ | │ │ │ ├── xxx.png + │ │ │ │ | │ │ │ ├── ... + │ │ │ │ | │ │ │ └── xxx.png +``` + +### Divided Dataset Information + +***Note: The table information below is divided by ourselves.*** + +| Class Name | Num. Train | Pct. Train | Num. Val | Pct. Val | Num. Test | Pct. Test | +| :--------: | :--------: | :--------: | :------: | :------: | :-------: | :-------: | +| background | 227 | 98.38 | 57 | 98.39 | - | - | +| clavicles | 227 | 1.62 | 57 | 1.61 | - | - | + +### Training commands + +To train models on a single server with one GPU. (default) + +```shell +mim train mmseg ./configs/${CONFIG_FILE} +``` + +### Testing commands + +To test models on a single server with one GPU. (default) + +```shell +mim test mmseg ./configs/${CONFIG_FILE} --checkpoint ${CHECKPOINT_PATH} +``` + + + +## Checklist + +- [x] Milestone 1: PR-ready, and acceptable to be one of the `projects/`. + + - [x] Finish the code + - [x] Basic docstrings & proper citation + - [ ] Test-time correctness + - [x] A full README + +- [x] Milestone 2: Indicates a successful model implementation. + + - [x] Training-time correctness + +- [ ] Milestone 3: Good to be a part of our core package! + + - [ ] Type hints and docstrings + - [ ] Unit tests + - [ ] Code polishing + - [ ] Metafile.yml + +- [ ] Move your modules into the core package following the codebase's file hierarchy structure. + +- [ ] Refactor your modules into the core package following the codebase's file hierarchy structure. diff --git a/projects/medical/2d_image/x_ray/crass/configs/crass_512x512.py b/projects/medical/2d_image/x_ray/crass/configs/crass_512x512.py new file mode 100644 index 00000000000..1425f50cc46 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/configs/crass_512x512.py @@ -0,0 +1,42 @@ +dataset_type = 'CRASSDataset' +data_root = 'data/' +img_scale = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=img_scale, keep_ratio=False), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') +] +train_dataloader = dict( + batch_size=16, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='train.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + ann_file='tval.txt', + data_prefix=dict(img_path='images/', seg_map_path='masks/'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) +test_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU', 'mDice']) diff --git a/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_crass-512x512.py b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_crass-512x512.py new file mode 100644 index 00000000000..b52bc78f790 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.0001-20k_crass-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './crass_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.crass_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.0001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_crass-512x512.py b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_crass-512x512.py new file mode 100644 index 00000000000..45242c65b48 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.001-20k_crass-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './crass_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.crass_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.001) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_crass-512x512.py b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_crass-512x512.py new file mode 100644 index 00000000000..bcf9d0a5ca5 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-0.01-20k_crass-512x512.py @@ -0,0 +1,17 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './crass_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.crass_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict(num_classes=2), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-lr0.01-sigmoid-20k_crass-512x512.py b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-lr0.01-sigmoid-20k_crass-512x512.py new file mode 100644 index 00000000000..0dde736bf76 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/configs/fcn-unet-s5-d16_unet_1xb16-lr0.01-sigmoid-20k_crass-512x512.py @@ -0,0 +1,18 @@ +_base_ = [ + 'mmseg::_base_/models/fcn_unet_s5-d16.py', './crass_512x512.py', + 'mmseg::_base_/default_runtime.py', + 'mmseg::_base_/schedules/schedule_20k.py' +] +custom_imports = dict(imports='datasets.crass_dataset') +img_scale = (512, 512) +data_preprocessor = dict(size=img_scale) +optimizer = dict(lr=0.01) +optim_wrapper = dict(optimizer=optimizer) +model = dict( + data_preprocessor=data_preprocessor, + decode_head=dict( + num_classes=2, loss_decode=dict(use_sigmoid=True), out_channels=1), + auxiliary_head=None, + test_cfg=dict(mode='whole', _delete_=True)) +vis_backends = None +visualizer = dict(vis_backends=vis_backends) diff --git a/projects/medical/2d_image/x_ray/crass/datasets/crass_dataset.py b/projects/medical/2d_image/x_ray/crass/datasets/crass_dataset.py new file mode 100644 index 00000000000..f6b5c5228bc --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/datasets/crass_dataset.py @@ -0,0 +1,30 @@ +from mmseg.datasets import BaseSegDataset +from mmseg.registry import DATASETS + + +@DATASETS.register_module() +class CRASSDataset(BaseSegDataset): + """CRASSDataset dataset. + + In segmentation map annotation for CRASSDataset, 0 stands for background, + which is included in 2 categories. ``reduce_zero_label`` is fixed to + False. The ``img_suffix`` is fixed to '.png' and ``seg_map_suffix`` is + fixed to '.png'. + Args: + img_suffix (str): Suffix of images. Default: '.png' + seg_map_suffix (str): Suffix of segmentation maps. Default: '.png' + reduce_zero_label (bool): Whether to mark label zero as ignored. + Default to False.. + """ + METAINFO = dict(classes=('background', 'clavicles')) + + def __init__(self, + img_suffix='.png', + seg_map_suffix='.png', + reduce_zero_label=False, + **kwargs) -> None: + super().__init__( + img_suffix=img_suffix, + seg_map_suffix=seg_map_suffix, + reduce_zero_label=reduce_zero_label, + **kwargs) diff --git a/projects/medical/2d_image/x_ray/crass/tools/prepare_dataset.py b/projects/medical/2d_image/x_ray/crass/tools/prepare_dataset.py new file mode 100644 index 00000000000..bbd5d8891d4 --- /dev/null +++ b/projects/medical/2d_image/x_ray/crass/tools/prepare_dataset.py @@ -0,0 +1,84 @@ +import glob +import os + +import cv2 +import SimpleITK as sitk +from PIL import Image + +root_path = 'data/' +img_suffix = '.tif' +seg_map_suffix = '.png' +save_img_suffix = '.png' +save_seg_map_suffix = '.png' + +src_img_train_dir = os.path.join(root_path, 'CRASS/data_train') +src_mask_train_dir = os.path.join(root_path, 'CRASS/mask_mhd') +src_img_test_dir = os.path.join(root_path, 'CRASS/data_test') + +tgt_img_train_dir = os.path.join(root_path, 'images/train/') +tgt_mask_train_dir = os.path.join(root_path, 'masks/train/') +tgt_img_test_dir = os.path.join(root_path, 'images/test/') +os.system('mkdir -p ' + tgt_img_train_dir) +os.system('mkdir -p ' + tgt_mask_train_dir) +os.system('mkdir -p ' + tgt_img_test_dir) + + +def filter_suffix_recursive(src_dir, suffix): + suffix = '.' + suffix if '.' not in suffix else suffix + file_paths = glob( + os.path.join(src_dir, '**', '*' + suffix), recursive=True) + file_names = [_.split('/')[-1] for _ in file_paths] + return sorted(file_paths), sorted(file_names) + + +def read_single_array_from_med(path): + return sitk.GetArrayFromImage(sitk.ReadImage(path)).squeeze() + + +def convert_meds_into_pngs(src_dir, + tgt_dir, + suffix='.dcm', + norm_min=0, + norm_max=255, + convert='RGB'): + if not os.path.exists(tgt_dir): + os.makedirs(tgt_dir) + + src_paths, src_names = filter_suffix_recursive(src_dir, suffix=suffix) + num = len(src_paths) + for i, (src_name, src_path) in enumerate(zip(src_names, src_paths)): + tgt_name = src_name.replace(suffix, '.png') + tgt_path = os.path.join(tgt_dir, tgt_name) + + img = read_single_array_from_med(src_path) + if norm_min is not None and norm_max is not None: + img = cv2.normalize(img, None, norm_min, norm_max, cv2.NORM_MINMAX, + cv2.CV_8U) + pil = Image.fromarray(img).convert(convert) + pil.save(tgt_path) + print(f'processed {i+1}/{num}.') + + +convert_meds_into_pngs( + src_img_train_dir, + tgt_img_train_dir, + suffix='.mhd', + norm_min=0, + norm_max=255, + convert='RGB') + +convert_meds_into_pngs( + src_img_test_dir, + tgt_img_test_dir, + suffix='.mhd', + norm_min=0, + norm_max=255, + convert='RGB') + +convert_meds_into_pngs( + src_mask_train_dir, + tgt_mask_train_dir, + suffix='.mhd', + norm_min=0, + norm_max=1, + convert='L') diff --git a/projects/pp_mobileseg/README.md b/projects/pp_mobileseg/README.md new file mode 100644 index 00000000000..c9f9c128e74 --- /dev/null +++ b/projects/pp_mobileseg/README.md @@ -0,0 +1,123 @@ +# PP-MobileSeg: Exploring Transformer Blocks for Efficient Mobile Segmentation. + +## Reference + +> [PP-MobileSeg: Explore the Fast and Accurate Semantic Segmentation Model on Mobile Devices. ](https://arxiv.org/abs/2304.05152) + +## Introduction + +Official Repo + +Code Snippet + +## Abstract + +With the success of transformers in computer vision, several attempts have been made to adapt transformers to mobile devices. However, their performance is not satisfied for some real world applications. Therefore, we propose PP-MobileSeg, a SOTA semantic segmentation model for mobile devices. + +It is composed of three newly proposed parts, the strideformer backbone, the Aggregated Attention Module(AAM), and the Valid Interpolate Module(VIM): + +- With the four-stage MobileNetV3 block as the feature extractor, we manage to extract rich local features of different receptive fields with little parameter overhead. Also, we further efficiently empower features from the last two stages with the global view using strided sea attention. +- To effectively fuse the features, we use AAM to filter the detail features with ensemble voting and add the semantic feature to it to enhance the semantic information to the most content. +- At last, we use VIM to upsample the downsampled feature to the original resolution and significantly decrease latency in model inference stage. It only interpolates classes present in the final prediction which only takes around 10% in the ADE20K dataset. This is a common scenario for datasets with large classes. Therefore it significantly decreases the latency of the final upsample process which takes the greatest part of the model's overall latency. + +Extensive experiments show that PP-MobileSeg achieves a superior params-accuracy-latency tradeoff compared to other SOTA methods. + +
+ +
+ +## Performance + +### ADE20K + +| Model | Backbone | Training Iters | Batchsize | Train Resolution | mIoU(%) | latency(ms)\* | params(M) | config | Links | +| ----------------- | ----------------- | -------------- | --------- | ---------------- | ------- | ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| PP-MobileSeg-Base | StrideFormer-Base | 80000 | 32 | 512x512 | 41.57% | 265.5 | 5.62 | [config](https://github.com/Yang-Changhui/mmsegmentation/tree/add_ppmobileseg/projects/pp_mobileseg/configs/pp_mobileseg) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pp_mobileseg/pp_mobileseg_mobilenetv3_2xb16_3rdparty-base_512x512-ade20k-f12b44f3.pth)\|[log](https://bj.bcebos.com/paddleseg/dygraph/ade20k/pp_mobileseg_base/train.log) | +| PP-MobileSeg-Tiny | StrideFormer-Tiny | 80000 | 32 | 512x512 | 36.39% | 215.3 | 1.61 | [config](https://github.com/Yang-Changhui/mmsegmentation/tree/add_ppmobileseg/projects/pp_mobileseg/configs/pp_mobileseg) | [model](https://download.openmmlab.com/mmsegmentation/v0.5/pp_mobileseg/pp_mobileseg_mobilenetv3_2xb16_3rdparty-tiny_512x512-ade20k-a351ebf5.pth)\|[log](https://bj.bcebos.com/paddleseg/dygraph/ade20k/pp_mobileseg_tiny/train.log) | + +## Usage + +Same as other models in MMsegmentation, you can run the following command to test the model at ${MMSEG_ROOT}: + +```shell +./tools/dist_test.sh projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_base.py checkpoints/pp_mobileseg_mobilenetv3_2xb16_3rdparty-base_512x512-ade20k-f12b44f3.pth 8 +``` + +## Inference with ONNXRuntime + +### Prerequisites + +**1. Install onnxruntime inference engine.** + +Choose one of the following ways to install onnxruntime. + +- CPU version + +```shell +pip install onnxruntime==1.15.1 +wget https://github.com/microsoft/onnxruntime/releases/download/v1.15.1/onnxruntime-linux-x64-1.15.1.tgz +tar -zxvf onnxruntime-linux-x64-1.15.1.tgz +export ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-1.15.1 +export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH +``` + +**2. Convert model to onnx file** + +- Install `mim` and `mmdeploy`. + +```shell +pip install openmim +mim install mmdeploy +git clone https://github.com/open-mmlab/mmdeploy.git +``` + +- Download pp_mobileseg model. + +```shell +wget https://download.openmmlab.com/mmsegmentation/v0.5/pp_mobileseg/pp_mobileseg_mobilenetv3_2xb16_3rdparty-tiny_512x512-ade20k-a351ebf5.pth +``` + +- Convert model to onnx files. + +```shell +python mmdeploy/tools/deploy.py mmdeploy/configs/mmseg/segmentation_onnxruntime_dynamic.py \ + configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_tiny.py \ + pp_mobileseg_mobilenetv3_2xb16_3rdparty-tiny_512x512-ade20k-a351ebf5.pth \ + ../../demo/demo.png \ + --work-dir mmdeploy_model/mmseg/ort \ + --show +``` + +**3. Run demo** + +```shell +python inference_onnx.py ${ONNX_FILE_PATH} ${IMAGE_PATH} [${MODEL_INPUT_SIZE} ${DEVICE} ${OUTPUT_IMAGE_PATH}] +``` + +Example: + +```shell +python inference_onnx.py mmdeploy_model/mmseg/ort/end2end.onnx ../../demo/demo.png +``` + +## Citation + +If you find our project useful in your research, please consider citing: + +``` +@misc{liu2021paddleseg, + title={PaddleSeg: A High-Efficient Development Toolkit for Image Segmentation}, + author={Yi Liu and Lutao Chu and Guowei Chen and Zewu Wu and Zeyu Chen and Baohua Lai and Yuying Hao}, + year={2021}, + eprint={2101.06175}, + archivePrefix={arXiv}, + primaryClass={cs.CV} +} + +@misc{paddleseg2019, + title={PaddleSeg, End-to-end image segmentation kit based on PaddlePaddle}, + author={PaddlePaddle Contributors}, + howpublished = {\url{https://github.com/PaddlePaddle/PaddleSeg}}, + year={2019} +} +``` diff --git a/projects/pp_mobileseg/backbones/__init__.py b/projects/pp_mobileseg/backbones/__init__.py new file mode 100644 index 00000000000..244b33d37a8 --- /dev/null +++ b/projects/pp_mobileseg/backbones/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .strideformer import StrideFormer + +__all__ = ['StrideFormer'] diff --git a/projects/pp_mobileseg/backbones/strideformer.py b/projects/pp_mobileseg/backbones/strideformer.py new file mode 100644 index 00000000000..3f09be5225d --- /dev/null +++ b/projects/pp_mobileseg/backbones/strideformer.py @@ -0,0 +1,958 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import math +import warnings + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import ConvModule, build_activation_layer +from mmcv.cnn.bricks.transformer import build_dropout +from mmengine.logging import print_log +from mmengine.model import BaseModule +from mmengine.runner.checkpoint import CheckpointLoader, load_state_dict + +from mmseg.registry import MODELS + + +@MODELS.register_module() +class StrideFormer(BaseModule): + """The StrideFormer implementation based on torch. + + The original article refers to:https://arxiv.org/abs/2304.05152 + Args: + mobileV3_cfg(list): Each sublist describe the config for a + MobileNetV3 block. + channels(list): The input channels for each MobileNetV3 block. + embed_dims(list): The channels of the features input to the sea + attention block. + key_dims(list, optional): The embeding dims for each head in + attention. + depths(list, optional): describes the depth of the attention block. + i,e: M,N. + num_heads(int, optional): The number of heads of the attention + blocks. + attn_ratios(int, optional): The expand ratio of V. + mlp_ratios(list, optional): The ratio of mlp blocks. + drop_path_rate(float, optional): The drop path rate in attention + block. + act_cfg(dict, optional): The activation layer of AAM: + Aggregate Attention Module. + inj_type(string, optional): The type of injection/AAM. + out_channels(int, optional): The output channels of the AAM. + dims(list, optional): The dimension of the fusion block. + out_feat_chs(list, optional): The input channels of the AAM. + stride_attention(bool, optional): whether to stride attention in + each attention layer. + pretrained(str, optional): the path of pretrained model. + """ + + def __init__( + self, + mobileV3_cfg, + channels, + embed_dims, + key_dims=[16, 24], + depths=[2, 2], + num_heads=8, + attn_ratios=2, + mlp_ratios=[2, 4], + drop_path_rate=0.1, + act_cfg=dict(type='ReLU'), + inj_type='AAM', + out_channels=256, + dims=(128, 160), + out_feat_chs=None, + stride_attention=True, + pretrained=None, + init_cfg=None, + ): + super().__init__(init_cfg=init_cfg) + assert not (init_cfg and pretrained + ), 'init_cfg and pretrained cannot be set at the same time' + if isinstance(pretrained, str): + warnings.warn('DeprecationWarning: pretrained is deprecated, ' + 'please use "init_cfg" instead') + self.init_cfg = dict(type='Pretrained', checkpoint=pretrained) + elif pretrained is not None: + raise TypeError('pretrained must be a str or None') + + self.depths = depths + self.cfgs = mobileV3_cfg + self.dims = dims + for i in range(len(self.cfgs)): + smb = StackedMV3Block( + cfgs=self.cfgs[i], + stem=True if i == 0 else False, + in_channels=channels[i], + ) + setattr(self, f'smb{i + 1}', smb) + for i in range(len(depths)): + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, depths[i]) + ] + trans = BasicLayer( + block_num=depths[i], + embedding_dim=embed_dims[i], + key_dim=key_dims[i], + num_heads=num_heads, + mlp_ratio=mlp_ratios[i], + attn_ratio=attn_ratios, + drop=0, + attn_drop=0.0, + drop_path=dpr, + act_cfg=act_cfg, + stride_attention=stride_attention, + ) + setattr(self, f'trans{i + 1}', trans) + + self.inj_type = inj_type + if self.inj_type == 'AAM': + self.inj_module = InjectionMultiSumallmultiallsum( + in_channels=out_feat_chs, out_channels=out_channels) + self.feat_channels = [ + out_channels, + ] + elif self.inj_type == 'AAMSx8': + self.inj_module = InjectionMultiSumallmultiallsumSimpx8( + in_channels=out_feat_chs, out_channels=out_channels) + self.feat_channels = [ + out_channels, + ] + elif self.inj_type == 'origin': + for i in range(len(dims)): + fuse = FusionBlock( + out_feat_chs[0] if i == 0 else dims[i - 1], + out_feat_chs[i + 1], + embed_dim=dims[i], + act_cfg=None, + ) + setattr(self, f'fuse{i + 1}', fuse) + self.feat_channels = [ + dims[i], + ] + else: + raise NotImplementedError(self.inj_module + ' is not implemented') + + self.pretrained = pretrained + # self.init_weights() + + def init_weights(self): + if (isinstance(self.init_cfg, dict) + and self.init_cfg.get('type') == 'Pretrained'): + checkpoint = CheckpointLoader.load_checkpoint( + self.init_cfg['checkpoint'], logger=None, map_location='cpu') + + if 'state_dict' in checkpoint: + state_dict = checkpoint['state_dict'] + else: + state_dict = checkpoint + + if 'pos_embed' in state_dict.keys(): + if self.pos_embed.shape != state_dict['pos_embed'].shape: + print_log(msg=f'Resize the pos_embed shape from ' + f'{state_dict["pos_embed"].shape} to ' + f'{self.pos_embed.shape}') + h, w = self.img_size + pos_size = int( + math.sqrt(state_dict['pos_embed'].shape[1] - 1)) + state_dict['pos_embed'] = self.resize_pos_embed( + state_dict['pos_embed'], + (h // self.patch_size, w // self.patch_size), + (pos_size, pos_size), + self.interpolate_mode, + ) + + load_state_dict(self, state_dict, strict=False, logger=None) + + def forward(self, x): + x_hw = x.shape[2:] + outputs = [] + num_smb_stage = len(self.cfgs) + num_trans_stage = len(self.depths) + + for i in range(num_smb_stage): + smb = getattr(self, f'smb{i + 1}') + x = smb(x) + + # 1/8 shared feat + if i == 1: + outputs.append(x) + if num_trans_stage + i >= num_smb_stage: + trans = getattr( + self, f'trans{i + num_trans_stage - num_smb_stage + 1}') + x = trans(x) + outputs.append(x) + if self.inj_type == 'origin': + x_detail = outputs[0] + for i in range(len(self.dims)): + fuse = getattr(self, f'fuse{i + 1}') + + x_detail = fuse(x_detail, outputs[i + 1]) + output = x_detail + else: + output = self.inj_module(outputs) + + return [output, x_hw] + + +class StackedMV3Block(nn.Module): + """The MobileNetV3 block. + + Args: + cfgs (list): The MobileNetV3 config list of a stage. + stem (bool): Whether is the first stage or not. + in_channels (int, optional): The channels of input image. Default: 3. + scale: float=1.0. + The coefficient that controls the size of network parameters. + + Returns: + model: nn.Module. + A stage of specific MobileNetV3 model depends on args. + """ + + def __init__(self, + cfgs, + stem, + in_channels, + scale=1.0, + norm_cfg=dict(type='BN')): + super().__init__() + + self.scale = scale + self.stem = stem + + if self.stem: + self.conv = ConvModule( + in_channels=3, + out_channels=_make_divisible(in_channels * self.scale), + kernel_size=3, + stride=2, + padding=1, + groups=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=dict(type='HSwish'), + ) + + self.blocks = nn.ModuleList() + for i, (k, exp, c, se, act, s) in enumerate(cfgs): + self.blocks.append( + ResidualUnit( + in_channel=_make_divisible(in_channels * self.scale), + mid_channel=_make_divisible(self.scale * exp), + out_channel=_make_divisible(self.scale * c), + kernel_size=k, + stride=s, + use_se=se, + act=act, + dilation=1, + )) + in_channels = _make_divisible(self.scale * c) + + def forward(self, x): + if self.stem: + x = self.conv(x) + for i, block in enumerate(self.blocks): + x = block(x) + + return x + + +class ResidualUnit(nn.Module): + """The Residual module. + + Args: + in_channel (int, optional): The channels of input feature. + mid_channel (int, optional): The channels of middle process. + out_channel (int, optional): The channels of output feature. + kernel_size (int, optional): The size of the convolving kernel. + stride (int, optional): The stride size. + use_se (bool, optional): if to use the SEModule. + act (string, optional): activation layer. + dilation (int, optional): The dilation size. + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN', requires_grad=True). + """ + + def __init__( + self, + in_channel, + mid_channel, + out_channel, + kernel_size, + stride, + use_se, + act=None, + dilation=1, + norm_cfg=dict(type='BN'), + ): + super().__init__() + self.if_shortcut = stride == 1 and in_channel == out_channel + self.if_se = use_se + self.expand_conv = ConvModule( + in_channels=in_channel, + out_channels=mid_channel, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=dict(type=act) if act is not None else None, + ) + self.bottleneck_conv = ConvModule( + in_channels=mid_channel, + out_channels=mid_channel, + kernel_size=kernel_size, + stride=stride, + padding=int((kernel_size - 1) // 2) * dilation, + bias=False, + groups=mid_channel, + dilation=dilation, + norm_cfg=norm_cfg, + act_cfg=dict(type=act) if act is not None else None, + ) + if self.if_se: + self.mid_se = SEModule(mid_channel) + self.linear_conv = ConvModule( + in_channels=mid_channel, + out_channels=out_channel, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + ) + + def forward(self, x): + identity = x + x = self.expand_conv(x) + x = self.bottleneck_conv(x) + if self.if_se: + x = self.mid_se(x) + x = self.linear_conv(x) + if self.if_shortcut: + x = torch.add(identity, x) + return x + + +class SEModule(nn.Module): + """SE Module. + + Args: + channel (int, optional): The channels of input feature. + reduction (int, optional): The channel reduction rate. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + """ + + def __init__(self, channel, reduction=4, act_cfg=dict(type='ReLU')): + super().__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.conv_act1 = ConvModule( + in_channels=channel, + out_channels=channel // reduction, + kernel_size=1, + norm_cfg=None, + act_cfg=act_cfg, + ) + + self.conv_act2 = ConvModule( + in_channels=channel // reduction, + out_channels=channel, + kernel_size=1, + norm_cfg=None, + act_cfg=dict(type='Hardsigmoid', slope=0.2, offset=0.5), + ) + + def forward(self, x): + identity = x + x = self.avg_pool(x) + x = self.conv_act1(x) + x = self.conv_act2(x) + return torch.mul(identity, x) + + +class BasicLayer(nn.Module): + """The transformer basic layer. + + Args: + block_num (int): the block nums of the transformer basic layer. + embedding_dim (int): The feature dimension. + key_dim (int): the key dim. + num_heads (int): Parallel attention heads. + mlp_ratio (float): the mlp ratio. + attn_ratio (float): the attention ratio. + drop (float): Probability of an element to be zeroed + after the feed forward layer.Default: 0.0. + attn_drop (float): The drop out rate for attention layer. + Default: 0.0. + drop_path (float): stochastic depth rate. Default 0.0. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + stride_attention (bool, optional): whether to stride attention in + each attention layer. + """ + + def __init__( + self, + block_num, + embedding_dim, + key_dim, + num_heads, + mlp_ratio=4.0, + attn_ratio=2.0, + drop=0.0, + attn_drop=0.0, + drop_path=None, + act_cfg=None, + stride_attention=None, + ): + super().__init__() + self.block_num = block_num + + self.transformer_blocks = nn.ModuleList() + for i in range(self.block_num): + self.transformer_blocks.append( + Block( + embedding_dim, + key_dim=key_dim, + num_heads=num_heads, + mlp_ratio=mlp_ratio, + attn_ratio=attn_ratio, + drop=drop, + drop_path=drop_path[i] + if isinstance(drop_path, list) else drop_path, + act_cfg=act_cfg, + stride_attention=stride_attention, + )) + + def forward(self, x): + for i in range(self.block_num): + x = self.transformer_blocks[i](x) + return x + + +class Block(nn.Module): + """the block of the transformer basic layer. + + Args: + dim (int): The feature dimension. + key_dim (int): The key dimension. + num_heads (int): Parallel attention heads. + mlp_ratio (float): the mlp ratio. + attn_ratio (float): the attention ratio. + drop (float): Probability of an element to be zeroed + after the feed forward layer.Default: 0.0. + drop_path (float): stochastic depth rate. Default 0.0. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + stride_attention (bool, optional): whether to stride attention in + each attention layer. + """ + + def __init__( + self, + dim, + key_dim, + num_heads, + mlp_ratio=4.0, + attn_ratio=2.0, + drop=0.0, + drop_path=0.0, + act_cfg=None, + stride_attention=None, + ): + super().__init__() + self.dim = dim + self.num_heads = num_heads + self.mlp_ratio = mlp_ratio + self.attn = SeaAttention( + dim, + key_dim=key_dim, + num_heads=num_heads, + attn_ratio=attn_ratio, + act_cfg=act_cfg, + stride_attention=stride_attention, + ) + self.drop_path = ( + build_dropout(dict(type='DropPath', drop_prob=drop_path)) + if drop_path > 0.0 else nn.Identity()) + mlp_hidden_dim = int(dim * mlp_ratio) + self.mlp = MLP( + in_features=dim, + hidden_features=mlp_hidden_dim, + act_cfg=act_cfg, + drop=drop, + ) + + def forward(self, x1): + x1 = x1 + self.drop_path(self.attn(x1)) + x1 = x1 + self.drop_path(self.mlp(x1)) + + return x1 + + +class SqueezeAxialPositionalEmbedding(nn.Module): + """the Squeeze Axial Positional Embedding. + + Args: + dim (int): The feature dimension. + shape (int): The patch size. + """ + + def __init__(self, dim, shape): + super().__init__() + self.pos_embed = nn.init.normal_( + nn.Parameter(torch.zeros(1, dim, shape))) + + def forward(self, x): + B, C, N = x.shape + x = x + F.interpolate( + self.pos_embed, size=(N, ), mode='linear', align_corners=False) + return x + + +class SeaAttention(nn.Module): + """The sea attention. + + Args: + dim (int): The feature dimension. + key_dim (int): The key dimension. + num_heads (int): number of attention heads. + attn_ratio (float): the attention ratio. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='LN') + stride_attention (bool, optional): whether to stride attention in + each attention layer. + """ + + def __init__( + self, + dim, + key_dim, + num_heads, + attn_ratio=4.0, + act_cfg=None, + norm_cfg=dict(type='BN'), + stride_attention=False, + ): + + super().__init__() + self.num_heads = num_heads + self.scale = key_dim**-0.5 + self.nh_kd = nh_kd = key_dim * num_heads + self.d = int(attn_ratio * key_dim) + self.dh = int(attn_ratio * key_dim) * num_heads + self.attn_ratio = attn_ratio + + self.to_q = ConvModule( + dim, nh_kd, 1, bias=False, norm_cfg=norm_cfg, act_cfg=None) + self.to_k = ConvModule( + dim, nh_kd, 1, bias=False, norm_cfg=norm_cfg, act_cfg=None) + + self.to_v = ConvModule( + dim, self.dh, 1, bias=False, norm_cfg=norm_cfg, act_cfg=None) + self.stride_attention = stride_attention + if self.stride_attention: + self.stride_conv = ConvModule( + dim, + dim, + kernel_size=3, + stride=2, + padding=1, + bias=True, + groups=dim, + norm_cfg=norm_cfg, + act_cfg=None, + ) + + self.proj = ConvModule( + self.dh, + dim, + 1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + order=('act', 'conv', 'norm'), + ) + self.proj_encode_row = ConvModule( + self.dh, + self.dh, + 1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + order=('act', 'conv', 'norm'), + ) + self.pos_emb_rowq = SqueezeAxialPositionalEmbedding(nh_kd, 16) + self.pos_emb_rowk = SqueezeAxialPositionalEmbedding(nh_kd, 16) + self.proj_encode_column = ConvModule( + self.dh, + self.dh, + 1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + order=('act', 'conv', 'norm'), + ) + self.pos_emb_columnq = SqueezeAxialPositionalEmbedding(nh_kd, 16) + self.pos_emb_columnk = SqueezeAxialPositionalEmbedding(nh_kd, 16) + self.dwconv = ConvModule( + 2 * self.dh, + 2 * self.dh, + 3, + padding=1, + groups=2 * self.dh, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + ) + self.pwconv = ConvModule( + 2 * self.dh, dim, 1, bias=False, norm_cfg=norm_cfg, act_cfg=None) + self.sigmoid = build_activation_layer(dict(type='HSigmoid')) + + def forward(self, x): + B, C, H_ori, W_ori = x.shape + if self.stride_attention: + x = self.stride_conv(x) + B, C, H, W = x.shape + + q = self.to_q(x) # [B, nhead*dim, H, W] + k = self.to_k(x) + v = self.to_v(x) + + qkv = torch.cat([q, k, v], dim=1) + qkv = self.dwconv(qkv) + qkv = self.pwconv(qkv) + + qrow = (self.pos_emb_rowq(q.mean(-1)).reshape( + [B, self.num_heads, -1, H]).permute( + (0, 1, 3, 2))) # [B, nhead, H, dim] + krow = self.pos_emb_rowk(k.mean(-1)).reshape( + [B, self.num_heads, -1, H]) # [B, nhead, dim, H] + vrow = (v.mean(-1).reshape([B, self.num_heads, -1, + H]).permute([0, 1, 3, 2]) + ) # [B, nhead, H, dim*attn_ratio] + + attn_row = torch.matmul(qrow, krow) * self.scale # [B, nhead, H, H] + attn_row = nn.functional.softmax(attn_row, dim=-1) + + xx_row = torch.matmul(attn_row, vrow) # [B, nhead, H, dim*attn_ratio] + xx_row = self.proj_encode_row( + xx_row.permute([0, 1, 3, 2]).reshape([B, self.dh, H, 1])) + + # squeeze column + qcolumn = ( + self.pos_emb_columnq(q.mean(-2)).reshape( + [B, self.num_heads, -1, W]).permute([0, 1, 3, 2])) + kcolumn = self.pos_emb_columnk(k.mean(-2)).reshape( + [B, self.num_heads, -1, W]) + vcolumn = ( + torch.mean(v, -2).reshape([B, self.num_heads, -1, + W]).permute([0, 1, 3, 2])) + + attn_column = torch.matmul(qcolumn, kcolumn) * self.scale + attn_column = nn.functional.softmax(attn_column, dim=-1) + + xx_column = torch.matmul(attn_column, vcolumn) # B nH W C + xx_column = self.proj_encode_column( + xx_column.permute([0, 1, 3, 2]).reshape([B, self.dh, 1, W])) + + xx = torch.add(xx_row, xx_column) # [B, self.dh, H, W] + xx = torch.add(v, xx) + + xx = self.proj(xx) + xx = self.sigmoid(xx) * qkv + if self.stride_attention: + xx = F.interpolate(xx, size=(H_ori, W_ori), mode='bilinear') + + return xx + + +class MLP(nn.Module): + """the Multilayer Perceptron. + + Args: + in_features (int): the input feature. + hidden_features (int): the hidden feature. + out_features (int): the output feature. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='PReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN') + drop (float): Probability of an element to be zeroed. + Default 0.0 + """ + + def __init__( + self, + in_features, + hidden_features=None, + out_features=None, + act_cfg=None, + norm_cfg=dict(type='BN'), + drop=0.0, + ): + super().__init__() + out_features = out_features or in_features + hidden_features = hidden_features or in_features + self.fc1 = ConvModule( + in_features, + hidden_features, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + ) + self.dwconv = ConvModule( + hidden_features, + hidden_features, + kernel_size=3, + padding=1, + groups=hidden_features, + norm_cfg=None, + act_cfg=act_cfg, + ) + + self.fc2 = ConvModule( + hidden_features, + out_features, + 1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + ) + self.drop = build_dropout(dict(type='Dropout', drop_prob=drop)) + + def forward(self, x): + x = self.fc1(x) + x = self.dwconv(x) + x = self.drop(x) + x = self.fc2(x) + x = self.drop(x) + return x + + +class FusionBlock(nn.Module): + """The feature fusion block. + + Args: + in_channel (int): the input channel. + out_channel (int): the output channel. + embed_dim (int): embedding dimension. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN') + """ + + def __init__( + self, + in_channel, + out_channel, + embed_dim, + norm_cfg=dict(type='BN'), + act_cfg=dict(type='ReLU'), + ) -> None: + super().__init__() + self.local_embedding = ConvModule( + in_channels=in_channel, + out_channels=embed_dim, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + ) + + self.global_act = ConvModule( + in_channels=out_channel, + out_channels=embed_dim, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg if act_cfg is not None else None, + ) + + def forward(self, x_l, x_g): + """ + x_g: global features + x_l: local features + """ + B, C, H, W = x_l.shape + + local_feat = self.local_embedding(x_l) + global_act = self.global_act(x_g) + sig_act = F.interpolate( + global_act, size=(H, W), mode='bilinear', align_corners=False) + + out = local_feat * sig_act + + return out + + +class InjectionMultiSumallmultiallsum(nn.Module): + """the Aggregate Attention Module. + + Args: + in_channels (tuple): the input channel. + out_channels (int): the output channel. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN') + """ + + def __init__( + self, + in_channels=(64, 128, 256, 384), + out_channels=256, + act_cfg=dict(type='Sigmoid'), + norm_cfg=dict(type='BN'), + ): + super().__init__() + self.embedding_list = nn.ModuleList() + self.act_embedding_list = nn.ModuleList() + self.act_list = nn.ModuleList() + for i in range(len(in_channels)): + self.embedding_list.append( + ConvModule( + in_channels=in_channels[i], + out_channels=out_channels, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + )) + self.act_embedding_list.append( + ConvModule( + in_channels=in_channels[i], + out_channels=out_channels, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + )) + + def forward(self, inputs): # x_x8, x_x16, x_x32, x_x64 + low_feat1 = F.interpolate(inputs[0], scale_factor=0.5, mode='bilinear') + low_feat1_act = self.act_embedding_list[0](low_feat1) + low_feat1 = self.embedding_list[0](low_feat1) + + low_feat2 = F.interpolate( + inputs[1], size=low_feat1.shape[-2:], mode='bilinear') + low_feat2_act = self.act_embedding_list[1](low_feat2) # x16 + low_feat2 = self.embedding_list[1](low_feat2) + + high_feat_act = F.interpolate( + self.act_embedding_list[2](inputs[2]), + size=low_feat2.shape[2:], + mode='bilinear', + ) + high_feat = F.interpolate( + self.embedding_list[2](inputs[2]), + size=low_feat2.shape[2:], + mode='bilinear') + + res = ( + low_feat1_act * low_feat2_act * high_feat_act * + (low_feat1 + low_feat2) + high_feat) + + return res + + +class InjectionMultiSumallmultiallsumSimpx8(nn.Module): + """the Aggregate Attention Module. + + Args: + in_channels (tuple): the input channel. + out_channels (int): the output channel. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN') + """ + + def __init__( + self, + in_channels=(64, 128, 256, 384), + out_channels=256, + act_cfg=dict(type='Sigmoid'), + norm_cfg=dict(type='BN'), + ): + super().__init__() + self.embedding_list = nn.ModuleList() + self.act_embedding_list = nn.ModuleList() + self.act_list = nn.ModuleList() + for i in range(len(in_channels)): + if i != 1: + self.embedding_list.append( + ConvModule( + in_channels=in_channels[i], + out_channels=out_channels, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=None, + )) + if i != 0: + self.act_embedding_list.append( + ConvModule( + in_channels=in_channels[i], + out_channels=out_channels, + kernel_size=1, + bias=False, + norm_cfg=norm_cfg, + act_cfg=act_cfg, + )) + + def forward(self, inputs): + # x_x8, x_x16, x_x32 + low_feat1 = self.embedding_list[0](inputs[0]) + + low_feat2 = F.interpolate( + inputs[1], size=low_feat1.shape[-2:], mode='bilinear') + low_feat2_act = self.act_embedding_list[0](low_feat2) + + high_feat_act = F.interpolate( + self.act_embedding_list[1](inputs[2]), + size=low_feat2.shape[2:], + mode='bilinear', + ) + high_feat = F.interpolate( + self.embedding_list[1](inputs[2]), + size=low_feat2.shape[2:], + mode='bilinear') + + res = low_feat2_act * high_feat_act * low_feat1 + high_feat + + return res + + +def _make_divisible(v, divisor=8, min_value=None): + if min_value is None: + min_value = divisor + new_v = max(min_value, int(v + divisor / 2) // divisor * divisor) + if new_v < 0.9 * v: + new_v += divisor + return new_v + + +@MODELS.register_module() +class Hardsigmoid(nn.Module): + """the hardsigmoid activation. + + Args: + slope (float, optional): The slope of hardsigmoid function. + Default is 0.1666667. + offset (float, optional): The offset of hardsigmoid function. + Default is 0.5. + inplace (bool): can optionally do the operation in-place. + Default: ``False`` + """ + + def __init__(self, slope=0.1666667, offset=0.5, inplace=False): + super().__init__() + self.slope = slope + self.offset = offset + + def forward(self, x): + return (x * self.slope + self.offset).clamp(0, 1) diff --git a/projects/pp_mobileseg/configs/_base_/datasets/ade20k.py b/projects/pp_mobileseg/configs/_base_/datasets/ade20k.py new file mode 100644 index 00000000000..48340d11eea --- /dev/null +++ b/projects/pp_mobileseg/configs/_base_/datasets/ade20k.py @@ -0,0 +1,68 @@ +# dataset settings +dataset_type = 'ADE20KDataset' +data_root = 'data/ade/ADEChallengeData2016' +crop_size = (512, 512) +train_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations', reduce_zero_label=True), + dict( + type='RandomResize', + scale=(2048, 512), + ratio_range=(0.5, 2.0), + keep_ratio=True), + dict(type='RandomCrop', crop_size=crop_size, cat_max_ratio=0.75), + dict(type='RandomFlip', prob=0.5), + dict(type='PhotoMetricDistortion'), + dict(type='PackSegInputs') +] +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='PackSegInputs') +] +img_ratios = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75] +tta_pipeline = [ + dict(type='LoadImageFromFile', backend_args=None), + dict( + type='TestTimeAug', + transforms=[ + [ + dict(type='Resize', scale_factor=r, keep_ratio=True) + for r in img_ratios + ], + [ + dict(type='RandomFlip', prob=0., direction='horizontal'), + dict(type='RandomFlip', prob=1., direction='horizontal') + ], [dict(type='LoadAnnotations')], [dict(type='PackSegInputs')] + ]) +] +train_dataloader = dict( + batch_size=4, + num_workers=4, + persistent_workers=True, + sampler=dict(type='InfiniteSampler', shuffle=True), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/training', seg_map_path='annotations/training'), + pipeline=train_pipeline)) +val_dataloader = dict( + batch_size=1, + num_workers=4, + persistent_workers=True, + sampler=dict(type='DefaultSampler', shuffle=False), + dataset=dict( + type=dataset_type, + data_root=data_root, + data_prefix=dict( + img_path='images/validation', + seg_map_path='annotations/validation'), + pipeline=test_pipeline)) +test_dataloader = val_dataloader + +val_evaluator = dict(type='IoUMetric', iou_metrics=['mIoU']) +test_evaluator = val_evaluator diff --git a/projects/pp_mobileseg/configs/_base_/default_runtime.py b/projects/pp_mobileseg/configs/_base_/default_runtime.py new file mode 100644 index 00000000000..272b4d24679 --- /dev/null +++ b/projects/pp_mobileseg/configs/_base_/default_runtime.py @@ -0,0 +1,15 @@ +default_scope = 'mmseg' +env_cfg = dict( + cudnn_benchmark=True, + mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), + dist_cfg=dict(backend='nccl'), +) +vis_backends = [dict(type='LocalVisBackend')] +visualizer = dict( + type='SegLocalVisualizer', vis_backends=vis_backends, name='visualizer') +log_processor = dict(by_epoch=False) +log_level = 'INFO' +load_from = None +resume = False + +tta_model = dict(type='SegTTAModel') diff --git a/projects/pp_mobileseg/configs/_base_/models/pp_mobile.py b/projects/pp_mobileseg/configs/_base_/models/pp_mobile.py new file mode 100644 index 00000000000..0c7695636f6 --- /dev/null +++ b/projects/pp_mobileseg/configs/_base_/models/pp_mobile.py @@ -0,0 +1,47 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255) + +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + # pretrained='open-mmlab://resnet50_v1c', + backbone=dict( + type='StrideFormer', + mobileV3_cfg=[ + # k t c, s + [[3, 16, 16, True, 'ReLU', 1], [3, 64, 32, False, 'ReLU', 2], + [3, 96, 32, False, 'ReLU', 1]], # cfg1 + [[5, 128, 64, True, 'HSwish', 2], [5, 240, 64, True, 'HSwish', + 1]], # cfg2 + [[5, 384, 128, True, 'HSwish', 2], + [5, 384, 128, True, 'HSwish', 1]], # cfg3 + [[5, 768, 192, True, 'HSwish', 2], + [5, 768, 192, True, 'HSwish', 1]], # cfg4 + ], + channels=[16, 32, 64, 128, 192], + depths=[3, 3], + embed_dims=[128, 192], + num_heads=8, + inj_type='AAMSx8', + out_feat_chs=[64, 128, 192], + act_cfg=dict(type='ReLU6'), + ), + decode_head=dict( + type='PPMobileSegHead', + num_classes=150, + in_channels=256, + dropout_ratio=0.1, + use_dw=True, + act_cfg=dict(type='ReLU'), + align_corners=False), + + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/projects/pp_mobileseg/configs/_base_/schedules/schedule_80k.py b/projects/pp_mobileseg/configs/_base_/schedules/schedule_80k.py new file mode 100644 index 00000000000..0dcd6c4d1bc --- /dev/null +++ b/projects/pp_mobileseg/configs/_base_/schedules/schedule_80k.py @@ -0,0 +1,24 @@ +# optimizer +optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005) +optim_wrapper = dict(type='OptimWrapper', optimizer=optimizer, clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='PolyLR', + eta_min=1e-4, + power=0.9, + begin=0, + end=80000, + by_epoch=False) +] +# training schedule for 80k +train_cfg = dict(type='IterBasedTrainLoop', max_iters=80000, val_interval=8000) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=8000), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) diff --git a/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_base.py b/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_base.py new file mode 100644 index 00000000000..4b68a927e20 --- /dev/null +++ b/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_base.py @@ -0,0 +1,18 @@ +_base_ = [ + '../_base_/models/pp_mobile.py', '../_base_/datasets/ade20k.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py' +] +# the custom import path is determined by your workspace path (i.e., where you run the command from) # noqa +custom_imports = dict( + imports=[ + 'projects.pp_mobileseg.backbones', 'projects.pp_mobileseg.decode_head' + ], + allow_failed_imports=False) +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pp_mobileseg/pp_mobileseg_mobilenetv3_3rdparty-base-ed0be681.pth' # noqa +crop_size = (512, 512) +data_preprocessor = dict(size=crop_size, test_cfg=dict(size_divisor=32)) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + data_preprocessor=data_preprocessor, + backbone=dict(init_cfg=dict(type='Pretrained', checkpoint=checkpoint)), + decode_head=dict(num_classes=150, upsample='intepolate')) diff --git a/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_tiny.py b/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_tiny.py new file mode 100644 index 00000000000..b78869e517a --- /dev/null +++ b/projects/pp_mobileseg/configs/pp_mobileseg/pp_mobileseg_mobilenetv3_2x16_80k_ade20k_512x512_tiny.py @@ -0,0 +1,45 @@ +_base_ = [ + '../_base_/models/pp_mobile.py', '../_base_/datasets/ade20k.py', + '../_base_/default_runtime.py', '../_base_/schedules/schedule_80k.py' +] +# the custom import path is determined by your workspace path (i.e., where you run the command from) # noqa +custom_imports = dict( + imports=[ + 'projects.pp_mobileseg.backbones', 'projects.pp_mobileseg.decode_head' + ], + allow_failed_imports=False) +checkpoint = 'https://download.openmmlab.com/mmsegmentation/v0.5/pp_mobileseg/pp_mobileseg_mobilenetv3_3rdparty-tiny-e4b35e96.pth' # noqa +crop_size = (512, 512) +data_preprocessor = dict(size=crop_size, test_cfg=dict(size_divisor=32)) +norm_cfg = dict(type='SyncBN', requires_grad=True) +model = dict( + data_preprocessor=data_preprocessor, + backbone=dict( + init_cfg=dict(type='Pretrained', checkpoint=checkpoint), + type='StrideFormer', + mobileV3_cfg=[ + # k t c, s + [[3, 16, 16, True, 'ReLU', 1], [3, 64, 32, False, 'ReLU', 2], + [3, 48, 24, False, 'ReLU', 1]], # cfg1 + [[5, 96, 32, True, 'HSwish', 2], [5, 96, 32, True, 'HSwish', + 1]], # cfg2 + [[5, 160, 64, True, 'HSwish', 2], [5, 160, 64, True, 'HSwish', + 1]], # cfg3 + [[3, 384, 128, True, 'HSwish', 2], + [3, 384, 128, True, 'HSwish', 1]], # cfg4 + ], + channels=[16, 24, 32, 64, 128], + depths=[2, 2], + embed_dims=[64, 128], + num_heads=4, + inj_type='AAM', + out_feat_chs=[32, 64, 128], + act_cfg=dict(type='ReLU6'), + ), + decode_head=dict( + num_classes=150, + in_channels=256, + use_dw=True, + act_cfg=dict(type='ReLU'), + upsample='intepolate'), +) diff --git a/projects/pp_mobileseg/decode_head/__init__.py b/projects/pp_mobileseg/decode_head/__init__.py new file mode 100644 index 00000000000..6f71b784e15 --- /dev/null +++ b/projects/pp_mobileseg/decode_head/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .pp_mobileseg_head import PPMobileSegHead + +__all__ = [ + 'PPMobileSegHead', +] diff --git a/projects/pp_mobileseg/decode_head/pp_mobileseg_head.py b/projects/pp_mobileseg/decode_head/pp_mobileseg_head.py new file mode 100644 index 00000000000..243f0263729 --- /dev/null +++ b/projects/pp_mobileseg/decode_head/pp_mobileseg_head.py @@ -0,0 +1,94 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import List + +import torch +import torch.nn as nn +import torch.nn.functional as F +from mmcv.cnn import ConvModule, build_conv_layer +from torch import Tensor + +from mmseg.registry import MODELS + + +@MODELS.register_module() +class PPMobileSegHead(nn.Module): + """the segmentation head. + + Args: + num_classes (int): the classes num. + in_channels (int): the input channels. + use_dw (bool): if to use deepwith convolution. + dropout_ratio (float): Probability of an element to be zeroed. + Default 0.0。 + align_corners (bool, optional): Geometrically, we consider the pixels + of the input and output as squares rather than points. + upsample (str): the upsample method. + out_channels (int): the output channel. + conv_cfg (dict): Config dict for convolution layer. + act_cfg (dict): Config dict for activation layer. + Default: dict(type='ReLU'). + norm_cfg (dict): Config dict for normalization layer. + Default: dict(type='BN'). + """ + + def __init__(self, + num_classes, + in_channels, + use_dw=True, + dropout_ratio=0.1, + align_corners=False, + upsample='intepolate', + out_channels=None, + conv_cfg=dict(type='Conv'), + act_cfg=dict(type='ReLU'), + norm_cfg=dict(type='BN')): + + super().__init__() + self.align_corners = align_corners + self.last_channels = in_channels + self.upsample = upsample + self.num_classes = num_classes + self.out_channels = out_channels + self.linear_fuse = ConvModule( + in_channels=self.last_channels, + out_channels=self.last_channels, + kernel_size=1, + bias=False, + groups=self.last_channels if use_dw else 1, + norm_cfg=norm_cfg, + act_cfg=act_cfg) + self.dropout = nn.Dropout2d(dropout_ratio) + self.conv_seg = build_conv_layer( + conv_cfg, self.last_channels, self.num_classes, kernel_size=1) + + def forward(self, x): + x, x_hw = x[0], x[1] + x = self.linear_fuse(x) + x = self.dropout(x) + x = self.conv_seg(x) + if self.upsample == 'intepolate' or self.training or \ + self.num_classes < 30: + x = F.interpolate( + x, x_hw, mode='bilinear', align_corners=self.align_corners) + elif self.upsample == 'vim': + labelset = torch.unique(torch.argmax(x, 1)) + x = torch.gather(x, 1, labelset) + x = F.interpolate( + x, x_hw, mode='bilinear', align_corners=self.align_corners) + + pred = torch.argmax(x, 1) + pred_retrieve = torch.zeros(pred.shape, dtype=torch.int32) + for i, val in enumerate(labelset): + pred_retrieve[pred == i] = labelset[i].cast('int32') + + x = pred_retrieve + else: + raise NotImplementedError(self.upsample, ' is not implemented') + + return [x] + + def predict(self, inputs, batch_img_metas: List[dict], test_cfg, + **kwargs) -> List[Tensor]: + """Forward function for testing, only ``pam_cam`` is used.""" + seg_logits = self.forward(inputs)[0] + return seg_logits diff --git a/projects/pp_mobileseg/inference_onnx.py b/projects/pp_mobileseg/inference_onnx.py new file mode 100644 index 00000000000..139d1b13243 --- /dev/null +++ b/projects/pp_mobileseg/inference_onnx.py @@ -0,0 +1,203 @@ +import argparse +import time +from typing import List, Tuple + +import cv2 +import loguru +import numpy as np +import onnxruntime as ort + +logger = loguru.logger + + +def parse_args(): + parser = argparse.ArgumentParser( + description='PP_Mobileseg ONNX inference demo.') + parser.add_argument('onnx_file', help='ONNX file path') + parser.add_argument('image_file', help='Input image file path') + parser.add_argument( + '--input-size', + type=int, + nargs='+', + default=[512, 512], + help='input image size') + parser.add_argument( + '--device', help='device type for inference', default='cpu') + parser.add_argument( + '--save-path', + help='path to save the output image', + default='output.jpg') + args = parser.parse_args() + return args + + +def preprocess( + img: np.ndarray, input_size: Tuple[int, int] = (512, 512) +) -> Tuple[np.ndarray, np.ndarray]: + """Preprocess image for inference.""" + img_shape = img.shape[:2] + # Resize + resized_img = cv2.resize(img, input_size) + + # Normalize + mean = np.array([123.575, 116.28, 103.53], dtype=np.float32) + std = np.array([58.395, 57.12, 57.375], dtype=np.float32) + resized_img = (resized_img - mean) / std + + return resized_img, img_shape + + +def build_session(onnx_file: str, device: str = 'cpu') -> ort.InferenceSession: + """Build onnxruntime session. + + Args: + onnx_file (str): ONNX file path. + device (str): Device type for inference. + + Returns: + sess (ort.InferenceSession): ONNXRuntime session. + """ + providers = ['CPUExecutionProvider' + ] if device == 'cpu' else ['CUDAExecutionProvider'] + sess = ort.InferenceSession(path_or_bytes=onnx_file, providers=providers) + + return sess + + +def inference(sess: ort.InferenceSession, img: np.ndarray) -> np.ndarray: + """Inference RTMPose model. + + Args: + sess (ort.InferenceSession): ONNXRuntime session. + img (np.ndarray): Input image in shape. + + Returns: + outputs (np.ndarray): Output of RTMPose model. + """ + # build input + input_img = [img.transpose(2, 0, 1).astype(np.float32)] + + # build output + sess_input = {sess.get_inputs()[0].name: input_img} + sess_output = [] + for out in sess.get_outputs(): + sess_output.append(out.name) + + # inference + outputs = sess.run(output_names=sess_output, input_feed=sess_input) + + return outputs + + +def postprocess(outputs: List[np.ndarray], + origin_shape: Tuple[int, int]) -> np.ndarray: + """Postprocess outputs of PP_Mobileseg model. + + Args: + outputs (List[np.ndarray]): Outputs of PP_Mobileseg model. + origin_shape (Tuple[int, int]): Input size of PP_Mobileseg model. + + Returns: + seg_map (np.ndarray): Segmentation map. + """ + seg_map = outputs[0][0][0] + seg_map = cv2.resize(seg_map.astype(np.float32), origin_shape) + return seg_map + + +def visualize(img: np.ndarray, + seg_map: np.ndarray, + filename: str = 'output.jpg', + opacity: float = 0.8) -> np.ndarray: + assert 0.0 <= opacity <= 1.0, 'opacity should be in range [0, 1]' + palette = np.array(PALETTE) + color_seg = np.zeros((seg_map.shape[0], seg_map.shape[1], 3), + dtype=np.uint8) + for label, color in enumerate(palette): + color_seg[seg_map == label, :] = color + # convert to BGR + color_seg = color_seg[..., ::-1] + + img = img * (1 - opacity) + color_seg * opacity + cv2.imwrite(filename, img) + + return img + + +def main(): + args = parse_args() + logger.info('Start running model inference...') + + # read image from file + logger.info(f'1. Read image from file {args.image_file}...') + img = cv2.imread(args.image_file) + + # build onnx model + logger.info(f'2. Build onnx model from {args.onnx_file}...') + sess = build_session(args.onnx_file, args.device) + + # preprocess + logger.info('3. Preprocess image...') + model_input_size = tuple(args.input_size) + assert len(model_input_size) == 2 + resized_img, origin_shape = preprocess(img, model_input_size) + + # inference + logger.info('4. Inference...') + start = time.time() + outputs = inference(sess, resized_img) + logger.info(f'Inference time: {time.time() - start:.4f}s') + + # postprocess + logger.info('5. Postprocess...') + h, w = origin_shape + seg_map = postprocess(outputs, (w, h)) + + # visualize + logger.info('6. Visualize...') + visualize(img, seg_map, args.save_path) + + logger.info('Done...') + + +PALETTE = [[120, 120, 120], [180, 120, 120], [6, 230, 230], [80, 50, 50], + [4, 200, 3], [120, 120, 80], [140, 140, 140], [204, 5, 255], + [230, 230, 230], [4, 250, 7], [224, 5, 255], [235, 255, 7], + [150, 5, 61], [120, 120, 70], [8, 255, 51], [255, 6, 82], + [143, 255, 140], [204, 255, 4], [255, 51, 7], [204, 70, 3], + [0, 102, 200], [61, 230, 250], [255, 6, 51], [11, 102, 255], + [255, 7, 71], [255, 9, 224], [9, 7, 230], [220, 220, 220], + [255, 9, 92], [112, 9, 255], [8, 255, 214], [7, 255, 224], + [255, 184, 6], [10, 255, 71], [255, 41, 10], [7, 255, 255], + [224, 255, 8], [102, 8, 255], [255, 61, 6], [255, 194, 7], + [255, 122, 8], [0, 255, 20], [255, 8, 41], [255, 5, 153], + [6, 51, 255], [235, 12, 255], [160, 150, 20], [0, 163, 255], + [140, 140, 140], [250, 10, 15], [20, 255, 0], [31, 255, 0], + [255, 31, 0], [255, 224, 0], [153, 255, 0], [0, 0, 255], + [255, 71, 0], [0, 235, 255], [0, 173, 255], [31, 0, 255], + [11, 200, 200], [255, 82, 0], [0, 255, 245], [0, 61, 255], + [0, 255, 112], [0, 255, 133], [255, 0, 0], [255, 163, 0], + [255, 102, 0], [194, 255, 0], [0, 143, 255], [51, 255, 0], + [0, 82, 255], [0, 255, 41], [0, 255, 173], [10, 0, 255], + [173, 255, 0], [0, 255, 153], [255, 92, 0], [255, 0, 255], + [255, 0, 245], [255, 0, 102], [255, 173, 0], [255, 0, 20], + [255, 184, 184], [0, 31, 255], [0, 255, 61], [0, 71, 255], + [255, 0, 204], [0, 255, 194], [0, 255, 82], [0, 10, 255], + [0, 112, 255], [51, 0, 255], [0, 194, 255], [0, 122, 255], + [0, 255, 163], [255, 153, 0], [0, 255, 10], [255, 112, 0], + [143, 255, 0], [82, 0, 255], [163, 255, 0], [255, 235, 0], + [8, 184, 170], [133, 0, 255], [0, 255, 92], [184, 0, 255], + [255, 0, 31], [0, 184, 255], [0, 214, 255], [255, 0, 112], + [92, 255, 0], [0, 224, 255], [112, 224, 255], [70, 184, 160], + [163, 0, 255], [153, 0, 255], [71, 255, 0], [255, 0, 163], + [255, 204, 0], [255, 0, 143], [0, 255, 235], [133, 255, 0], + [255, 0, 235], [245, 0, 255], [255, 0, 122], [255, 245, 0], + [10, 190, 212], [214, 255, 0], [0, 204, 255], [20, 0, 255], + [255, 255, 0], [0, 153, 255], [0, 41, 255], [0, 255, 204], + [41, 0, 255], [41, 255, 0], [173, 0, 255], [0, 245, 255], + [71, 0, 255], [122, 0, 255], [0, 255, 184], [0, 92, 255], + [184, 255, 0], [0, 133, 255], [255, 214, 0], [25, 194, 194], + [102, 255, 0], [92, 0, 255]] + +if __name__ == '__main__': + main() diff --git a/projects/sam_inference_demo/README.md b/projects/sam_inference_demo/README.md new file mode 100644 index 00000000000..f8077b8729f --- /dev/null +++ b/projects/sam_inference_demo/README.md @@ -0,0 +1,40 @@ +# Introducing the Segment Anything Model (SAM) Inference Demo! + +Welcome to the Segment Anything (SA) Inference Demo, a user-friendly implementation based on the original Segment Anything project. Our demo allows you to experience the power and versatility of the Segment Anything Model (SAM) through an easy-to-use API. + +With this inference demo, you can explore the capabilities of the Segment Anything Model and witness its effectiveness in various tasks and image distributions. For more information on the original project, dataset, and model, please visit the official website at https://segment-anything.com. + +### Prerequisites + +- Python 3.10 +- PyTorch 1.13 +- MMEngine >= v0.7.2 +- MMCV >= v2.0.0 + +### Installation + +We assume that you have already installed PyTorch. If not, please follow the instructions on the [PyTorch website](https://pytorch.org/). + +**1. Install MMEngine & MMCV** + +```shell +pip install openmim +mim install mmengine +mim install 'mmcv>=2.0.0' +``` + +**2. Install MMPretrain** + +```shell +pip install git+https://github.com/open-mmlab/mmpretrain.git@dev +``` + +**3. Install MMSegmentation** + +```shell +pip install mmsegmentation +``` + +### Usage + +Open the `sam_image_demo.ipynb` notebook and follow the instructions to run the demo. diff --git a/projects/sam_inference_demo/sam/__init__.py b/projects/sam_inference_demo/sam/__init__.py new file mode 100644 index 00000000000..82b6b78469c --- /dev/null +++ b/projects/sam_inference_demo/sam/__init__.py @@ -0,0 +1,2 @@ +from .modeling import * # noqa +from .utils import * # noqa diff --git a/projects/sam_inference_demo/sam/modeling/__init__.py b/projects/sam_inference_demo/sam/modeling/__init__.py new file mode 100644 index 00000000000..9892a6b085d --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/__init__.py @@ -0,0 +1,12 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from .mask_decoder import MaskDecoder +from .prompt_encoder import PromptEncoder +from .sam import SAM +from .transformer import TwoWayTransformer + +__all__ = ['SAM', 'MaskDecoder', 'PromptEncoder', 'TwoWayTransformer'] diff --git a/projects/sam_inference_demo/sam/modeling/common.py b/projects/sam_inference_demo/sam/modeling/common.py new file mode 100644 index 00000000000..d2892761122 --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/common.py @@ -0,0 +1,45 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from typing import Type + +import torch +import torch.nn as nn + + +class MLPBlock(nn.Module): + + def __init__( + self, + embedding_dim: int, + mlp_dim: int, + act: Type[nn.Module] = nn.GELU, + ) -> None: + super().__init__() + self.lin1 = nn.Linear(embedding_dim, mlp_dim) + self.lin2 = nn.Linear(mlp_dim, embedding_dim) + self.act = act() + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.lin2(self.act(self.lin1(x))) + + +# From https://github.com/facebookresearch/detectron2/blob/main/detectron2/layers/batch_norm.py # noqa +# Itself from https://github.com/facebookresearch/ConvNeXt/blob/d1fa8f6fef0a165b27399986cc2bdacc92777e40/models/convnext.py#L119 # noqa +class LayerNorm2d(nn.Module): + + def __init__(self, num_channels: int, eps: float = 1e-6) -> None: + super().__init__() + self.weight = nn.Parameter(torch.ones(num_channels)) + self.bias = nn.Parameter(torch.zeros(num_channels)) + self.eps = eps + + def forward(self, x: torch.Tensor) -> torch.Tensor: + u = x.mean(1, keepdim=True) + s = (x - u).pow(2).mean(1, keepdim=True) + x = (x - u) / torch.sqrt(s + self.eps) + x = self.weight[:, None, None] * x + self.bias[:, None, None] + return x diff --git a/projects/sam_inference_demo/sam/modeling/mask_decoder.py b/projects/sam_inference_demo/sam/modeling/mask_decoder.py new file mode 100644 index 00000000000..9ad616b5899 --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/mask_decoder.py @@ -0,0 +1,196 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# Borrowed from https://github.com/facebookresearch/segment-anything + +from typing import List, Tuple + +import torch +from torch import Tensor, nn +from torch.nn import functional as F + +from mmseg.registry import MODELS +from .common import LayerNorm2d + + +@MODELS.register_module() +class MaskDecoder(nn.Module): + + def __init__( + self, + *, + transformer_dim: int, + transformer: dict, + num_multimask_outputs: int = 3, + act_cfg: dict = dict(type='GELU'), + iou_head_depth: int = 3, + iou_head_hidden_dim: int = 256, + ) -> None: + """Predicts masks given an image and prompt embeddings, using a + tranformer architecture. + + Borrowed from https://github.com/facebookresearch/segment-anything + + Arguments: + transformer_dim (int): the channel dimension of the transformer + transformer (nn.Module): the transformer used to predict masks + num_multimask_outputs (int): the number of masks to predict + when disambiguating masks + activation (nn.Module): the type of activation to use when + upscaling masks + iou_head_depth (int): the depth of the MLP used to predict + mask quality + iou_head_hidden_dim (int): the hidden dimension of the MLP + used to predict mask quality + """ + super().__init__() + self.transformer_dim = transformer_dim + self.transformer = MODELS.build(transformer) + + self.num_multimask_outputs = num_multimask_outputs + + self.iou_token = nn.Embedding(1, transformer_dim) + self.num_mask_tokens = num_multimask_outputs + 1 + self.mask_tokens = nn.Embedding(self.num_mask_tokens, transformer_dim) + + activation = MODELS.build(act_cfg) + self.output_upscaling = nn.Sequential( + nn.ConvTranspose2d( + transformer_dim, transformer_dim // 4, kernel_size=2, + stride=2), + LayerNorm2d(transformer_dim // 4), + activation, + nn.ConvTranspose2d( + transformer_dim // 4, + transformer_dim // 8, + kernel_size=2, + stride=2), + activation, + ) + self.output_hypernetworks_mlps = nn.ModuleList([ + MLP(transformer_dim, transformer_dim, transformer_dim // 8, 3) + for i in range(self.num_mask_tokens) + ]) + + self.iou_prediction_head = MLP(transformer_dim, iou_head_hidden_dim, + self.num_mask_tokens, iou_head_depth) + + def forward( + self, + image_embeddings: Tensor, + image_pe: Tensor, + sparse_prompt_embeddings: Tensor, + dense_prompt_embeddings: Tensor, + multimask_output: bool, + ) -> Tuple[Tensor, Tensor]: + """Predict masks given image and prompt embeddings. + + Borrowed from https://github.com/facebookresearch/segment-anything + + Arguments: + image_embeddings (Tensor): the embeddings from the image encoder + image_pe (Tensor): positional encoding with the shape of + image_embeddings + sparse_prompt_embeddings (Tensor): the embeddings of + the points and boxes + dense_prompt_embeddings (Tensor): the embeddings of the mask inputs + multimask_output (bool): Whether to return multiple masks or a single + mask. + + Returns: + Tensor: batched predicted masks + Tensor: batched predictions of mask quality + """ + masks, iou_pred = self.predict_masks( + image_embeddings=image_embeddings, + image_pe=image_pe, + sparse_prompt_embeddings=sparse_prompt_embeddings, + dense_prompt_embeddings=dense_prompt_embeddings, + ) + + # Select the correct mask or masks for output + if multimask_output: + mask_slice = slice(1, None) + else: + mask_slice = slice(0, 1) + masks = masks[:, mask_slice, :, :] + iou_pred = iou_pred[:, mask_slice] + + # Prepare output + return masks, iou_pred + + def predict_masks( + self, + image_embeddings: Tensor, + image_pe: Tensor, + sparse_prompt_embeddings: Tensor, + dense_prompt_embeddings: Tensor, + ) -> Tuple[Tensor, Tensor]: + """Predicts masks. + + See 'forward' for more details. + """ + # Concatenate output tokens + output_tokens = torch.cat( + [self.iou_token.weight, self.mask_tokens.weight], dim=0) + output_tokens = output_tokens.unsqueeze(0).expand( + sparse_prompt_embeddings.size(0), -1, -1) + tokens = torch.cat((output_tokens, sparse_prompt_embeddings), dim=1) + + # Expand per-image data in batch direction to be per-mask + src = torch.repeat_interleave(image_embeddings, tokens.shape[0], dim=0) + src = src + dense_prompt_embeddings + pos_src = torch.repeat_interleave(image_pe, tokens.shape[0], dim=0) + b, c, h, w = src.shape + + # Run the transformer + hs, src = self.transformer(src, pos_src, tokens) + iou_token_out = hs[:, 0, :] + mask_tokens_out = hs[:, 1:(1 + self.num_mask_tokens), :] + + # Upscale mask embeddings and predict masks using the mask tokens + src = src.transpose(1, 2).view(b, c, h, w) + upscaled_embedding = self.output_upscaling(src) + hyper_in_list: List[Tensor] = [] + for i in range(self.num_mask_tokens): + hyper_in_list.append(self.output_hypernetworks_mlps[i]( + mask_tokens_out[:, i, :])) + hyper_in = torch.stack(hyper_in_list, dim=1) + b, c, h, w = upscaled_embedding.shape + masks = (hyper_in @ upscaled_embedding.view(b, c, h * w)).view( + b, -1, h, w) + + # Generate mask quality predictions + iou_pred = self.iou_prediction_head(iou_token_out) + + return masks, iou_pred + + +# Lightly adapted from +# https://github.com/facebookresearch/MaskFormer/blob/main/mask_former/modeling/transformer/transformer_predictor.py # noqa +class MLP(nn.Module): + + def __init__( + self, + input_dim: int, + hidden_dim: int, + output_dim: int, + num_layers: int, + sigmoid_output: bool = False, + ) -> None: + super().__init__() + self.num_layers = num_layers + h = [hidden_dim] * (num_layers - 1) + self.layers = nn.ModuleList( + nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim])) + self.sigmoid_output = sigmoid_output + + def forward(self, x): + for i, layer in enumerate(self.layers): + x = F.relu(layer(x)) if i < self.num_layers - 1 else layer(x) + if self.sigmoid_output: + x = F.sigmoid(x) + return x diff --git a/projects/sam_inference_demo/sam/modeling/prompt_encoder.py b/projects/sam_inference_demo/sam/modeling/prompt_encoder.py new file mode 100644 index 00000000000..6b7c0833871 --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/prompt_encoder.py @@ -0,0 +1,227 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# Borrowed from https://github.com/facebookresearch/segment-anything + +from typing import Any, Optional, Tuple, Type + +import numpy as np +import torch +from torch import nn + +from mmseg.registry import MODELS +from .common import LayerNorm2d + + +@MODELS.register_module() +class PromptEncoder(nn.Module): + + def __init__( + self, + embed_dim: int, + image_embedding_size: Tuple[int, int], + input_image_size: Tuple[int, int], + mask_in_chans: int, + activation: Type[nn.Module] = nn.GELU, + ) -> None: + """Encodes prompts for input to SAM's mask decoder. + + Arguments: + embed_dim (int): The prompts' embedding dimension + image_embedding_size (tuple(int, int)): The spatial size of the + image embedding, as (H, W). + input_image_size (int): The padded size of the image as input + to the image encoder, as (H, W). + mask_in_chans (int): The number of hidden channels used for + encoding input masks. + activation (nn.Module): The activation to use when encoding + input masks. + """ + super().__init__() + self.embed_dim = embed_dim + self.input_image_size = input_image_size + self.image_embedding_size = image_embedding_size + self.pe_layer = PositionEmbeddingRandom(embed_dim // 2) + + self.num_point_embeddings: int = 4 # pos/neg point + 2 box corners + point_embeddings = [ + nn.Embedding(1, embed_dim) + for i in range(self.num_point_embeddings) + ] + self.point_embeddings = nn.ModuleList(point_embeddings) + self.not_a_point_embed = nn.Embedding(1, embed_dim) + + self.mask_input_size = (4 * image_embedding_size[0], + 4 * image_embedding_size[1]) + self.mask_downscaling = nn.Sequential( + nn.Conv2d(1, mask_in_chans // 4, kernel_size=2, stride=2), + LayerNorm2d(mask_in_chans // 4), + activation(), + nn.Conv2d( + mask_in_chans // 4, mask_in_chans, kernel_size=2, stride=2), + LayerNorm2d(mask_in_chans), + activation(), + nn.Conv2d(mask_in_chans, embed_dim, kernel_size=1), + ) + self.no_mask_embed = nn.Embedding(1, embed_dim) + + def get_dense_pe(self) -> torch.Tensor: + """Returns the positional encoding used to encode point prompts, + applied to a dense set of points the shape of the image encoding. + + Returns: + torch.Tensor: Positional encoding with shape + 1x(embed_dim)x(embedding_h)x(embedding_w) + """ + return self.pe_layer(self.image_embedding_size).unsqueeze(0) + + def _embed_points( + self, + points: torch.Tensor, + labels: torch.Tensor, + pad: bool, + ) -> torch.Tensor: + """Embeds point prompts.""" + points = points + 0.5 # Shift to center of pixel + if pad: + padding_point = torch.zeros((points.shape[0], 1, 2), + device=points.device) + padding_label = -torch.ones( + (labels.shape[0], 1), device=labels.device) + points = torch.cat([points, padding_point], dim=1) + labels = torch.cat([labels, padding_label], dim=1) + point_embedding = self.pe_layer.forward_with_coords( + points, self.input_image_size) + point_embedding[labels == -1] = 0.0 + point_embedding[labels == -1] += self.not_a_point_embed.weight + point_embedding[labels == 0] += self.point_embeddings[0].weight + point_embedding[labels == 1] += self.point_embeddings[1].weight + return point_embedding + + def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor: + """Embeds box prompts.""" + boxes = boxes + 0.5 # Shift to center of pixel + coords = boxes.reshape(-1, 2, 2) + corner_embedding = self.pe_layer.forward_with_coords( + coords, self.input_image_size) + corner_embedding[:, 0, :] += self.point_embeddings[2].weight + corner_embedding[:, 1, :] += self.point_embeddings[3].weight + return corner_embedding + + def _embed_masks(self, masks: torch.Tensor) -> torch.Tensor: + """Embeds mask inputs.""" + mask_embedding = self.mask_downscaling(masks) + return mask_embedding + + def _get_batch_size( + self, + points: Optional[Tuple[torch.Tensor, torch.Tensor]], + boxes: Optional[torch.Tensor], + masks: Optional[torch.Tensor], + ) -> int: + """Gets the batch size of the output given the batch size of the input + prompts.""" + if points is not None: + return points[0].shape[0] + elif boxes is not None: + return boxes.shape[0] + elif masks is not None: + return masks.shape[0] + else: + return 1 + + def _get_device(self) -> torch.device: + return self.point_embeddings[0].weight.device + + def forward( + self, + points: Optional[Tuple[torch.Tensor, torch.Tensor]], + boxes: Optional[torch.Tensor], + masks: Optional[torch.Tensor], + ) -> Tuple[torch.Tensor, torch.Tensor]: + """Embeds different types of prompts, returning both sparse and dense + embeddings. + + Arguments: + points (tuple(torch.Tensor, torch.Tensor) or none): point coordinates + and labels to embed. + boxes (torch.Tensor or none): boxes to embed + masks (torch.Tensor or none): masks to embed + + Returns: + torch.Tensor: sparse embeddings for the points and boxes, with shape + BxNx(embed_dim), where N is determined by the number of input points + and boxes. + torch.Tensor: dense embeddings for the masks, in the shape + Bx(embed_dim)x(embed_H)x(embed_W) + """ # noqa + bs = self._get_batch_size(points, boxes, masks) + sparse_embeddings = torch.empty((bs, 0, self.embed_dim), + device=self._get_device()) + if points is not None: + coords, labels = points + point_embeddings = self._embed_points( + coords, labels, pad=(boxes is None)) + sparse_embeddings = torch.cat( + [sparse_embeddings, point_embeddings], dim=1) + if boxes is not None: + box_embeddings = self._embed_boxes(boxes) + sparse_embeddings = torch.cat([sparse_embeddings, box_embeddings], + dim=1) + + if masks is not None: + dense_embeddings = self._embed_masks(masks) + else: + dense_embeddings = self.no_mask_embed.weight.reshape( + 1, -1, 1, 1).expand(bs, -1, self.image_embedding_size[0], + self.image_embedding_size[1]) + + return sparse_embeddings, dense_embeddings + + +class PositionEmbeddingRandom(nn.Module): + """Positional encoding using random spatial frequencies.""" + + def __init__(self, + num_pos_feats: int = 64, + scale: Optional[float] = None) -> None: + super().__init__() + if scale is None or scale <= 0.0: + scale = 1.0 + self.register_buffer( + 'positional_encoding_gaussian_matrix', + scale * torch.randn((2, num_pos_feats)), + ) + + def _pe_encoding(self, coords: torch.Tensor) -> torch.Tensor: + """Positionally encode points that are normalized to [0,1].""" + # assuming coords are in [0, 1]^2 square and have d_1 x ... x d_n x 2 shape # noqa + coords = 2 * coords - 1 + coords = coords @ self.positional_encoding_gaussian_matrix + coords = 2 * np.pi * coords + # outputs d_1 x ... x d_n x C shape + return torch.cat([torch.sin(coords), torch.cos(coords)], dim=-1) + + def forward(self, size: Tuple[int, int]) -> torch.Tensor: + """Generate positional encoding for a grid of the specified size.""" + h, w = size + device: Any = self.positional_encoding_gaussian_matrix.device + grid = torch.ones((h, w), device=device, dtype=torch.float32) + y_embed = grid.cumsum(dim=0) - 0.5 + x_embed = grid.cumsum(dim=1) - 0.5 + y_embed = y_embed / h + x_embed = x_embed / w + + pe = self._pe_encoding(torch.stack([x_embed, y_embed], dim=-1)) + return pe.permute(2, 0, 1) # C x H x W + + def forward_with_coords(self, coords_input: torch.Tensor, + image_size: Tuple[int, int]) -> torch.Tensor: + """Positionally encode points that are not normalized to [0,1].""" + coords = coords_input.clone() + coords[:, :, 0] = coords[:, :, 0] / image_size[1] + coords[:, :, 1] = coords[:, :, 1] / image_size[0] + return self._pe_encoding(coords.to(torch.float)) # B x N x C diff --git a/projects/sam_inference_demo/sam/modeling/sam.py b/projects/sam_inference_demo/sam/modeling/sam.py new file mode 100644 index 00000000000..c61c1eca4e7 --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/sam.py @@ -0,0 +1,188 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# Borrowed from https://github.com/facebookresearch/segment-anything + +from typing import Any, Dict, List, Tuple + +import torch +from torch import nn +from torch.nn import functional as F + +from mmseg.registry import MODELS +from .mask_decoder import MaskDecoder +from .prompt_encoder import PromptEncoder + + +@MODELS.register_module() +class SAM(nn.Module): + mask_threshold: float = 0.0 + image_format: str = 'RGB' + + def __init__( + self, + image_encoder_cfg: dict, + prompt_encoder_cfg: dict, + mask_decoder_cfg: dict, + pixel_mean: List[float] = [123.675, 116.28, 103.53], + pixel_std: List[float] = [58.395, 57.12, 57.375], + ) -> None: + """SAM predicts object masks from an image and input prompts. Borrowed + from https://github.com/facebookresearch/segment-anything. + + Arguments: + image_encoder (ViTSAM): The backbone used to encode the + image into image embeddings that allow for efficient mask + prediction. + prompt_encoder (PromptEncoder): Encodes various types of input + prompts. + mask_decoder (MaskDecoder): Predicts masks from the image embeddings + and encoded prompts. + pixel_mean (list(float)): Mean values for normalizing pixels in the + input image. + pixel_std (list(float)): Std values for normalizing pixels in the + input image. + """ + super().__init__() + self.image_encoder = MODELS.build(image_encoder_cfg) + self.prompt_encoder: PromptEncoder = MODELS.build(prompt_encoder_cfg) + self.mask_decoder: MaskDecoder = MODELS.build(mask_decoder_cfg) + self.register_buffer('pixel_mean', + torch.Tensor(pixel_mean).view(-1, 1, 1), False) + self.register_buffer('pixel_std', + torch.Tensor(pixel_std).view(-1, 1, 1), False) + + @property + def device(self) -> Any: + return self.pixel_mean.device + + @torch.no_grad() + def forward( + self, + batched_input: List[Dict[str, Any]], + multimask_output: bool, + ) -> List[Dict[str, torch.Tensor]]: + """Predicts masks end-to-end from provided images and prompts. If + prompts are not known in advance, using SamPredictor is recommended + over calling the model directly. + + Borrowed from https://github.com/facebookresearch/segment-anything + + Arguments: + batched_input (list(dict)): A list over input images, each a + dictionary with the following keys. A prompt key can be + excluded if it is not present. + 'image': The image as a torch tensor in 3xHxW format, + already transformed for input to the model. + 'original_size': (tuple(int, int)) The original size of + the image before transformation, as (H, W). + 'point_coords': (torch.Tensor) Batched point prompts for + this image, with shape BxNx2. Already transformed to the + input frame of the model. + 'point_labels': (torch.Tensor) Batched labels for point prompts, + with shape BxN. + 'boxes': (torch.Tensor) Batched box inputs, with shape Bx4. + Already transformed to the input frame of the model. + 'mask_inputs': (torch.Tensor) Batched mask inputs to the model, + in the form Bx1xHxW. + multimask_output (bool): Whether the model should predict multiple + disambiguating masks, or return a single mask. + + Returns: + (list(dict)): A list over input images, where each element is + as dictionary with the following keys. + 'masks': (torch.Tensor) Batched binary mask predictions, + with shape BxCxHxW, where B is the number of input prompts, + C is determiend by multimask_output, and (H, W) is the + original size of the image. + 'iou_predictions': (torch.Tensor) The model's predictions + of mask quality, in shape BxC. + 'low_res_logits': (torch.Tensor) Low resolution logits with + shape BxCxHxW, where H=W=256. Can be passed as mask input + to subsequent iterations of prediction. + """ + input_images = torch.stack( + [self.preprocess(x['image']) for x in batched_input], dim=0) + image_embeddings = self.image_encoder(input_images) + + outputs = [] + for image_record, curr_embedding in zip(batched_input, + image_embeddings): + if 'point_coords' in image_record: + points = (image_record['point_coords'], + image_record['point_labels']) + else: + points = None + sparse_embeddings, dense_embeddings = self.prompt_encoder( + points=points, + boxes=image_record.get('boxes', None), + masks=image_record.get('mask_inputs', None), + ) + low_res_masks, iou_predictions = self.mask_decoder( + image_embeddings=curr_embedding.unsqueeze(0), + image_pe=self.prompt_encoder.get_dense_pe(), + sparse_prompt_embeddings=sparse_embeddings, + dense_prompt_embeddings=dense_embeddings, + multimask_output=multimask_output, + ) + masks = self.postprocess_masks( + low_res_masks, + input_size=image_record['image'].shape[-2:], + original_size=image_record['original_size'], + ) + masks = masks > self.mask_threshold + outputs.append({ + 'masks': masks, + 'iou_predictions': iou_predictions, + 'low_res_logits': low_res_masks, + }) + return outputs + + def postprocess_masks( + self, + masks: torch.Tensor, + input_size: Tuple[int, ...], + original_size: Tuple[int, ...], + ) -> torch.Tensor: + """Remove padding and upscale masks to the original image size. + + Borrowed from https://github.com/facebookresearch/segment-anything + + Arguments: + masks (torch.Tensor): Batched masks from the mask_decoder, + in BxCxHxW format. + input_size (tuple(int, int)): The size of the image input to the + model, in (H, W) format. Used to remove padding. + original_size (tuple(int, int)): The original size of the image + before resizing for input to the model, in (H, W) format. + + Returns: + (torch.Tensor): Batched masks in BxCxHxW format, where (H, W) + is given by original_size. + """ + masks = F.interpolate( + masks, + self.image_encoder.img_size, + mode='bilinear', + align_corners=False, + ) + masks = masks[..., :input_size[0], :input_size[1]] + masks = F.interpolate( + masks, original_size, mode='bilinear', align_corners=False) + return masks + + def preprocess(self, x: torch.Tensor) -> torch.Tensor: + """Normalize pixel values and pad to a square input.""" + # Normalize colors + x = (x - self.pixel_mean) / self.pixel_std + + # Pad + h, w = x.shape[-2:] + img_size = max(self.image_encoder.img_size) + padh = img_size - h + padw = img_size - w + x = F.pad(x, (0, padw, 0, padh)) + return x diff --git a/projects/sam_inference_demo/sam/modeling/transformer.py b/projects/sam_inference_demo/sam/modeling/transformer.py new file mode 100644 index 00000000000..c56f602487d --- /dev/null +++ b/projects/sam_inference_demo/sam/modeling/transformer.py @@ -0,0 +1,241 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +import math +from typing import Tuple, Type + +import torch +from torch import Tensor, nn + +from mmseg.registry import MODELS +from .common import MLPBlock + + +@MODELS.register_module() +class TwoWayTransformer(nn.Module): + + def __init__( + self, + depth: int, + embedding_dim: int, + num_heads: int, + mlp_dim: int, + activation: Type[nn.Module] = nn.ReLU, + attention_downsample_rate: int = 2, + ) -> None: + """A transformer decoder that attends to an input image using queries + whose positional embedding is supplied. + + Args: + depth (int): number of layers in the transformer + embedding_dim (int): the channel dimension for the input embeddings + num_heads (int): the number of heads for multihead attention. Must + divide embedding_dim + mlp_dim (int): the channel dimension internal to the MLP block + activation (nn.Module): the activation to use in the MLP block + """ + super().__init__() + self.depth = depth + self.embedding_dim = embedding_dim + self.num_heads = num_heads + self.mlp_dim = mlp_dim + self.layers = nn.ModuleList() + + for i in range(depth): + self.layers.append( + TwoWayAttentionBlock( + embedding_dim=embedding_dim, + num_heads=num_heads, + mlp_dim=mlp_dim, + activation=activation, + attention_downsample_rate=attention_downsample_rate, + skip_first_layer_pe=(i == 0), + )) + + self.final_attn_token_to_image = Attention( + embedding_dim, + num_heads, + downsample_rate=attention_downsample_rate) + self.norm_final_attn = nn.LayerNorm(embedding_dim) + + def forward( + self, + image_embedding: Tensor, + image_pe: Tensor, + point_embedding: Tensor, + ) -> Tuple[Tensor, Tensor]: + """ + Args: + image_embedding (torch.Tensor): image to attend to. Should be shape + B x embedding_dim x h x w for any h and w. + image_pe (torch.Tensor): the positional encoding to add to the image. Must + have the same shape as image_embedding. + point_embedding (torch.Tensor): the embedding to add to the query points. + Must have shape B x N_points x embedding_dim for any N_points. + + Returns: + torch.Tensor: the processed point_embedding + torch.Tensor: the processed image_embedding + """ # noqa E501 + # BxCxHxW -> BxHWxC == B x N_image_tokens x C + bs, c, h, w = image_embedding.shape + image_embedding = image_embedding.flatten(2).permute(0, 2, 1) + image_pe = image_pe.flatten(2).permute(0, 2, 1) + + # Prepare queries + queries = point_embedding + keys = image_embedding + + # Apply transformer blocks and final layernorm + for layer in self.layers: + queries, keys = layer( + queries=queries, + keys=keys, + query_pe=point_embedding, + key_pe=image_pe, + ) + + # Apply the final attenion layer from the points to the image + q = queries + point_embedding + k = keys + image_pe + attn_out = self.final_attn_token_to_image(q=q, k=k, v=keys) + queries = queries + attn_out + queries = self.norm_final_attn(queries) + + return queries, keys + + +class TwoWayAttentionBlock(nn.Module): + + def __init__( + self, + embedding_dim: int, + num_heads: int, + mlp_dim: int = 2048, + activation: Type[nn.Module] = nn.ReLU, + attention_downsample_rate: int = 2, + skip_first_layer_pe: bool = False, + ) -> None: + """A transformer block with four layers: (1) self-attention of sparse + inputs, (2) cross attention of sparse inputs to dense inputs, (3) mlp + block on sparse inputs, and (4) cross attention of dense inputs to + sparse inputs. + + Arguments: + embedding_dim (int): the channel dimension of the embeddings + num_heads (int): the number of heads in the attention layers + mlp_dim (int): the hidden dimension of the mlp block + activation (nn.Module): the activation of the mlp block + skip_first_layer_pe (bool): skip the PE on the first layer + """ + super().__init__() + self.self_attn = Attention(embedding_dim, num_heads) + self.norm1 = nn.LayerNorm(embedding_dim) + + self.cross_attn_token_to_image = Attention( + embedding_dim, + num_heads, + downsample_rate=attention_downsample_rate) + self.norm2 = nn.LayerNorm(embedding_dim) + + self.mlp = MLPBlock(embedding_dim, mlp_dim, activation) + self.norm3 = nn.LayerNorm(embedding_dim) + + self.norm4 = nn.LayerNorm(embedding_dim) + self.cross_attn_image_to_token = Attention( + embedding_dim, + num_heads, + downsample_rate=attention_downsample_rate) + + self.skip_first_layer_pe = skip_first_layer_pe + + def forward(self, queries: Tensor, keys: Tensor, query_pe: Tensor, + key_pe: Tensor) -> Tuple[Tensor, Tensor]: + # Self attention block + if self.skip_first_layer_pe: + queries = self.self_attn(q=queries, k=queries, v=queries) + else: + q = queries + query_pe + attn_out = self.self_attn(q=q, k=q, v=queries) + queries = queries + attn_out + queries = self.norm1(queries) + + # Cross attention block, tokens attending to image embedding + q = queries + query_pe + k = keys + key_pe + attn_out = self.cross_attn_token_to_image(q=q, k=k, v=keys) + queries = queries + attn_out + queries = self.norm2(queries) + + # MLP block + mlp_out = self.mlp(queries) + queries = queries + mlp_out + queries = self.norm3(queries) + + # Cross attention block, image embedding attending to tokens + q = queries + query_pe + k = keys + key_pe + attn_out = self.cross_attn_image_to_token(q=k, k=q, v=queries) + keys = keys + attn_out + keys = self.norm4(keys) + + return queries, keys + + +class Attention(nn.Module): + """An attention layer that allows for downscaling the size of the embedding + after projection to queries, keys, and values.""" + + def __init__( + self, + embedding_dim: int, + num_heads: int, + downsample_rate: int = 1, + ) -> None: + super().__init__() + self.embedding_dim = embedding_dim + self.internal_dim = embedding_dim // downsample_rate + self.num_heads = num_heads + assert self.internal_dim % num_heads == 0, 'num_heads must divide embedding_dim.' # noqa E501 + + self.q_proj = nn.Linear(embedding_dim, self.internal_dim) + self.k_proj = nn.Linear(embedding_dim, self.internal_dim) + self.v_proj = nn.Linear(embedding_dim, self.internal_dim) + self.out_proj = nn.Linear(self.internal_dim, embedding_dim) + + def _separate_heads(self, x: Tensor, num_heads: int) -> Tensor: + b, n, c = x.shape + x = x.reshape(b, n, num_heads, c // num_heads) + return x.transpose(1, 2) # B x N_heads x N_tokens x C_per_head + + def _recombine_heads(self, x: Tensor) -> Tensor: + b, n_heads, n_tokens, c_per_head = x.shape + x = x.transpose(1, 2) + return x.reshape(b, n_tokens, n_heads * c_per_head) # B x N_tokens x C + + def forward(self, q: Tensor, k: Tensor, v: Tensor) -> Tensor: + # Input projections + q = self.q_proj(q) + k = self.k_proj(k) + v = self.v_proj(v) + + # Separate into heads + q = self._separate_heads(q, self.num_heads) + k = self._separate_heads(k, self.num_heads) + v = self._separate_heads(v, self.num_heads) + + # Attention + _, _, _, c_per_head = q.shape + attn = q @ k.permute(0, 1, 3, 2) # B x N_heads x N_tokens x N_tokens + attn = attn / math.sqrt(c_per_head) + attn = torch.softmax(attn, dim=-1) + + # Get output + out = attn @ v + out = self._recombine_heads(out) + out = self.out_proj(out) + + return out diff --git a/projects/sam_inference_demo/sam/sam_inferencer.py b/projects/sam_inference_demo/sam/sam_inferencer.py new file mode 100644 index 00000000000..2da2e959c09 --- /dev/null +++ b/projects/sam_inference_demo/sam/sam_inferencer.py @@ -0,0 +1,688 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from typing import Any, Dict, List, Optional, Tuple + +import numpy as np +import torch +from mmengine.runner.checkpoint import load_checkpoint +# yapf: disable +from sam.utils import (MaskData, area_from_rle, batch_iterator, + batched_mask_to_box, box_xyxy_to_xywh, + build_all_layer_point_grids, calculate_stability_score, + coco_encode_rle, generate_crop_boxes, + is_box_near_crop_edge, mask_to_rle_pytorch, + remove_small_regions, rle_to_mask, uncrop_boxes_xyxy, + uncrop_masks, uncrop_points) +from torchvision.ops.boxes import batched_nms, box_area + +from mmseg.registry import MODELS, TRANSFORMS + +# yapf: enable + +model_zoo = { + 'base': + 'https://download.openmmlab.com/mmsegmentation/v0.5/sam/sam_vit-base-p16_3rdparty_sa1b-1024x1024_20230413-78a25eed.pth', # noqa + 'large': + 'https://download.openmmlab.com/mmsegmentation/v0.5/sam/sam_vit-large-p16_3rdparty_sa1b-1024x1024_20230413-940520da.pth', # noqa + 'huge': + 'https://download.openmmlab.com/mmsegmentation/v0.5/sam/sam_vit-huge-p16_3rdparty_sa1b-1024x1024_20230413-faaf96f6.pth', # noqa +} + + +class SAMInferencer: + + def __init__(self, arch: str = 'base') -> None: + assert arch in ['base', 'large', 'huge'] + self.model = self.init_model(arch) + self.transform = TRANSFORMS.build( + dict( + type='ResizeLongestSide', + target_length=max(self.model.image_encoder.img_size))) + + def set_image( + self, + image: np.ndarray, + image_format: str = 'RGB', + ) -> None: + """Calculates the image embeddings for the provided image, allowing + masks to be predicted with the 'predict' method. + + Arguments: + image (np.ndarray): The image for calculating masks. Expects an + image in HWC uint8 format, with pixel values in [0, 255]. + image_format (str): The color format of the image, in ['RGB', 'BGR']. + """ + assert image_format in [ + 'RGB', + 'BGR', + ], f"image_format must be in ['RGB', 'BGR'], is {image_format}." + if image_format != self.model.image_format: + image = image[..., ::-1] + + # Transform the image to the form expected by the model + input_image = self.transform.apply_image(image) + input_image_torch = torch.as_tensor(input_image, device=self.device) + input_image_torch = input_image_torch.permute( + 2, 0, 1).contiguous()[None, :, :, :] + + self.set_torch_image(input_image_torch, image.shape[:2]) + + @torch.no_grad() + def set_torch_image( + self, + transformed_image: torch.Tensor, + original_image_size: Tuple[int, ...], + ) -> None: + """Calculates the image embeddings for the provided image, allowing + masks to be predicted with the 'predict' method. Expects the input + image to be already transformed to the format expected by the model. + + Arguments: + transformed_image (torch.Tensor): The input image, with shape + 1x3xHxW, which has been transformed with ResizeLongestSide. + original_image_size (tuple(int, int)): The size of the image + before transformation, in (H, W) format. + """ + assert (len(transformed_image.shape) == 4 + and transformed_image.shape[1] == 3 + and max(*transformed_image.shape[2:]) == max( + self.model.image_encoder.img_size) + ), 'set_torch_image input must be BCHW with long side' + f' {self.model.image_encoder.img_size}.' + self.reset_image() + + self.original_size = original_image_size + self.input_size = tuple(transformed_image.shape[-2:]) + input_image = self.model.preprocess(transformed_image) + self.features = self.model.image_encoder(input_image)[0] + self.is_image_set = True + + def predict( + self, + point_coords: Optional[np.ndarray] = None, + point_labels: Optional[np.ndarray] = None, + box: Optional[np.ndarray] = None, + mask_input: Optional[np.ndarray] = None, + multimask_output: bool = True, + return_logits: bool = False, + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """Predict masks for the given input prompts, using the currently set + image. + + Arguments: + point_coords (np.ndarray or None): A Nx2 array of point prompts to the + model. Each point is in (X,Y) in pixels. + point_labels (np.ndarray or None): A length N array of labels for the + point prompts. 1 indicates a foreground point and 0 indicates a + background point. + box (np.ndarray or None): A length 4 array given a box prompt to the + model, in XYXY format. + mask_input (np.ndarray): A low resolution mask input to the model, typically + coming from a previous prediction iteration. Has form 1xHxW, where + for SAM, H=W=256. + multimask_output (bool): If true, the model will return three masks. + For ambiguous input prompts (such as a single click), this will often + produce better masks than a single prediction. If only a single + mask is needed, the model's predicted quality score can be used + to select the best mask. For non-ambiguous prompts, such as multiple + input prompts, multimask_output=False can give better results. + return_logits (bool): If true, returns un-thresholded masks logits + instead of a binary mask. + + Returns: + (np.ndarray): The output masks in CxHxW format, where C is the + number of masks, and (H, W) is the original image size. + (np.ndarray): An array of length C containing the model's + predictions for the quality of each mask. + (np.ndarray): An array of shape CxHxW, where C is the number + of masks and H=W=256. These low resolution logits can be passed to + a subsequent iteration as mask input. + """ # noqa + if not self.is_image_set: + raise RuntimeError( + 'An image must be set with .set_image(...) before mask' + 'prediction.') + + # Transform input prompts + coords_torch = None + labels_torch = None + box_torch = None + mask_input_torch = None + + if point_coords is not None: + assert ( + point_labels is not None + ), 'point_labels must be supplied if point_coords is supplied.' + point_coords = self.transform.apply_coords(point_coords, + self.original_size) + coords_torch = torch.as_tensor( + point_coords, dtype=torch.float, device=self.device) + labels_torch = torch.as_tensor( + point_labels, dtype=torch.int, device=self.device) + coords_torch, labels_torch = coords_torch[ + None, :, :], labels_torch[None, :] + if box is not None: + box = self.transform.apply_boxes(box, self.original_size) + box_torch = torch.as_tensor( + box, dtype=torch.float, device=self.device) + box_torch = box_torch[None, :] + if mask_input is not None: + mask_input_torch = torch.as_tensor( + mask_input, dtype=torch.float, device=self.device) + mask_input_torch = mask_input_torch[None, :, :, :] + + masks, iou_predictions, low_res_masks = self.predict_torch( + coords_torch, + labels_torch, + box_torch, + mask_input_torch, + multimask_output, + return_logits=return_logits, + ) + + masks = masks[0].detach().cpu().numpy() + iou_predictions = iou_predictions[0].detach().cpu().numpy() + low_res_masks = low_res_masks[0].detach().cpu().numpy() + return masks, iou_predictions, low_res_masks + + @torch.no_grad() + def predict_torch( + self, + point_coords: Optional[torch.Tensor], + point_labels: Optional[torch.Tensor], + boxes: Optional[torch.Tensor] = None, + mask_input: Optional[torch.Tensor] = None, + multimask_output: bool = True, + return_logits: bool = False, + ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """Predict masks for the given input prompts, using the currently set + image. Input prompts are batched torch tensors and are expected to + already be transformed to the input frame using ResizeLongestSide. + + Arguments: + point_coords (torch.Tensor or None): A BxNx2 array of point prompts to the + model. Each point is in (X,Y) in pixels. + point_labels (torch.Tensor or None): A BxN array of labels for the + point prompts. 1 indicates a foreground point and 0 indicates a + background point. + box (np.ndarray or None): A Bx4 array given a box prompt to the + model, in XYXY format. + mask_input (np.ndarray): A low resolution mask input to the model, typically + coming from a previous prediction iteration. Has form Bx1xHxW, where + for SAM, H=W=256. Masks returned by a previous iteration of the + predict method do not need further transformation. + multimask_output (bool): If true, the model will return three masks. + For ambiguous input prompts (such as a single click), this will often + produce better masks than a single prediction. If only a single + mask is needed, the model's predicted quality score can be used + to select the best mask. For non-ambiguous prompts, such as multiple + input prompts, multimask_output=False can give better results. + return_logits (bool): If true, returns un-thresholded masks logits + instead of a binary mask. + + Returns: + (torch.Tensor): The output masks in BxCxHxW format, where C is the + number of masks, and (H, W) is the original image size. + (torch.Tensor): An array of shape BxC containing the model's + predictions for the quality of each mask. + (torch.Tensor): An array of shape BxCxHxW, where C is the number + of masks and H=W=256. These low res logits can be passed to + a subsequent iteration as mask input. + """ # noqa + if not self.is_image_set: + raise RuntimeError( + 'An image must be set with .set_image(...) before mask ' + 'prediction.') + + if point_coords is not None: + points = (point_coords, point_labels) + else: + points = None + + # Embed prompts + sparse_embeddings, dense_embeddings = self.model.prompt_encoder( + points=points, + boxes=boxes, + masks=mask_input, + ) + + # Predict masks + low_res_masks, iou_predictions = self.model.mask_decoder( + image_embeddings=self.features, + image_pe=self.model.prompt_encoder.get_dense_pe(), + sparse_prompt_embeddings=sparse_embeddings, + dense_prompt_embeddings=dense_embeddings, + multimask_output=multimask_output, + ) + + # Upscale the masks to the original image resolution + masks = self.model.postprocess_masks(low_res_masks, self.input_size, + self.original_size) + + if not return_logits: + masks = masks > self.model.mask_threshold + + return masks, iou_predictions, low_res_masks + + def get_image_embedding(self) -> torch.Tensor: + """Returns the image embeddings for the currently set image, with shape + 1xCxHxW, where C is the embedding dimension and (H,W) are the embedding + spatial dimension of SAM (typically C=256, H=W=64).""" + if not self.is_image_set: + raise RuntimeError( + 'An image must be set with .set_image(...) to generate an ' + 'embedding.') + assert self.features is not None, 'Features must exist if an image has' + ' been set.' + return self.features + + @property + def device(self) -> torch.device: + return self.model.device + + def reset_image(self) -> None: + """Resets the currently set image.""" + self.is_image_set = False + self.features = None + self.orig_h = None + self.orig_w = None + self.input_h = None + self.input_w = None + + def init_model(self, arch: str): + model = MODELS.build( + dict( + type='SAM', + image_encoder_cfg=dict( + type='mmpretrain.ViTSAM', + arch=arch, + img_size=1024, + patch_size=16, + out_channels=256, + use_abs_pos=True, + use_rel_pos=True, + window_size=14, + ), + prompt_encoder_cfg=dict( + type='PromptEncoder', + embed_dim=256, + image_embedding_size=(64, 64), + input_image_size=(1024, 1024), + mask_in_chans=16, + ), + mask_decoder_cfg=dict( + type='MaskDecoder', + num_multimask_outputs=3, + transformer=dict( + type='TwoWayTransformer', + depth=2, + embedding_dim=256, + mlp_dim=2048, + num_heads=8, + ), + transformer_dim=256, + iou_head_depth=3, + iou_head_hidden_dim=256, + ))) + load_checkpoint(model, model_zoo.get(arch), strict=True) + if torch.cuda.is_available(): + model = model.cuda() + return model + + +class SamAutomaticMaskGenerator: + + def __init__( + self, + arch: str = 'base', + points_per_side: Optional[int] = 32, + points_per_batch: int = 64, + pred_iou_thresh: float = 0.88, + stability_score_thresh: float = 0.95, + stability_score_offset: float = 1.0, + box_nms_thresh: float = 0.7, + crop_n_layers: int = 0, + crop_nms_thresh: float = 0.7, + crop_overlap_ratio: float = 512 / 1500, + crop_n_points_downscale_factor: int = 1, + point_grids: Optional[List[np.ndarray]] = None, + min_mask_region_area: int = 0, + output_mode: str = 'binary_mask', + ) -> None: + """Using a SAM model, generates masks for the entire image. Generates a + grid of point prompts over the image, then filters low quality and + duplicate masks. The default settings are chosen for SAM with a ViT-H + backbone. + + Arguments: + arch (str): The SAM model to use for mask prediction. + points_per_side (int or None): The number of points to be sampled + along one side of the image. The total number of points is + points_per_side**2. If None, 'point_grids' must provide explicit + point sampling. + points_per_batch (int): Sets the number of points run simultaneously + by the model. Higher numbers may be faster but use more GPU memory. + pred_iou_thresh (float): A filtering threshold in [0,1], using the + model's predicted mask quality. + stability_score_thresh (float): A filtering threshold in [0,1], using + the stability of the mask under changes to the cutoff used to binarize + the model's mask predictions. + stability_score_offset (float): The amount to shift the cutoff when + calculated the stability score. + box_nms_thresh (float): The box IoU cutoff used by non-maximal + suppression to filter duplicate masks. + crops_n_layers (int): If >0, mask prediction will be run again on + crops of the image. Sets the number of layers to run, where each + layer has 2**i_layer number of image crops. + crops_nms_thresh (float): The box IoU cutoff used by non-maximal + suppression to filter duplicate masks between different crops. + crop_overlap_ratio (float): Sets the degree to which crops overlap. + In the first crop layer, crops will overlap by this fraction of + the image length. Later layers with more crops scale down this overlap. + crop_n_points_downscale_factor (int): The number of points-per-side + sampled in layer n is scaled down by crop_n_points_downscale_factor**n. + point_grids (list(np.ndarray) or None): A list over explicit grids + of points used for sampling, normalized to [0,1]. The nth grid in the + list is used in the nth crop layer. Exclusive with points_per_side. + min_mask_region_area (int): If >0, postprocessing will be applied + to remove disconnected regions and holes in masks with area smaller + than min_mask_region_area. Requires opencv. + output_mode (str): The form masks are returned in. Can be 'binary_mask', + 'uncompressed_rle', or 'coco_rle'. 'coco_rle' requires pycocotools. + For large resolutions, 'binary_mask' may consume large amounts of + memory. + """ # noqa + + assert (points_per_side is None) != ( + point_grids is None + ), 'Exactly one of points_per_side or point_grid must be provided.' + if points_per_side is not None: + self.point_grids = build_all_layer_point_grids( + points_per_side, + crop_n_layers, + crop_n_points_downscale_factor, + ) + elif point_grids is not None: + self.point_grids = point_grids + else: + raise ValueError( + "Can't have both points_per_side and point_grid be None.") + + assert output_mode in [ + 'binary_mask', + 'uncompressed_rle', + 'coco_rle', + ], f'Unknown output_mode {output_mode}.' + if output_mode == 'coco_rle': + from pycocotools import \ + mask as mask_utils # type: ignore # noqa: F401 + + if min_mask_region_area > 0: + import cv2 # type: ignore # noqa: F401 + + self.predictor = SAMInferencer(arch) + self.points_per_batch = points_per_batch + self.pred_iou_thresh = pred_iou_thresh + self.stability_score_thresh = stability_score_thresh + self.stability_score_offset = stability_score_offset + self.box_nms_thresh = box_nms_thresh + self.crop_n_layers = crop_n_layers + self.crop_nms_thresh = crop_nms_thresh + self.crop_overlap_ratio = crop_overlap_ratio + self.crop_n_points_downscale_factor = crop_n_points_downscale_factor + self.min_mask_region_area = min_mask_region_area + self.output_mode = output_mode + + @torch.no_grad() + def generate(self, image: np.ndarray) -> List[Dict[str, Any]]: + """Generates masks for the given image. + + Arguments: + image (np.ndarray): The image to generate masks for, in HWC uint8 format. + + Returns: + list(dict(str, any)): A list over records for masks. Each record is + a dict containing the following keys: + segmentation (dict(str, any) or np.ndarray): The mask. If + output_mode='binary_mask', is an array of shape HW. Otherwise, + is a dictionary containing the RLE. + bbox (list(float)): The box around the mask, in XYWH format. + area (int): The area in pixels of the mask. + predicted_iou (float): The model's own prediction of the mask's + quality. This is filtered by the pred_iou_thresh parameter. + point_coords (list(list(float))): The point coordinates input + to the model to generate this mask. + stability_score (float): A measure of the mask's quality. This + is filtered on using the stability_score_thresh parameter. + crop_box (list(float)): The crop of the image used to generate + the mask, given in XYWH format. + """ # noqa + + # Generate masks + mask_data = self._generate_masks(image) + + # Filter small disconnected regions and holes in masks + if self.min_mask_region_area > 0: + mask_data = self.postprocess_small_regions( + mask_data, + self.min_mask_region_area, + max(self.box_nms_thresh, self.crop_nms_thresh), + ) + + # Encode masks + if self.output_mode == 'coco_rle': + mask_data['segmentations'] = [ + coco_encode_rle(rle) for rle in mask_data['rles'] + ] + elif self.output_mode == 'binary_mask': + mask_data['segmentations'] = [ + rle_to_mask(rle) for rle in mask_data['rles'] + ] + else: + mask_data['segmentations'] = mask_data['rles'] + + # Write mask records + curr_anns = [] + for idx in range(len(mask_data['segmentations'])): + ann = { + 'segmentation': + mask_data['segmentations'][idx], + 'area': + area_from_rle(mask_data['rles'][idx]), + 'bbox': + box_xyxy_to_xywh(mask_data['boxes'][idx]).tolist(), + 'predicted_iou': + mask_data['iou_preds'][idx].item(), + 'point_coords': [mask_data['points'][idx].tolist()], + 'stability_score': + mask_data['stability_score'][idx].item(), + 'crop_box': + box_xyxy_to_xywh(mask_data['crop_boxes'][idx]).tolist(), + } + curr_anns.append(ann) + + return curr_anns + + def _generate_masks(self, image: np.ndarray) -> MaskData: + orig_size = image.shape[:2] + crop_boxes, layer_idxs = generate_crop_boxes(orig_size, + self.crop_n_layers, + self.crop_overlap_ratio) + + # Iterate over image crops + data = MaskData() + for crop_box, layer_idx in zip(crop_boxes, layer_idxs): + crop_data = self._process_crop(image, crop_box, layer_idx, + orig_size) + data.cat(crop_data) + + # Remove duplicate masks between crops + if len(crop_boxes) > 1: + # Prefer masks from smaller crops + scores = 1 / box_area(data['crop_boxes']) + scores = scores.to(data['boxes'].device) + keep_by_nms = batched_nms( + data['boxes'].float(), + scores, + torch.zeros(len(data['boxes'])), # categories + iou_threshold=self.crop_nms_thresh, + ) + data.filter(keep_by_nms) + + data.to_numpy() + return data + + def _process_crop( + self, + image: np.ndarray, + crop_box: List[int], + crop_layer_idx: int, + orig_size: Tuple[int, ...], + ) -> MaskData: + # Crop the image and calculate embeddings + x0, y0, x1, y1 = crop_box + cropped_im = image[y0:y1, x0:x1, :] + cropped_im_size = cropped_im.shape[:2] + self.predictor.set_image(cropped_im) + + # Get points for this crop + points_scale = np.array(cropped_im_size)[None, ::-1] + points_for_image = self.point_grids[crop_layer_idx] * points_scale + + # Generate masks for this crop in batches + data = MaskData() + for (points, ) in batch_iterator(self.points_per_batch, + points_for_image): + batch_data = self._process_batch(points, cropped_im_size, crop_box, + orig_size) + data.cat(batch_data) + del batch_data + self.predictor.reset_image() + + # Remove duplicates within this crop. + keep_by_nms = batched_nms( + data['boxes'].float(), + data['iou_preds'], + torch.zeros(len(data['boxes'])), # categories + iou_threshold=self.box_nms_thresh, + ) + data.filter(keep_by_nms) + + # Return to the original image frame + data['boxes'] = uncrop_boxes_xyxy(data['boxes'], crop_box) + data['points'] = uncrop_points(data['points'], crop_box) + data['crop_boxes'] = torch.tensor( + [crop_box for _ in range(len(data['rles']))]) + + return data + + def _process_batch( + self, + points: np.ndarray, + im_size: Tuple[int, ...], + crop_box: List[int], + orig_size: Tuple[int, ...], + ) -> MaskData: + orig_h, orig_w = orig_size + + # Run model on this batch + transformed_points = self.predictor.transform.apply_coords( + points, im_size) + in_points = torch.as_tensor( + transformed_points, device=self.predictor.device) + in_labels = torch.ones( + in_points.shape[0], dtype=torch.int, device=in_points.device) + masks, iou_preds, _ = self.predictor.predict_torch( + in_points[:, None, :], + in_labels[:, None], + multimask_output=True, + return_logits=True, + ) + + # Serialize predictions and store in MaskData + data = MaskData( + masks=masks.flatten(0, 1), + iou_preds=iou_preds.flatten(0, 1), + points=torch.as_tensor(points.repeat(masks.shape[1], axis=0)), + ) + del masks + + # Filter by predicted IoU + if self.pred_iou_thresh > 0.0: + keep_mask = data['iou_preds'] > self.pred_iou_thresh + data.filter(keep_mask) + + # Calculate stability score + data['stability_score'] = calculate_stability_score( + data['masks'], self.predictor.model.mask_threshold, + self.stability_score_offset) + if self.stability_score_thresh > 0.0: + keep_mask = data['stability_score'] >= self.stability_score_thresh + data.filter(keep_mask) + + # Threshold masks and calculate boxes + data['masks'] = data['masks'] > self.predictor.model.mask_threshold + data['boxes'] = batched_mask_to_box(data['masks']) + + # Filter boxes that touch crop boundaries + keep_mask = ~is_box_near_crop_edge(data['boxes'], crop_box, + [0, 0, orig_w, orig_h]) + if not torch.all(keep_mask): + data.filter(keep_mask) + + # Compress to RLE + data['masks'] = uncrop_masks(data['masks'], crop_box, orig_h, orig_w) + data['rles'] = mask_to_rle_pytorch(data['masks']) + del data['masks'] + + return data + + @staticmethod + def postprocess_small_regions(mask_data: MaskData, min_area: int, + nms_thresh: float) -> MaskData: + """Removes small disconnected regions and holes in masks, then reruns + box NMS to remove any new duplicates. + + Edits mask_data in place. + + Requires open-cv as a dependency. + """ + if len(mask_data['rles']) == 0: + return mask_data + + # Filter small disconnected regions and holes + new_masks = [] + scores = [] + for rle in mask_data['rles']: + mask = rle_to_mask(rle) + + mask, changed = remove_small_regions(mask, min_area, mode='holes') + unchanged = not changed + mask, changed = remove_small_regions( + mask, min_area, mode='islands') + unchanged = unchanged and not changed + + new_masks.append(torch.as_tensor(mask).unsqueeze(0)) + # Give score=0 to changed masks and score=1 to unchanged masks + # so NMS will prefer ones that didn't need postprocessing + scores.append(float(unchanged)) + + # Recalculate boxes and remove any new duplicates + masks = torch.cat(new_masks, dim=0) + boxes = batched_mask_to_box(masks) + keep_by_nms = batched_nms( + boxes.float(), + torch.as_tensor(scores), + torch.zeros(len(boxes)), # categories + iou_threshold=nms_thresh, + ) + + # Only recalculate RLEs for masks that have changed + for i_mask in keep_by_nms: + if scores[i_mask] == 0.0: + mask_torch = masks[i_mask].unsqueeze(0) + mask_data['rles'][i_mask] = mask_to_rle_pytorch(mask_torch)[0] + mask_data['boxes'][i_mask] = boxes[ + i_mask] # update res directly + mask_data.filter(keep_by_nms) + + return mask_data diff --git a/projects/sam_inference_demo/sam/utils/__init__.py b/projects/sam_inference_demo/sam/utils/__init__.py new file mode 100644 index 00000000000..5d33e33aeef --- /dev/null +++ b/projects/sam_inference_demo/sam/utils/__init__.py @@ -0,0 +1,2 @@ +from .amg import * # noqa: F403 F401 +from .transforms import ResizeLongestSide # noqa: F403 F401 diff --git a/projects/sam_inference_demo/sam/utils/amg.py b/projects/sam_inference_demo/sam/utils/amg.py new file mode 100644 index 00000000000..3ba359901f7 --- /dev/null +++ b/projects/sam_inference_demo/sam/utils/amg.py @@ -0,0 +1,355 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +# https://github.com/facebookresearch/segment-anything + +import math +from copy import deepcopy +from itertools import product +from typing import Any, Dict, Generator, ItemsView, List, Tuple + +import numpy as np +import torch + + +class MaskData: + """A structure for storing masks and their related data in batched format. + + Implements basic filtering and concatenation. + """ + + def __init__(self, **kwargs) -> None: + for v in kwargs.values(): + assert isinstance( + v, (list, np.ndarray, torch.Tensor) + ), 'MaskData only supports list, numpy arrays, and torch tensors.' + self._stats = dict(**kwargs) + + def __setitem__(self, key: str, item: Any) -> None: + assert isinstance( + item, (list, np.ndarray, torch.Tensor) + ), 'MaskData only supports list, numpy arrays, and torch tensors.' + self._stats[key] = item + + def __delitem__(self, key: str) -> None: + del self._stats[key] + + def __getitem__(self, key: str) -> Any: + return self._stats[key] + + def items(self) -> ItemsView[str, Any]: + return self._stats.items() + + def filter(self, keep: torch.Tensor) -> None: + for k, v in self._stats.items(): + if v is None: + self._stats[k] = None + elif isinstance(v, torch.Tensor): + self._stats[k] = v[torch.as_tensor(keep, device=v.device)] + elif isinstance(v, np.ndarray): + self._stats[k] = v[keep.detach().cpu().numpy()] + elif isinstance(v, list) and keep.dtype == torch.bool: + self._stats[k] = [a for i, a in enumerate(v) if keep[i]] + elif isinstance(v, list): + self._stats[k] = [v[i] for i in keep] + else: + raise TypeError( + f'MaskData key {k} has an unsupported type {type(v)}.') + + def cat(self, new_stats: 'MaskData') -> None: + for k, v in new_stats.items(): + if k not in self._stats or self._stats[k] is None: + self._stats[k] = deepcopy(v) + elif isinstance(v, torch.Tensor): + self._stats[k] = torch.cat([self._stats[k], v], dim=0) + elif isinstance(v, np.ndarray): + self._stats[k] = np.concatenate([self._stats[k], v], axis=0) + elif isinstance(v, list): + self._stats[k] = self._stats[k] + deepcopy(v) + else: + raise TypeError( + f'MaskData key {k} has an unsupported type {type(v)}.') + + def to_numpy(self) -> None: + for k, v in self._stats.items(): + if isinstance(v, torch.Tensor): + self._stats[k] = v.detach().cpu().numpy() + + +def is_box_near_crop_edge(boxes: torch.Tensor, + crop_box: List[int], + orig_box: List[int], + atol: float = 20.0) -> torch.Tensor: + """Filter masks at the edge of a crop, but not at the edge of the original + image.""" + crop_box_torch = torch.as_tensor( + crop_box, dtype=torch.float, device=boxes.device) + orig_box_torch = torch.as_tensor( + orig_box, dtype=torch.float, device=boxes.device) + boxes = uncrop_boxes_xyxy(boxes, crop_box).float() + near_crop_edge = torch.isclose( + boxes, crop_box_torch[None, :], atol=atol, rtol=0) + near_image_edge = torch.isclose( + boxes, orig_box_torch[None, :], atol=atol, rtol=0) + near_crop_edge = torch.logical_and(near_crop_edge, ~near_image_edge) + return torch.any(near_crop_edge, dim=1) + + +def box_xyxy_to_xywh(box_xyxy: torch.Tensor) -> torch.Tensor: + box_xywh = deepcopy(box_xyxy) + box_xywh[2] = box_xywh[2] - box_xywh[0] + box_xywh[3] = box_xywh[3] - box_xywh[1] + return box_xywh + + +def batch_iterator(batch_size: int, *args) -> Generator[List[Any], None, None]: + assert len(args) > 0 and all( + len(a) == len(args[0]) for a in + args), 'Batched iteration must have inputs of all the same size.' + n_batches = len(args[0]) // batch_size + int( + len(args[0]) % batch_size != 0) + for b in range(n_batches): + yield [arg[b * batch_size:(b + 1) * batch_size] for arg in args] + + +def mask_to_rle_pytorch(tensor: torch.Tensor) -> List[Dict[str, Any]]: + """Encodes masks to an uncompressed RLE, in the format expected by pycoco + tools.""" + # Put in fortran order and flatten h,w + b, h, w = tensor.shape + tensor = tensor.permute(0, 2, 1).flatten(1) + + # Compute change indices + diff = tensor[:, 1:] ^ tensor[:, :-1] + change_indices = diff.nonzero() + + # Encode run length + out = [] + for i in range(b): + cur_idxs = change_indices[change_indices[:, 0] == i, 1] + cur_idxs = torch.cat([ + torch.tensor([0], dtype=cur_idxs.dtype, device=cur_idxs.device), + cur_idxs + 1, + torch.tensor([h * w], dtype=cur_idxs.dtype, + device=cur_idxs.device), + ]) + btw_idxs = cur_idxs[1:] - cur_idxs[:-1] + counts = [] if tensor[i, 0] == 0 else [0] + counts.extend(btw_idxs.detach().cpu().tolist()) + out.append({'size': [h, w], 'counts': counts}) + return out + + +def rle_to_mask(rle: Dict[str, Any]) -> np.ndarray: + """Compute a binary mask from an uncompressed RLE.""" + h, w = rle['size'] + mask = np.empty(h * w, dtype=bool) + idx = 0 + parity = False + for count in rle['counts']: + mask[idx:idx + count] = parity + idx += count + parity ^= True + mask = mask.reshape(w, h) + return mask.transpose() # Put in C order + + +def area_from_rle(rle: Dict[str, Any]) -> int: + return sum(rle['counts'][1::2]) + + +def calculate_stability_score(masks: torch.Tensor, mask_threshold: float, + threshold_offset: float) -> torch.Tensor: + """Computes the stability score for a batch of masks. + + The stability score is the IoU between the binary masks obtained by + thresholding the predicted mask logits at high and low values. + """ + # One mask is always contained inside the other. + # Save memory by preventing unnecessary cast to torch.int64 + intersections = ((masks > (mask_threshold + threshold_offset)).sum( + -1, dtype=torch.int16).sum(-1, dtype=torch.int32)) + unions = ((masks > (mask_threshold - threshold_offset)).sum( + -1, dtype=torch.int16).sum(-1, dtype=torch.int32)) + return intersections / unions + + +def build_point_grid(n_per_side: int) -> np.ndarray: + """Generates a 2D grid of points evenly spaced in [0,1]x[0,1].""" + offset = 1 / (2 * n_per_side) + points_one_side = np.linspace(offset, 1 - offset, n_per_side) + points_x = np.tile(points_one_side[None, :], (n_per_side, 1)) + points_y = np.tile(points_one_side[:, None], (1, n_per_side)) + points = np.stack([points_x, points_y], axis=-1).reshape(-1, 2) + return points + + +def build_all_layer_point_grids(n_per_side: int, n_layers: int, + scale_per_layer: int) -> List[np.ndarray]: + """Generates point grids for all crop layers.""" + points_by_layer = [] + for i in range(n_layers + 1): + n_points = int(n_per_side / (scale_per_layer**i)) + points_by_layer.append(build_point_grid(n_points)) + return points_by_layer + + +def generate_crop_boxes( + im_size: Tuple[int, ...], n_layers: int, + overlap_ratio: float) -> Tuple[List[List[int]], List[int]]: + """Generates a list of crop boxes of different sizes. + + Each layer has (2**i)**2 boxes for the ith layer. + """ + crop_boxes, layer_idxs = [], [] + im_h, im_w = im_size + short_side = min(im_h, im_w) + + # Original image + crop_boxes.append([0, 0, im_w, im_h]) + layer_idxs.append(0) + + def crop_len(orig_len, n_crops, overlap): + return int(math.ceil((overlap * (n_crops - 1) + orig_len) / n_crops)) + + for i_layer in range(n_layers): + n_crops_per_side = 2**(i_layer + 1) + overlap = int(overlap_ratio * short_side * (2 / n_crops_per_side)) + + crop_w = crop_len(im_w, n_crops_per_side, overlap) + crop_h = crop_len(im_h, n_crops_per_side, overlap) + + crop_box_x0 = [ + int((crop_w - overlap) * i) for i in range(n_crops_per_side) + ] + crop_box_y0 = [ + int((crop_h - overlap) * i) for i in range(n_crops_per_side) + ] + + # Crops in XYWH format + for x0, y0 in product(crop_box_x0, crop_box_y0): + box = [x0, y0, min(x0 + crop_w, im_w), min(y0 + crop_h, im_h)] + crop_boxes.append(box) + layer_idxs.append(i_layer + 1) + + return crop_boxes, layer_idxs + + +def uncrop_boxes_xyxy(boxes: torch.Tensor, + crop_box: List[int]) -> torch.Tensor: + x0, y0, _, _ = crop_box + offset = torch.tensor([[x0, y0, x0, y0]], device=boxes.device) + # Check if boxes has a channel dimension + if len(boxes.shape) == 3: + offset = offset.unsqueeze(1) + return boxes + offset + + +def uncrop_points(points: torch.Tensor, crop_box: List[int]) -> torch.Tensor: + x0, y0, _, _ = crop_box + offset = torch.tensor([[x0, y0]], device=points.device) + # Check if points has a channel dimension + if len(points.shape) == 3: + offset = offset.unsqueeze(1) + return points + offset + + +def uncrop_masks(masks: torch.Tensor, crop_box: List[int], orig_h: int, + orig_w: int) -> torch.Tensor: + x0, y0, x1, y1 = crop_box + if x0 == 0 and y0 == 0 and x1 == orig_w and y1 == orig_h: + return masks + # Coordinate transform masks + pad_x, pad_y = orig_w - (x1 - x0), orig_h - (y1 - y0) + pad = (x0, pad_x - x0, y0, pad_y - y0) + return torch.nn.functional.pad(masks, pad, value=0) + + +def remove_small_regions(mask: np.ndarray, area_thresh: float, + mode: str) -> Tuple[np.ndarray, bool]: + """Removes small disconnected regions and holes in a mask. + + Returns the mask and an indicator of if the mask has been modified. + """ + import cv2 # type: ignore + + assert mode in ['holes', 'islands'] + correct_holes = mode == 'holes' + working_mask = (correct_holes ^ mask).astype(np.uint8) + n_labels, regions, stats, _ = cv2.connectedComponentsWithStats( + working_mask, 8) + sizes = stats[:, -1][1:] # Row 0 is background label + small_regions = [i + 1 for i, s in enumerate(sizes) if s < area_thresh] + if len(small_regions) == 0: + return mask, False + fill_labels = [0] + small_regions + if not correct_holes: + fill_labels = [i for i in range(n_labels) if i not in fill_labels] + # If every region is below threshold, keep largest + if len(fill_labels) == 0: + fill_labels = [int(np.argmax(sizes)) + 1] + mask = np.isin(regions, fill_labels) + return mask, True + + +def coco_encode_rle(uncompressed_rle: Dict[str, Any]) -> Dict[str, Any]: + from pycocotools import mask as mask_utils # type: ignore + + h, w = uncompressed_rle['size'] + rle = mask_utils.frPyObjects(uncompressed_rle, h, w) + rle['counts'] = rle['counts'].decode( + 'utf-8') # Necessary to serialize with json + return rle + + +def batched_mask_to_box(masks: torch.Tensor) -> torch.Tensor: + """Calculates boxes in XYXY format around masks. + + Return [0,0,0,0] for an empty mask. For input shape C1xC2x...xHxW, the + output shape is C1xC2x...x4. + """ + # torch.max below raises an error on empty inputs, just skip in this case + if torch.numel(masks) == 0: + return torch.zeros(*masks.shape[:-2], 4, device=masks.device) + + # Normalize shape to CxHxW + shape = masks.shape + h, w = shape[-2:] + if len(shape) > 2: + masks = masks.flatten(0, -3) + else: + masks = masks.unsqueeze(0) + + # Get top and bottom edges + in_height, _ = torch.max(masks, dim=-1) + in_height_coords = in_height * torch.arange( + h, device=in_height.device)[None, :] + bottom_edges, _ = torch.max(in_height_coords, dim=-1) + in_height_coords = in_height_coords + h * (~in_height) + top_edges, _ = torch.min(in_height_coords, dim=-1) + + # Get left and right edges + in_width, _ = torch.max(masks, dim=-2) + in_width_coords = in_width * torch.arange( + w, device=in_width.device)[None, :] + right_edges, _ = torch.max(in_width_coords, dim=-1) + in_width_coords = in_width_coords + w * (~in_width) + left_edges, _ = torch.min(in_width_coords, dim=-1) + + # If the mask is empty the right edge will be to the left of the left edge. + # Replace these boxes with [0, 0, 0, 0] + empty_filter = (right_edges < left_edges) | (bottom_edges < top_edges) + out = torch.stack([left_edges, top_edges, right_edges, bottom_edges], + dim=-1) + out = out * (~empty_filter).unsqueeze(-1) + + # Return to original shape + if len(shape) > 2: + out = out.reshape(*shape[:-2], 4) + else: + out = out[0] + + return out diff --git a/projects/sam_inference_demo/sam/utils/transforms.py b/projects/sam_inference_demo/sam/utils/transforms.py new file mode 100644 index 00000000000..484fd6691cf --- /dev/null +++ b/projects/sam_inference_demo/sam/utils/transforms.py @@ -0,0 +1,110 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. + +# This source code is licensed under the license found in the +# LICENSE file in the root directory of this source tree. + +from copy import deepcopy +from typing import Tuple + +import numpy as np +import torch +from torch.nn import functional as F +from torchvision.transforms.functional import resize # type: ignore +from torchvision.transforms.functional import to_pil_image + +from mmseg.registry import TRANSFORMS + + +@TRANSFORMS.register_module() +class ResizeLongestSide: + """Resizes images to longest side 'target_length', as well as provides + methods for resizing coordinates and boxes. + + Provides methods for transforming both numpy array and batched torch + tensors. + """ + + def __init__(self, target_length: int) -> None: + self.target_length = target_length + + def apply_image(self, image: np.ndarray) -> np.ndarray: + """Expects a numpy array with shape HxWxC in uint8 format.""" + target_size = self.get_preprocess_shape(image.shape[0], image.shape[1], + self.target_length) + return np.array(resize(to_pil_image(image), target_size)) + + def apply_coords(self, coords: np.ndarray, + original_size: Tuple[int, ...]) -> np.ndarray: + """Expects a numpy array of length 2 in the final dimension. + + Requires the original image size in (H, W) format. + """ + old_h, old_w = original_size + new_h, new_w = self.get_preprocess_shape(original_size[0], + original_size[1], + self.target_length) + coords = deepcopy(coords).astype(float) + coords[..., 0] = coords[..., 0] * (new_w / old_w) + coords[..., 1] = coords[..., 1] * (new_h / old_h) + return coords + + def apply_boxes(self, boxes: np.ndarray, + original_size: Tuple[int, ...]) -> np.ndarray: + """Expects a numpy array shape Bx4. + + Requires the original image size in (H, W) format. + """ + boxes = self.apply_coords(boxes.reshape(-1, 2, 2), original_size) + return boxes.reshape(-1, 4) + + def apply_image_torch(self, image: torch.Tensor) -> torch.Tensor: + """Expects batched images with shape BxCxHxW and float format. + + This transformation may not exactly match apply_image. apply_image is + the transformation expected by the model. + """ + # Expects an image in BCHW format. May not exactly match apply_image. + target_size = self.get_preprocess_shape(image.shape[0], image.shape[1], + self.target_length) + return F.interpolate( + image, + target_size, + mode='bilinear', + align_corners=False, + antialias=True) + + def apply_coords_torch(self, coords: torch.Tensor, + original_size: Tuple[int, ...]) -> torch.Tensor: + """Expects a torch tensor with length 2 in the last dimension. + + Requires the original image size in (H, W) format. + """ + old_h, old_w = original_size + new_h, new_w = self.get_preprocess_shape(original_size[0], + original_size[1], + self.target_length) + coords = deepcopy(coords).to(torch.float) + coords[..., 0] = coords[..., 0] * (new_w / old_w) + coords[..., 1] = coords[..., 1] * (new_h / old_h) + return coords + + def apply_boxes_torch(self, boxes: torch.Tensor, + original_size: Tuple[int, ...]) -> torch.Tensor: + """Expects a torch tensor with shape Bx4. + + Requires the original image size in (H, W) format. + """ + boxes = self.apply_coords_torch(boxes.reshape(-1, 2, 2), original_size) + return boxes.reshape(-1, 4) + + @staticmethod + def get_preprocess_shape(oldh: int, oldw: int, + long_side_length: int) -> Tuple[int, int]: + """Compute the output size given input size and target long side + length.""" + scale = long_side_length * 1.0 / max(oldh, oldw) + newh, neww = oldh * scale, oldw * scale + neww = int(neww + 0.5) + newh = int(newh + 0.5) + return (newh, neww) diff --git a/projects/sam_inference_demo/sam_image_demo.ipynb b/projects/sam_inference_demo/sam_image_demo.ipynb new file mode 100644 index 00000000000..1cb433fae9b --- /dev/null +++ b/projects/sam_inference_demo/sam_image_demo.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import cv2\n", + "\n", + "import sam # noqa: F401\n", + "from sam.sam_inferencer import SAMInferencer\n", + "\n", + "\n", + "def show_mask(mask, ax, random_color=False):\n", + " if random_color:\n", + " color = np.concatenate([np.random.random(3), np.array([0.6])], axis=0)\n", + " else:\n", + " color = np.array([30/255, 144/255, 255/255, 0.6])\n", + " h, w = mask.shape[-2:]\n", + " mask_image = mask.reshape(h, w, 1) * color.reshape(1, 1, -1)\n", + " ax.imshow(mask_image)\n", + " \n", + "def show_points(coords, labels, ax, marker_size=375):\n", + " pos_points = coords[labels==1]\n", + " neg_points = coords[labels==0]\n", + " ax.scatter(pos_points[:, 0], pos_points[:, 1], color='green', marker='*', s=marker_size, edgecolor='white', linewidth=1.25)\n", + " ax.scatter(neg_points[:, 0], neg_points[:, 1], color='red', marker='*', s=marker_size, edgecolor='white', linewidth=1.25) \n", + " \n", + "def show_box(box, ax):\n", + " x0, y0 = box[0], box[1]\n", + " w, h = box[2] - box[0], box[3] - box[1]\n", + " ax.add_patch(plt.Rectangle((x0, y0), w, h, edgecolor='green', facecolor=(0,0,0,0), lw=2))\n", + "\n", + "image = cv2.imread('../../demo/demo.png')\n", + "image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n", + "plt.figure(figsize=(10,10))\n", + "plt.imshow(image)\n", + "plt.axis('on')\n", + "plt.show()\n", + "print(image.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "inferencer = SAMInferencer(arch='huge')\n", + "inferencer.set_image(image)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "input_point = np.array([[280, 230], [500, 300]])\n", + "input_label = np.array([1, 1])\n", + "plt.figure(figsize=(10,10))\n", + "plt.imshow(image)\n", + "show_points(input_point, input_label, plt.gca())\n", + "plt.axis('on')\n", + "plt.show() " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "masks, scores, logits = inferencer.predict(\n", + " point_coords=input_point,\n", + " point_labels=input_label,\n", + " multimask_output=True,\n", + ")\n", + "for i, (mask, score) in enumerate(zip(masks, scores)):\n", + " plt.figure(figsize=(10,10))\n", + " plt.imshow(image)\n", + " show_mask(mask, plt.gca(), random_color=True)\n", + " show_points(input_point, input_label, plt.gca())\n", + " plt.title(f\"Mask {i+1}, Score: {score:.3f}\", fontsize=18)\n", + " plt.axis('off')\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "pt1.13", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/projects/van/README.md b/projects/van/README.md new file mode 100644 index 00000000000..be0ba362faa --- /dev/null +++ b/projects/van/README.md @@ -0,0 +1,101 @@ +# Visual Attention Network (VAN) for Segmentation + +This repo is a PyTorch implementation of applying **VAN** (**Visual Attention Network**) to semantic segmentation. + +The code is an integration from [VAN-Segmentation](https://github.com/Visual-Attention-Network/VAN-Segmentation/blob/main/README.md?plain=1) + +More details can be found in [**Visual Attention Network**](https://arxiv.org/abs/2202.09741). + +## Citation + +```bib +@article{guo2022visual, + title={Visual Attention Network}, + author={Guo, Meng-Hao and Lu, Cheng-Ze and Liu, Zheng-Ning and Cheng, Ming-Ming and Hu, Shi-Min}, + journal={arXiv preprint arXiv:2202.09741}, + year={2022} +} +``` + +## Results + +**Notes**: Pre-trained models can be found in [TsingHua Cloud](https://cloud.tsinghua.edu.cn/d/0100f0cea37d41ba8d08/). + +Results can be found in [VAN-Segmentation](https://github.com/Visual-Attention-Network/VAN-Segmentation/blob/main/README.md?plain=1) + +We provide evaluation results of the converted weights. + +| Method | Backbone | mIoU | Download | +| :-----: | :----------: | :---: | :--------------------------------------------------------------------------------------------------------------------------------------------: | +| UPerNet | VAN-B2 | 49.35 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b2-in1kpre_upernet_3rdparty_512x512-ade20k_20230522-19c58aee.pth) | +| UPerNet | VAN-B3 | 49.71 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b3-in1kpre_upernet_3rdparty_512x512-ade20k_20230522-653bd6b7.pth) | +| UPerNet | VAN-B4 | 51.56 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b4-in1kpre_upernet_3rdparty_512x512-ade20k_20230522-653bd6b7.pth) | +| UPerNet | VAN-B4-in22k | 52.61 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b4-in22kpre_upernet_3rdparty_512x512-ade20k_20230522-4a4d744a.pth) | +| UPerNet | VAN-B5-in22k | 53.11 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b5-in22kpre_upernet_3rdparty_512x512-ade20k_20230522-5bb6f2b4.pth) | +| UPerNet | VAN-B6-in22k | 54.25 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b6-in22kpre_upernet_3rdparty_512x512-ade20k_20230522-e226b363.pth) | +| FPN | VAN-B0 | 38.65 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b0-in1kpre_fpn_3rdparty_512x512-ade20k_20230522-75a76298.pth) | +| FPN | VAN-B1 | 43.22 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b1-in1kpre_fpn_3rdparty_512x512-ade20k_20230522-104499ff.pth) | +| FPN | VAN-B2 | 46.84 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b2-in1kpre_fpn_3rdparty_512x512-ade20k_20230522-7074e6f8.pth) | +| FPN | VAN-B3 | 48.32 | [model](https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b3-in1kpre_fpn_3rdparty_512x512-ade20k_20230522-2c3b7f5e.pth) | + +## Preparation + +Install MMSegmentation and download ADE20K according to the guidelines in MMSegmentation. + +## Requirement + +**Step 0.** Install [MMCV](https://github.com/open-mmlab/mmcv) using [MIM](https://github.com/open-mmlab/mim). + +```shell +pip install -U openmim +mim install mmengine +mim install "mmcv>=2.0.0" +``` + +**Step 1.** Install MMSegmentation. + +Case a: If you develop and run mmseg directly, install it from source: + +```shell +git clone -b main https://github.com/open-mmlab/mmsegmentation.git +cd mmsegmentation +pip install -v -e . +``` + +Case b: If you use mmsegmentation as a dependency or third-party package, install it with pip: + +```shell +pip install "mmsegmentation>=1.0.0" +``` + +## Training + +If you use 4 GPUs for training by default. Run: + +```bash +bash tools/dist_train.sh projects/van/configs/van/van-b2_pre1k_upernet_4xb2-160k_ade20k-512x512.py 4 +``` + +## Evaluation + +To evaluate the model, an example is: + +```bash +bash tools/dist_train.sh projects/van/configs/van/van-b2_pre1k_upernet_4xb2-160k_ade20k-512x512.py work_dirs/van-b2_pre1k_upernet_4xb2-160k_ade20k-512x512/iter_160000.pth 4 --eval mIoU +``` + +## FLOPs + +To calculate FLOPs for a model, run: + +```bash +bash tools/analysis_tools/get_flops.py projects/van/configs/van/van-b2_pre1k_upernet_4xb2-160k_ade20k-512x512.py --shape 512 512 +``` + +## Acknowledgment + +Our implementation is mainly based on [mmsegmentation](https://github.com/open-mmlab/mmsegmentation/tree/v0.12.0), [Swin-Transformer](https://github.com/SwinTransformer/Swin-Transformer-Semantic-Segmentation), [PoolFormer](https://github.com/sail-sg/poolformer), [Enjoy-Hamburger](https://github.com/Gsunshine/Enjoy-Hamburger) and [VAN-Segmentation](https://github.com/Visual-Attention-Network/VAN-Segmentation/blob/main/README.md?plain=1). Thanks for their authors. + +## LICENSE + +This repo is under the Apache-2.0 license. For commercial use, please contact the authors. diff --git a/projects/van/backbones/__init__.py b/projects/van/backbones/__init__.py new file mode 100644 index 00000000000..071995de294 --- /dev/null +++ b/projects/van/backbones/__init__.py @@ -0,0 +1,4 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from .van import VAN + +__all__ = ['VAN'] diff --git a/projects/van/backbones/van.py b/projects/van/backbones/van.py new file mode 100644 index 00000000000..301834a7587 --- /dev/null +++ b/projects/van/backbones/van.py @@ -0,0 +1,124 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import warnings + +import torch +import torch.nn as nn +from mmengine.model import BaseModule + +from mmseg.models.backbones.mscan import (MSCAN, MSCABlock, + MSCASpatialAttention, + OverlapPatchEmbed) +from mmseg.registry import MODELS + + +class VANAttentionModule(BaseModule): + + def __init__(self, in_channels): + super().__init__() + self.conv0 = nn.Conv2d( + in_channels, in_channels, 5, padding=2, groups=in_channels) + self.conv_spatial = nn.Conv2d( + in_channels, + in_channels, + 7, + stride=1, + padding=9, + groups=in_channels, + dilation=3) + self.conv1 = nn.Conv2d(in_channels, in_channels, 1) + + def forward(self, x): + u = x.clone() + attn = self.conv0(x) + attn = self.conv_spatial(attn) + attn = self.conv1(attn) + return u * attn + + +class VANSpatialAttention(MSCASpatialAttention): + + def __init__(self, in_channels, act_cfg=dict(type='GELU')): + super().__init__(in_channels, act_cfg=act_cfg) + self.spatial_gating_unit = VANAttentionModule(in_channels) + + +class VANBlock(MSCABlock): + + def __init__(self, + channels, + mlp_ratio=4., + drop=0., + drop_path=0., + act_cfg=dict(type='GELU'), + norm_cfg=dict(type='SyncBN', requires_grad=True)): + super().__init__( + channels, + mlp_ratio=mlp_ratio, + drop=drop, + drop_path=drop_path, + act_cfg=act_cfg, + norm_cfg=norm_cfg) + self.attn = VANSpatialAttention(channels) + + +@MODELS.register_module() +class VAN(MSCAN): + + def __init__(self, + in_channels=3, + embed_dims=[64, 128, 256, 512], + mlp_ratios=[8, 8, 4, 4], + drop_rate=0., + drop_path_rate=0., + depths=[3, 4, 6, 3], + num_stages=4, + act_cfg=dict(type='GELU'), + norm_cfg=dict(type='SyncBN', requires_grad=True), + pretrained=None, + init_cfg=None): + super(MSCAN, self).__init__(init_cfg=init_cfg) + + assert not (init_cfg and pretrained), \ + 'init_cfg and pretrained cannot be set at the same time' + if isinstance(pretrained, str): + warnings.warn('DeprecationWarning: pretrained is deprecated, ' + 'please use "init_cfg" instead') + self.init_cfg = dict(type='Pretrained', checkpoint=pretrained) + elif pretrained is not None: + raise TypeError('pretrained must be a str or None') + + self.depths = depths + self.num_stages = num_stages + + # stochastic depth decay rule + dpr = [ + x.item() for x in torch.linspace(0, drop_path_rate, sum(depths)) + ] + cur = 0 + + for i in range(num_stages): + patch_embed = OverlapPatchEmbed( + patch_size=7 if i == 0 else 3, + stride=4 if i == 0 else 2, + in_channels=in_channels if i == 0 else embed_dims[i - 1], + embed_dim=embed_dims[i], + norm_cfg=norm_cfg) + + block = nn.ModuleList([ + VANBlock( + channels=embed_dims[i], + mlp_ratio=mlp_ratios[i], + drop=drop_rate, + drop_path=dpr[cur + j], + act_cfg=act_cfg, + norm_cfg=norm_cfg) for j in range(depths[i]) + ]) + norm = nn.LayerNorm(embed_dims[i]) + cur += depths[i] + + setattr(self, f'patch_embed{i + 1}', patch_embed) + setattr(self, f'block{i + 1}', block) + setattr(self, f'norm{i + 1}', norm) + + def init_weights(self): + return super().init_weights() diff --git a/projects/van/configs/_base_/datasets/ade20k.py b/projects/van/configs/_base_/datasets/ade20k.py new file mode 100644 index 00000000000..69b3c2a73b8 --- /dev/null +++ b/projects/van/configs/_base_/datasets/ade20k.py @@ -0,0 +1,14 @@ +# dataset settings +_base_ = '../../../../../configs/_base_/datasets/ade20k.py' + +test_pipeline = [ + dict(type='LoadImageFromFile'), + dict(type='Resize', scale=(2048, 512), keep_ratio=True), + dict(type='ResizeToMultiple', size_divisor=32), + # add loading annotation after ``Resize`` because ground truth + # does not need to do resize data transform + dict(type='LoadAnnotations', reduce_zero_label=True), + dict(type='PackSegInputs') +] +val_dataloader = dict(dataset=dict(pipeline=test_pipeline)) +test_dataloader = val_dataloader diff --git a/projects/van/configs/_base_/models/van_fpn.py b/projects/van/configs/_base_/models/van_fpn.py new file mode 100644 index 00000000000..c7fd7391f77 --- /dev/null +++ b/projects/van/configs/_base_/models/van_fpn.py @@ -0,0 +1,43 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) + +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255, + size=(512, 512)) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='VAN', + embed_dims=[32, 64, 160, 256], + drop_rate=0.0, + drop_path_rate=0.1, + depths=[3, 3, 5, 2], + act_cfg=dict(type='GELU'), + norm_cfg=norm_cfg, + init_cfg=dict()), + neck=dict( + type='FPN', + in_channels=[32, 64, 160, 256], + out_channels=256, + num_outs=4), + decode_head=dict( + type='FPNHead', + in_channels=[256, 256, 256, 256], + in_index=[0, 1, 2, 3], + feature_strides=[4, 8, 16, 32], + channels=128, + dropout_ratio=0.1, + num_classes=150, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/projects/van/configs/_base_/models/van_upernet.py b/projects/van/configs/_base_/models/van_upernet.py new file mode 100644 index 00000000000..8f94c0d9d84 --- /dev/null +++ b/projects/van/configs/_base_/models/van_upernet.py @@ -0,0 +1,51 @@ +# model settings +norm_cfg = dict(type='SyncBN', requires_grad=True) + +data_preprocessor = dict( + type='SegDataPreProcessor', + mean=[123.675, 116.28, 103.53], + std=[58.395, 57.12, 57.375], + bgr_to_rgb=True, + pad_val=0, + seg_pad_val=255, + size=(512, 512)) +model = dict( + type='EncoderDecoder', + data_preprocessor=data_preprocessor, + backbone=dict( + type='VAN', + embed_dims=[32, 64, 160, 256], + drop_rate=0.0, + drop_path_rate=0.1, + depths=[3, 3, 5, 2], + act_cfg=dict(type='GELU'), + norm_cfg=norm_cfg, + init_cfg=dict()), + decode_head=dict( + type='UPerHead', + in_channels=[32, 64, 160, 256], + in_index=[0, 1, 2, 3], + pool_scales=(1, 2, 3, 6), + channels=512, + dropout_ratio=0.1, + num_classes=150, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0)), + auxiliary_head=dict( + type='FCNHead', + in_channels=160, + in_index=2, + channels=256, + num_convs=1, + concat_input=False, + dropout_ratio=0.1, + num_classes=150, + norm_cfg=norm_cfg, + align_corners=False, + loss_decode=dict( + type='CrossEntropyLoss', use_sigmoid=False, loss_weight=0.4)), + # model training and testing settings + train_cfg=dict(), + test_cfg=dict(mode='whole')) diff --git a/projects/van/configs/van/van-b0_fpn_8xb4-40k_ade20k-512x512.py b/projects/van/configs/van/van-b0_fpn_8xb4-40k_ade20k-512x512.py new file mode 100644 index 00000000000..2faf3788a71 --- /dev/null +++ b/projects/van/configs/van/van-b0_fpn_8xb4-40k_ade20k-512x512.py @@ -0,0 +1,8 @@ +_base_ = './van-b2_fpn_8xb4-40k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b0_3rdparty_20230522-956f5e0d.pth' # noqa +model = dict( + backbone=dict( + embed_dims=[32, 64, 160, 256], + depths=[3, 3, 5, 2], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path)), + neck=dict(in_channels=[32, 64, 160, 256])) diff --git a/projects/van/configs/van/van-b1_fpn_8xb4-40k_ade20k-512x512.py b/projects/van/configs/van/van-b1_fpn_8xb4-40k_ade20k-512x512.py new file mode 100644 index 00000000000..cf64a7138b2 --- /dev/null +++ b/projects/van/configs/van/van-b1_fpn_8xb4-40k_ade20k-512x512.py @@ -0,0 +1,6 @@ +_base_ = './van-b2_fpn_8xb4-40k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b1_3rdparty_20230522-3adb117f.pth' # noqa +model = dict( + backbone=dict( + depths=[2, 2, 4, 2], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path))) diff --git a/projects/van/configs/van/van-b2_fpn_8xb4-40k_ade20k-512x512.py b/projects/van/configs/van/van-b2_fpn_8xb4-40k_ade20k-512x512.py new file mode 100644 index 00000000000..965fa1cd363 --- /dev/null +++ b/projects/van/configs/van/van-b2_fpn_8xb4-40k_ade20k-512x512.py @@ -0,0 +1,53 @@ +_base_ = [ + '../_base_/models/van_fpn.py', + '../_base_/datasets/ade20k.py', + '../../../../configs/_base_/default_runtime.py', +] +custom_imports = dict(imports=['projects.van.backbones']) +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b2_3rdparty_20230522-636fac93.pth' # noqa +model = dict( + type='EncoderDecoder', + backbone=dict( + embed_dims=[64, 128, 320, 512], + depths=[3, 3, 12, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.2), + neck=dict(in_channels=[64, 128, 320, 512]), + decode_head=dict(num_classes=150)) + +train_dataloader = dict(batch_size=4) + +# we use 8 gpu instead of 4 in mmsegmentation, so lr*2 and max_iters/2 +gpu_multiples = 2 +max_iters = 80000 // gpu_multiples +interval = 8000 // gpu_multiples +optim_wrapper = dict( + type='OptimWrapper', + optimizer=dict( + type='AdamW', + lr=0.0001 * gpu_multiples, + # betas=(0.9, 0.999), + weight_decay=0.0001), + clip_grad=None) +# learning policy +param_scheduler = [ + dict( + type='PolyLR', + power=0.9, + eta_min=0.0, + begin=0, + end=max_iters, + by_epoch=False, + ) +] +train_cfg = dict( + type='IterBasedTrainLoop', max_iters=max_iters, val_interval=interval) +val_cfg = dict(type='ValLoop') +test_cfg = dict(type='TestLoop') +default_hooks = dict( + timer=dict(type='IterTimerHook'), + logger=dict(type='LoggerHook', interval=50, log_metric_by_epoch=False), + param_scheduler=dict(type='ParamSchedulerHook'), + checkpoint=dict(type='CheckpointHook', by_epoch=False, interval=interval), + sampler_seed=dict(type='DistSamplerSeedHook'), + visualization=dict(type='SegVisualizationHook')) diff --git a/projects/van/configs/van/van-b2_upernet_4xb2-160k_ade20k-512x512.py b/projects/van/configs/van/van-b2_upernet_4xb2-160k_ade20k-512x512.py new file mode 100644 index 00000000000..c529606a202 --- /dev/null +++ b/projects/van/configs/van/van-b2_upernet_4xb2-160k_ade20k-512x512.py @@ -0,0 +1,46 @@ +_base_ = [ + '../_base_/models/van_upernet.py', '../_base_/datasets/ade20k.py', + '../../../../configs/_base_/default_runtime.py', + '../../../../configs/_base_/schedules/schedule_160k.py' +] +custom_imports = dict(imports=['projects.van.backbones']) +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b2_3rdparty_20230522-636fac93.pth' # noqa +model = dict( + type='EncoderDecoder', + backbone=dict( + embed_dims=[64, 128, 320, 512], + depths=[3, 3, 12, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path)), + decode_head=dict(in_channels=[64, 128, 320, 512], num_classes=150), + auxiliary_head=dict(in_channels=320, num_classes=150)) + +# AdamW optimizer +# no weight decay for position embedding & layer norm in backbone +optim_wrapper = dict( + _delete_=True, + type='OptimWrapper', + optimizer=dict( + type='AdamW', lr=0.00006, betas=(0.9, 0.999), weight_decay=0.01), + clip_grad=None, + paramwise_cfg=dict( + custom_keys={ + 'absolute_pos_embed': dict(decay_mult=0.), + 'relative_position_bias_table': dict(decay_mult=0.), + 'norm': dict(decay_mult=0.) + })) +# learning policy +param_scheduler = [ + dict( + type='LinearLR', start_factor=1e-6, by_epoch=False, begin=0, end=1500), + dict( + type='PolyLR', + power=1.0, + begin=1500, + end=_base_.train_cfg.max_iters, + eta_min=0.0, + by_epoch=False, + ) +] + +# By default, models are trained on 8 GPUs with 2 images per GPU +train_dataloader = dict(batch_size=2) diff --git a/projects/van/configs/van/van-b3_fpn_8xb4-40k_ade20k-512x512.py b/projects/van/configs/van/van-b3_fpn_8xb4-40k_ade20k-512x512.py new file mode 100644 index 00000000000..b0493fe4f9f --- /dev/null +++ b/projects/van/configs/van/van-b3_fpn_8xb4-40k_ade20k-512x512.py @@ -0,0 +1,11 @@ +_base_ = './van-b2_fpn_8xb4-40k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b3_3rdparty_20230522-a184e051.pth' # noqa +model = dict( + type='EncoderDecoder', + backbone=dict( + embed_dims=[64, 128, 320, 512], + depths=[3, 5, 27, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.3), + neck=dict(in_channels=[64, 128, 320, 512])) +train_dataloader = dict(batch_size=4) diff --git a/projects/van/configs/van/van-b3_upernet_4xb2-160k_ade20k-512x512.py b/projects/van/configs/van/van-b3_upernet_4xb2-160k_ade20k-512x512.py new file mode 100644 index 00000000000..8201801d992 --- /dev/null +++ b/projects/van/configs/van/van-b3_upernet_4xb2-160k_ade20k-512x512.py @@ -0,0 +1,8 @@ +_base_ = './van-b2_upernet_4xb2-160k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b3_3rdparty_20230522-a184e051.pth' # noqa +model = dict( + type='EncoderDecoder', + backbone=dict( + depths=[3, 5, 27, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.3)) diff --git a/projects/van/configs/van/van-b4-in22kpre_upernet_4xb4-160k_ade20k-512x512.py b/projects/van/configs/van/van-b4-in22kpre_upernet_4xb4-160k_ade20k-512x512.py new file mode 100644 index 00000000000..15c8f7ca6ee --- /dev/null +++ b/projects/van/configs/van/van-b4-in22kpre_upernet_4xb4-160k_ade20k-512x512.py @@ -0,0 +1,10 @@ +_base_ = './van-b2_upernet_4xb2-160k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b4-in22k_3rdparty_20230522-5e31cafb.pth' # noqa +model = dict( + backbone=dict( + depths=[3, 6, 40, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.4)) + +# By default, models are trained on 8 GPUs with 2 images per GPU +train_dataloader = dict(batch_size=4) diff --git a/projects/van/configs/van/van-b4_upernet_4xb4-160k_ade20k-512x512.py b/projects/van/configs/van/van-b4_upernet_4xb4-160k_ade20k-512x512.py new file mode 100644 index 00000000000..33ae049d0c0 --- /dev/null +++ b/projects/van/configs/van/van-b4_upernet_4xb4-160k_ade20k-512x512.py @@ -0,0 +1,10 @@ +_base_ = './van-b2_upernet_4xb2-160k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b4_3rdparty_20230522-1d71c077.pth' # noqa +model = dict( + backbone=dict( + depths=[3, 6, 40, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.4)) + +# By default, models are trained on 4 GPUs with 4 images per GPU +train_dataloader = dict(batch_size=4) diff --git a/projects/van/configs/van/van-b5-in22kpre_upernet_4xb2-160k_ade20k-512x512.py b/projects/van/configs/van/van-b5-in22kpre_upernet_4xb2-160k_ade20k-512x512.py new file mode 100644 index 00000000000..f36c6242bdf --- /dev/null +++ b/projects/van/configs/van/van-b5-in22kpre_upernet_4xb2-160k_ade20k-512x512.py @@ -0,0 +1,10 @@ +_base_ = './van-b2_upernet_4xb2-160k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b5-in22k_3rdparty_20230522-b26134d7.pth' # noqa +model = dict( + backbone=dict( + embed_dims=[96, 192, 480, 768], + depths=[3, 3, 24, 3], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.4), + decode_head=dict(in_channels=[96, 192, 480, 768], num_classes=150), + auxiliary_head=dict(in_channels=480, num_classes=150)) diff --git a/projects/van/configs/van/van-b6-in22kpre_upernet_4xb2-160k_ade20k-512x512.py b/projects/van/configs/van/van-b6-in22kpre_upernet_4xb2-160k_ade20k-512x512.py new file mode 100644 index 00000000000..aa529efed8c --- /dev/null +++ b/projects/van/configs/van/van-b6-in22kpre_upernet_4xb2-160k_ade20k-512x512.py @@ -0,0 +1,10 @@ +_base_ = './van-b2_upernet_4xb2-160k_ade20k-512x512.py' +ckpt_path = 'https://download.openmmlab.com/mmsegmentation/v0.5/van_3rdparty/van-b6-in22k_3rdparty_20230522-5e5172a3.pth' # noqa +model = dict( + backbone=dict( + embed_dims=[96, 192, 384, 768], + depths=[6, 6, 90, 6], + init_cfg=dict(type='Pretrained', checkpoint=ckpt_path), + drop_path_rate=0.5), + decode_head=dict(in_channels=[96, 192, 384, 768], num_classes=150), + auxiliary_head=dict(in_channels=384, num_classes=150)) diff --git a/requirements.txt b/requirements.txt index 6da5adea757..501bddc8843 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ -r requirements/optional.txt -r requirements/runtime.txt -r requirements/tests.txt +-r requirements/multimodal.txt diff --git a/requirements/albu.txt b/requirements/albu.txt new file mode 100644 index 00000000000..f421fbbdc47 --- /dev/null +++ b/requirements/albu.txt @@ -0,0 +1 @@ +albumentations>=0.3.2 --no-binary qudida,albumentations diff --git a/requirements/docs.txt b/requirements/docs.txt index 8e98c16fc72..19632d36aba 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -4,3 +4,4 @@ myst-parser sphinx==4.0.2 sphinx_copybutton sphinx_markdown_tables +urllib3<2.0.0 diff --git a/requirements/multimodal.txt b/requirements/multimodal.txt new file mode 100644 index 00000000000..2195d0d9ef8 --- /dev/null +++ b/requirements/multimodal.txt @@ -0,0 +1,2 @@ +ftfy +regex diff --git a/requirements/optional.txt b/requirements/optional.txt index 5eca649247e..b0310f52960 100644 --- a/requirements/optional.txt +++ b/requirements/optional.txt @@ -1,2 +1,22 @@ cityscapesscripts +-e git+https://github.com/openai/CLIP.git@main#egg=clip + +# for vpd model +diffusers +einops==0.3.0 +imageio==2.9.0 +imageio-ffmpeg==0.4.2 +invisible-watermark +kornia==0.6 +-e git+https://github.com/CompVis/stable-diffusion@21f890f#egg=latent-diffusion nibabel +omegaconf==2.1.1 +pudb==2019.2 +pytorch-lightning==1.4.2 +streamlit>=0.73.1 +-e git+https://github.com/CompVis/taming-transformers.git@master#egg=taming-transformers +test-tube>=0.7.5 +timm +torch-fidelity==0.3.0 +torchmetrics==0.6.0 +transformers==4.19.2 diff --git a/requirements/tests.txt b/requirements/tests.txt index 74fc76146d8..3fff2520d7c 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,6 +1,8 @@ codecov flake8 +ftfy interrogate pytest +regex xdoctest>=0.10.0 yapf diff --git a/resources/miaomiao_qrcode.jpg b/resources/miaomiao_qrcode.jpg new file mode 100644 index 00000000000..d34cbae6fd1 Binary files /dev/null and b/resources/miaomiao_qrcode.jpg differ diff --git a/setup.cfg b/setup.cfg index dc5ea071110..2ea07600c0b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,4 +16,4 @@ default_section = THIRDPARTY skip = *.po,*.ts,*.ipynb count = quiet-level = 3 -ignore-words-list = formating,sur,hist,dota,warmup +ignore-words-list = formating,sur,hist,dota,warmup,damon diff --git a/setup.py b/setup.py index 854dd186054..45d923db60e 100755 --- a/setup.py +++ b/setup.py @@ -123,7 +123,7 @@ def add_mim_extension(): else: return - filenames = ['tools', 'configs', 'model-index.yml'] + filenames = ['tools', 'configs', 'model-index.yml', 'dataset-index.yml'] repo_path = osp.dirname(__file__) mim_path = osp.join(repo_path, 'mmseg', '.mim') os.makedirs(mim_path, exist_ok=True) @@ -175,7 +175,7 @@ def add_mim_extension(): author='MMSegmentation Contributors', author_email='openmmlab@gmail.com', keywords='computer vision, semantic segmentation', - url='http://github.com/open-mmlab/mmsegmentation', + url='https://github.com/open-mmlab/mmsegmentation', packages=find_packages(exclude=('configs', 'tools', 'demo')), include_package_data=True, classifiers=[ @@ -194,6 +194,7 @@ def add_mim_extension(): 'tests': parse_requirements('requirements/tests.txt'), 'optional': parse_requirements('requirements/optional.txt'), 'mim': parse_requirements('requirements/mminstall.txt'), + 'multimodal': parse_requirements('requirements/multimodal.txt'), }, ext_modules=[], zip_safe=False) diff --git a/tests/data/dsdl_seg/config.py b/tests/data/dsdl_seg/config.py new file mode 100755 index 00000000000..8eed751c2f7 --- /dev/null +++ b/tests/data/dsdl_seg/config.py @@ -0,0 +1,13 @@ +# Copyright (c) OpenMMLab. All rights reserved. +local = dict( + type='LocalFileReader', + working_dir='/nvme/share_data/VOC2012', +) + +ali_oss = dict( + type='AliOSSFileReader', + access_key_secret='your secret key of aliyun oss', + endpoint='your endpoint of aliyun oss', + access_key_id='your access key of aliyun oss', + bucket_name='your bucket name of aliyun oss', + working_dir='the relative path of your media dir in the bucket') diff --git a/tests/data/dsdl_seg/defs/class-dom.yaml b/tests/data/dsdl_seg/defs/class-dom.yaml new file mode 100755 index 00000000000..e5dd598c4ae --- /dev/null +++ b/tests/data/dsdl_seg/defs/class-dom.yaml @@ -0,0 +1,24 @@ +$dsdl-version: "0.5.0" +VOCClassDom: + $def: class_domain + classes: + - aeroplane + - bicycle + - bird + - boat + - bottle + - bus + - car + - cat + - chair + - cow + - diningtable + - dog + - horse + - motorbike + - person + - pottedplant + - sheep + - sofa + - train + - tvmonitor diff --git a/tests/data/dsdl_seg/defs/segmentation-def.yaml b/tests/data/dsdl_seg/defs/segmentation-def.yaml new file mode 100755 index 00000000000..057139ed57e --- /dev/null +++ b/tests/data/dsdl_seg/defs/segmentation-def.yaml @@ -0,0 +1,15 @@ +$dsdl-version: "0.5.0" + +ImageMedia: + $def: struct + $fields: + image: Image + image_shape: ImageShape + +SegmentationSample: + $def: struct + $params: ['cdom'] + $fields: + media: ImageMedia + label_map: LabelMap[dom=$cdom] + instance_map: InstanceMap diff --git a/tests/data/dsdl_seg/set-train/train.yaml b/tests/data/dsdl_seg/set-train/train.yaml new file mode 100755 index 00000000000..69872445a53 --- /dev/null +++ b/tests/data/dsdl_seg/set-train/train.yaml @@ -0,0 +1,15 @@ +$dsdl-version: "0.5.0" +$import: + - ../defs/segmentation-def + - ../defs/class-dom +meta: + dataset_name: "VOC2012" + sub_dataset_name: "train" + task_type: "Segmentation" + dataset_homepage: "http://host.robots.ox.ac.uk/pascal/VOC/voc2012/index.html" + dataset_publisher: "University of Leeds | ETHZ, Zurich | University of Edinburgh\ + \ |Microsoft Research Cambridge | University of Oxford" + OpenDataLab_address: "https://opendatalab.com/PASCAL_VOC2012/download" +data: + sample-type: SegmentationSample[cdom=VOCClassDom] + sample-path: train_samples.json diff --git a/tests/data/dsdl_seg/set-train/train_samples.json b/tests/data/dsdl_seg/set-train/train_samples.json new file mode 100755 index 00000000000..559f5845721 --- /dev/null +++ b/tests/data/dsdl_seg/set-train/train_samples.json @@ -0,0 +1 @@ +{"samples": [{"media": {"image": "JPEGImages/2007_000032.jpg", "image_shape": [281, 500]}, "label_map": "SegmentationClass/2007_000032.png", "instance_map": "SegmentationObject/2007_000032.png"}, {"media": {"image": "JPEGImages/2007_000039.jpg", "image_shape": [375, 500]}, "label_map": "SegmentationClass/2007_000039.png", "instance_map": "SegmentationObject/2007_000039.png"}, {"media": {"image": "JPEGImages/2007_000063.jpg", "image_shape": [375, 500]}, "label_map": "SegmentationClass/2007_000063.png", "instance_map": "SegmentationObject/2007_000063.png"}]} diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/train/0004a4c0-d4dff0ad.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/train/0004a4c0-d4dff0ad.jpg new file mode 100644 index 00000000000..4724a3d9302 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/train/0004a4c0-d4dff0ad.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/train/00054602-3bf57337.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/train/00054602-3bf57337.jpg new file mode 100644 index 00000000000..5efe06b99a4 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/train/00054602-3bf57337.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/train/00067cfb-e535423e.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/train/00067cfb-e535423e.jpg new file mode 100644 index 00000000000..2233c03c763 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/train/00067cfb-e535423e.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d06fefd-f7be05a6.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d06fefd-f7be05a6.jpg new file mode 100644 index 00000000000..535087b5a95 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d06fefd-f7be05a6.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d128593-0ccfea4c.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d128593-0ccfea4c.jpg new file mode 100644 index 00000000000..7f2971afdee Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d128593-0ccfea4c.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d15b18b-1e0d6e3f.jpg b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d15b18b-1e0d6e3f.jpg new file mode 100644 index 00000000000..31a951d4830 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/images/10k/val/7d15b18b-1e0d6e3f.jpg differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/0004a4c0-d4dff0ad.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/0004a4c0-d4dff0ad.png new file mode 100644 index 00000000000..086a8d50647 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/0004a4c0-d4dff0ad.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00054602-3bf57337.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00054602-3bf57337.png new file mode 100644 index 00000000000..43338c283cc Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00054602-3bf57337.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00067cfb-e535423e.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00067cfb-e535423e.png new file mode 100644 index 00000000000..7c0ad1d5d90 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/train/00067cfb-e535423e.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d128593-0ccfea4c.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d128593-0ccfea4c.png new file mode 100644 index 00000000000..43338c283cc Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d128593-0ccfea4c.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d15b18b-1e0d6e3f.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d15b18b-1e0d6e3f.png new file mode 100644 index 00000000000..43338c283cc Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d15b18b-1e0d6e3f.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d2f7975-e0c1c5a7.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d2f7975-e0c1c5a7.png new file mode 100644 index 00000000000..7c0ad1d5d90 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/colormaps/val/7d2f7975-e0c1c5a7.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/0004a4c0-d4dff0ad.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/0004a4c0-d4dff0ad.png new file mode 100644 index 00000000000..5c6bf5e1581 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/0004a4c0-d4dff0ad.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00054602-3bf57337.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00054602-3bf57337.png new file mode 100644 index 00000000000..c525a768885 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00054602-3bf57337.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00067cfb-e535423e.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00067cfb-e535423e.png new file mode 100644 index 00000000000..7dfd3af4e3a Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/train/00067cfb-e535423e.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d06fefd-f7be05a6.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d06fefd-f7be05a6.png new file mode 100644 index 00000000000..7dfd3af4e3a Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d06fefd-f7be05a6.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d128593-0ccfea4c.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d128593-0ccfea4c.png new file mode 100644 index 00000000000..c525a768885 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d128593-0ccfea4c.png differ diff --git a/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d15b18b-1e0d6e3f.png b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d15b18b-1e0d6e3f.png new file mode 100644 index 00000000000..c525a768885 Binary files /dev/null and b/tests/data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val/7d15b18b-1e0d6e3f.png differ diff --git a/tests/data/pseudo_nyu_dataset/annotations/bookstore_0001d_00001.png b/tests/data/pseudo_nyu_dataset/annotations/bookstore_0001d_00001.png new file mode 100644 index 00000000000..77e343603ad Binary files /dev/null and b/tests/data/pseudo_nyu_dataset/annotations/bookstore_0001d_00001.png differ diff --git a/tests/data/pseudo_nyu_dataset/images/bookstore_0001d_00001.jpg b/tests/data/pseudo_nyu_dataset/images/bookstore_0001d_00001.jpg new file mode 100644 index 00000000000..7892ed47e7d Binary files /dev/null and b/tests/data/pseudo_nyu_dataset/images/bookstore_0001d_00001.jpg differ diff --git a/tests/test_apis/test_inferencer.py b/tests/test_apis/test_inferencer.py index 497eae4a011..d8dbce8f385 100644 --- a/tests/test_apis/test_inferencer.py +++ b/tests/test_apis/test_inferencer.py @@ -3,76 +3,16 @@ import numpy as np import torch -import torch.nn as nn from mmengine import ConfigDict -from torch.utils.data import DataLoader, Dataset +from utils import * # noqa: F401, F403 from mmseg.apis import MMSegInferencer -from mmseg.models import EncoderDecoder -from mmseg.models.decode_heads.decode_head import BaseDecodeHead from mmseg.registry import MODELS from mmseg.utils import register_all_modules -@MODELS.register_module(name='InferExampleHead') -class ExampleDecodeHead(BaseDecodeHead): - - def __init__(self, num_classes=19, out_channels=None): - super().__init__( - 3, 3, num_classes=num_classes, out_channels=out_channels) - - def forward(self, inputs): - return self.cls_seg(inputs[0]) - - -@MODELS.register_module(name='InferExampleBackbone') -class ExampleBackbone(nn.Module): - - def __init__(self): - super().__init__() - self.conv = nn.Conv2d(3, 3, 3) - - def init_weights(self, pretrained=None): - pass - - def forward(self, x): - return [self.conv(x)] - - -@MODELS.register_module(name='InferExampleModel') -class ExampleModel(EncoderDecoder): - - def __init__(self, **kwargs): - super().__init__(**kwargs) - - -class ExampleDataset(Dataset): - - def __init__(self) -> None: - super().__init__() - self.pipeline = [ - dict(type='LoadImageFromFile'), - dict(type='LoadAnnotations'), - dict(type='PackSegInputs') - ] - - def __getitem__(self, idx): - return dict(img=torch.tensor([1]), img_metas=dict()) - - def __len__(self): - return 1 - - def test_inferencer(): register_all_modules() - test_dataset = ExampleDataset() - data_loader = DataLoader( - test_dataset, - batch_size=1, - sampler=None, - num_workers=0, - shuffle=False, - ) visualizer = dict( type='SegLocalVisualizer', @@ -87,7 +27,14 @@ def test_inferencer(): decode_head=dict(type='InferExampleHead'), test_cfg=dict(mode='whole')), visualizer=visualizer, - test_dataloader=data_loader) + test_dataloader=dict( + dataset=dict( + type='ExampleDataset', + pipeline=[ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') + ]), )) cfg = ConfigDict(cfg_dict) model = MODELS.build(cfg.model) diff --git a/tests/test_apis/test_rs_inferencer.py b/tests/test_apis/test_rs_inferencer.py new file mode 100644 index 00000000000..03423d9680e --- /dev/null +++ b/tests/test_apis/test_rs_inferencer.py @@ -0,0 +1,73 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +from unittest import TestCase + +import numpy as np +from mmengine import ConfigDict, init_default_scope +from utils import * # noqa: F401, F403 + +from mmseg.apis import RSImage, RSInferencer +from mmseg.registry import MODELS + + +class TestRSImage(TestCase): + + def test_read_whole_image(self): + init_default_scope('mmseg') + img_path = osp.join( + osp.dirname(__file__), + '../data/pseudo_loveda_dataset/img_dir/0.png') + rs_image = RSImage(img_path) + window_size = (16, 16) + rs_image.create_grids(window_size) + image_data = rs_image.read(rs_image.grids[0]) + self.assertIsNotNone(image_data) + + def test_write_image_data(self): + init_default_scope('mmseg') + img_path = osp.join( + osp.dirname(__file__), + '../data/pseudo_loveda_dataset/img_dir/0.png') + rs_image = RSImage(img_path) + window_size = (16, 16) + rs_image.create_grids(window_size) + data = np.random.random((16, 16)).astype(np.int8) + rs_image.write(data, rs_image.grids[0]) + + +class TestRSInferencer(TestCase): + + def test_read_and_inference(self): + init_default_scope('mmseg') + cfg_dict = dict( + model=dict( + type='InferExampleModel', + data_preprocessor=dict(type='SegDataPreProcessor'), + backbone=dict(type='InferExampleBackbone'), + decode_head=dict(type='InferExampleHead'), + test_cfg=dict(mode='whole')), + test_dataloader=dict( + dataset=dict( + type='ExampleDataset', + pipeline=[ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') + ])), + test_pipeline=[ + dict(type='LoadImageFromFile'), + dict(type='LoadAnnotations'), + dict(type='PackSegInputs') + ]) + cfg = ConfigDict(cfg_dict) + model = MODELS.build(cfg.model) + model.cfg = cfg + inferencer = RSInferencer.from_model(model) + + img_path = osp.join( + osp.dirname(__file__), + '../data/pseudo_loveda_dataset/img_dir/0.png') + rs_image = RSImage(img_path) + window_size = (16, 16) + stride = (16, 16) + inferencer.run(rs_image, window_size, stride) diff --git a/tests/test_apis/utils.py b/tests/test_apis/utils.py new file mode 100644 index 00000000000..0a9928fccf1 --- /dev/null +++ b/tests/test_apis/utils.py @@ -0,0 +1,38 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch.nn as nn + +from mmseg.models import EncoderDecoder +from mmseg.models.decode_heads.decode_head import BaseDecodeHead +from mmseg.registry import MODELS + + +@MODELS.register_module(name='InferExampleHead') +class ExampleDecodeHead(BaseDecodeHead): + + def __init__(self, num_classes=19, out_channels=None): + super().__init__( + 3, 3, num_classes=num_classes, out_channels=out_channels) + + def forward(self, inputs): + return self.cls_seg(inputs[0]) + + +@MODELS.register_module(name='InferExampleBackbone') +class ExampleBackbone(nn.Module): + + def __init__(self): + super().__init__() + self.conv = nn.Conv2d(3, 3, 3) + + def init_weights(self, pretrained=None): + pass + + def forward(self, x): + return [self.conv(x)] + + +@MODELS.register_module(name='InferExampleModel') +class ExampleModel(EncoderDecoder): + + def __init__(self, **kwargs): + super().__init__(**kwargs) diff --git a/tests/test_config.py b/tests/test_config.py index 13de460181c..cdd85ff57cd 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -30,6 +30,7 @@ def _get_config_directory(): def test_config_build_segmentor(): """Test that all segmentation models defined in the configs can be initialized.""" + init_default_scope('mmseg') config_dpath = _get_config_directory() print(f'Found config_dpath = {config_dpath!r}') @@ -92,7 +93,12 @@ def test_config_data_pipeline(): del config_mod.train_pipeline[0] del config_mod.test_pipeline[0] # remove loading annotation in test pipeline - del config_mod.test_pipeline[-2] + load_anno_idx = -1 + for i in range(len(config_mod.test_pipeline)): + if config_mod.test_pipeline[i].type in ('LoadAnnotations', + 'LoadDepthAnnotation'): + load_anno_idx = i + del config_mod.test_pipeline[load_anno_idx] train_pipeline = Compose(config_mod.train_pipeline) test_pipeline = Compose(config_mod.test_pipeline) @@ -101,6 +107,7 @@ def test_config_data_pipeline(): if to_float32: img = img.astype(np.float32) seg = np.random.randint(0, 255, size=(1024, 2048, 1), dtype=np.uint8) + depth = np.random.rand(1024, 2048).astype(np.float32) results = dict( filename='test_img.png', @@ -108,24 +115,30 @@ def test_config_data_pipeline(): img=img, img_shape=img.shape, ori_shape=img.shape, - gt_seg_map=seg) + gt_seg_map=seg, + gt_depth_map=depth) results['seg_fields'] = ['gt_seg_map'] - + _check_concat_cd_input(config_mod, results) print(f'Test training data pipeline: \n{train_pipeline!r}') output_results = train_pipeline(results) assert output_results is not None - results = dict( - filename='test_img.png', - ori_filename='test_img.png', - img=img, - img_shape=img.shape, - ori_shape=img.shape) + _check_concat_cd_input(config_mod, results) print(f'Test testing data pipeline: \n{test_pipeline!r}') output_results = test_pipeline(results) assert output_results is not None +def _check_concat_cd_input(config_mod: Config, results: dict): + keys = [] + pipeline = config_mod.train_pipeline.copy() + pipeline.extend(config_mod.test_pipeline) + for t in pipeline: + keys.append(t.type) + if 'ConcatCDInput' in keys: + results.update({'img2': results['img']}) + + def _check_decode_head(decode_head_cfg, decode_head): if isinstance(decode_head_cfg, list): assert isinstance(decode_head, nn.ModuleList) @@ -149,14 +162,14 @@ def _check_decode_head(decode_head_cfg, decode_head): elif input_transform == 'resize_concat': assert sum(in_channels) == decode_head.in_channels else: - assert isinstance(in_channels, int) assert in_channels == decode_head.in_channels - assert isinstance(decode_head.in_index, int) if decode_head_cfg['type'] == 'PointHead': assert decode_head_cfg.channels+decode_head_cfg.num_classes == \ decode_head.fc_seg.in_channels assert decode_head.fc_seg.out_channels == decode_head_cfg.num_classes + elif decode_head_cfg['type'] == 'VPDDepthHead': + assert decode_head.out_channels == 1 else: assert decode_head_cfg.channels == decode_head.conv_seg.in_channels assert decode_head.conv_seg.out_channels == decode_head_cfg.num_classes diff --git a/tests/test_datasets/test_dataset.py b/tests/test_datasets/test_dataset.py index db4a7799069..2904e09cedd 100644 --- a/tests/test_datasets/test_dataset.py +++ b/tests/test_datasets/test_dataset.py @@ -5,15 +5,21 @@ import pytest -from mmseg.datasets import (ADE20KDataset, BaseSegDataset, CityscapesDataset, - COCOStuffDataset, DecathlonDataset, ISPRSDataset, +from mmseg.datasets import (ADE20KDataset, BaseSegDataset, BDD100KDataset, + CityscapesDataset, COCOStuffDataset, + DecathlonDataset, DSDLSegDataset, ISPRSDataset, LIPDataset, LoveDADataset, MapillaryDataset_v1, - MapillaryDataset_v2, PascalVOCDataset, + MapillaryDataset_v2, NYUDataset, PascalVOCDataset, PotsdamDataset, REFUGEDataset, SynapseDataset, iSAIDDataset) from mmseg.registry import DATASETS from mmseg.utils import get_classes, get_palette +try: + from dsdl.dataset import DSDLDataset +except ImportError: + DSDLDataset = None + def test_classes(): assert list( @@ -32,7 +38,7 @@ def test_classes(): MapillaryDataset_v1.METAINFO['classes']) == get_classes('mapillary_v1') assert list( MapillaryDataset_v2.METAINFO['classes']) == get_classes('mapillary_v2') - + assert list(BDD100KDataset.METAINFO['classes']) == get_classes('bdd100k') with pytest.raises(ValueError): get_classes('unsupported') @@ -89,7 +95,7 @@ def test_palette(): MapillaryDataset_v1.METAINFO['palette']) == get_palette('mapillary_v1') assert list( MapillaryDataset_v2.METAINFO['palette']) == get_palette('mapillary_v2') - + assert list(BDD100KDataset.METAINFO['palette']) == get_palette('bdd100k') with pytest.raises(ValueError): get_palette('unsupported') @@ -326,6 +332,19 @@ def test_mapillary(): assert len(test_dataset) == 1 +def test_bdd100k(): + test_dataset = BDD100KDataset( + pipeline=[], + data_prefix=dict( + img_path=osp.join( + osp.dirname(__file__), + '../data/pseudo_bdd100k_dataset/images/10k/val'), + seg_map_path=osp.join( + osp.dirname(__file__), + '../data/pseudo_bdd100k_dataset/labels/sem_seg/masks/val'))) + assert len(test_dataset) == 3 + + @pytest.mark.parametrize('dataset, classes', [ ('ADE20KDataset', ('wall', 'building')), ('CityscapesDataset', ('road', 'sidewalk')), @@ -433,3 +452,24 @@ def test_custom_dataset_custom_palette(): ann_file=tempfile.mkdtemp(), metainfo=dict(classes=('bus', 'car'), palette=[[200, 200, 200]]), lazy_init=True) + + +def test_dsdlseg_dataset(): + if DSDLDataset is not None: + dataset = DSDLSegDataset( + data_root='tests/data/dsdl_seg', ann_file='set-train/train.yaml') + assert len(dataset) == 3 + assert len(dataset.metainfo['classes']) == 21 + else: + ImportWarning('Package `dsdl` is not installed.') + + +def test_nyu_dataset(): + dataset = NYUDataset( + data_root='tests/data/pseudo_nyu_dataset', + data_prefix=dict(img_path='images', depth_map_path='annotations'), + ) + assert len(dataset) == 1 + data = dataset[0] + assert data.get('depth_map_path', None) is not None + assert data.get('category_id', -1) == 26 diff --git a/tests/test_datasets/test_loading.py b/tests/test_datasets/test_loading.py index 5ce624bff6a..3eea6e3f9dd 100644 --- a/tests/test_datasets/test_loading.py +++ b/tests/test_datasets/test_loading.py @@ -7,10 +7,11 @@ import numpy as np from mmcv.transforms import LoadImageFromFile -from mmseg.datasets.transforms import (LoadAnnotations, - LoadBiomedicalAnnotation, +from mmseg.datasets.transforms import LoadAnnotations # noqa +from mmseg.datasets.transforms import (LoadBiomedicalAnnotation, LoadBiomedicalData, LoadBiomedicalImageFromFile, + LoadDepthAnnotation, LoadImageFromNDArray) @@ -276,3 +277,19 @@ def test_load_biomedical_data(self): "decode_backend='numpy', " 'to_xyz=False, ' 'backend_args=None)') + + def test_load_depth_annotation(self): + input_results = dict( + img_path='tests/data/pseudo_nyu_dataset/images/' + 'bookstore_0001d_00001.jpg', + depth_map_path='tests/data/pseudo_nyu_dataset/' + 'annotations/bookstore_0001d_00001.png', + category_id=-1, + seg_fields=[]) + transform = LoadDepthAnnotation(depth_rescale_factor=0.001) + results = transform(input_results) + assert 'gt_depth_map' in results + assert results['gt_depth_map'].shape[:2] == mmcv.imread( + input_results['depth_map_path']).shape[:2] + assert results['gt_depth_map'].dtype == np.float32 + assert 'gt_depth_map' in results['seg_fields'] diff --git a/tests/test_datasets/test_transform.py b/tests/test_datasets/test_transform.py index 92d6c6106d2..e73e558ee8e 100644 --- a/tests/test_datasets/test_transform.py +++ b/tests/test_datasets/test_transform.py @@ -1,6 +1,7 @@ # Copyright (c) OpenMMLab. All rights reserved. import copy import os.path as osp +from unittest import TestCase import mmcv import numpy as np @@ -11,7 +12,8 @@ from mmseg.datasets.transforms import * # noqa from mmseg.datasets.transforms import (LoadBiomedicalData, LoadBiomedicalImageFromFile, - PhotoMetricDistortion, RandomCrop) + PhotoMetricDistortion, RandomCrop, + RandomDepthMix) from mmseg.registry import TRANSFORMS init_default_scope('mmseg') @@ -184,6 +186,14 @@ def test_flip(): assert np.equal(original_img, results['img']).all() assert np.equal(original_seg, results['gt_semantic_seg']).all() + results['gt_depth_map'] = seg + results['seg_fields'] = ['gt_depth_map'] + results = flip_module(results) + flip_module = TRANSFORMS.build(transform) + results = flip_module(results) + assert np.equal(original_img, results['img']).all() + assert np.equal(original_seg, results['gt_depth_map']).all() + def test_random_rotate_flip(): with pytest.raises(AssertionError): @@ -1160,3 +1170,104 @@ def test_biomedical_3d_flip(): results = transform(results) assert np.equal(original_img, results['img']).all() assert np.equal(original_seg, results['gt_seg_map']).all() + + +def test_albu_transform(): + results = dict( + img_path=osp.join(osp.dirname(__file__), '../data/color.jpg')) + + # Define simple pipeline + load = dict(type='LoadImageFromFile') + load = TRANSFORMS.build(load) + + albu_transform = dict( + type='Albu', transforms=[dict(type='ChannelShuffle', p=1)]) + albu_transform = TRANSFORMS.build(albu_transform) + + normalize = dict(type='Normalize', mean=[0] * 3, std=[0] * 3, to_rgb=True) + normalize = TRANSFORMS.build(normalize) + + # Execute transforms + results = load(results) + results = albu_transform(results) + results = normalize(results) + + assert results['img'].dtype == np.float32 + + +def test_albu_channel_order(): + results = dict( + img_path=osp.join(osp.dirname(__file__), '../data/color.jpg')) + + # Define simple pipeline + load = dict(type='LoadImageFromFile') + load = TRANSFORMS.build(load) + + # Transform is modifying B channel + albu_transform = dict( + type='Albu', + transforms=[ + dict( + type='RGBShift', + r_shift_limit=0, + g_shift_limit=0, + b_shift_limit=200, + p=1) + ]) + albu_transform = TRANSFORMS.build(albu_transform) + + # Execute transforms + results_load = load(results) + results_albu = albu_transform(results_load) + + # assert only Green and Red channel are not modified + np.testing.assert_array_equal(results_albu['img'][..., 1:], + results_load['img'][..., 1:]) + + # assert Blue channel is modified + with pytest.raises(AssertionError): + np.testing.assert_array_equal(results_albu['img'][..., 0], + results_load['img'][..., 0]) + + +class TestRandomDepthMix(TestCase): + + def setUp(self): + self.transform = RandomDepthMix(prob=1.0) + + def test_transform_shape(self): + # Create a dummy result dict + results = { + 'img_shape': (10, 10), + 'img': np.random.rand(10, 10, 3), + 'gt_depth_map': np.random.rand(10, 10) + } + transformed = self.transform.transform(results) + + # Check if the shape remains the same + self.assertEqual(results['img'].shape, transformed['img'].shape) + + def test_transform_values(self): + # Create a dummy result dict + results = { + 'img_shape': (10, 10), + 'img': np.zeros((10, 10, 3)), + 'gt_depth_map': np.ones((10, 10)) + } + transformed = self.transform.transform(results) + + # Assuming the transformation modifies a portion of the image, + # it shouldn't remain all zeros + self.assertFalse(np.all(transformed['img'] == 0)) + + def test_invalid_image_dimension(self): + # Create a dummy result dict with invalid image dimension + results = { + 'img_shape': (10, 10), + 'img': np.random.rand(10, 10, 3, 3), + 'gt_depth_map': np.random.rand(10, 10) + } + + # Check if a ValueError is raised for invalid dimension + with self.assertRaises(ValueError): + self.transform.transform(results) diff --git a/tests/test_evaluation/test_metrics/test_depth_metric.py b/tests/test_evaluation/test_metrics/test_depth_metric.py new file mode 100644 index 00000000000..a172db8fa20 --- /dev/null +++ b/tests/test_evaluation/test_metrics/test_depth_metric.py @@ -0,0 +1,85 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import os.path as osp +import shutil +from unittest import TestCase + +import torch +from mmengine.structures import PixelData + +from mmseg.evaluation import DepthMetric +from mmseg.structures import SegDataSample + + +class TestDepthMetric(TestCase): + + def _demo_mm_inputs(self, + batch_size=2, + image_shapes=(3, 64, 64), + num_classes=5): + """Create a superset of inputs needed to run test or train batches. + + Args: + batch_size (int): batch size. Default to 2. + image_shapes (List[tuple], Optional): image shape. + Default to (3, 64, 64) + num_classes (int): number of different classes. + Default to 5. + """ + if isinstance(image_shapes, list): + assert len(image_shapes) == batch_size + else: + image_shapes = [image_shapes] * batch_size + + data_samples = [] + for idx in range(batch_size): + image_shape = image_shapes[idx] + _, h, w = image_shape + + data_sample = SegDataSample() + gt_depth_map = torch.rand((1, h, w)) * 10 + data_sample.gt_depth_map = PixelData(data=gt_depth_map) + + data_samples.append(data_sample.to_dict()) + + return data_samples + + def _demo_mm_model_output(self, + data_samples, + batch_size=2, + image_shapes=(3, 64, 64), + num_classes=5): + + _, h, w = image_shapes + + for data_sample in data_samples: + data_sample['pred_depth_map'] = dict(data=torch.randn(1, h, w)) + + data_sample[ + 'img_path'] = 'tests/data/pseudo_dataset/imgs/00000_img.jpg' + return data_samples + + def test_evaluate(self): + """Test using the metric in the same way as Evalutor.""" + + data_samples = self._demo_mm_inputs() + data_samples = self._demo_mm_model_output(data_samples) + + depth_metric = DepthMetric() + depth_metric.process([0] * len(data_samples), data_samples) + res = depth_metric.compute_metrics(depth_metric.results) + self.assertIsInstance(res, dict) + + # test save depth map file in output_dir + depth_metric = DepthMetric(output_dir='tmp') + depth_metric.process([0] * len(data_samples), data_samples) + assert osp.exists('tmp') + assert osp.isfile('tmp/00000_img.png') + shutil.rmtree('tmp') + + # test format_only + depth_metric = DepthMetric(output_dir='tmp', format_only=True) + depth_metric.process([0] * len(data_samples), data_samples) + assert depth_metric.results == [] + assert osp.exists('tmp') + assert osp.isfile('tmp/00000_img.png') + shutil.rmtree('tmp') diff --git a/tests/test_models/test_assigners/test_hungarian_assigner.py b/tests/test_models/test_assigners/test_hungarian_assigner.py new file mode 100644 index 00000000000..2cdb1de839d --- /dev/null +++ b/tests/test_models/test_assigners/test_hungarian_assigner.py @@ -0,0 +1,77 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from unittest import TestCase + +import torch +from mmengine.structures import InstanceData + +from mmseg.models.assigners import HungarianAssigner + + +class TestHungarianAssigner(TestCase): + + def test_init(self): + with self.assertRaises(AssertionError): + HungarianAssigner([]) + + def test_hungarian_match_assigner(self): + assigner = HungarianAssigner([ + dict(type='ClassificationCost', weight=2.0), + dict(type='CrossEntropyLossCost', weight=5.0, use_sigmoid=True), + dict(type='DiceCost', weight=5.0, pred_act=True, eps=1.0) + ]) + num_classes = 3 + num_masks = 10 + num_points = 20 + gt_instances = InstanceData() + gt_instances.labels = torch.randint(0, num_classes, (num_classes, )) + gt_instances.masks = torch.randint(0, 2, (num_classes, num_points)) + pred_instances = InstanceData() + pred_instances.scores = torch.rand((num_masks, num_classes)) + pred_instances.masks = torch.rand((num_masks, num_points)) + + matched_quiery_inds, matched_label_inds = \ + assigner.assign(pred_instances, gt_instances) + unique_quiery_inds = torch.unique(matched_quiery_inds) + unique_label_inds = torch.unique(matched_label_inds) + self.assertTrue(len(unique_quiery_inds) == len(matched_quiery_inds)) + self.assertTrue( + torch.equal(unique_label_inds, torch.arange(0, num_classes))) + + def test_cls_match_cost(self): + num_classes = 3 + num_masks = 10 + gt_instances = InstanceData() + gt_instances.labels = torch.randint(0, num_classes, (num_classes, )) + pred_instances = InstanceData() + pred_instances.scores = torch.rand((num_masks, num_classes)) + + # test ClassificationCost + assigner = HungarianAssigner(dict(type='ClassificationCost')) + matched_quiery_inds, matched_label_inds = \ + assigner.assign(pred_instances, gt_instances) + unique_quiery_inds = torch.unique(matched_quiery_inds) + unique_label_inds = torch.unique(matched_label_inds) + self.assertTrue(len(unique_quiery_inds) == len(matched_quiery_inds)) + self.assertTrue( + torch.equal(unique_label_inds, torch.arange(0, num_classes))) + + def test_mask_match_cost(self): + num_classes = 3 + num_masks = 10 + num_points = 20 + gt_instances = InstanceData() + gt_instances.masks = torch.randint(0, 2, (num_classes, num_points)) + pred_instances = InstanceData() + pred_instances.masks = torch.rand((num_masks, num_points)) + + # test DiceCost + assigner = HungarianAssigner( + dict(type='DiceCost', pred_act=True, eps=1.0)) + assign_result = assigner.assign(pred_instances, gt_instances) + self.assertTrue(len(assign_result[0]) == len(assign_result[1])) + + # test CrossEntropyLossCost + assigner = HungarianAssigner( + dict(type='CrossEntropyLossCost', use_sigmoid=True)) + assign_result = assigner.assign(pred_instances, gt_instances) + self.assertTrue(len(assign_result[0]) == len(assign_result[1])) diff --git a/tests/test_models/test_backbones/test_clip_text_encoder.py b/tests/test_models/test_backbones/test_clip_text_encoder.py new file mode 100644 index 00000000000..ea06c5b5b3f --- /dev/null +++ b/tests/test_models/test_backbones/test_clip_text_encoder.py @@ -0,0 +1,43 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from mmengine import Config +from mmengine.registry import init_default_scope + +from mmseg.models.text_encoder import CLIPTextEncoder +from mmseg.utils import get_classes + + +def test_clip_text_encoder(): + init_default_scope('mmseg') + # test vocabulary + output_dims = 8 + embed_dims = 32 + vocabulary = ['cat', 'dog', 'bird', 'car', 'bike'] + cfg = dict( + vocabulary=vocabulary, + templates=['a photo of a {}.'], + embed_dims=embed_dims, + output_dims=output_dims) + cfg = Config(cfg) + + text_encoder = CLIPTextEncoder(**cfg) + if torch.cuda.is_available(): + text_encoder = text_encoder.cuda() + + with torch.no_grad(): + class_embeds = text_encoder() + assert class_embeds.shape == (len(vocabulary) + 1, output_dims) + + # test dataset name + cfg = dict( + dataset_name='vaihingen', + templates=['a photo of a {}.'], + embed_dims=embed_dims, + output_dims=output_dims) + cfg = Config(cfg) + + text_encoder = CLIPTextEncoder(**cfg) + with torch.no_grad(): + class_embeds = text_encoder() + class_nums = len(get_classes('vaihingen')) + assert class_embeds.shape == (class_nums + 1, output_dims) diff --git a/tests/test_models/test_backbones/test_vpd.py b/tests/test_models/test_backbones/test_vpd.py new file mode 100644 index 00000000000..a268159155e --- /dev/null +++ b/tests/test_models/test_backbones/test_vpd.py @@ -0,0 +1,51 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from os.path import dirname, join +from unittest import TestCase + +import torch +from mmengine import Config + +import mmseg +from mmseg.models.backbones import VPD + + +class TestVPD(TestCase): + + def setUp(self) -> None: + + repo_dpath = dirname(dirname(mmseg.__file__)) + config_dpath = join(repo_dpath, 'configs/_base_/models/vpd_sd.py') + vpd_cfg = Config.fromfile(config_dpath).stable_diffusion_cfg + vpd_cfg.pop('checkpoint') + + self.vpd_model = VPD( + diffusion_cfg=vpd_cfg, + class_embed_path='https://download.openmmlab.com/mmsegmentation/' + 'v0.5/vpd/nyu_class_embeddings.pth', + class_embed_select=True, + pad_shape=64, + unet_cfg=dict(use_attn=False), + ) + + def test_forward(self): + # test forward without class_id + x = torch.randn(1, 3, 60, 60) + with torch.no_grad(): + out = self.vpd_model(x) + + self.assertEqual(len(out), 4) + self.assertListEqual(list(out[0].shape), [1, 320, 8, 8]) + self.assertListEqual(list(out[1].shape), [1, 640, 4, 4]) + self.assertListEqual(list(out[2].shape), [1, 1280, 2, 2]) + self.assertListEqual(list(out[3].shape), [1, 1280, 1, 1]) + + # test forward with class_id + x = torch.randn(1, 3, 60, 60) + with torch.no_grad(): + out = self.vpd_model((x, torch.tensor([2]))) + + self.assertEqual(len(out), 4) + self.assertListEqual(list(out[0].shape), [1, 320, 8, 8]) + self.assertListEqual(list(out[1].shape), [1, 640, 4, 4]) + self.assertListEqual(list(out[2].shape), [1, 1280, 2, 2]) + self.assertListEqual(list(out[3].shape), [1, 1280, 1, 1]) diff --git a/tests/test_models/test_heads/test_san_head.py b/tests/test_models/test_heads/test_san_head.py new file mode 100644 index 00000000000..af85a6e2ca0 --- /dev/null +++ b/tests/test_models/test_heads/test_san_head.py @@ -0,0 +1,126 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch +from mmengine import Config +from mmengine.structures import PixelData + +from mmseg.models.decode_heads import SideAdapterCLIPHead +from mmseg.structures import SegDataSample +from .utils import list_to_cuda + + +def test_san_head(): + H, W = (64, 64) + clip_channels = 64 + img_channels = 4 + num_queries = 40 + out_dims = 64 + num_classes = 19 + cfg = dict( + num_classes=num_classes, + deep_supervision_idxs=[4], + san_cfg=dict( + in_channels=img_channels, + embed_dims=128, + clip_channels=clip_channels, + num_queries=num_queries, + cfg_encoder=dict(num_encode_layer=4, mlp_ratio=2, num_heads=2), + cfg_decoder=dict( + num_heads=4, + num_layers=1, + embed_channels=32, + mlp_channels=32, + num_mlp=2, + rescale=True)), + maskgen_cfg=dict( + sos_token_num=num_queries, + embed_dims=clip_channels, + out_dims=out_dims, + num_heads=4, + mlp_ratio=2), + train_cfg=dict( + num_points=100, + oversample_ratio=3.0, + importance_sample_ratio=0.75, + assigner=dict( + type='HungarianAssigner', + match_costs=[ + dict(type='ClassificationCost', weight=2.0), + dict( + type='CrossEntropyLossCost', + weight=5.0, + use_sigmoid=True), + dict(type='DiceCost', weight=5.0, pred_act=True, eps=1.0) + ])), + loss_decode=[ + dict( + type='CrossEntropyLoss', + loss_name='loss_cls_ce', + loss_weight=2.0, + class_weight=[1.0] * num_classes + [0.1]), + dict( + type='CrossEntropyLoss', + use_sigmoid=True, + loss_name='loss_mask_ce', + loss_weight=5.0), + dict( + type='DiceLoss', + ignore_index=None, + naive_dice=True, + eps=1, + loss_name='loss_mask_dice', + loss_weight=5.0) + ]) + + cfg = Config(cfg) + head = SideAdapterCLIPHead(**cfg) + + inputs = torch.rand((2, img_channels, H, W)) + clip_feature = [[ + torch.rand((2, clip_channels, H // 2, W // 2)), + torch.rand((2, clip_channels)) + ], + [ + torch.rand((2, clip_channels, H // 2, W // 2)), + torch.rand((2, clip_channels)) + ], + [ + torch.rand((2, clip_channels, H // 2, W // 2)), + torch.rand((2, clip_channels)) + ], + [ + torch.rand((2, clip_channels, H // 2, W // 2)), + torch.rand((2, clip_channels)) + ]] + class_embed = torch.rand((num_classes + 1, out_dims)) + + data_samples = [] + for i in range(2): + data_sample = SegDataSample() + img_meta = {} + img_meta['img_shape'] = (H, W) + img_meta['ori_shape'] = (H, W) + data_sample.gt_sem_seg = PixelData( + data=torch.randint(0, num_classes, (1, H, W))) + data_sample.set_metainfo(img_meta) + data_samples.append(data_sample) + + batch_img_metas = [] + for data_sample in data_samples: + batch_img_metas.append(data_sample.metainfo) + + if torch.cuda.is_available(): + head = head.cuda() + data = list_to_cuda([inputs, clip_feature, class_embed]) + for data_sample in data_samples: + data_sample.gt_sem_seg.data = data_sample.gt_sem_seg.data.cuda() + else: + data = [inputs, clip_feature, class_embed] + + # loss test + loss_dict = head.loss(data, data_samples, None) + assert isinstance(loss_dict, dict) + + # prediction test + with torch.no_grad(): + seg_logits = head.predict(data, batch_img_metas, None) + assert seg_logits.shape == torch.Size((2, num_classes, H, W)) diff --git a/tests/test_models/test_heads/test_vpd_depth_head.py b/tests/test_models/test_heads/test_vpd_depth_head.py new file mode 100644 index 00000000000..e3a4f7558ec --- /dev/null +++ b/tests/test_models/test_heads/test_vpd_depth_head.py @@ -0,0 +1,50 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from unittest import TestCase + +import torch +from mmengine.structures import PixelData + +from mmseg.models.decode_heads import VPDDepthHead +from mmseg.structures import SegDataSample + + +class TestVPDDepthHead(TestCase): + + def setUp(self): + """Set up common resources.""" + self.in_channels = [320, 640, 1280, 1280] + self.max_depth = 10.0 + self.loss_decode = dict( + type='SiLogLoss' + ) # Replace with your actual loss type and parameters + self.vpd_depth_head = VPDDepthHead( + max_depth=self.max_depth, + in_channels=self.in_channels, + loss_decode=self.loss_decode) + + def test_forward(self): + """Test the forward method.""" + # Create a mock input tensor. Replace shape as per your needs. + x = [ + torch.randn(1, 320, 32, 32), + torch.randn(1, 640, 16, 16), + torch.randn(1, 1280, 8, 8), + torch.randn(1, 1280, 4, 4) + ] + + output = self.vpd_depth_head.forward(x) + print(output.shape) + + self.assertEqual(output.shape, (1, 1, 256, 256)) + + def test_loss_by_feat(self): + """Test the loss_by_feat method.""" + # Create mock data for `pred_depth_map` and `batch_data_samples`. + pred_depth_map = torch.randn(1, 1, 32, 32) + gt_depth_map = PixelData(data=torch.rand(1, 32, 32)) + batch_data_samples = [SegDataSample(gt_depth_map=gt_depth_map)] + + loss = self.vpd_depth_head.loss_by_feat(pred_depth_map, + batch_data_samples) + + self.assertIsNotNone(loss) diff --git a/tests/test_models/test_heads/utils.py b/tests/test_models/test_heads/utils.py index 335e261a5e5..72823401552 100644 --- a/tests/test_models/test_heads/utils.py +++ b/tests/test_models/test_heads/utils.py @@ -20,3 +20,12 @@ def to_cuda(module, data): for i in range(len(data)): data[i] = data[i].cuda() return module, data + + +def list_to_cuda(data): + if isinstance(data, list): + for i in range(len(data)): + data[i] = list_to_cuda(data[i]) + return data + else: + return data.cuda() diff --git a/tests/test_models/test_losses/test_dice_loss.py b/tests/test_models/test_losses/test_dice_loss.py new file mode 100644 index 00000000000..34253dae12e --- /dev/null +++ b/tests/test_models/test_losses/test_dice_loss.py @@ -0,0 +1,96 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import pytest +import torch + +from mmseg.models.losses import DiceLoss + + +@pytest.mark.parametrize('naive_dice', [True, False]) +def test_dice_loss(naive_dice): + loss_class = DiceLoss + pred = torch.rand((1, 10, 4, 4)) + target = torch.randint(0, 10, (1, 4, 4)) + weight = torch.rand(1) + # Test loss forward + loss = loss_class(naive_dice=naive_dice)(pred, target) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with weight + loss = loss_class(naive_dice=naive_dice)(pred, target, weight) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with reduction_override + loss = loss_class(naive_dice=naive_dice)( + pred, target, reduction_override='mean') + assert isinstance(loss, torch.Tensor) + + # Test loss forward with avg_factor + loss = loss_class(naive_dice=naive_dice)(pred, target, avg_factor=10) + assert isinstance(loss, torch.Tensor) + + with pytest.raises(ValueError): + # loss can evaluate with avg_factor only if + # reduction is None, 'none' or 'mean'. + reduction_override = 'sum' + loss_class(naive_dice=naive_dice)( + pred, target, avg_factor=10, reduction_override=reduction_override) + + # Test loss forward with avg_factor and reduction + for reduction_override in [None, 'none', 'mean']: + loss_class(naive_dice=naive_dice)( + pred, target, avg_factor=10, reduction_override=reduction_override) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with has_acted=False and use_sigmoid=False + for use_sigmoid in [True, False]: + loss_class( + use_sigmoid=use_sigmoid, activate=True, + naive_dice=naive_dice)(pred, target) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with weight.ndim != loss.ndim + with pytest.raises(AssertionError): + weight = torch.rand((2, 8)) + loss_class(naive_dice=naive_dice)(pred, target, weight) + + # Test loss forward with len(weight) != len(pred) + with pytest.raises(AssertionError): + weight = torch.rand(8) + loss_class(naive_dice=naive_dice)(pred, target, weight) + + # Test _expand_onehot_labels_dice + pred = torch.tensor([[[[1, 1], [1, 0]], [[0, 1], [1, 1]]]]).float() + target = torch.tensor([[[0, 0], [0, 1]]]) + target_onehot = torch.tensor([[[[1, 1], [1, 0]], [[0, 0], [0, 1]]]]) + weight = torch.rand(1) + loss = loss_class(naive_dice=naive_dice)(pred, target, weight) + loss_onehot = loss_class(naive_dice=naive_dice)(pred, target_onehot, + weight) + assert torch.equal(loss, loss_onehot) + + # Test Whether Loss is 0 when pred == target, eps == 0 and naive_dice=False + target = torch.randint(0, 2, (1, 10, 4, 4)) + pred = target.float() + target = target.sigmoid() + weight = torch.rand(1) + loss = loss_class( + naive_dice=False, use_sigmoid=True, eps=0)(pred, target, weight) + assert loss.item() == 0 + + # Test ignore_index when ignore_index is the only class + with pytest.raises(AssertionError): + pred = torch.ones((1, 1, 4, 4)) + target = torch.randint(0, 1, (1, 4, 4)) + weight = torch.rand(1) + loss = loss_class( + naive_dice=naive_dice, use_sigmoid=False, ignore_index=0, + eps=0)(pred, target, weight) + + # Test ignore_index with naive_dice = False + pred = torch.tensor([[[[1, 1], [1, 0]], [[0, 1], [1, 1]]]]).float() + target = torch.tensor([[[[1, 1], [1, 0]], [[1, 0], [0, 1]]]]).sigmoid() + weight = torch.rand(1) + loss = loss_class( + naive_dice=False, use_sigmoid=True, ignore_index=1, + eps=0)(pred, target, weight) + assert loss.item() == 0 diff --git a/tests/test_models/test_losses/test_huasdorff_distance_loss.py b/tests/test_models/test_losses/test_huasdorff_distance_loss.py new file mode 100644 index 00000000000..29c2732d3f1 --- /dev/null +++ b/tests/test_models/test_losses/test_huasdorff_distance_loss.py @@ -0,0 +1,29 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import pytest +import torch + +from mmseg.models.losses import HuasdorffDisstanceLoss + + +def test_huasdorff_distance_loss(): + loss_class = HuasdorffDisstanceLoss + pred = torch.rand((10, 8, 6, 6)) + target = torch.rand((10, 6, 6)) + class_weight = torch.rand(8) + + # Test loss forward + loss = loss_class()(pred, target) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with avg_factor + loss = loss_class()(pred, target, avg_factor=10) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with avg_factor and reduction is None, 'sum' and 'mean' + for reduction in [None, 'sum', 'mean']: + loss = loss_class()(pred, target, avg_factor=10, reduction=reduction) + assert isinstance(loss, torch.Tensor) + + # Test loss forward with class_weight + with pytest.raises(AssertionError): + loss_class(class_weight=class_weight)(pred, target) diff --git a/tests/test_models/test_losses/test_kldiv_loss.py b/tests/test_models/test_losses/test_kldiv_loss.py new file mode 100644 index 00000000000..48bcc4bfd9f --- /dev/null +++ b/tests/test_models/test_losses/test_kldiv_loss.py @@ -0,0 +1,40 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import torch + +from mmseg.models.losses.kldiv_loss import KLDivLoss + + +def test_kldiv_loss_with_none_reduction(): + loss_class = KLDivLoss + pred = torch.rand((8, 5, 5)) + target = torch.rand((8, 5, 5)) + reduction = 'none' + + # Test loss forward + loss = loss_class(reduction=reduction)(pred, target) + assert isinstance(loss, torch.Tensor) + assert loss.shape == (8, 5, 5), f'{loss.shape}' + + +def test_kldiv_loss_with_mean_reduction(): + loss_class = KLDivLoss + pred = torch.rand((8, 5, 5)) + target = torch.rand((8, 5, 5)) + reduction = 'mean' + + # Test loss forward + loss = loss_class(reduction=reduction)(pred, target) + assert isinstance(loss, torch.Tensor) + assert loss.shape == (8, ), f'{loss.shape}' + + +def test_kldiv_loss_with_sum_reduction(): + loss_class = KLDivLoss + pred = torch.rand((8, 5, 5)) + target = torch.rand((8, 5, 5)) + reduction = 'sum' + + # Test loss forward + loss = loss_class(reduction=reduction)(pred, target) + assert isinstance(loss, torch.Tensor) + assert loss.shape == (8, ), f'{loss.shape}' diff --git a/tests/test_models/test_losses/test_silog_loss.py b/tests/test_models/test_losses/test_silog_loss.py new file mode 100644 index 00000000000..022434bcc14 --- /dev/null +++ b/tests/test_models/test_losses/test_silog_loss.py @@ -0,0 +1,20 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from unittest import TestCase + +import torch + +from mmseg.models.losses import SiLogLoss + + +class TestSiLogLoss(TestCase): + + def test_SiLogLoss_forward(self): + pred = torch.tensor([[1.0, 2.0], [3.5, 4.0]], dtype=torch.float32) + target = torch.tensor([[0.0, 2.0], [3.0, 4.0]], dtype=torch.float32) + weight = torch.tensor([1.0, 0.5], dtype=torch.float32) + + loss_module = SiLogLoss() + loss = loss_module.forward(pred, target, weight) + + expected_loss = 0.02 + self.assertAlmostEqual(loss.item(), expected_loss, places=2) diff --git a/tests/test_models/test_segmentors/test_depth_estimator.py b/tests/test_models/test_segmentors/test_depth_estimator.py new file mode 100644 index 00000000000..e819c9e7633 --- /dev/null +++ b/tests/test_models/test_segmentors/test_depth_estimator.py @@ -0,0 +1,64 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from copy import deepcopy +from os.path import dirname, join +from unittest import TestCase + +import torch +from mmengine import Config, ConfigDict +from mmengine.structures import PixelData + +import mmseg +from mmseg.models.segmentors import DepthEstimator +from mmseg.structures import SegDataSample + + +class TestDepthEstimator(TestCase): + + def setUp(self) -> None: + repo_dpath = dirname(dirname(mmseg.__file__)) + config_dpath = join(repo_dpath, 'configs/_base_/models/vpd_sd.py') + vpd_cfg = Config.fromfile(config_dpath).stable_diffusion_cfg + vpd_cfg.pop('checkpoint') + + backbone_cfg = dict( + type='VPD', + diffusion_cfg=vpd_cfg, + class_embed_path='https://download.openmmlab.com/mmsegmentation/' + 'v0.5/vpd/nyu_class_embeddings.pth', + class_embed_select=True, + pad_shape=64, + unet_cfg=dict(use_attn=False), + ) + + head_cfg = dict( + type='VPDDepthHead', + max_depth=10, + ) + + self.model = DepthEstimator( + backbone=backbone_cfg, decode_head=head_cfg) + + inputs = torch.randn(1, 3, 64, 80) + data_sample = SegDataSample() + data_sample.gt_depth_map = PixelData(data=torch.rand(1, 64, 80)) + data_sample.set_metainfo(dict(img_shape=(64, 80), ori_shape=(64, 80))) + self.data = dict(inputs=inputs, data_samples=[data_sample]) + + def test_slide_flip_inference(self): + + self.model.test_cfg = ConfigDict( + dict(mode='slide_flip', crop_size=(64, 64), stride=(16, 16))) + + with torch.no_grad(): + out = self.model.predict(**deepcopy(self.data)) + + self.assertEqual(len(out), 1) + self.assertIn('pred_depth_map', out[0].keys()) + self.assertListEqual(list(out[0].pred_depth_map.shape), [64, 80]) + + def test__forward(self): + data = deepcopy(self.data) + data['inputs'] = data['inputs'][:, :, :64, :64] + with torch.no_grad(): + out = self.model._forward(**data) + self.assertListEqual(list(out.shape), [1, 1, 64, 64]) diff --git a/tests/test_models/test_segmentors/test_multimodal_encoder_decoder.py b/tests/test_models/test_segmentors/test_multimodal_encoder_decoder.py new file mode 100644 index 00000000000..75258d89a7d --- /dev/null +++ b/tests/test_models/test_segmentors/test_multimodal_encoder_decoder.py @@ -0,0 +1,24 @@ +# Copyright (c) OpenMMLab. All rights reserved. +from mmengine import ConfigDict + +from mmseg.models import build_segmentor +from tests.test_models.test_segmentors.utils import \ + _segmentor_forward_train_test + + +def test_multimodal_encoder_decoder(): + + cfg = ConfigDict( + type='MultimodalEncoderDecoder', + asymetric_input=False, + image_encoder=dict(type='ExampleBackbone', out_indices=[1, 2, 3, 4]), + text_encoder=dict( + type='ExampleTextEncoder', + vocabulary=['A', 'B', 'C'], + output_dims=3), + decode_head=dict( + type='ExampleDecodeHead', out_channels=1, num_classes=2), + train_cfg=None, + test_cfg=dict(mode='whole')) + segmentor = build_segmentor(cfg) + _segmentor_forward_train_test(segmentor) diff --git a/tests/test_models/test_segmentors/test_seg_tta_model.py b/tests/test_models/test_segmentors/test_seg_tta_model.py index 3c9699e8df4..1e152ed0565 100644 --- a/tests/test_models/test_segmentors/test_seg_tta_model.py +++ b/tests/test_models/test_segmentors/test_seg_tta_model.py @@ -1,4 +1,6 @@ # Copyright (c) OpenMMLab. All rights reserved. +import tempfile + import torch from mmengine import ConfigDict from mmengine.model import BaseTTAModel @@ -37,7 +39,8 @@ def test_encoder_decoder_tta(): ori_shape=(10, 10), img_shape=(10 + i, 10 + i), flip=(i % 2 == 0), - flip_direction=flip_direction), + flip_direction=flip_direction, + img_path=tempfile.mktemp()), gt_sem_seg=PixelData(data=torch.randint(0, 19, (1, 10, 10)))) ]) diff --git a/tests/test_models/test_segmentors/utils.py b/tests/test_models/test_segmentors/utils.py index 6b440df906d..ac31e2b2774 100644 --- a/tests/test_models/test_segmentors/utils.py +++ b/tests/test_models/test_segmentors/utils.py @@ -52,15 +52,22 @@ def _demo_mm_inputs(input_shape=(1, 3, 8, 16), num_classes=10): @MODELS.register_module() class ExampleBackbone(nn.Module): - def __init__(self): + def __init__(self, out_indices=None): super().__init__() self.conv = nn.Conv2d(3, 3, 3) + self.out_indices = out_indices def init_weights(self, pretrained=None): pass def forward(self, x): - return [self.conv(x)] + if self.out_indices is None: + return [self.conv(x)] + else: + outs = [] + for i in self.out_indices: + outs.append(self.conv(x)) + return outs @MODELS.register_module() @@ -74,6 +81,18 @@ def forward(self, inputs): return self.cls_seg(inputs[0]) +@MODELS.register_module() +class ExampleTextEncoder(nn.Module): + + def __init__(self, vocabulary=None, output_dims=None): + super().__init__() + self.vocabulary = vocabulary + self.output_dims = output_dims + + def forward(self): + return torch.randn((len(self.vocabulary), self.output_dims)) + + @MODELS.register_module() class ExampleCascadeDecodeHead(BaseCascadeDecodeHead): @@ -132,3 +151,32 @@ def _segmentor_forward_train_test(segmentor): data_batch = dict(inputs=imgs, data_samples=data_samples) results = segmentor.forward(imgs, data_samples, mode='tensor') assert isinstance(results, torch.Tensor) + + +def _segmentor_predict(segmentor): + if isinstance(segmentor.decode_head, nn.ModuleList): + num_classes = segmentor.decode_head[-1].num_classes + else: + num_classes = segmentor.decode_head.num_classes + # batch_size=2 for BatchNorm + mm_inputs = _demo_mm_inputs(num_classes=num_classes) + + # convert to cuda Tensor if applicable + if torch.cuda.is_available(): + segmentor = segmentor.cuda() + + # check data preprocessor + if not hasattr(segmentor, + 'data_preprocessor') or segmentor.data_preprocessor is None: + segmentor.data_preprocessor = SegDataPreProcessor() + + mm_inputs = segmentor.data_preprocessor(mm_inputs, True) + imgs = mm_inputs.pop('imgs') + data_samples = mm_inputs.pop('data_samples') + + # Test predict + with torch.no_grad(): + segmentor.eval() + data_batch = dict(inputs=imgs, data_samples=data_samples) + outputs = segmentor.predict(**data_batch) + assert isinstance(outputs, list) diff --git a/tests/test_visualization/test_local_visualizer.py b/tests/test_visualization/test_local_visualizer.py index b60a9b87507..e3b2a88cfb7 100644 --- a/tests/test_visualization/test_local_visualizer.py +++ b/tests/test_visualization/test_local_visualizer.py @@ -155,3 +155,59 @@ def _assert_image_and_shape(self, out_file, out_shape): assert os.path.exists(out_file) drawn_img = cv2.imread(out_file) assert drawn_img.shape == out_shape + + def test_add_datasample_depth(self): + h = 10 + w = 12 + out_file = 'out_file' + + image = np.random.randint(0, 256, size=(h, w, 3)).astype('uint8') + + # test gt_depth_map + gt_depth_map = PixelData(data=torch.rand(1, h, w)) + + def test_add_datasample_forward_depth(gt_depth_map): + data_sample = SegDataSample() + data_sample.gt_depth_map = gt_depth_map + + with tempfile.TemporaryDirectory() as tmp_dir: + seg_local_visualizer = SegLocalVisualizer( + vis_backends=[dict(type='LocalVisBackend')], + save_dir=tmp_dir) + seg_local_visualizer.dataset_meta = dict( + classes=('background', 'foreground'), + palette=[[120, 120, 120], [6, 230, 230]]) + + # test out_file + seg_local_visualizer.add_datasample(out_file, image, + data_sample) + + assert os.path.exists( + osp.join(tmp_dir, 'vis_data', 'vis_image', + out_file + '_0.png')) + drawn_img = cv2.imread( + osp.join(tmp_dir, 'vis_data', 'vis_image', + out_file + '_0.png')) + assert drawn_img.shape == (h * 2, w, 3) + + # test gt_instances and pred_instances + + pred_depth_map = PixelData(data=torch.rand(1, h, w)) + + data_sample.pred_depth_map = pred_depth_map + + seg_local_visualizer.add_datasample(out_file, image, + data_sample) + self._assert_image_and_shape( + osp.join(tmp_dir, 'vis_data', 'vis_image', + out_file + '_0.png'), (h * 2, w * 2, 3)) + + seg_local_visualizer.add_datasample( + out_file, image, data_sample, draw_gt=False) + self._assert_image_and_shape( + osp.join(tmp_dir, 'vis_data', 'vis_image', + out_file + '_0.png'), (h * 2, w, 3)) + + if torch.cuda.is_available(): + test_add_datasample_forward_depth(gt_depth_map.cuda()) + test_add_datasample_forward_depth(gt_depth_map) diff --git a/tools/analysis_tools/confusion_matrix.py b/tools/analysis_tools/confusion_matrix.py index 9a87bc14c9b..39756cdfdd2 100644 --- a/tools/analysis_tools/confusion_matrix.py +++ b/tools/analysis_tools/confusion_matrix.py @@ -5,10 +5,14 @@ import matplotlib.pyplot as plt import numpy as np from matplotlib.ticker import MultipleLocator -from mmengine import Config, DictAction -from mmengine.utils import ProgressBar, load +from mmengine.config import Config, DictAction +from mmengine.registry import init_default_scope +from mmengine.utils import mkdir_or_exist, progressbar +from PIL import Image -from mmseg.datasets import build_dataset +from mmseg.registry import DATASETS + +init_default_scope('mmseg') def parse_args(): @@ -16,7 +20,7 @@ def parse_args(): description='Generate confusion matrix from segmentation results') parser.add_argument('config', help='test config file path') parser.add_argument( - 'prediction_path', help='prediction path where test .pkl result') + 'prediction_path', help='prediction path where test folder result') parser.add_argument( 'save_dir', help='directory where confusion matrix will be saved') parser.add_argument( @@ -50,15 +54,23 @@ def calculate_confusion_matrix(dataset, results): dataset (Dataset): Test or val dataset. results (list[ndarray]): A list of segmentation results in each image. """ - n = len(dataset.CLASSES) + n = len(dataset.METAINFO['classes']) confusion_matrix = np.zeros(shape=[n, n]) assert len(dataset) == len(results) - prog_bar = ProgressBar(len(results)) + ignore_index = dataset.ignore_index + reduce_zero_label = dataset.reduce_zero_label + prog_bar = progressbar.ProgressBar(len(results)) for idx, per_img_res in enumerate(results): res_segm = per_img_res - gt_segm = dataset.get_gt_seg_map_by_idx(idx) + gt_segm = dataset[idx]['data_samples'] \ + .gt_sem_seg.data.squeeze().numpy().astype(np.uint8) + gt_segm, res_segm = gt_segm.flatten(), res_segm.flatten() + if reduce_zero_label: + gt_segm = gt_segm - 1 + to_ignore = gt_segm == ignore_index + + gt_segm, res_segm = gt_segm[~to_ignore], res_segm[~to_ignore] inds = n * gt_segm + res_segm - inds = inds.flatten() mat = np.bincount(inds, minlength=n**2).reshape(n, n) confusion_matrix += mat prog_bar.update() @@ -70,7 +82,7 @@ def plot_confusion_matrix(confusion_matrix, save_dir=None, show=True, title='Normalized Confusion Matrix', - color_theme='winter'): + color_theme='OrRd'): """Draw confusion matrix with matplotlib. Args: @@ -89,14 +101,15 @@ def plot_confusion_matrix(confusion_matrix, num_classes = len(labels) fig, ax = plt.subplots( - figsize=(2 * num_classes, 2 * num_classes * 0.8), dpi=180) + figsize=(2 * num_classes, 2 * num_classes * 0.8), dpi=300) cmap = plt.get_cmap(color_theme) im = ax.imshow(confusion_matrix, cmap=cmap) - plt.colorbar(mappable=im, ax=ax) + colorbar = plt.colorbar(mappable=im, ax=ax) + colorbar.ax.tick_params(labelsize=20) # 设置 colorbar 标签的字体大小 - title_font = {'weight': 'bold', 'size': 12} + title_font = {'weight': 'bold', 'size': 20} ax.set_title(title, fontdict=title_font) - label_font = {'size': 10} + label_font = {'size': 40} plt.ylabel('Ground Truth Label', fontdict=label_font) plt.xlabel('Prediction Label', fontdict=label_font) @@ -116,8 +129,8 @@ def plot_confusion_matrix(confusion_matrix, # draw label ax.set_xticks(np.arange(num_classes)) ax.set_yticks(np.arange(num_classes)) - ax.set_xticklabels(labels) - ax.set_yticklabels(labels) + ax.set_xticklabels(labels, fontsize=20) + ax.set_yticklabels(labels, fontsize=20) ax.tick_params( axis='x', bottom=False, top=True, labelbottom=False, labeltop=True) @@ -135,13 +148,14 @@ def plot_confusion_matrix(confusion_matrix, ) if not np.isnan(confusion_matrix[i, j]) else -1), ha='center', va='center', - color='w', - size=7) + color='k', + size=20) ax.set_ylim(len(confusion_matrix) - 0.5, -0.5) # matplotlib>3.1.1 fig.tight_layout() if save_dir is not None: + mkdir_or_exist(save_dir) plt.savefig( os.path.join(save_dir, 'confusion_matrix.png'), format='png') if show: @@ -155,7 +169,12 @@ def main(): if args.cfg_options is not None: cfg.merge_from_dict(args.cfg_options) - results = load(args.prediction_path) + results = [] + for img in sorted(os.listdir(args.prediction_path)): + img = os.path.join(args.prediction_path, img) + image = Image.open(img) + image = np.copy(image) + results.append(image) assert isinstance(results, list) if isinstance(results[0], np.ndarray): @@ -163,17 +182,11 @@ def main(): else: raise TypeError('invalid type of prediction results') - if isinstance(cfg.data.test, dict): - cfg.data.test.test_mode = True - elif isinstance(cfg.data.test, list): - for ds_cfg in cfg.data.test: - ds_cfg.test_mode = True - - dataset = build_dataset(cfg.data.test) + dataset = DATASETS.build(cfg.test_dataloader.dataset) confusion_matrix = calculate_confusion_matrix(dataset, results) plot_confusion_matrix( confusion_matrix, - dataset.CLASSES, + dataset.METAINFO['classes'], save_dir=args.save_dir, show=args.show, title=args.title, diff --git a/tools/analysis_tools/visualization_cam.py b/tools/analysis_tools/visualization_cam.py new file mode 100644 index 00000000000..00cdb3e04ab --- /dev/null +++ b/tools/analysis_tools/visualization_cam.py @@ -0,0 +1,127 @@ +# Copyright (c) OpenMMLab. All rights reserved. +"""Use the pytorch-grad-cam tool to visualize Class Activation Maps (CAM). + +requirement: pip install grad-cam +""" + +from argparse import ArgumentParser + +import numpy as np +import torch +import torch.nn.functional as F +from mmengine import Config +from mmengine.model import revert_sync_batchnorm +from PIL import Image +from pytorch_grad_cam import GradCAM +from pytorch_grad_cam.utils.image import preprocess_image, show_cam_on_image + +from mmseg.apis import inference_model, init_model, show_result_pyplot +from mmseg.utils import register_all_modules + + +class SemanticSegmentationTarget: + """wrap the model. + + requirement: pip install grad-cam + + Args: + category (int): Visualization class. + mask (ndarray): Mask of class. + size (tuple): Image size. + """ + + def __init__(self, category, mask, size): + self.category = category + self.mask = torch.from_numpy(mask) + self.size = size + if torch.cuda.is_available(): + self.mask = self.mask.cuda() + + def __call__(self, model_output): + model_output = torch.unsqueeze(model_output, dim=0) + model_output = F.interpolate( + model_output, size=self.size, mode='bilinear') + model_output = torch.squeeze(model_output, dim=0) + + return (model_output[self.category, :, :] * self.mask).sum() + + +def main(): + parser = ArgumentParser() + parser.add_argument('img', help='Image file') + parser.add_argument('config', help='Config file') + parser.add_argument('checkpoint', help='Checkpoint file') + parser.add_argument( + '--out-file', + default='prediction.png', + help='Path to output prediction file') + parser.add_argument( + '--cam-file', default='vis_cam.png', help='Path to output cam file') + parser.add_argument( + '--target-layers', + default='backbone.layer4[2]', + help='Target layers to visualize CAM') + parser.add_argument( + '--category-index', default='7', help='Category to visualize CAM') + parser.add_argument( + '--device', default='cuda:0', help='Device used for inference') + args = parser.parse_args() + + # build the model from a config file and a checkpoint file + register_all_modules() + model = init_model(args.config, args.checkpoint, device=args.device) + if args.device == 'cpu': + model = revert_sync_batchnorm(model) + + # test a single image + result = inference_model(model, args.img) + + # show the results + show_result_pyplot( + model, + args.img, + result, + draw_gt=False, + show=False if args.out_file is not None else True, + out_file=args.out_file) + + # result data conversion + prediction_data = result.pred_sem_seg.data + pre_np_data = prediction_data.cpu().numpy().squeeze(0) + + target_layers = args.target_layers + target_layers = [eval(f'model.{target_layers}')] + + category = int(args.category_index) + mask_float = np.float32(pre_np_data == category) + + # data processing + image = np.array(Image.open(args.img).convert('RGB')) + height, width = image.shape[0], image.shape[1] + rgb_img = np.float32(image) / 255 + config = Config.fromfile(args.config) + image_mean = config.data_preprocessor['mean'] + image_std = config.data_preprocessor['std'] + input_tensor = preprocess_image( + rgb_img, + mean=[x / 255 for x in image_mean], + std=[x / 255 for x in image_std]) + + # Grad CAM(Class Activation Maps) + # Can also be LayerCAM, XGradCAM, GradCAMPlusPlus, EigenCAM, EigenGradCAM + targets = [ + SemanticSegmentationTarget(category, mask_float, (height, width)) + ] + with GradCAM( + model=model, + target_layers=target_layers, + use_cuda=torch.cuda.is_available()) as cam: + grayscale_cam = cam(input_tensor=input_tensor, targets=targets)[0, :] + cam_image = show_cam_on_image(rgb_img, grayscale_cam, use_rgb=True) + + # save cam file + Image.fromarray(cam_image).save(args.cam_file) + + +if __name__ == '__main__': + main() diff --git a/tools/dataset_converters/isaid.py b/tools/dataset_converters/isaid.py index 1da264d975e..1d5ccd9c776 100644 --- a/tools/dataset_converters/isaid.py +++ b/tools/dataset_converters/isaid.py @@ -91,7 +91,7 @@ def slide_crop_image(src_path, out_dir, mode, patch_H, patch_W, overlap): x_end) + '.png' # print(image) save_path_image = osp.join(out_dir, 'img_dir', mode, str(image)) - img_patch.save(save_path_image) + img_patch.save(save_path_image, format='BMP') def slide_crop_label(src_path, out_dir, mode, patch_H, patch_W, overlap): diff --git a/tools/dataset_converters/levircd.py b/tools/dataset_converters/levircd.py new file mode 100644 index 00000000000..8717f3e856b --- /dev/null +++ b/tools/dataset_converters/levircd.py @@ -0,0 +1,99 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import glob +import math +import os +import os.path as osp + +import mmcv +import numpy as np +from mmengine.utils import ProgressBar + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Convert levir-cd dataset to mmsegmentation format') + parser.add_argument('--dataset_path', help='potsdam folder path') + parser.add_argument('-o', '--out_dir', help='output path') + parser.add_argument( + '--clip_size', + type=int, + help='clipped size of image after preparation', + default=256) + parser.add_argument( + '--stride_size', + type=int, + help='stride of clipping original images', + default=256) + args = parser.parse_args() + return args + + +def main(): + args = parse_args() + input_folder = args.dataset_path + png_files = glob.glob( + os.path.join(input_folder, '**/*.png'), recursive=True) + output_folder = args.out_dir + prog_bar = ProgressBar(len(png_files)) + for png_file in png_files: + new_path = os.path.join( + output_folder, + os.path.relpath(os.path.dirname(png_file), input_folder)) + os.makedirs(os.path.dirname(new_path), exist_ok=True) + label = False + if 'label' in png_file: + label = True + clip_big_image(png_file, new_path, args, label) + prog_bar.update() + + +def clip_big_image(image_path, clip_save_dir, args, to_label=False): + image = mmcv.imread(image_path) + + h, w, c = image.shape + clip_size = args.clip_size + stride_size = args.stride_size + + num_rows = math.ceil((h - clip_size) / stride_size) if math.ceil( + (h - clip_size) / + stride_size) * stride_size + clip_size >= h else math.ceil( + (h - clip_size) / stride_size) + 1 + num_cols = math.ceil((w - clip_size) / stride_size) if math.ceil( + (w - clip_size) / + stride_size) * stride_size + clip_size >= w else math.ceil( + (w - clip_size) / stride_size) + 1 + + x, y = np.meshgrid(np.arange(num_cols + 1), np.arange(num_rows + 1)) + xmin = x * clip_size + ymin = y * clip_size + + xmin = xmin.ravel() + ymin = ymin.ravel() + xmin_offset = np.where(xmin + clip_size > w, w - xmin - clip_size, + np.zeros_like(xmin)) + ymin_offset = np.where(ymin + clip_size > h, h - ymin - clip_size, + np.zeros_like(ymin)) + boxes = np.stack([ + xmin + xmin_offset, ymin + ymin_offset, + np.minimum(xmin + clip_size, w), + np.minimum(ymin + clip_size, h) + ], + axis=1) + + if to_label: + image[image == 255] = 1 + image = image[:, :, 0] + for box in boxes: + start_x, start_y, end_x, end_y = box + clipped_image = image[start_y:end_y, start_x:end_x] \ + if to_label else image[start_y:end_y, start_x:end_x, :] + idx = osp.basename(image_path).split('.')[0] + mmcv.imwrite( + clipped_image.astype(np.uint8), + osp.join(clip_save_dir, + f'{idx}_{start_x}_{start_y}_{end_x}_{end_y}.png')) + + +if __name__ == '__main__': + main() diff --git a/tools/dataset_converters/nyu.py b/tools/dataset_converters/nyu.py new file mode 100644 index 00000000000..49e09e7af68 --- /dev/null +++ b/tools/dataset_converters/nyu.py @@ -0,0 +1,89 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os.path as osp +import shutil +import tempfile +import zipfile + +from mmengine.utils import mkdir_or_exist + + +def parse_args(): + parser = argparse.ArgumentParser( + description='Convert NYU Depth dataset to mmsegmentation format') + parser.add_argument('raw_data', help='the path of raw data') + parser.add_argument( + '-o', '--out_dir', help='output path', default='./data/nyu') + args = parser.parse_args() + return args + + +def reorganize(raw_data_dir: str, out_dir: str): + """Reorganize NYU Depth dataset files into the required directory + structure. + + Args: + raw_data_dir (str): Path to the raw data directory. + out_dir (str): Output directory for the organized dataset. + """ + + def move_data(data_list, dst_prefix, fname_func): + """Move data files from source to destination directory. + + Args: + data_list (list): List of data file paths. + dst_prefix (str): Prefix to be added to destination paths. + fname_func (callable): Function to process file names + """ + for data_item in data_list: + data_item = data_item.strip().strip('/') + new_item = fname_func(data_item) + shutil.move( + osp.join(raw_data_dir, data_item), + osp.join(out_dir, dst_prefix, new_item)) + + def process_phase(phase): + """Process a dataset phase (e.g., 'train' or 'test').""" + with open(osp.join(raw_data_dir, f'nyu_{phase}.txt')) as f: + data = filter(lambda x: len(x.strip()) > 0, f.readlines()) + data = map(lambda x: x.split()[:2], data) + images, annos = zip(*data) + + move_data(images, f'images/{phase}', + lambda x: x.replace('/rgb', '')) + move_data(annos, f'annotations/{phase}', + lambda x: x.replace('/sync_depth', '')) + + process_phase('train') + process_phase('test') + + +def main(): + args = parse_args() + + print('Making directories...') + mkdir_or_exist(args.out_dir) + for subdir in [ + 'images/train', 'images/test', 'annotations/train', + 'annotations/test' + ]: + mkdir_or_exist(osp.join(args.out_dir, subdir)) + + print('Generating images and annotations...') + + if args.raw_data.endswith('.zip'): + with tempfile.TemporaryDirectory() as tmp_dir: + zip_file = zipfile.ZipFile(args.raw_data) + zip_file.extractall(tmp_dir) + reorganize(osp.join(tmp_dir, 'nyu'), args.out_dir) + else: + assert osp.isdir( + args.raw_data + ), 'the argument --raw-data should be either a zip file or directory.' + reorganize(args.raw_data, args.out_dir) + + print('Done!') + + +if __name__ == '__main__': + main() diff --git a/tools/misc/publish_model.py b/tools/misc/publish_model.py index c1bbc9ac1ad..e035ad90e85 100644 --- a/tools/misc/publish_model.py +++ b/tools/misc/publish_model.py @@ -1,9 +1,12 @@ # Copyright (c) OpenMMLab. All rights reserved. import argparse import subprocess +from hashlib import sha256 import torch +BLOCK_SIZE = 128 * 1024 + def parse_args(): parser = argparse.ArgumentParser( @@ -14,6 +17,17 @@ def parse_args(): return args +def sha256sum(filename: str) -> str: + """Compute SHA256 message digest from a file.""" + hash_func = sha256() + byte_array = bytearray(BLOCK_SIZE) + memory_view = memoryview(byte_array) + with open(filename, 'rb', buffering=0) as file: + for block in iter(lambda: file.readinto(memory_view), 0): + hash_func.update(memory_view[:block]) + return hash_func.hexdigest() + + def process_checkpoint(in_file, out_file): checkpoint = torch.load(in_file, map_location='cpu') # remove optimizer for smaller file size @@ -22,7 +36,7 @@ def process_checkpoint(in_file, out_file): # if it is necessary to remove some sensitive data in checkpoint['meta'], # add the code here. torch.save(checkpoint, out_file) - sha = subprocess.check_output(['sha256sum', out_file]).decode() + sha = sha256sum(in_file) final_file = out_file.rstrip('.pth') + f'-{sha[:8]}.pth' subprocess.Popen(['mv', out_file, final_file]) diff --git a/tools/model_converters/clip2mmseg.py b/tools/model_converters/clip2mmseg.py new file mode 100644 index 00000000000..9a97e4b04ab --- /dev/null +++ b/tools/model_converters/clip2mmseg.py @@ -0,0 +1,163 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os.path as osp +from collections import OrderedDict + +import mmengine +import torch +from mmengine.runner import CheckpointLoader + + +def convert_vitlayer(paras): + new_para_name = '' + if paras[0] == 'ln_1': + new_para_name = '.'.join(['ln1'] + paras[1:]) + elif paras[0] == 'attn': + new_para_name = '.'.join(['attn.attn'] + paras[1:]) + elif paras[0] == 'ln_2': + new_para_name = '.'.join(['ln2'] + paras[1:]) + elif paras[0] == 'mlp': + if paras[1] == 'c_fc': + new_para_name = '.'.join(['ffn.layers.0.0'] + paras[-1:]) + else: + new_para_name = '.'.join(['ffn.layers.1'] + paras[-1:]) + else: + print(f'Wrong for {paras}') + return new_para_name + + +def convert_translayer(paras): + new_para_name = '' + if paras[0] == 'attn': + new_para_name = '.'.join(['attentions.0.attn'] + paras[1:]) + elif paras[0] == 'ln_1': + new_para_name = '.'.join(['norms.0'] + paras[1:]) + elif paras[0] == 'ln_2': + new_para_name = '.'.join(['norms.1'] + paras[1:]) + elif paras[0] == 'mlp': + if paras[1] == 'c_fc': + new_para_name = '.'.join(['ffns.0.layers.0.0'] + paras[2:]) + elif paras[1] == 'c_proj': + new_para_name = '.'.join(['ffns.0.layers.1'] + paras[2:]) + else: + print(f'Wrong for {paras}') + else: + print(f'Wrong for {paras}') + return new_para_name + + +def convert_key_name(ckpt, visual_split): + new_ckpt = OrderedDict() + for k, v in ckpt.items(): + key_list = k.split('.') + if key_list[0] == 'visual': + new_transform_name = 'image_encoder' + if key_list[1] == 'class_embedding': + new_name = '.'.join([new_transform_name, 'cls_token']) + elif key_list[1] == 'positional_embedding': + new_name = '.'.join([new_transform_name, 'pos_embed']) + elif key_list[1] == 'conv1': + new_name = '.'.join([ + new_transform_name, 'patch_embed.projection', key_list[2] + ]) + elif key_list[1] == 'ln_pre': + new_name = '.'.join( + [new_transform_name, key_list[1], key_list[2]]) + elif key_list[1] == 'transformer': + new_layer_name = 'layers' + layer_index = key_list[3] + paras = key_list[4:] + if int(layer_index) < visual_split: + new_para_name = convert_vitlayer(paras) + new_name = '.'.join([ + new_transform_name, new_layer_name, layer_index, + new_para_name + ]) + else: + new_para_name = convert_translayer(paras) + new_transform_name = 'decode_head.rec_with_attnbias' + new_layer_name = 'layers' + layer_index = str(int(layer_index) - visual_split) + new_name = '.'.join([ + new_transform_name, new_layer_name, layer_index, + new_para_name + ]) + elif key_list[1] == 'proj': + new_name = 'decode_head.rec_with_attnbias.proj.weight' + elif key_list[1] == 'ln_post': + new_name = k.replace('visual', 'decode_head.rec_with_attnbias') + else: + print(f'pop parameter: {k}') + continue + else: + text_encoder_name = 'text_encoder' + if key_list[0] == 'transformer': + layer_name = 'transformer' + layer_index = key_list[2] + paras = key_list[3:] + new_para_name = convert_translayer(paras) + new_name = '.'.join([ + text_encoder_name, layer_name, layer_index, new_para_name + ]) + elif key_list[0] in [ + 'positional_embedding', 'text_projection', 'bg_embed', + 'attn_mask', 'logit_scale', 'token_embedding', 'ln_final' + ]: + new_name = 'text_encoder.' + k + else: + print(f'pop parameter: {k}') + continue + new_ckpt[new_name] = v + + return new_ckpt + + +def convert_tensor(ckpt): + cls_token = ckpt['image_encoder.cls_token'] + new_cls_token = cls_token.unsqueeze(0).unsqueeze(0) + ckpt['image_encoder.cls_token'] = new_cls_token + pos_embed = ckpt['image_encoder.pos_embed'] + new_pos_embed = pos_embed.unsqueeze(0) + ckpt['image_encoder.pos_embed'] = new_pos_embed + proj_weight = ckpt['decode_head.rec_with_attnbias.proj.weight'] + new_proj_weight = proj_weight.transpose(1, 0) + ckpt['decode_head.rec_with_attnbias.proj.weight'] = new_proj_weight + return ckpt + + +def main(): + parser = argparse.ArgumentParser( + description='Convert keys in timm pretrained vit models to ' + 'MMSegmentation style.') + parser.add_argument('src', help='src model path or url') + # The dst path must be a full path of the new checkpoint. + parser.add_argument('dst', help='save path') + args = parser.parse_args() + + if any([s in args.src for s in ['B-16', 'b16', 'base_patch16']]): + visual_split = 9 + elif any([s in args.src for s in ['L-14', 'l14', 'large_patch14']]): + visual_split = 18 + else: + print('Make sure the clip model is ViT-B/16 or ViT-L/14!') + visual_split = -1 + checkpoint = CheckpointLoader.load_checkpoint(args.src, map_location='cpu') + if isinstance(checkpoint, torch.jit.RecursiveScriptModule): + state_dict = checkpoint.state_dict() + else: + if 'state_dict' in checkpoint: + # timm checkpoint + state_dict = checkpoint['state_dict'] + elif 'model' in checkpoint: + # deit checkpoint + state_dict = checkpoint['model'] + else: + state_dict = checkpoint + weight = convert_key_name(state_dict, visual_split) + weight = convert_tensor(weight) + mmengine.mkdir_or_exist(osp.dirname(args.dst)) + torch.save(weight, args.dst) + + +if __name__ == '__main__': + main() diff --git a/tools/model_converters/san2mmseg.py b/tools/model_converters/san2mmseg.py new file mode 100644 index 00000000000..301a46608e0 --- /dev/null +++ b/tools/model_converters/san2mmseg.py @@ -0,0 +1,220 @@ +# Copyright (c) OpenMMLab. All rights reserved. +import argparse +import os.path as osp +from collections import OrderedDict + +import mmengine +import torch +from mmengine.runner import CheckpointLoader + + +def convert_key_name(ckpt): + new_ckpt = OrderedDict() + + for k, v in ckpt.items(): + key_list = k.split('.') + if key_list[0] == 'clip_visual_extractor': + new_transform_name = 'image_encoder' + if key_list[1] == 'class_embedding': + new_name = '.'.join([new_transform_name, 'cls_token']) + elif key_list[1] == 'positional_embedding': + new_name = '.'.join([new_transform_name, 'pos_embed']) + elif key_list[1] == 'conv1': + new_name = '.'.join([ + new_transform_name, 'patch_embed.projection', key_list[2] + ]) + elif key_list[1] == 'ln_pre': + new_name = '.'.join( + [new_transform_name, key_list[1], key_list[2]]) + elif key_list[1] == 'resblocks': + new_layer_name = 'layers' + layer_index = key_list[2] + paras = key_list[3:] + if paras[0] == 'ln_1': + new_para_name = '.'.join(['ln1'] + key_list[4:]) + elif paras[0] == 'attn': + new_para_name = '.'.join(['attn.attn'] + key_list[4:]) + elif paras[0] == 'ln_2': + new_para_name = '.'.join(['ln2'] + key_list[4:]) + elif paras[0] == 'mlp': + if paras[1] == 'c_fc': + new_para_name = '.'.join(['ffn.layers.0.0'] + + key_list[-1:]) + else: + new_para_name = '.'.join(['ffn.layers.1'] + + key_list[-1:]) + new_name = '.'.join([ + new_transform_name, new_layer_name, layer_index, + new_para_name + ]) + elif key_list[0] == 'side_adapter_network': + decode_head_name = 'decode_head' + module_name = 'side_adapter_network' + if key_list[1] == 'vit_model': + if key_list[2] == 'blocks': + layer_name = 'encode_layers' + layer_index = key_list[3] + paras = key_list[4:] + if paras[0] == 'norm1': + new_para_name = '.'.join(['ln1'] + key_list[5:]) + elif paras[0] == 'attn': + new_para_name = '.'.join(key_list[4:]) + new_para_name = new_para_name.replace( + 'attn.qkv.', 'attn.attn.in_proj_') + new_para_name = new_para_name.replace( + 'attn.proj', 'attn.attn.out_proj') + elif paras[0] == 'norm2': + new_para_name = '.'.join(['ln2'] + key_list[5:]) + elif paras[0] == 'mlp': + new_para_name = '.'.join(['ffn'] + key_list[5:]) + new_para_name = new_para_name.replace( + 'fc1', 'layers.0.0') + new_para_name = new_para_name.replace( + 'fc2', 'layers.1') + else: + print(f'Wrong for {k}') + new_name = '.'.join([ + decode_head_name, module_name, layer_name, layer_index, + new_para_name + ]) + elif key_list[2] == 'pos_embed': + new_name = '.'.join( + [decode_head_name, module_name, 'pos_embed']) + elif key_list[2] == 'patch_embed': + new_name = '.'.join([ + decode_head_name, module_name, 'patch_embed', + 'projection', key_list[4] + ]) + else: + print(f'Wrong for {k}') + elif key_list[1] == 'query_embed' or key_list[ + 1] == 'query_pos_embed': + new_name = '.'.join( + [decode_head_name, module_name, key_list[1]]) + elif key_list[1] == 'fusion_layers': + layer_name = 'conv_clips' + layer_index = key_list[2][-1] + paras = '.'.join(key_list[3:]) + new_para_name = paras.replace('input_proj.0', '0') + new_para_name = new_para_name.replace('input_proj.1', '1.conv') + new_name = '.'.join([ + decode_head_name, module_name, layer_name, layer_index, + new_para_name + ]) + elif key_list[1] == 'mask_decoder': + new_name = 'decode_head.' + k + else: + print(f'Wrong for {k}') + elif key_list[0] == 'clip_rec_head': + module_name = 'rec_with_attnbias' + if key_list[1] == 'proj': + new_name = '.'.join( + [decode_head_name, module_name, 'proj.weight']) + elif key_list[1] == 'ln_post': + new_name = '.'.join( + [decode_head_name, module_name, 'ln_post', key_list[2]]) + elif key_list[1] == 'resblocks': + new_layer_name = 'layers' + layer_index = key_list[2] + paras = key_list[3:] + if paras[0] == 'ln_1': + new_para_name = '.'.join(['norms.0'] + paras[1:]) + elif paras[0] == 'attn': + new_para_name = '.'.join(['attentions.0.attn'] + paras[1:]) + elif paras[0] == 'ln_2': + new_para_name = '.'.join(['norms.1'] + paras[1:]) + elif paras[0] == 'mlp': + if paras[1] == 'c_fc': + new_para_name = '.'.join(['ffns.0.layers.0.0'] + + paras[2:]) + elif paras[1] == 'c_proj': + new_para_name = '.'.join(['ffns.0.layers.1'] + + paras[2:]) + else: + print(f'Wrong for {k}') + new_name = '.'.join([ + decode_head_name, module_name, new_layer_name, layer_index, + new_para_name + ]) + else: + print(f'Wrong for {k}') + elif key_list[0] == 'ov_classifier': + text_encoder_name = 'text_encoder' + if key_list[1] == 'transformer': + layer_name = 'transformer' + layer_index = key_list[3] + paras = key_list[4:] + if paras[0] == 'attn': + new_para_name = '.'.join(['attentions.0.attn'] + paras[1:]) + elif paras[0] == 'ln_1': + new_para_name = '.'.join(['norms.0'] + paras[1:]) + elif paras[0] == 'ln_2': + new_para_name = '.'.join(['norms.1'] + paras[1:]) + elif paras[0] == 'mlp': + if paras[1] == 'c_fc': + new_para_name = '.'.join(['ffns.0.layers.0.0'] + + paras[2:]) + elif paras[1] == 'c_proj': + new_para_name = '.'.join(['ffns.0.layers.1'] + + paras[2:]) + else: + print(f'Wrong for {k}') + else: + print(f'Wrong for {k}') + new_name = '.'.join([ + text_encoder_name, layer_name, layer_index, new_para_name + ]) + elif key_list[1] in [ + 'positional_embedding', 'text_projection', 'bg_embed', + 'attn_mask', 'logit_scale', 'token_embedding', 'ln_final' + ]: + new_name = k.replace('ov_classifier', 'text_encoder') + else: + print(f'Wrong for {k}') + elif key_list[0] == 'criterion': + new_name = k + else: + print(f'Wrong for {k}') + new_ckpt[new_name] = v + return new_ckpt + + +def convert_tensor(ckpt): + cls_token = ckpt['image_encoder.cls_token'] + new_cls_token = cls_token.unsqueeze(0).unsqueeze(0) + ckpt['image_encoder.cls_token'] = new_cls_token + pos_embed = ckpt['image_encoder.pos_embed'] + new_pos_embed = pos_embed.unsqueeze(0) + ckpt['image_encoder.pos_embed'] = new_pos_embed + proj_weight = ckpt['decode_head.rec_with_attnbias.proj.weight'] + new_proj_weight = proj_weight.transpose(1, 0) + ckpt['decode_head.rec_with_attnbias.proj.weight'] = new_proj_weight + return ckpt + + +def main(): + parser = argparse.ArgumentParser( + description='Convert keys in timm pretrained vit models to ' + 'MMSegmentation style.') + parser.add_argument('src', help='src model path or url') + # The dst path must be a full path of the new checkpoint. + parser.add_argument('dst', help='save path') + args = parser.parse_args() + + checkpoint = CheckpointLoader.load_checkpoint(args.src, map_location='cpu') + if 'state_dict' in checkpoint: + # timm checkpoint + state_dict = checkpoint['state_dict'] + elif 'model' in checkpoint: + # deit checkpoint + state_dict = checkpoint['model'] + else: + state_dict = checkpoint + weight = convert_key_name(state_dict) + weight = convert_tensor(weight) + mmengine.mkdir_or_exist(osp.dirname(args.dst)) + torch.save(weight, args.dst) + + +if __name__ == '__main__': + main() diff --git a/tools/test.py b/tools/test.py index 64da2bc2616..0d7f39b3a8b 100644 --- a/tools/test.py +++ b/tools/test.py @@ -47,7 +47,10 @@ def parse_args(): help='job launcher') parser.add_argument( '--tta', action='store_true', help='Test time augmentation') - parser.add_argument('--local_rank', type=int, default=0) + # When using PyTorch version >= 2.0.0, the `torch.distributed.launch` + # will pass the `--local-rank` parameter to `tools/train.py` instead + # of `--local_rank`. + parser.add_argument('--local_rank', '--local-rank', type=int, default=0) args = parser.parse_args() if 'LOCAL_RANK' not in os.environ: os.environ['LOCAL_RANK'] = str(args.local_rank) @@ -65,8 +68,8 @@ def trigger_visualization_hook(cfg, args): visualization_hook['show'] = True visualization_hook['wait_time'] = args.wait_time if args.show_dir: - visulizer = cfg.visualizer - visulizer['save_dir'] = args.show_dir + visualizer = cfg.visualizer + visualizer['save_dir'] = args.show_dir else: raise RuntimeError( 'VisualizationHook must be included in default_hooks.' diff --git a/tools/train.py b/tools/train.py index 17213066648..10fdaa1874b 100644 --- a/tools/train.py +++ b/tools/train.py @@ -40,7 +40,10 @@ def parse_args(): choices=['none', 'pytorch', 'slurm', 'mpi'], default='none', help='job launcher') - parser.add_argument('--local_rank', type=int, default=0) + # When using PyTorch version >= 2.0.0, the `torch.distributed.launch` + # will pass the `--local-rank` parameter to `tools/train.py` instead + # of `--local_rank`. + parser.add_argument('--local_rank', '--local-rank', type=int, default=0) args = parser.parse_args() if 'LOCAL_RANK' not in os.environ: os.environ['LOCAL_RANK'] = str(args.local_rank)