From bebe69724761f6a9de7b752c84cd9f8e231f0ff3 Mon Sep 17 00:00:00 2001 From: "hongliang.yuan" Date: Thu, 13 Mar 2025 15:19:03 +0800 Subject: [PATCH] del useless code in acmix acnet fasternet repvgg repmlp Swin-Transformer wavemlp_pytorch --- cv/classification/acmix/pytorch/README.md | 13 +- .../acmix/pytorch/Swin-Transformer/README.md | 69 -- .../acmix/pytorch/Swin-Transformer/build.py | 303 ----- .../acmix/pytorch/Swin-Transformer/config.py | 236 ---- .../acmix_swin_small_patch4_window7_224.yaml | 12 - .../acmix_swin_tiny_patch4_window7_224.yaml | 12 - .../swin_base_patch4_window12_384.yaml | 13 - .../configs/swin_base_patch4_window7_224.yaml | 9 - .../swin_large_patch4_window12_384.yaml | 13 - .../swin_large_patch4_window7_224.yaml | 9 - .../swin_small_patch4_window7_224.yaml | 9 - .../configs/swin_tiny_patch4_window7_224.yaml | 9 - .../pytorch/Swin-Transformer/data/__init__.py | 1 - .../pytorch/Swin-Transformer/data/build.py | 128 --- .../data/cached_image_folder.py | 251 ----- .../pytorch/Swin-Transformer/data/samplers.py | 29 - .../Swin-Transformer/data/zipreader.py | 103 -- .../acmix/pytorch/Swin-Transformer/logger.py | 41 - .../pytorch/Swin-Transformer/lr_scheduler.py | 102 -- .../acmix/pytorch/Swin-Transformer/main.py | 383 ------- .../Swin-Transformer/models/__init__.py | 1 - .../pytorch/Swin-Transformer/models/build.py | 51 - .../models/swin_transformer.py | 590 ---------- .../models/swin_transformer_acmix.py | 650 ----------- .../pytorch/Swin-Transformer/optimizer.py | 57 - .../acmix/pytorch/Swin-Transformer/utils.py | 92 -- .../acmix/pytorch/figure/main.png | Bin 282015 -> 0 bytes .../acmix/pytorch/figure/result.png | Bin 152627 -> 0 bytes .../acmix/pytorch/figure/shift.png | Bin 116502 -> 0 bytes cv/classification/acmix/pytorch/run.sh | 23 - cv/classification/acnet/pytorch/README.md | 4 +- cv/classification/fasternet/pytorch/README.md | 3 + .../fasternet/pytorch/cfg/fasternet_l.yaml | 72 -- .../fasternet/pytorch/cfg/fasternet_m.yaml | 72 -- .../fasternet/pytorch/cfg/fasternet_s.yaml | 72 -- .../fasternet/pytorch/cfg/fasternet_t0.yaml | 72 -- .../fasternet/pytorch/cfg/fasternet_t1.yaml | 72 -- .../fasternet/pytorch/cfg/fasternet_t2.yaml | 72 -- .../fasternet/pytorch/data/__init__.py | 0 .../pytorch/data/custom_imagenet_data.py | 237 ---- .../fasternet/pytorch/data/data_api.py | 47 - .../fasternet/pytorch/detection/README.MD | 75 -- .../pytorch/detection/backbones/__init__.py | 1 - .../pytorch/detection/backbones/fasternet.py | 59 - .../fasternet/pytorch/detection/benchmark.py | 197 ---- .../configs/_base_/datasets/coco_detection.py | 49 - .../configs/_base_/datasets/coco_instance.py | 49 - .../configs/_base_/default_runtime.py | 27 - .../_base_/models/mask_rcnn_r50_fpn.py | 120 -- .../configs/_base_/schedules/schedule_1x.py | 11 - .../configs/_base_/schedules/schedule_20e.py | 11 - .../configs/_base_/schedules/schedule_2x.py | 11 - .../mask_rcnn_fasternet_l_fpn_1x_coco.py | 22 - .../mask_rcnn_fasternet_m_fpn_1x_coco.py | 22 - .../mask_rcnn_fasternet_s_fpn_1x_coco.py | 22 - .../fasternet/pytorch/detection/dist_test.sh | 22 - .../fasternet/pytorch/detection/dist_train.sh | 20 - .../fasternet/pytorch/detection/get_flops.py | 112 -- .../fasternet/pytorch/detection/test.py | 276 ----- .../fasternet/pytorch/detection/train.py | 243 ---- .../fasternet/pytorch/models/__init__.py | 1 - .../fasternet/pytorch/models/fasternet.py | 360 ------ .../fasternet/pytorch/models/model_api.py | 158 --- .../fasternet/pytorch/models/registry.py | 9 - .../fasternet/pytorch/requirements.txt | 18 +- .../fasternet/pytorch/train_test.py | 152 --- .../fasternet/pytorch/utils/__init__.py | 0 .../fasternet/pytorch/utils/fuse_conv_bn.py | 60 - .../fasternet/pytorch/utils/loss.py | 71 -- .../fasternet/pytorch/utils/utils.py | 188 ---- cv/classification/repmlp/pytorch/LICENSE | 21 - cv/classification/repmlp/pytorch/README.md | 9 + cv/classification/repmlp/pytorch/config.py | 215 ---- cv/classification/repmlp/pytorch/convert.py | 33 - cv/classification/repmlp/pytorch/cutout.py | 55 - .../repmlp/pytorch/data/__init__.py | 1 - .../repmlp/pytorch/data/build.py | 195 ---- .../pytorch/data/cached_image_folder.py | 252 ----- .../repmlp/pytorch/data/samplers.py | 30 - .../repmlp/pytorch/data/zipreader.py | 104 -- cv/classification/repmlp/pytorch/logger.py | 42 - .../repmlp/pytorch/lr_scheduler.py | 102 -- .../repmlp/pytorch/main_repmlp.py | 417 ------- cv/classification/repmlp/pytorch/optimizer.py | 68 -- cv/classification/repmlp/pytorch/randaug.py | 407 ------- cv/classification/repmlp/pytorch/repmlpnet.py | 325 ------ cv/classification/repmlp/pytorch/test.py | 135 --- cv/classification/repmlp/pytorch/utils.py | 193 ---- cv/classification/repvgg/pytorch/LICENSE | 21 - cv/classification/repvgg/pytorch/README.md | 19 +- .../repvgg/pytorch/data/__init__.py | 1 - .../repvgg/pytorch/data/build.py | 188 ---- .../pytorch/data/cached_image_folder.py | 244 ---- .../repvgg/pytorch/data/lmdb_dataset.py | 164 --- .../repvgg/pytorch/data/samplers.py | 21 - .../repvgg/pytorch/data/zipreader.py | 96 -- .../repvgg/pytorch/example_pspnet.py | 161 --- .../pytorch/jizhi_submit_train_repvgg.py | 34 - cv/classification/repvgg/pytorch/main.py | 414 ------- .../pytorch/quantization/quant_qat_train.py | 426 ------- .../pytorch/quantization/repvgg_quantized.py | 63 -- cv/classification/repvgg/pytorch/repvgg.py | 303 ----- .../repvgg/pytorch/repvggplus.py | 293 ----- .../repvgg/pytorch/repvggplus_custom_L2.py | 268 ----- cv/classification/repvgg/pytorch/se_block.py | 22 - .../repvgg/pytorch/tools/convert.py | 46 - .../repvgg/pytorch/tools/insert_bn.py | 217 ---- .../repvgg/pytorch/tools/verify.py | 30 - .../repvgg/pytorch/train/config.py | 217 ---- .../repvgg/pytorch/train/cutout.py | 55 - .../repvgg/pytorch/train/logger.py | 41 - .../repvgg/pytorch/train/lr_scheduler.py | 101 -- .../repvgg/pytorch/train/optimizer.py | 71 -- .../repvgg/pytorch/train/randaug.py | 407 ------- cv/classification/repvgg/pytorch/utils.py | 249 ---- .../swin_transformer/pytorch/.gitignore | 135 --- .../pytorch/CODE_OF_CONDUCT.md | 9 - .../swin_transformer/pytorch/LICENSE | 21 - .../swin_transformer/pytorch/MODELHUB.md | 71 -- .../swin_transformer/pytorch/README.md | 11 +- .../swin_transformer/pytorch/README_IX.md | 18 - .../swin_transformer/pytorch/SECURITY.md | 41 - .../swin_transformer/pytorch/SUPPORT.md | 25 - .../swin_transformer/pytorch/config.py | 318 ------ ..._patch4_window12_384_22kto1k_finetune.yaml | 20 - ...win_base_patch4_window12_384_finetune.yaml | 20 - .../swin/swin_base_patch4_window7_224.yaml | 9 - .../swin_base_patch4_window7_224_22k.yaml | 18 - ...e_patch4_window7_224_22kto1k_finetune.yaml | 16 - ..._patch4_window12_384_22kto1k_finetune.yaml | 20 - .../swin_large_patch4_window7_224_22k.yaml | 18 - ...e_patch4_window7_224_22kto1k_finetune.yaml | 16 - .../swin/swin_small_patch4_window7_224.yaml | 9 - .../swin_small_patch4_window7_224_22k.yaml | 18 - ...l_patch4_window7_224_22kto1k_finetune.yaml | 16 - .../swin_tiny_c24_patch4_window8_256.yaml | 11 - .../swin/swin_tiny_patch4_window7_224.yaml | 9 - .../swin_tiny_patch4_window7_224_22k.yaml | 18 - ...y_patch4_window7_224_22kto1k_finetune.yaml | 16 - .../swin_mlp_base_patch4_window7_224.yaml | 9 - .../swin_mlp_tiny_c12_patch4_window8_256.yaml | 11 - .../swin_mlp_tiny_c24_patch4_window8_256.yaml | 11 - .../swin_mlp_tiny_c6_patch4_window8_256.yaml | 11 - ...atch4_window12_192_16expert_32gpu_22k.yaml | 31 - ...atch4_window12_192_32expert_32gpu_22k.yaml | 31 - ...patch4_window12_192_8expert_32gpu_22k.yaml | 31 - ..._192_cosine_router_32expert_32gpu_22k.yaml | 32 - ...patch4_window12_192_densebaseline_22k.yaml | 26 - ...atch4_window12_192_16expert_32gpu_22k.yaml | 31 - ...atch4_window12_192_32expert_32gpu_22k.yaml | 31 - ...atch4_window12_192_64expert_64gpu_22k.yaml | 31 - ...patch4_window12_192_8expert_32gpu_22k.yaml | 31 - ..._192_cosine_router_32expert_32gpu_22k.yaml | 32 - ...patch4_window12_192_densebaseline_22k.yaml | 26 - .../swinv2_base_patch4_window12_192_22k.yaml | 19 - ...tch4_window12to16_192to256_22kto1k_ft.yaml | 19 - ...tch4_window12to24_192to384_22kto1k_ft.yaml | 21 - .../swinv2_base_patch4_window16_256.yaml | 11 - .../swinv2_base_patch4_window8_256.yaml | 11 - .../swinv2_large_patch4_window12_192_22k.yaml | 19 - ...tch4_window12to16_192to256_22kto1k_ft.yaml | 19 - ...tch4_window12to24_192to384_22kto1k_ft.yaml | 21 - .../swinv2_small_patch4_window16_256.yaml | 11 - .../swinv2_small_patch4_window8_256.yaml | 11 - .../swinv2_tiny_patch4_window16_256.yaml | 11 - .../swinv2_tiny_patch4_window8_256.yaml | 11 - .../swin_transformer/pytorch/data/__init__.py | 3 - .../swin_transformer/pytorch/data/build.py | 162 --- .../pytorch/data/cached_image_folder.py | 252 ----- .../pytorch/data/imagenet22k_dataset.py | 55 - .../pytorch/data/map22kto1k.txt | 1000 ----------------- .../swin_transformer/pytorch/data/samplers.py | 29 - .../pytorch/data/zipreader.py | 103 -- .../pytorch/figures/teaser.png | Bin 930622 -> 0 bytes .../swin_transformer/pytorch/get_started.md | 268 ----- .../pytorch/kernels/window_process/setup.py | 12 - .../window_process/swin_window_process.cpp | 132 --- .../swin_window_process_kernel.cu | 323 ------ .../kernels/window_process/unit_test.py | 250 ----- .../kernels/window_process/window_process.py | 63 -- .../swin_transformer/pytorch/logger.py | 41 - .../swin_transformer/pytorch/lr_scheduler.py | 104 -- .../swin_transformer/pytorch/main.py | 345 ------ .../swin_transformer/pytorch/main_moe.py | 369 ------ .../pytorch/models/__init__.py | 1 - .../swin_transformer/pytorch/models/build.py | 104 -- .../pytorch/models/swin_mlp.py | 468 -------- .../pytorch/models/swin_transformer.py | 614 ---------- .../pytorch/models/swin_transformer_moe.py | 824 -------------- .../pytorch/models/swin_transformer_v2.py | 633 ----------- .../swin_transformer/pytorch/optimizer.py | 59 - .../swin_transformer/pytorch/utils.py | 223 ---- .../swin_transformer/pytorch/utils_moe.py | 241 ---- cv/classification/wavemlp/pytorch/.gitignore | 1 - cv/classification/wavemlp/pytorch/License.txt | 204 ---- cv/classification/wavemlp/pytorch/README.md | 15 +- ...HIRD PARTY OPEN SOURCE SOFTWARE NOTICE.txt | 853 -------------- .../wavemlp/pytorch/data/myloader.py | 160 --- .../wavemlp/pytorch/data/rasampler.py | 67 -- .../wavemlp/pytorch/figures/patm.PNG | Bin 84733 -> 0 bytes .../wavemlp/pytorch/figures/res.PNG | Bin 100803 -> 0 bytes .../wavemlp/pytorch/models/wavemlp.py | 330 ------ cv/classification/wavemlp/pytorch/run.sh | 43 - cv/classification/wavemlp/pytorch/train.py | 858 -------------- 204 files changed, 60 insertions(+), 23665 deletions(-) delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/README.md delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/build.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/config.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_small_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_tiny_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window12_384.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window12_384.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_small_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_tiny_patch4_window7_224.yaml delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/data/__init__.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/data/build.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/data/cached_image_folder.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/data/samplers.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/data/zipreader.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/logger.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/lr_scheduler.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/main.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/models/__init__.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/models/build.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer_acmix.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/optimizer.py delete mode 100644 cv/classification/acmix/pytorch/Swin-Transformer/utils.py delete mode 100644 cv/classification/acmix/pytorch/figure/main.png delete mode 100644 cv/classification/acmix/pytorch/figure/result.png delete mode 100644 cv/classification/acmix/pytorch/figure/shift.png delete mode 100644 cv/classification/acmix/pytorch/run.sh delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml delete mode 100644 cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml delete mode 100644 cv/classification/fasternet/pytorch/data/__init__.py delete mode 100644 cv/classification/fasternet/pytorch/data/custom_imagenet_data.py delete mode 100644 cv/classification/fasternet/pytorch/data/data_api.py delete mode 100644 cv/classification/fasternet/pytorch/detection/README.MD delete mode 100644 cv/classification/fasternet/pytorch/detection/backbones/__init__.py delete mode 100644 cv/classification/fasternet/pytorch/detection/backbones/fasternet.py delete mode 100644 cv/classification/fasternet/pytorch/detection/benchmark.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py delete mode 100644 cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py delete mode 100755 cv/classification/fasternet/pytorch/detection/dist_test.sh delete mode 100755 cv/classification/fasternet/pytorch/detection/dist_train.sh delete mode 100644 cv/classification/fasternet/pytorch/detection/get_flops.py delete mode 100644 cv/classification/fasternet/pytorch/detection/test.py delete mode 100644 cv/classification/fasternet/pytorch/detection/train.py delete mode 100644 cv/classification/fasternet/pytorch/models/__init__.py delete mode 100644 cv/classification/fasternet/pytorch/models/fasternet.py delete mode 100644 cv/classification/fasternet/pytorch/models/model_api.py delete mode 100644 cv/classification/fasternet/pytorch/models/registry.py delete mode 100644 cv/classification/fasternet/pytorch/train_test.py delete mode 100644 cv/classification/fasternet/pytorch/utils/__init__.py delete mode 100644 cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py delete mode 100644 cv/classification/fasternet/pytorch/utils/loss.py delete mode 100644 cv/classification/fasternet/pytorch/utils/utils.py delete mode 100644 cv/classification/repmlp/pytorch/LICENSE delete mode 100644 cv/classification/repmlp/pytorch/config.py delete mode 100644 cv/classification/repmlp/pytorch/convert.py delete mode 100644 cv/classification/repmlp/pytorch/cutout.py delete mode 100644 cv/classification/repmlp/pytorch/data/__init__.py delete mode 100644 cv/classification/repmlp/pytorch/data/build.py delete mode 100644 cv/classification/repmlp/pytorch/data/cached_image_folder.py delete mode 100644 cv/classification/repmlp/pytorch/data/samplers.py delete mode 100644 cv/classification/repmlp/pytorch/data/zipreader.py delete mode 100644 cv/classification/repmlp/pytorch/logger.py delete mode 100644 cv/classification/repmlp/pytorch/lr_scheduler.py delete mode 100644 cv/classification/repmlp/pytorch/main_repmlp.py delete mode 100644 cv/classification/repmlp/pytorch/optimizer.py delete mode 100644 cv/classification/repmlp/pytorch/randaug.py delete mode 100644 cv/classification/repmlp/pytorch/repmlpnet.py delete mode 100644 cv/classification/repmlp/pytorch/test.py delete mode 100644 cv/classification/repmlp/pytorch/utils.py delete mode 100755 cv/classification/repvgg/pytorch/LICENSE delete mode 100755 cv/classification/repvgg/pytorch/data/__init__.py delete mode 100755 cv/classification/repvgg/pytorch/data/build.py delete mode 100755 cv/classification/repvgg/pytorch/data/cached_image_folder.py delete mode 100755 cv/classification/repvgg/pytorch/data/lmdb_dataset.py delete mode 100755 cv/classification/repvgg/pytorch/data/samplers.py delete mode 100755 cv/classification/repvgg/pytorch/data/zipreader.py delete mode 100755 cv/classification/repvgg/pytorch/example_pspnet.py delete mode 100755 cv/classification/repvgg/pytorch/jizhi_submit_train_repvgg.py delete mode 100755 cv/classification/repvgg/pytorch/main.py delete mode 100755 cv/classification/repvgg/pytorch/quantization/quant_qat_train.py delete mode 100755 cv/classification/repvgg/pytorch/quantization/repvgg_quantized.py delete mode 100755 cv/classification/repvgg/pytorch/repvgg.py delete mode 100755 cv/classification/repvgg/pytorch/repvggplus.py delete mode 100755 cv/classification/repvgg/pytorch/repvggplus_custom_L2.py delete mode 100755 cv/classification/repvgg/pytorch/se_block.py delete mode 100755 cv/classification/repvgg/pytorch/tools/convert.py delete mode 100755 cv/classification/repvgg/pytorch/tools/insert_bn.py delete mode 100755 cv/classification/repvgg/pytorch/tools/verify.py delete mode 100755 cv/classification/repvgg/pytorch/train/config.py delete mode 100755 cv/classification/repvgg/pytorch/train/cutout.py delete mode 100755 cv/classification/repvgg/pytorch/train/logger.py delete mode 100755 cv/classification/repvgg/pytorch/train/lr_scheduler.py delete mode 100755 cv/classification/repvgg/pytorch/train/optimizer.py delete mode 100755 cv/classification/repvgg/pytorch/train/randaug.py delete mode 100755 cv/classification/repvgg/pytorch/utils.py delete mode 100644 cv/classification/swin_transformer/pytorch/.gitignore delete mode 100644 cv/classification/swin_transformer/pytorch/CODE_OF_CONDUCT.md delete mode 100644 cv/classification/swin_transformer/pytorch/LICENSE delete mode 100644 cv/classification/swin_transformer/pytorch/MODELHUB.md delete mode 100644 cv/classification/swin_transformer/pytorch/README_IX.md delete mode 100644 cv/classification/swin_transformer/pytorch/SECURITY.md delete mode 100644 cv/classification/swin_transformer/pytorch/SUPPORT.md delete mode 100644 cv/classification/swin_transformer/pytorch/config.py delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window12_384_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_c24_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22kto1k_finetune.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_base_patch4_window7_224.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c12_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c24_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c6_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_16expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_32expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_8expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_densebaseline_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_64expert_64gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_densebaseline_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window16_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window16_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window16_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window8_256.yaml delete mode 100644 cv/classification/swin_transformer/pytorch/data/__init__.py delete mode 100644 cv/classification/swin_transformer/pytorch/data/build.py delete mode 100644 cv/classification/swin_transformer/pytorch/data/cached_image_folder.py delete mode 100644 cv/classification/swin_transformer/pytorch/data/imagenet22k_dataset.py delete mode 100644 cv/classification/swin_transformer/pytorch/data/map22kto1k.txt delete mode 100644 cv/classification/swin_transformer/pytorch/data/samplers.py delete mode 100644 cv/classification/swin_transformer/pytorch/data/zipreader.py delete mode 100644 cv/classification/swin_transformer/pytorch/figures/teaser.png delete mode 100644 cv/classification/swin_transformer/pytorch/get_started.md delete mode 100644 cv/classification/swin_transformer/pytorch/kernels/window_process/setup.py delete mode 100644 cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process.cpp delete mode 100644 cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process_kernel.cu delete mode 100644 cv/classification/swin_transformer/pytorch/kernels/window_process/unit_test.py delete mode 100644 cv/classification/swin_transformer/pytorch/kernels/window_process/window_process.py delete mode 100644 cv/classification/swin_transformer/pytorch/logger.py delete mode 100644 cv/classification/swin_transformer/pytorch/lr_scheduler.py delete mode 100644 cv/classification/swin_transformer/pytorch/main.py delete mode 100644 cv/classification/swin_transformer/pytorch/main_moe.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/__init__.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/build.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/swin_mlp.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/swin_transformer.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/swin_transformer_moe.py delete mode 100644 cv/classification/swin_transformer/pytorch/models/swin_transformer_v2.py delete mode 100644 cv/classification/swin_transformer/pytorch/optimizer.py delete mode 100644 cv/classification/swin_transformer/pytorch/utils.py delete mode 100644 cv/classification/swin_transformer/pytorch/utils_moe.py delete mode 100644 cv/classification/wavemlp/pytorch/.gitignore delete mode 100644 cv/classification/wavemlp/pytorch/License.txt delete mode 100644 cv/classification/wavemlp/pytorch/THIRD PARTY OPEN SOURCE SOFTWARE NOTICE.txt delete mode 100644 cv/classification/wavemlp/pytorch/data/myloader.py delete mode 100644 cv/classification/wavemlp/pytorch/data/rasampler.py delete mode 100644 cv/classification/wavemlp/pytorch/figures/patm.PNG delete mode 100644 cv/classification/wavemlp/pytorch/figures/res.PNG delete mode 100644 cv/classification/wavemlp/pytorch/models/wavemlp.py delete mode 100644 cv/classification/wavemlp/pytorch/run.sh delete mode 100644 cv/classification/wavemlp/pytorch/train.py diff --git a/cv/classification/acmix/pytorch/README.md b/cv/classification/acmix/pytorch/README.md index bb82c565c..a64b45247 100644 --- a/cv/classification/acmix/pytorch/README.md +++ b/cv/classification/acmix/pytorch/README.md @@ -5,8 +5,11 @@ Convolution and self-attention are two powerful techniques for representation learning, and they are usually considered as two peer approaches that are distinct from each other. In this paper, we show that there exists a strong underlying relation between them, in the sense that the bulk of computations of these two paradigms are in fact done with the same operation. Specifically, we first show that a traditional convolution with kernel size k x k can be decomposed into k^2 individual 1x1 convolutions, followed by shift and summation operations. Then, we interpret the projections of queries, keys, and values in self-attention module as multiple 1x1 convolutions, followed by the computation of attention weights and aggregation of the values. Therefore, the first stage of both two modules comprises the similar operation. More importantly, the first stage contributes a dominant computation complexity (square of the channel size) comparing to the second stage. This observation naturally leads to an elegant integration of these two seemingly distinct paradigms, i.e., a mixed model that enjoys the benefit of both self-Attention and Convolution (ACmix), while having minimum computational overhead compared to the pure convolution or self-attention counterpart. Extensive experiments show that our model achieves consistently improved results over competitive baselines on image recognition and downstream tasks. Code and pre-trained models will be released at https://github.com/LeapLabTHU/ACmix and https://gitee.com/mindspore/models. ## Step 1: Installing packages -``` +```bash +git clone https://github.com/LeapLabTHU/ACmix.git pip install termcolor==1.1.0 yacs==0.1.8 timm==0.4.5 +cd ACmix/Swin-Transformer +git checkout 81dddb6dff98f5e238a7fb6ab174e256489c07fa ``` Sign up and login in [ImageNet official website](https://www.image-net.org/index.php), then choose 'Download' to download the whole ImageNet dataset. Specify `/path/to/imagenet` to your ImageNet path in later training process. @@ -30,8 +33,10 @@ imagenet ## Step 2: Training ### Swin-S + ACmix on ImageNet using 8 cards: -``` -bash run.sh 8 acmix_swin_small_patch4_window7_224.yaml /path/to/imagenet +```bash +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' main.py +python3 -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py --cfg configs/acmix_swin_small_patch4_window7_224.yaml --data-path /path/to/imagenet --batch-size 128 ``` ## Results on BI-V100 @@ -42,4 +47,4 @@ bash run.sh 8 acmix_swin_small_patch4_window7_224.yaml /path/to/imagenet ## Reference -https://github.com/leaplabthu/acmix \ No newline at end of file +[acmix](https://github.com/leaplabthu/acmix) \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/README.md b/cv/classification/acmix/pytorch/Swin-Transformer/README.md deleted file mode 100644 index df824eca6..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Swin Transformer - -This folder contains the implementation of the ACmix based on Swin Transformer models for image classification. - -### Requirements - -+ Python 3.7 - -+ PyTorch==1.8.0 - -+ torchvision==0.9.0 - -+ timm==0.3.2 - -+ opencv-python==4.4.0.46 - -+ termcolor==1.1.0 - -+ yacs==0.1.8 - -+ Install Apex: - - ```python - git clone https://github.com/NVIDIA/apex - cd apex - pip install -v --disable-pip-version-check --no-cache-dir --global-option="--cpp_ext" --global-option="--cuda_ext" ./ - ``` - -### Data preparation - -We use standard ImageNet dataset, you can download it from http://image-net.org/. The file structure should look like: - -``` -$ tree data -imagenet -├── train -│ ├── class1 -│ │ ├── img1.jpeg -│ │ ├── img2.jpeg -│ │ └── ... -│ ├── class2 -│ │ ├── img3.jpeg -│ │ └── ... -│ └── ... -└── val - ├── class1 - │ ├── img4.jpeg - │ ├── img5.jpeg - │ └── ... - ├── class2 - │ ├── img6.jpeg - │ └── ... - └── ... -``` - -### Run - -Train Swin-T + ACmix on ImageNet - -```python -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py --cfg configs/acmix_swin_tiny_patch4_window7_224.yaml --data-path --batch-size 128 -``` - -Train Swin-S + ACmix on ImageNet - -```python -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py --cfg configs/acmix_swin_small_patch4_window7_224.yaml --data-path --batch-size 128 -``` - diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/build.py b/cv/classification/acmix/pytorch/Swin-Transformer/build.py deleted file mode 100644 index efcd6f363..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/build.py +++ /dev/null @@ -1,303 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from .swin_transformer import SwinTransformer -from .swin_transformer_hac import SwinTransformer_hac -from .swin_transformer_hac_v3 import SwinTransformer_hac_v3 -from .swin_transformer_hac_v4 import SwinTransformer_hac_v4 -from .swin_transformer_hac_v5 import SwinTransformer_hac_v5 -from .swin_transformer_hac_v6 import SwinTransformer_hac_v6 -from .swin_transformer_hac_v7 import SwinTransformer_hac_v7 -from .swin_transformer_hac_v8 import SwinTransformer_hac_v8 -from .swin_transformer_hac_v9 import SwinTransformer_hac_v9 -from .swin_transformer_hac_v10 import SwinTransformer_hac_v10 -from .swin_transformer_hac_v11 import SwinTransformer_hac_v11 -from .swin_transformer_hac_v12 import SwinTransformer_hac_v12 -from .swin_transformer_hac_v13 import SwinTransformer_hac_v13 -from .swin_transformer_hac_v14 import SwinTransformer_hac_v14 -from .swin_transformer_hac_v15 import SwinTransformer_hac_v15 -from .swin_transformer_hac_v16 import SwinTransformer_hac_v16 - - -def build_model(config): - model_type = config.MODEL.TYPE - if model_type == 'swin': - model = SwinTransformer(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac': - model = SwinTransformer_hac(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v3': - model = SwinTransformer_hac_v3(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v4': - model = SwinTransformer_hac_v4(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v5': - model = SwinTransformer_hac_v5(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v6': - model = SwinTransformer_hac_v6(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v7': - model = SwinTransformer_hac_v7(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v8': - model = SwinTransformer_hac_v8(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v9': - model = SwinTransformer_hac_v9(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v10': - model = SwinTransformer_hac_v10(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v11': - model = SwinTransformer_hac_v11(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v12': - model = SwinTransformer_hac_v12(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v13': - model = SwinTransformer_hac_v13(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v14': - model = SwinTransformer_hac_v14(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v15': - model = SwinTransformer_hac_v15(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_hac_v16': - model = SwinTransformer_hac_v16(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - else: - raise NotImplementedError(f"Unkown model: {model_type}") - - return model diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/config.py b/cv/classification/acmix/pytorch/Swin-Transformer/config.py deleted file mode 100644 index 5f150f841..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/config.py +++ /dev/null @@ -1,236 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# --------------------------------------------------------' - -import os -import yaml -from yacs.config import CfgNode as CN - -_C = CN() - -# Base config files -_C.BASE = [''] - -# ----------------------------------------------------------------------------- -# Data settings -# ----------------------------------------------------------------------------- -_C.DATA = CN() -# Batch size for a single GPU, could be overwritten by command line argument -_C.DATA.BATCH_SIZE = 128 -# Path to dataset, could be overwritten by command line argument -_C.DATA.DATA_PATH = '' -# Dataset name -_C.DATA.DATASET = 'imagenet' -# Input image size -_C.DATA.IMG_SIZE = 224 -# Interpolation to resize image (random, bilinear, bicubic) -_C.DATA.INTERPOLATION = 'bicubic' -# Use zipped dataset instead of folder dataset -# could be overwritten by command line argument -_C.DATA.ZIP_MODE = False -# Cache Data in Memory, could be overwritten by command line argument -_C.DATA.CACHE_MODE = 'part' -# Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU. -_C.DATA.PIN_MEMORY = True -# Number of data loading threads -_C.DATA.NUM_WORKERS = 8 - -# ----------------------------------------------------------------------------- -# Model settings -# ----------------------------------------------------------------------------- -_C.MODEL = CN() -# Model type -_C.MODEL.TYPE = 'swin' -# Model name -_C.MODEL.NAME = 'swin_tiny_patch4_window7_224' -# Checkpoint to resume, could be overwritten by command line argument -_C.MODEL.RESUME = '' -# Number of classes, overwritten in data preparation -_C.MODEL.NUM_CLASSES = 1000 -# Dropout rate -_C.MODEL.DROP_RATE = 0.0 -# Drop path rate -_C.MODEL.DROP_PATH_RATE = 0.1 -# Label Smoothing -_C.MODEL.LABEL_SMOOTHING = 0.1 - -# Swin Transformer parameters -_C.MODEL.SWIN = CN() -_C.MODEL.SWIN.PATCH_SIZE = 4 -_C.MODEL.SWIN.IN_CHANS = 3 -_C.MODEL.SWIN.EMBED_DIM = 96 -_C.MODEL.SWIN.DEPTHS = [2, 2, 6, 2] -_C.MODEL.SWIN.NUM_HEADS = [3, 6, 12, 24] -_C.MODEL.SWIN.WINDOW_SIZE = 7 -_C.MODEL.SWIN.MLP_RATIO = 4. -_C.MODEL.SWIN.QKV_BIAS = True -_C.MODEL.SWIN.QK_SCALE = None -_C.MODEL.SWIN.APE = False -_C.MODEL.SWIN.PATCH_NORM = True - -# ----------------------------------------------------------------------------- -# Training settings -# ----------------------------------------------------------------------------- -_C.TRAIN = CN() -_C.TRAIN.START_EPOCH = 0 -_C.TRAIN.EPOCHS = 300 -_C.TRAIN.WARMUP_EPOCHS = 20 -_C.TRAIN.WEIGHT_DECAY = 0.05 -_C.TRAIN.BASE_LR = 5e-4 -_C.TRAIN.WARMUP_LR = 5e-7 -_C.TRAIN.MIN_LR = 5e-6 -# Clip gradient norm -_C.TRAIN.CLIP_GRAD = 5.0 -# Auto resume from latest checkpoint -_C.TRAIN.AUTO_RESUME = True -# Gradient accumulation steps -# could be overwritten by command line argument -_C.TRAIN.ACCUMULATION_STEPS = 0 -# Whether to use gradient checkpointing to save memory -# could be overwritten by command line argument -_C.TRAIN.USE_CHECKPOINT = False - -# LR scheduler -_C.TRAIN.LR_SCHEDULER = CN() -_C.TRAIN.LR_SCHEDULER.NAME = 'cosine' -# Epoch interval to decay LR, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_EPOCHS = 30 -# LR decay rate, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_RATE = 0.1 - -# Optimizer -_C.TRAIN.OPTIMIZER = CN() -_C.TRAIN.OPTIMIZER.NAME = 'adamw' -# Optimizer Epsilon -_C.TRAIN.OPTIMIZER.EPS = 1e-8 -# Optimizer Betas -_C.TRAIN.OPTIMIZER.BETAS = (0.9, 0.999) -# SGD momentum -_C.TRAIN.OPTIMIZER.MOMENTUM = 0.9 - -# ----------------------------------------------------------------------------- -# Augmentation settings -# ----------------------------------------------------------------------------- -_C.AUG = CN() -# Color jitter factor -_C.AUG.COLOR_JITTER = 0.4 -# Use AutoAugment policy. "v0" or "original" -_C.AUG.AUTO_AUGMENT = 'rand-m9-mstd0.5-inc1' -# Random erase prob -_C.AUG.REPROB = 0.25 -# Random erase mode -_C.AUG.REMODE = 'pixel' -# Random erase count -_C.AUG.RECOUNT = 1 -# Mixup alpha, mixup enabled if > 0 -_C.AUG.MIXUP = 0.8 -# Cutmix alpha, cutmix enabled if > 0 -_C.AUG.CUTMIX = 1.0 -# Cutmix min/max ratio, overrides alpha and enables cutmix if set -_C.AUG.CUTMIX_MINMAX = None -# Probability of performing mixup or cutmix when either/both is enabled -_C.AUG.MIXUP_PROB = 1.0 -# Probability of switching to cutmix when both mixup and cutmix enabled -_C.AUG.MIXUP_SWITCH_PROB = 0.5 -# How to apply mixup/cutmix params. Per "batch", "pair", or "elem" -_C.AUG.MIXUP_MODE = 'batch' - -# ----------------------------------------------------------------------------- -# Testing settings -# ----------------------------------------------------------------------------- -_C.TEST = CN() -# Whether to use center crop when testing -_C.TEST.CROP = True - -# ----------------------------------------------------------------------------- -# Misc -# ----------------------------------------------------------------------------- -# Mixed precision opt level, if O0, no amp is used ('O0', 'O1', 'O2') -# overwritten by command line argument -_C.AMP_OPT_LEVEL = '' -# Path to output folder, overwritten by command line argument -_C.OUTPUT = '' -# Tag of experiment, overwritten by command line argument -_C.TAG = 'default' -# Frequency to save checkpoint -_C.SAVE_FREQ = 1 -# Frequency to logging info -_C.PRINT_FREQ = 10 -# Fixed random seed -_C.SEED = 0 -# Perform evaluation only, overwritten by command line argument -_C.EVAL_MODE = False -# Test throughput only, overwritten by command line argument -_C.THROUGHPUT_MODE = False -# local rank for DistributedDataParallel, given by command line argument -_C.LOCAL_RANK = 0 - - -def _update_config_from_file(config, cfg_file): - config.defrost() - with open(cfg_file, 'r') as f: - yaml_cfg = yaml.load(f, Loader=yaml.FullLoader) - - for cfg in yaml_cfg.setdefault('BASE', ['']): - if cfg: - _update_config_from_file( - config, os.path.join(os.path.dirname(cfg_file), cfg) - ) - print('=> merge config from {}'.format(cfg_file)) - config.merge_from_file(cfg_file) - config.freeze() - - -def update_config(config, args): - _update_config_from_file(config, args.cfg) - - config.defrost() - if args.opts: - config.merge_from_list(args.opts) - - # merge from specific arguments - if args.batch_size: - config.DATA.BATCH_SIZE = args.batch_size - if args.data_path: - config.DATA.DATA_PATH = args.data_path - if args.zip: - config.DATA.ZIP_MODE = True - if args.cache_mode: - config.DATA.CACHE_MODE = args.cache_mode - if args.resume: - config.MODEL.RESUME = args.resume - if args.accumulation_steps: - config.TRAIN.ACCUMULATION_STEPS = args.accumulation_steps - if args.use_checkpoint: - config.TRAIN.USE_CHECKPOINT = True - if args.amp_opt_level: - config.AMP_OPT_LEVEL = args.amp_opt_level - if args.output: - config.OUTPUT = args.output - if args.tag: - config.TAG = args.tag - if args.eval: - config.EVAL_MODE = True - if args.throughput: - config.THROUGHPUT_MODE = True - - # set local rank for distributed training - config.LOCAL_RANK = args.local_rank - - # output folder - config.OUTPUT = os.path.join(config.OUTPUT, config.MODEL.NAME, config.TAG) - - config.freeze() - - -def get_config(args): - """Get a yacs CfgNode object with default values.""" - # Return a clone so that the defaults will not be altered - # This is for the "local variable" use pattern - config = _C.clone() - update_config(config, args) - - return config diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_small_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_small_patch4_window7_224.yaml deleted file mode 100644 index e19750693..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_small_patch4_window7_224.yaml +++ /dev/null @@ -1,12 +0,0 @@ -TRAIN: - EPOCHS: 300 - -MODEL: - TYPE: swin_acmix - NAME: acmix_swin_small_patch4_window7_224 - DROP_PATH_RATE: 0.3 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_tiny_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_tiny_patch4_window7_224.yaml deleted file mode 100644 index 9111a1740..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/acmix_swin_tiny_patch4_window7_224.yaml +++ /dev/null @@ -1,12 +0,0 @@ -TRAIN: - EPOCHS: 300 - -MODEL: - TYPE: swin_acmix - NAME: acmix_swin_tiny_patch4_window7_224 - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window12_384.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window12_384.yaml deleted file mode 100644 index b54deb781..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window12_384.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# only for evaluation -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swin - NAME: swin_base_patch4_window12_384 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window7_224.yaml deleted file mode 100644 index b29612858..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_base_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_base_patch4_window7_224 - DROP_PATH_RATE: 0.5 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window12_384.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window12_384.yaml deleted file mode 100644 index bacf5f6a1..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window12_384.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# only for evaluation -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swin - NAME: swin_large_patch4_window12_384 - SWIN: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 12 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window7_224.yaml deleted file mode 100644 index df8af4cec..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_large_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# only for evaluation -MODEL: - TYPE: swin - NAME: swin_large_patch4_window7_224 - SWIN: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_small_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_small_patch4_window7_224.yaml deleted file mode 100644 index 8f5c40fda..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_small_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_small_patch4_window7_224 - DROP_PATH_RATE: 0.3 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_tiny_patch4_window7_224.yaml b/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_tiny_patch4_window7_224.yaml deleted file mode 100644 index 851c7451f..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/configs/swin_tiny_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_tiny_patch4_window7_224 - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/data/__init__.py b/cv/classification/acmix/pytorch/Swin-Transformer/data/__init__.py deleted file mode 100644 index 70c633ce6..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .build import build_loader \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/data/build.py b/cv/classification/acmix/pytorch/Swin-Transformer/data/build.py deleted file mode 100644 index 840d92557..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/data/build.py +++ /dev/null @@ -1,128 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import torch -import numpy as np -import torch.distributed as dist -from torchvision import datasets, transforms -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data import Mixup -from timm.data import create_transform -from timm.data.transforms import _pil_interp - -from .cached_image_folder import CachedImageFolder -from .samplers import SubsetRandomSampler - - -def build_loader(config): - config.defrost() - dataset_train, config.MODEL.NUM_CLASSES = build_dataset(is_train=True, config=config) - config.freeze() - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build train dataset") - dataset_val, _ = build_dataset(is_train=False, config=config) - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build val dataset") - - num_tasks = dist.get_world_size() - global_rank = dist.get_rank() - if config.DATA.ZIP_MODE and config.DATA.CACHE_MODE == 'part': - indices = np.arange(dist.get_rank(), len(dataset_train), dist.get_world_size()) - sampler_train = SubsetRandomSampler(indices) - else: - sampler_train = torch.utils.data.DistributedSampler( - dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - - indices = np.arange(dist.get_rank(), len(dataset_val), dist.get_world_size()) - sampler_val = SubsetRandomSampler(indices) - - data_loader_train = torch.utils.data.DataLoader( - dataset_train, sampler=sampler_train, - batch_size=config.DATA.BATCH_SIZE, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=True, - ) - - data_loader_val = torch.utils.data.DataLoader( - dataset_val, sampler=sampler_val, - batch_size=config.DATA.BATCH_SIZE, - shuffle=False, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=False - ) - - # setup mixup / cutmix - mixup_fn = None - mixup_active = config.AUG.MIXUP > 0 or config.AUG.CUTMIX > 0. or config.AUG.CUTMIX_MINMAX is not None - if mixup_active: - mixup_fn = Mixup( - mixup_alpha=config.AUG.MIXUP, cutmix_alpha=config.AUG.CUTMIX, cutmix_minmax=config.AUG.CUTMIX_MINMAX, - prob=config.AUG.MIXUP_PROB, switch_prob=config.AUG.MIXUP_SWITCH_PROB, mode=config.AUG.MIXUP_MODE, - label_smoothing=config.MODEL.LABEL_SMOOTHING, num_classes=config.MODEL.NUM_CLASSES) - - return dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn - - -def build_dataset(is_train, config): - transform = build_transform(is_train, config) - if config.DATA.DATASET == 'imagenet': - prefix = 'train' if is_train else 'val' - if config.DATA.ZIP_MODE: - ann_file = prefix + "_map.txt" - prefix = prefix + ".zip@/" - dataset = CachedImageFolder(config.DATA.DATA_PATH, ann_file, prefix, transform, - cache_mode=config.DATA.CACHE_MODE if is_train else 'part') - else: - root = os.path.join(config.DATA.DATA_PATH, prefix) - dataset = datasets.ImageFolder(root, transform=transform) - nb_classes = 1000 - else: - raise NotImplementedError("We only support ImageNet Now.") - - return dataset, nb_classes - - -def build_transform(is_train, config): - resize_im = config.DATA.IMG_SIZE > 32 - if is_train: - # this should always dispatch to transforms_imagenet_train - transform = create_transform( - input_size=config.DATA.IMG_SIZE, - is_training=True, - color_jitter=config.AUG.COLOR_JITTER if config.AUG.COLOR_JITTER > 0 else None, - auto_augment=config.AUG.AUTO_AUGMENT if config.AUG.AUTO_AUGMENT != 'none' else None, - re_prob=config.AUG.REPROB, - re_mode=config.AUG.REMODE, - re_count=config.AUG.RECOUNT, - interpolation=config.DATA.INTERPOLATION, - ) - if not resize_im: - # replace RandomResizedCropAndInterpolation with - # RandomCrop - transform.transforms[0] = transforms.RandomCrop(config.DATA.IMG_SIZE, padding=4) - return transform - - t = [] - if resize_im: - if config.TEST.CROP: - size = int((256 / 224) * config.DATA.IMG_SIZE) - t.append( - transforms.Resize(size, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - # to maintain same ratio w.r.t. 224 images - ) - t.append(transforms.CenterCrop(config.DATA.IMG_SIZE)) - else: - t.append( - transforms.Resize((config.DATA.IMG_SIZE, config.DATA.IMG_SIZE), - interpolation=_pil_interp(config.DATA.INTERPOLATION)) - ) - - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - return transforms.Compose(t) diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/data/cached_image_folder.py b/cv/classification/acmix/pytorch/Swin-Transformer/data/cached_image_folder.py deleted file mode 100644 index 79db42d68..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/data/cached_image_folder.py +++ /dev/null @@ -1,251 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import io -import os -import time -import torch.distributed as dist -import torch.utils.data as data -from PIL import Image - -from .zipreader import is_zip_path, ZipReader - - -def has_file_allowed_extension(filename, extensions): - """Checks if a file is an allowed extension. - Args: - filename (string): path to a file - Returns: - bool: True if the filename ends with a known image extension - """ - filename_lower = filename.lower() - return any(filename_lower.endswith(ext) for ext in extensions) - - -def find_classes(dir): - classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))] - classes.sort() - class_to_idx = {classes[i]: i for i in range(len(classes))} - return classes, class_to_idx - - -def make_dataset(dir, class_to_idx, extensions): - images = [] - dir = os.path.expanduser(dir) - for target in sorted(os.listdir(dir)): - d = os.path.join(dir, target) - if not os.path.isdir(d): - continue - - for root, _, fnames in sorted(os.walk(d)): - for fname in sorted(fnames): - if has_file_allowed_extension(fname, extensions): - path = os.path.join(root, fname) - item = (path, class_to_idx[target]) - images.append(item) - - return images - - -def make_dataset_with_ann(ann_file, img_prefix, extensions): - images = [] - with open(ann_file, "r") as f: - contents = f.readlines() - for line_str in contents: - path_contents = [c for c in line_str.split('\t')] - im_file_name = path_contents[0] - class_index = int(path_contents[1]) - - assert str.lower(os.path.splitext(im_file_name)[-1]) in extensions - item = (os.path.join(img_prefix, im_file_name), class_index) - - images.append(item) - - return images - - -class DatasetFolder(data.Dataset): - """A generic data loader where the samples are arranged in this way: :: - root/class_x/xxx.ext - root/class_x/xxy.ext - root/class_x/xxz.ext - root/class_y/123.ext - root/class_y/nsdf3.ext - root/class_y/asd932_.ext - Args: - root (string): Root directory path. - loader (callable): A function to load a sample given its path. - extensions (list[string]): A list of allowed extensions. - transform (callable, optional): A function/transform that takes in - a sample and returns a transformed version. - E.g, ``transforms.RandomCrop`` for images. - target_transform (callable, optional): A function/transform that takes - in the target and transforms it. - Attributes: - samples (list): List of (sample path, class_index) tuples - """ - - def __init__(self, root, loader, extensions, ann_file='', img_prefix='', transform=None, target_transform=None, - cache_mode="no"): - # image folder mode - if ann_file == '': - _, class_to_idx = find_classes(root) - samples = make_dataset(root, class_to_idx, extensions) - # zip mode - else: - samples = make_dataset_with_ann(os.path.join(root, ann_file), - os.path.join(root, img_prefix), - extensions) - - if len(samples) == 0: - raise (RuntimeError("Found 0 files in subfolders of: " + root + "\n" + - "Supported extensions are: " + ",".join(extensions))) - - self.root = root - self.loader = loader - self.extensions = extensions - - self.samples = samples - self.labels = [y_1k for _, y_1k in samples] - self.classes = list(set(self.labels)) - - self.transform = transform - self.target_transform = target_transform - - self.cache_mode = cache_mode - if self.cache_mode != "no": - self.init_cache() - - def init_cache(self): - assert self.cache_mode in ["part", "full"] - n_sample = len(self.samples) - global_rank = dist.get_rank() - world_size = dist.get_world_size() - - samples_bytes = [None for _ in range(n_sample)] - start_time = time.time() - for index in range(n_sample): - if index % (n_sample // 10) == 0: - t = time.time() - start_time - print(f'global_rank {dist.get_rank()} cached {index}/{n_sample} takes {t:.2f}s per block') - start_time = time.time() - path, target = self.samples[index] - if self.cache_mode == "full": - samples_bytes[index] = (ZipReader.read(path), target) - elif self.cache_mode == "part" and index % world_size == global_rank: - samples_bytes[index] = (ZipReader.read(path), target) - else: - samples_bytes[index] = (path, target) - self.samples = samples_bytes - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (sample, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - sample = self.loader(path) - if self.transform is not None: - sample = self.transform(sample) - if self.target_transform is not None: - target = self.target_transform(target) - - return sample, target - - def __len__(self): - return len(self.samples) - - def __repr__(self): - fmt_str = 'Dataset ' + self.__class__.__name__ + '\n' - fmt_str += ' Number of datapoints: {}\n'.format(self.__len__()) - fmt_str += ' Root Location: {}\n'.format(self.root) - tmp = ' Transforms (if any): ' - fmt_str += '{0}{1}\n'.format(tmp, self.transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - tmp = ' Target Transforms (if any): ' - fmt_str += '{0}{1}'.format(tmp, self.target_transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - return fmt_str - - -IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif'] - - -def pil_loader(path): - # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835) - if isinstance(path, bytes): - img = Image.open(io.BytesIO(path)) - elif is_zip_path(path): - data = ZipReader.read(path) - img = Image.open(io.BytesIO(data)) - else: - with open(path, 'rb') as f: - img = Image.open(f) - return img.convert('RGB') - - -def accimage_loader(path): - import accimage - try: - return accimage.Image(path) - except IOError: - # Potentially a decoding problem, fall back to PIL.Image - return pil_loader(path) - - -def default_img_loader(path): - from torchvision import get_image_backend - if get_image_backend() == 'accimage': - return accimage_loader(path) - else: - return pil_loader(path) - - -class CachedImageFolder(DatasetFolder): - """A generic data loader where the images are arranged in this way: :: - root/dog/xxx.png - root/dog/xxy.png - root/dog/xxz.png - root/cat/123.png - root/cat/nsdf3.png - root/cat/asd932_.png - Args: - root (string): Root directory path. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - loader (callable, optional): A function to load an image given its path. - Attributes: - imgs (list): List of (image path, class_index) tuples - """ - - def __init__(self, root, ann_file='', img_prefix='', transform=None, target_transform=None, - loader=default_img_loader, cache_mode="no"): - super(CachedImageFolder, self).__init__(root, loader, IMG_EXTENSIONS, - ann_file=ann_file, img_prefix=img_prefix, - transform=transform, target_transform=target_transform, - cache_mode=cache_mode) - self.imgs = self.samples - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (image, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - image = self.loader(path) - if self.transform is not None: - img = self.transform(image) - else: - img = image - if self.target_transform is not None: - target = self.target_transform(target) - - return img, target diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/data/samplers.py b/cv/classification/acmix/pytorch/Swin-Transformer/data/samplers.py deleted file mode 100644 index 596e22099..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/data/samplers.py +++ /dev/null @@ -1,29 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch - - -class SubsetRandomSampler(torch.utils.data.Sampler): - r"""Samples elements randomly from a given list of indices, without replacement. - - Arguments: - indices (sequence): a sequence of indices - """ - - def __init__(self, indices): - self.epoch = 0 - self.indices = indices - - def __iter__(self): - return (self.indices[i] for i in torch.randperm(len(self.indices))) - - def __len__(self): - return len(self.indices) - - def set_epoch(self, epoch): - self.epoch = epoch diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/data/zipreader.py b/cv/classification/acmix/pytorch/Swin-Transformer/data/zipreader.py deleted file mode 100644 index 060bc46a7..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/data/zipreader.py +++ /dev/null @@ -1,103 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import zipfile -import io -import numpy as np -from PIL import Image -from PIL import ImageFile - -ImageFile.LOAD_TRUNCATED_IMAGES = True - - -def is_zip_path(img_or_path): - """judge if this is a zip path""" - return '.zip@' in img_or_path - - -class ZipReader(object): - """A class to read zipped files""" - zip_bank = dict() - - def __init__(self): - super(ZipReader, self).__init__() - - @staticmethod - def get_zipfile(path): - zip_bank = ZipReader.zip_bank - if path not in zip_bank: - zfile = zipfile.ZipFile(path, 'r') - zip_bank[path] = zfile - return zip_bank[path] - - @staticmethod - def split_zip_style_path(path): - pos_at = path.index('@') - assert pos_at != -1, "character '@' is not found from the given path '%s'" % path - - zip_path = path[0: pos_at] - folder_path = path[pos_at + 1:] - folder_path = str.strip(folder_path, '/') - return zip_path, folder_path - - @staticmethod - def list_folder(path): - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - folder_list = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - len(os.path.splitext(file_foler_name)[-1]) == 0 and \ - file_foler_name != folder_path: - if len(folder_path) == 0: - folder_list.append(file_foler_name) - else: - folder_list.append(file_foler_name[len(folder_path) + 1:]) - - return folder_list - - @staticmethod - def list_files(path, extension=None): - if extension is None: - extension = ['.*'] - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - file_lists = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - str.lower(os.path.splitext(file_foler_name)[-1]) in extension: - if len(folder_path) == 0: - file_lists.append(file_foler_name) - else: - file_lists.append(file_foler_name[len(folder_path) + 1:]) - - return file_lists - - @staticmethod - def read(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - return data - - @staticmethod - def imread(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - try: - im = Image.open(io.BytesIO(data)) - except: - print("ERROR IMG LOADED: ", path_img) - random_img = np.random.rand(224, 224, 3) * 255 - im = Image.fromarray(np.uint8(random_img)) - return im diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/logger.py b/cv/classification/acmix/pytorch/Swin-Transformer/logger.py deleted file mode 100644 index a066e55ba..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/logger.py +++ /dev/null @@ -1,41 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import sys -import logging -import functools -from termcolor import colored - - -@functools.lru_cache() -def create_logger(output_dir, dist_rank=0, name=''): - # create logger - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.propagate = False - - # create formatter - fmt = '[%(asctime)s %(name)s] (%(filename)s %(lineno)d): %(levelname)s %(message)s' - color_fmt = colored('[%(asctime)s %(name)s]', 'green') + \ - colored('(%(filename)s %(lineno)d)', 'yellow') + ': %(levelname)s %(message)s' - - # create console handlers for master process - if dist_rank == 0: - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setLevel(logging.DEBUG) - console_handler.setFormatter( - logging.Formatter(fmt=color_fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(console_handler) - - # create file handlers - file_handler = logging.FileHandler(os.path.join(output_dir, f'log_rank{dist_rank}.txt'), mode='a') - file_handler.setLevel(logging.DEBUG) - file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(file_handler) - - return logger diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/lr_scheduler.py b/cv/classification/acmix/pytorch/Swin-Transformer/lr_scheduler.py deleted file mode 100644 index 4d27289be..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/lr_scheduler.py +++ /dev/null @@ -1,102 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -from timm.scheduler.cosine_lr import CosineLRScheduler -from timm.scheduler.step_lr import StepLRScheduler -from timm.scheduler.scheduler import Scheduler - - -def build_scheduler(config, optimizer, n_iter_per_epoch): - num_steps = int(config.TRAIN.EPOCHS * n_iter_per_epoch) - warmup_steps = int(config.TRAIN.WARMUP_EPOCHS * n_iter_per_epoch) - decay_steps = int(config.TRAIN.LR_SCHEDULER.DECAY_EPOCHS * n_iter_per_epoch) - - lr_scheduler = None - if config.TRAIN.LR_SCHEDULER.NAME == 'cosine': - lr_scheduler = CosineLRScheduler( - optimizer, - t_initial=num_steps, - t_mul=1., - lr_min=config.TRAIN.MIN_LR, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - cycle_limit=1, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'linear': - lr_scheduler = LinearLRScheduler( - optimizer, - t_initial=num_steps, - lr_min_rate=0.01, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'step': - lr_scheduler = StepLRScheduler( - optimizer, - decay_t=decay_steps, - decay_rate=config.TRAIN.LR_SCHEDULER.DECAY_RATE, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - - return lr_scheduler - - -class LinearLRScheduler(Scheduler): - def __init__(self, - optimizer: torch.optim.Optimizer, - t_initial: int, - lr_min_rate: float, - warmup_t=0, - warmup_lr_init=0., - t_in_epochs=True, - noise_range_t=None, - noise_pct=0.67, - noise_std=1.0, - noise_seed=42, - initialize=True, - ) -> None: - super().__init__( - optimizer, param_group_field="lr", - noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, - initialize=initialize) - - self.t_initial = t_initial - self.lr_min_rate = lr_min_rate - self.warmup_t = warmup_t - self.warmup_lr_init = warmup_lr_init - self.t_in_epochs = t_in_epochs - if self.warmup_t: - self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] - super().update_groups(self.warmup_lr_init) - else: - self.warmup_steps = [1 for _ in self.base_values] - - def _get_lr(self, t): - if t < self.warmup_t: - lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] - else: - t = t - self.warmup_t - total_t = self.t_initial - self.warmup_t - lrs = [v - ((v - v * self.lr_min_rate) * (t / total_t)) for v in self.base_values] - return lrs - - def get_epoch_values(self, epoch: int): - if self.t_in_epochs: - return self._get_lr(epoch) - else: - return None - - def get_update_values(self, num_updates: int): - if not self.t_in_epochs: - return self._get_lr(num_updates) - else: - return None diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/main.py b/cv/classification/acmix/pytorch/Swin-Transformer/main.py deleted file mode 100644 index 796be9e76..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/main.py +++ /dev/null @@ -1,383 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import time -import argparse -import datetime -import numpy as np - -import torch -import torch.backends.cudnn as cudnn -import torch.distributed as dist - -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.utils import accuracy, AverageMeter - -from config import get_config -from models import build_model -from data import build_loader -from lr_scheduler import build_scheduler -from optimizer import build_optimizer -from logger import create_logger -from utils import load_checkpoint, save_checkpoint, get_grad_norm, auto_resume_helper, reduce_tensor - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - - -def parse_option(): - parser = argparse.ArgumentParser('Swin Transformer training and evaluation script', add_help=False) - parser.add_argument('--cfg', type=str, required=True, metavar="FILE", help='path to config file', ) - parser.add_argument( - "--opts", - help="Modify config options by adding 'KEY VALUE' pairs. ", - default=None, - nargs='+', - ) - - # easy config modification - parser.add_argument('--batch-size', type=int, help="batch size for single GPU") - parser.add_argument('--data-path', type=str, help='path to dataset') - parser.add_argument('--zip', action='store_true', help='use zipped dataset instead of folder dataset') - parser.add_argument('--cache-mode', type=str, default='part', choices=['no', 'full', 'part'], - help='no: no cache, ' - 'full: cache all data, ' - 'part: sharding the dataset into nonoverlapping pieces and only cache one piece') - parser.add_argument('--resume', help='resume from checkpoint') - parser.add_argument('--accumulation-steps', type=int, help="gradient accumulation steps") - parser.add_argument('--use-checkpoint', action='store_true', - help="whether to use gradient checkpointing to save memory") - parser.add_argument('--amp-opt-level', type=str, default='O2', choices=['O0', 'O1', 'O2'], - help='mixed precision opt level, if O0, no amp is used') - parser.add_argument('--output', default='output', type=str, metavar='PATH', - help='root of output folder, the full path is // (default: output)') - parser.add_argument('--tag', help='tag of experiment') - parser.add_argument('--eval', action='store_true', help='Perform evaluation only') - parser.add_argument('--throughput', action='store_true', help='Test throughput only') - - # distributed training - parser.add_argument("--local_rank", type=int, required=True, help='local rank for DistributedDataParallel') - parser.add_argument('--debug', action='store_true', default=False, - help='Debug mode.') - - args, unparsed = parser.parse_known_args() - - config = get_config(args) - - return args, config - - -def backward_hook(module, grad_input, grad_output): - #print("==="*20) - print('Inside ' + module.__class__.__name__ + ' backward') - #print("input:") - #print([x.shape if x is not None else 0 for x in grad_input]) - #print("ouput:") - #print([x.shape if x is not None else 0 for x in grad_output]) - - -def forward_hook(module, fea_input, fea_output): - #print("==="*20) - print('Inside ' + module.__class__.__name__ + ' forward') - #print("input: ") - #print([x.shape if x is not None else 0 for x in fea_input]) - #print("ouput:") - #print([x.shape if x is not None else 0 for x in fea_output]) - - -def main(args, config): - dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn = build_loader(config) - - logger.info(f"Creating model:{config.MODEL.TYPE}/{config.MODEL.NAME}") - model = build_model(config) - model.cuda() - logger.info(str(model)) - - if args.debug: - for net in model.children(): - net.register_backward_hook(backward_hook) - net.register_forward_hook(forward_hook) - - optimizer = build_optimizer(config, model) - if config.AMP_OPT_LEVEL != "O0": - model, optimizer = amp.initialize(model, optimizer, opt_level=config.AMP_OPT_LEVEL) - model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.LOCAL_RANK], broadcast_buffers=False) - model_without_ddp = model.module - - n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params: {n_parameters}") - if hasattr(model_without_ddp, 'flops'): - flops = model_without_ddp.flops() - logger.info(f"number of GFLOPs: {flops / 1e9}") - - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train)) - - if config.AUG.MIXUP > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif config.MODEL.LABEL_SMOOTHING > 0.: - criterion = LabelSmoothingCrossEntropy(smoothing=config.MODEL.LABEL_SMOOTHING) - else: - criterion = torch.nn.CrossEntropyLoss() - - max_accuracy = 0.0 - - if config.TRAIN.AUTO_RESUME: - resume_file = auto_resume_helper(config.OUTPUT) - if resume_file: - if config.MODEL.RESUME: - logger.warning(f"auto-resume changing resume file from {config.MODEL.RESUME} to {resume_file}") - config.defrost() - config.MODEL.RESUME = resume_file - config.freeze() - logger.info(f'auto resuming from {resume_file}') - else: - logger.info(f'no checkpoint found in {config.OUTPUT}, ignoring auto resume') - - if config.MODEL.RESUME: - max_accuracy = load_checkpoint(config, model_without_ddp, optimizer, lr_scheduler, logger) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - if config.EVAL_MODE: - return - - if config.THROUGHPUT_MODE: - throughput(data_loader_val, model, logger) - return - - logger.info("Start training") - start_time = time.time() - for epoch in range(config.TRAIN.START_EPOCH, config.TRAIN.EPOCHS): - logger.info(f"epoch: {epoch}") - data_loader_train.sampler.set_epoch(epoch) - - train_one_epoch(config, model, criterion, data_loader_train, optimizer, epoch, mixup_fn, lr_scheduler) - if dist.get_rank() == 0 and (epoch % config.SAVE_FREQ == 0 or epoch == (config.TRAIN.EPOCHS - 1)): - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger) - - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - max_accuracy = max(max_accuracy, acc1) - logger.info(f'Max accuracy: {max_accuracy:.2f}%') - - total_time = time.time() - start_time - total_time_str = str(datetime.timedelta(seconds=int(total_time))) - logger.info('Training time {}'.format(total_time_str)) - - -def train_one_epoch(config, model, criterion, data_loader, optimizer, epoch, mixup_fn, lr_scheduler): - model.train() - optimizer.zero_grad() - - num_steps = len(data_loader) - batch_time = AverageMeter() - loss_meter = AverageMeter() - norm_meter = AverageMeter() - - ngpus = dist.get_world_size() - count = 0 - fps_start = time.time() - start = time.time() - end = time.time() - for idx, (samples, targets) in enumerate(data_loader): - samples = samples.cuda(non_blocking=True) - targets = targets.cuda(non_blocking=True) - - if mixup_fn is not None: - samples, targets = mixup_fn(samples, targets) - - outputs = model(samples) - count += len(samples) - - if config.TRAIN.ACCUMULATION_STEPS > 1: - loss = criterion(outputs, targets) - loss = loss / config.TRAIN.ACCUMULATION_STEPS - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - if (idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0: - optimizer.step() - optimizer.zero_grad() - lr_scheduler.step_update(epoch * num_steps + idx) - else: - loss = criterion(outputs, targets) - optimizer.zero_grad() - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - optimizer.step() - lr_scheduler.step_update(epoch * num_steps + idx) - - torch.cuda.synchronize() - - loss_meter.update(loss.item(), targets.size(0)) - norm_meter.update(grad_norm) - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - lr = optimizer.param_groups[0]['lr'] - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - etas = batch_time.avg * (num_steps - idx) - fps = count * ngpus / (time.time() - fps_start) - logger.info( - f'Train: [{epoch}/{config.TRAIN.EPOCHS}][{idx}/{num_steps}]\t' - f'eta {datetime.timedelta(seconds=int(etas))} lr {lr:.6f}\t' - f'time {batch_time.val:.4f} ({batch_time.avg:.4f})\t' - f'fps {fps:.4f}\t' - f'loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'grad_norm {norm_meter.val:.4f} ({norm_meter.avg:.4f})\t' - f'mem {memory_used:.0f}MB') - count = 0 - fps_start = time.time() - epoch_time = time.time() - start - logger.info(f"EPOCH {epoch} training takes {datetime.timedelta(seconds=int(epoch_time))}") - - -@torch.no_grad() -def validate(config, data_loader, model): - criterion = torch.nn.CrossEntropyLoss() - model.eval() - - batch_time = AverageMeter() - loss_meter = AverageMeter() - acc1_meter = AverageMeter() - acc5_meter = AverageMeter() - - end = time.time() - for idx, (images, target) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - output = model(images) - - # measure accuracy and record loss - loss = criterion(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - acc1 = reduce_tensor(acc1) - acc5 = reduce_tensor(acc5) - loss = reduce_tensor(loss) - - loss_meter.update(loss.item(), target.size(0)) - acc1_meter.update(acc1.item(), target.size(0)) - acc5_meter.update(acc5.item(), target.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - logger.info( - f'Test: [{idx}/{len(data_loader)}]\t' - f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' - f'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' - f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' - f'Mem {memory_used:.0f}MB') - logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') - return acc1_meter.avg, acc5_meter.avg, loss_meter.avg - - -@torch.no_grad() -def throughput(data_loader, model, logger): - model.eval() - - for idx, (images, _) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - batch_size = images.shape[0] - for i in range(50): - model(images) - torch.cuda.synchronize() - logger.info(f"throughput averaged with 30 times") - tic1 = time.time() - for i in range(30): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - logger.info(f"batch_size {batch_size} throughput {30 * batch_size / (tic2 - tic1)}") - return - - -if __name__ == '__main__': - args, config = parse_option() - - if config.AMP_OPT_LEVEL != "O0": - assert amp is not None, "amp not installed!" - - if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ: - rank = int(os.environ["RANK"]) - world_size = int(os.environ['WORLD_SIZE']) - print(f"RANK and WORLD_SIZE in environ: {rank}/{world_size}") - else: - rank = -1 - world_size = -1 - torch.cuda.set_device(config.LOCAL_RANK) - torch.distributed.init_process_group(backend='nccl', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.barrier() - - seed = config.SEED + dist.get_rank() - torch.manual_seed(seed) - np.random.seed(seed) - cudnn.benchmark = True - - # linear scale the learning rate according to total batch size, may not be optimal - linear_scaled_lr = config.TRAIN.BASE_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_warmup_lr = config.TRAIN.WARMUP_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_min_lr = config.TRAIN.MIN_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - # gradient accumulation also need to scale the learning rate - if config.TRAIN.ACCUMULATION_STEPS > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_warmup_lr = linear_scaled_warmup_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_min_lr = linear_scaled_min_lr * config.TRAIN.ACCUMULATION_STEPS - config.defrost() - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_LR = linear_scaled_warmup_lr - config.TRAIN.MIN_LR = linear_scaled_min_lr - config.freeze() - - os.makedirs(config.OUTPUT, exist_ok=True) - logger = create_logger(output_dir=config.OUTPUT, dist_rank=dist.get_rank(), name=f"{config.MODEL.NAME}") - - if dist.get_rank() == 0: - path = os.path.join(config.OUTPUT, "config.json") - with open(path, "w") as f: - f.write(config.dump()) - logger.info(f"Full config saved to {path}") - - # print config - logger.info(config.dump()) - - main(args, config) diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/models/__init__.py b/cv/classification/acmix/pytorch/Swin-Transformer/models/__init__.py deleted file mode 100644 index 2d9c65e39..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .build import build_model \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/models/build.py b/cv/classification/acmix/pytorch/Swin-Transformer/models/build.py deleted file mode 100644 index b49ce11c3..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/models/build.py +++ /dev/null @@ -1,51 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from .swin_transformer import SwinTransformer -from .swin_transformer_acmix import SwinTransformer_acmix - - -def build_model(config): - model_type = config.MODEL.TYPE - if model_type == 'swin': - model = SwinTransformer(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - elif model_type == 'swin_acmix': - model = SwinTransformer_acmix(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - else: - raise NotImplementedError(f"Unkown model: {model_type}") - - return model diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer.py b/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer.py deleted file mode 100644 index de1419086..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer.py +++ /dev/null @@ -1,590 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ - -class GELU(nn.Module): - - def forward(self, x): - return F.gelu(x) - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=GELU, drop=0.): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 - - -class WindowAttention(nn.Module): - r""" Window based multi-head self attention (W-MSA) module with relative position bias. - It supports both of shifted and non-shifted window. - - Args: - dim (int): Number of input channels. - window_size (tuple[int]): The height and width of the window. - num_heads (int): Number of attention heads. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set - attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 - proj_drop (float, optional): Dropout ratio of output. Default: 0.0 - """ - - def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.): - - super().__init__() - self.dim = dim - self.window_size = window_size # Wh, Ww - self.num_heads = num_heads - head_dim = dim // num_heads - self.scale = qk_scale or head_dim ** -0.5 - - # define a parameter table of relative position bias - self.relative_position_bias_table = nn.Parameter( - torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH - - # get pair-wise relative position index for each token inside the window - coords_h = torch.arange(self.window_size[0]) - coords_w = torch.arange(self.window_size[1]) - coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww - coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += self.window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 - relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - self.register_buffer("relative_position_index", relative_position_index) - - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) - self.attn_drop = nn.Dropout(attn_drop) - self.proj = nn.Linear(dim, dim) - self.proj_drop = nn.Dropout(proj_drop) - - trunc_normal_(self.relative_position_bias_table, std=.02) - self.softmax = nn.Softmax(dim=-1) - - def forward(self, x, mask=None): - """ - Args: - x: input features with shape of (num_windows*B, N, C) - mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None - """ - B_, N, C = x.shape - qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) - q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) - - q = q * self.scale - attn = (q @ k.transpose(-2, -1)) - - relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( - self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH - relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww - attn = attn + relative_position_bias.unsqueeze(0) - - 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) - else: - attn = self.softmax(attn) - - attn = self.attn_drop(attn) - - x = (attn @ v).transpose(1, 2).reshape(B_, N, C) - x = self.proj(x) - x = self.proj_drop(x) - return x - - def extra_repr(self) -> str: - return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}' - - def flops(self, N): - # calculate flops for 1 window with token length of N - flops = 0 - # qkv = self.qkv(x) - flops += N * self.dim * 3 * self.dim - # attn = (q @ k.transpose(-2, -1)) - flops += self.num_heads * N * (self.dim // self.num_heads) * N - # x = (attn @ v) - flops += self.num_heads * N * N * (self.dim // self.num_heads) - # x = self.proj(x) - flops += N * self.dim * self.dim - return flops - - -class SwinTransformerBlock(nn.Module): - r""" Swin Transformer Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0., - act_layer=GELU, norm_layer=nn.LayerNorm): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.norm1 = norm_layer(dim) - self.attn = WindowAttention( - dim, window_size=to_2tuple(self.window_size), num_heads=num_heads, - qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) - - if self.shift_size > 0: - # calculate attention mask for SW-MSA - H, W = self.input_resolution - img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1 - 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 - - mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1 - 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: - attn_mask = None - - self.register_buffer("attn_mask", attn_mask) - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = self.norm1(x) - x = x.view(B, H, W, C) - - # cyclic shift - if self.shift_size > 0: - shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) - else: - shifted_x = x - - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C - - # W-MSA/SW-MSA - attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C - - # merge windows - attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) - shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C - - # 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 - x = x.view(B, H * W, C) - - # FFN - x = shortcut + self.drop_path(x) - x = x + self.drop_path(self.mlp(self.norm2(x))) - - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - # W-MSA/SW-MSA - nW = H * W / self.window_size / self.window_size - flops += nW * self.attn.flops(self.window_size * self.window_size) - # mlp - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(4 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.norm(x) - x = self.reduction(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = H * W * self.dim - flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin Transformer layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., - drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinTransformerBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop, attn_drop=attn_drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - for blk in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(blk, x) - else: - x = blk(x) - if self.downsample is not None: - x = self.downsample(x) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinTransformer(nn.Module): - r""" Swin Transformer - A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - - https://arxiv.org/pdf/2103.14030 - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin Transformer layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None - drop_rate (float): Dropout rate. Default: 0 - attn_drop_rate (float): Attention dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None, - drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - use_checkpoint=False, **kwargs): - super().__init__() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=.02) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop_rate, attn_drop=attn_drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - use_checkpoint=use_checkpoint) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {'relative_position_bias_table'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - - for layer in self.layers: - x = layer(x) - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x - - def forward(self, x): - x = self.forward_features(x) - x = self.head(x) - return x - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer_acmix.py b/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer_acmix.py deleted file mode 100644 index 3c84da9b6..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/models/swin_transformer_acmix.py +++ /dev/null @@ -1,650 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer + ACmix -# Copyright (c) 2021 Xuran Pan -# Written by Xuran Pan -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ - -class GELU(nn.Module): - - def forward(self, x): - return F.gelu(x) - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=GELU, drop=0.): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 ones(tensor): - if tensor is not None: - tensor.data.fill_(0.5) - -def zeros(tensor): - if tensor is not None: - tensor.data.fill_(0.0) - - -class WindowAttention_acmix(nn.Module): - r""" Window based multi-head self attention (W-MSA) module with relative position bias. - It supports both of shifted and non-shifted window. - - Args: - dim (int): Number of input channels. - window_size (tuple[int]): The height and width of the window. - num_heads (int): Number of attention heads. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set - attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 - proj_drop (float, optional): Dropout ratio of output. Default: 0.0 - """ - - def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.): - - super().__init__() - self.dim = dim - self.window_size = window_size # Wh, Ww - self.num_heads = num_heads - head_dim = dim // num_heads - self.scale = qk_scale or head_dim ** -0.5 - - # define a parameter table of relative position bias - self.relative_position_bias_table = nn.Parameter( - torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH - - # get pair-wise relative position index for each token inside the window - coords_h = torch.arange(self.window_size[0]) - coords_w = torch.arange(self.window_size[1]) - coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww - coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += self.window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 - relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - self.register_buffer("relative_position_index", relative_position_index) - - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) - self.attn_drop = nn.Dropout(attn_drop) - self.proj = nn.Linear(dim, dim) - self.proj_drop = nn.Dropout(proj_drop) - - trunc_normal_(self.relative_position_bias_table, std=.02) - self.softmax = nn.Softmax(dim=-1) - - # fully connected layer in Fig.2 - self.fc = nn.Conv2d(3*self.num_heads, 9, kernel_size=1, bias=True) - # group convolution layer in Fig.3 - self.dep_conv = nn.Conv2d(9*dim//self.num_heads, dim, kernel_size=3, bias=True, groups=dim//self.num_heads, padding=1) - # rates for both paths - self.rate1 = torch.nn.Parameter(torch.Tensor(1)) - self.rate2 = torch.nn.Parameter(torch.Tensor(1)) - self.reset_parameters() - - def reset_parameters(self): - ones(self.rate1) - ones(self.rate2) - # shift initialization for group convolution - kernel = torch.zeros(9, 3, 3) - for i in range(9): - kernel[i, i//3, i%3] = 1. - kernel = kernel.squeeze(0).repeat(self.dim, 1, 1, 1) - self.dep_conv.weight = nn.Parameter(data=kernel, requires_grad=True) - self.dep_conv.bias = zeros(self.dep_conv.bias) - - - def forward(self, x, H, W, mask=None): - """ - Args: - x: input features with shape of (B, H, W, C) - mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None - """ - - qkv = self.qkv(x) - - # fully connected layer - f_all = qkv.reshape(x.shape[0], H*W, 3*self.num_heads, -1).permute(0, 2, 1, 3) # B, 3*nhead, H*W, C//nhead - f_conv = self.fc(f_all).permute(0, 3, 1, 2).reshape(x.shape[0], 9*x.shape[-1]//self.num_heads, H, W) # B, 9*C//nhead, H, W - # group conovlution - out_conv = self.dep_conv(f_conv).permute(0, 2, 3, 1) # B, H, W, C - - # partition windows - qkv = window_partition(qkv, self.window_size[0]) # nW*B, window_size, window_size, C - - B_, _, _, C = qkv.shape - - qkv = qkv.view(-1, self.window_size[0] * self.window_size[1], C) # nW*B, window_size*window_size, C - - N = self.window_size[0] * self.window_size[1] - C = C // 3 - - qkv = qkv.reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) - q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) - - q = q * self.scale - attn = (q @ k.transpose(-2, -1)) - - relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( - self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH - relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww - attn = attn + relative_position_bias.unsqueeze(0) - - 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) - else: - attn = self.softmax(attn) - - attn = self.attn_drop(attn) - - x = (attn @ v).transpose(1, 2).reshape(B_, N, C) - x = self.proj(x) - - # merge windows - x = x.view(-1, self.window_size[0], self.window_size[1], C) - x = window_reverse(x, self.window_size[0], H, W) # B H' W' C - - x = self.rate1 * x + self.rate2 * out_conv - - x = self.proj_drop(x) - return x - - def extra_repr(self) -> str: - return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}' - - def flops(self, N): - # calculate flops for 1 window with token length of N - flops = 0 - # qkv = self.qkv(x) - flops += N * self.dim * 3 * self.dim - # attn = (q @ k.transpose(-2, -1)) - flops += self.num_heads * N * (self.dim // self.num_heads) * N - # x = (attn @ v) - flops += self.num_heads * N * N * (self.dim // self.num_heads) - # x = self.proj(x) - flops += N * self.dim * self.dim - return flops - - -class SwinTransformerBlock(nn.Module): - r""" Swin Transformer Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0., - act_layer=GELU, norm_layer=nn.LayerNorm): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.norm1 = norm_layer(dim) - self.attn = WindowAttention_acmix( - dim, window_size=to_2tuple(self.window_size), num_heads=num_heads, - qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) - - if self.shift_size > 0: - # calculate attention mask for SW-MSA - H, W = self.input_resolution - img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1 - 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 - - mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1 - 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: - attn_mask = None - - self.register_buffer("attn_mask", attn_mask) - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = self.norm1(x) - x = x.view(B, H, W, C) - - # cyclic shift - if self.shift_size > 0: - shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) - else: - shifted_x = x - - shifted_x = self.attn(shifted_x, H, W, mask=self.attn_mask) - - # 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 - x = x.view(B, H * W, C) - - # FFN - x = shortcut + self.drop_path(x) - x = x + self.drop_path(self.mlp(self.norm2(x))) - - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - # W-MSA/SW-MSA - nW = H * W / self.window_size / self.window_size - flops += nW * self.attn.flops(self.window_size * self.window_size) - # mlp - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - - # FC for ACmix - flops += 3 * self.dim * H * W * 9 - # Group convolution for ACmix - flops += 9 * self.dim * 9 * H * W - - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(4 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.norm(x) - x = self.reduction(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = H * W * self.dim - flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin Transformer layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., - drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinTransformerBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop, attn_drop=attn_drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - for blk in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(blk, x) - else: - x = blk(x) - if self.downsample is not None: - x = self.downsample(x) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinTransformer_acmix(nn.Module): - r""" Swin Transformer - A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - - https://arxiv.org/pdf/2103.14030 - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin Transformer layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None - drop_rate (float): Dropout rate. Default: 0 - attn_drop_rate (float): Attention dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None, - drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - use_checkpoint=False, **kwargs): - super().__init__() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=.02) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop_rate, attn_drop=attn_drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - use_checkpoint=use_checkpoint) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {'relative_position_bias_table'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - - for layer in self.layers: - x = layer(x) - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x - - def forward(self, x): - x = self.forward_features(x) - x = self.head(x) - return x - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops - - -if __name__ == '__main__': - - model = SwinTransformer_acmix(depths=[2,2,6,2], drop_path_rate=0.3) - print(model.flops()) - total_trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad) - print(f'{total_trainable_params:,} training parameters.') \ No newline at end of file diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/optimizer.py b/cv/classification/acmix/pytorch/Swin-Transformer/optimizer.py deleted file mode 100644 index 3c57ce0bc..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/optimizer.py +++ /dev/null @@ -1,57 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from torch import optim as optim - - -def build_optimizer(config, model): - """ - Build optimizer, set weight decay of normalization to 0 by default. - """ - skip = {} - skip_keywords = {} - if hasattr(model, 'no_weight_decay'): - skip = model.no_weight_decay() - if hasattr(model, 'no_weight_decay_keywords'): - skip_keywords = model.no_weight_decay_keywords() - parameters = set_weight_decay(model, skip, skip_keywords) - - opt_lower = config.TRAIN.OPTIMIZER.NAME.lower() - optimizer = None - if opt_lower == 'sgd': - optimizer = optim.SGD(parameters, momentum=config.TRAIN.OPTIMIZER.MOMENTUM, nesterov=True, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - elif opt_lower == 'adamw': - optimizer = optim.AdamW(parameters, eps=config.TRAIN.OPTIMIZER.EPS, betas=config.TRAIN.OPTIMIZER.BETAS, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - - return optimizer - - -def set_weight_decay(model, skip_list=(), skip_keywords=()): - has_decay = [] - no_decay = [] - - for name, param in model.named_parameters(): - if not param.requires_grad: - continue # frozen weights - if len(param.shape) == 1 or name.endswith(".bias") or (name in skip_list) or \ - check_keywords_in_name(name, skip_keywords): - no_decay.append(param) - # print(f"{name} has no weight decay") - else: - has_decay.append(param) - return [{'params': has_decay}, - {'params': no_decay, 'weight_decay': 0.}] - - -def check_keywords_in_name(name, keywords=()): - isin = False - for keyword in keywords: - if keyword in name: - isin = True - return isin diff --git a/cv/classification/acmix/pytorch/Swin-Transformer/utils.py b/cv/classification/acmix/pytorch/Swin-Transformer/utils.py deleted file mode 100644 index fd2df673f..000000000 --- a/cv/classification/acmix/pytorch/Swin-Transformer/utils.py +++ /dev/null @@ -1,92 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import torch -import torch.distributed as dist - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - - -def load_checkpoint(config, model, optimizer, lr_scheduler, logger): - logger.info(f"==============> Resuming form {config.MODEL.RESUME}....................") - if config.MODEL.RESUME.startswith('https'): - checkpoint = torch.hub.load_state_dict_from_url( - config.MODEL.RESUME, map_location='cpu', check_hash=True) - else: - checkpoint = torch.load(config.MODEL.RESUME, map_location='cpu') - msg = model.load_state_dict(checkpoint['model'], strict=False) - logger.info(msg) - max_accuracy = 0.0 - if not config.EVAL_MODE and 'optimizer' in checkpoint and 'lr_scheduler' in checkpoint and 'epoch' in checkpoint: - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['lr_scheduler']) - config.defrost() - config.TRAIN.START_EPOCH = checkpoint['epoch'] + 1 - config.freeze() - if 'amp' in checkpoint and config.AMP_OPT_LEVEL != "O0" and checkpoint['config'].AMP_OPT_LEVEL != "O0": - amp.load_state_dict(checkpoint['amp']) - logger.info(f"=> loaded successfully '{config.MODEL.RESUME}' (epoch {checkpoint['epoch']})") - if 'max_accuracy' in checkpoint: - max_accuracy = checkpoint['max_accuracy'] - - del checkpoint - torch.cuda.empty_cache() - return max_accuracy - - -def save_checkpoint(config, epoch, model, max_accuracy, optimizer, lr_scheduler, logger): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'epoch': epoch, - 'config': config} - if config.AMP_OPT_LEVEL != "O0": - save_state['amp'] = amp.state_dict() - - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - - -def get_grad_norm(parameters, norm_type=2): - if isinstance(parameters, torch.Tensor): - parameters = [parameters] - parameters = list(filter(lambda p: p.grad is not None, parameters)) - norm_type = float(norm_type) - total_norm = 0 - for p in parameters: - param_norm = p.grad.data.norm(norm_type) - total_norm += param_norm.item() ** norm_type - total_norm = total_norm ** (1. / norm_type) - return total_norm - - -def auto_resume_helper(output_dir): - checkpoints = os.listdir(output_dir) - checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith('pth')] - print(f"All checkpoints founded in {output_dir}: {checkpoints}") - if len(checkpoints) > 0: - latest_checkpoint = max([os.path.join(output_dir, d) for d in checkpoints], key=os.path.getmtime) - print(f"The latest checkpoint founded: {latest_checkpoint}") - resume_file = latest_checkpoint - else: - resume_file = None - return resume_file - - -def reduce_tensor(tensor): - rt = tensor.clone() - dist.all_reduce(rt, op=dist.ReduceOp.SUM) - rt /= dist.get_world_size() - return rt diff --git a/cv/classification/acmix/pytorch/figure/main.png b/cv/classification/acmix/pytorch/figure/main.png deleted file mode 100644 index 8330bdf936214182637a23affa964790b6941741..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282015 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

_LN|H-2b%KM=VDs$b}uUvo4LWqZlr&wX&fe2`! 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

9Bv3l=p+^T<&NjBKqy{vR<7@u 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%0D9zt}i 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 OdN20zZMmqf-~R#g@=me< diff --git a/cv/classification/acmix/pytorch/figure/result.png b/cv/classification/acmix/pytorch/figure/result.png deleted file mode 100644 index 6c2171f54aa091381c5c2d6b7dc3ac8a9f9b9069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152627 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

  • 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

    3xohVm`rJDyYem7HkBIRji1P|E&w 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 Ks)foAg8mn8LJCFz diff --git a/cv/classification/acmix/pytorch/figure/shift.png b/cv/classification/acmix/pytorch/figure/shift.png deleted file mode 100644 index ff1e52529d75db9f090a52dd490052d044328c14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116502 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

    nYvQIQgDi-v5F)l)TIQVDln=UZxY& zkiW0wJJ9oNU(`93OZ<%Hp-N<*qW|py$(~CQZ{oWkDPru`Z`!d7>*rG+wQ+QqgqWWE z9ysiI>-3`ErE}PgL@v85k)ET2;pxYRI+a1_(+XL>I4%CH1hhFN0n0rl|R zXa8W~qS!uRUVWYxB_j*V&r@nDa&iktUL=yByTH$Q%TDjav;Q^xqrB2hzEjohBZ;Nd zlTh7pl=vr7<_3 z-z6fk@*n1W38pF_(Z{em7pHkVLq4MinTEH6A(P;S(#{Q8v@(> z|AES^`XWmVtYqY2px(1*dBS>y_am#mUXs&wZpJJ9fzO!rwM#5%Jl_*;e+RDWAGkyZ zdsp3l$`6KeKvR(rCzIVnH|qRFl;i>hJ6wNj=IeqVgCLi4N->hGX^dtz^+4~2KV9za zUsRE3?h*#4F$A=Cym|DN5#mVR{poYkJAU3)nX-a73aB@QrY4K=rQvn+<=O&EPWD!Z z*W^_04`}18LOTJL5fBr3?DxK~5`AJQu*?grq@yv-^OZhlMda?R{^)isHMRVi zq}(9i{=n06BFYD6C4PUL4-@|U+ZB=13NMAaCl*O4#Gqw<@^9n7 z>}IXlEN)v~ZU!COh5_w0LK&Q?CFxz!7C$I^2?yJXR)yR&)P|CwMt6YOhrWV?o}Ql5 zrLDK9ZzG{hQIxJ$s(?pP$C~mH?wTlOx)yv!`cvX-b;9qpvrC1o*XNcFy9ykg*_PAc z&@6tW<58f#j7 z_`W#zm*cHruDXkd%V!1dn_Y{l)m+||hM6@dH$;wgrOk!!B)t38Ho#c3{gV}T#CG!? z-dOT#+y>%iBBePZ0IdNlUF*W8&X?_`X^ei-P#e8kzyW%{o)i{Y0`WNG`2y$dRnO1< zMs=U2Z7Ga?saRsh5K9bmk01y`c+AI(-p~W^pXM zP^d4E{hU>@e|cpp)6Y1ynP~OlRgJQF?Ll4b3o#dmqRWXEe+GMh+ety4MNRD{ z@$|z#O!b)DLJ%~o9)XRG`UvoQei@3K7J%6|yE|ZL0p=!900V8%PtcpoJbFYcB9a7z zF5D7U?+a!_-(9jC&3r~Cri=bi!7}iiBl}w}9ls6R=!Np7mQCifAMj@hBPIZG=DX)) zTbG@j+>6{d;-Cs(9}Ug1^`bEH?3MI?RcBDu#*|J$pb1(?*kSUIYrsYi)7|2|iJZ=d zHm$XK(*GfAFcTE6unePbk#I&8zJKb&V|e`wW8NG3kjLw3XvCuZpy%aTOmMxdygWTO zcNCl>BXYDz2h|6FdAbE!Y+@Z}?)p_vjVHf88+9Gf$5W#>f;!vqL;xh8pzis1U55%U zjaA=gGDLQ^=-mp)-Y3XNNgrY=(q{kp7LO0JvxZ(i?F|8_^{u}cY>WF_`9Eb9hzIK@ zs$6YAY2@@_ago?hIH`N)l}+=vZ$lFSX&*o4xs?3*!wkc@N1^@3QgM@gaBy0^5MO^J>f{Wo zz;?)m`o_)=CPReL?y@KRv#{0N%a+Yyzpp+*#d9wa?eu<8L&9ydGh>kKOR(nk`z4~B zwIyMEb~QWXk`gtVR!dgDd+r>r7Gr~wlN+2IFlCuHZ+59E{uiXfOi{SD6fU|^&;K{U z-yAk#z!a(UrZ%T$q~dNNaR5XC*1%$Xn`wn9tpx`kybZO8q=Yhu%*}+tX=xS~7Q|qs zi)d4jsF5RYQmI)RA(U>3iBz)yquo5+M@?{7oyX;pYFAVPEVU43X+mKAnzj8aNKHShGG%X6v&&@~P2uC-Y3-JuI{4t<=E?CAN zi1#hL8~pazlg%M74V@nASeFK|6c&CMQ;7@qAjhno@dp5X&cE8m-q`9`Kl|q96WN^+ z{GIGG$Li$42)7#bxcO6NBuNU?Sv2o?6lCHKl}{L0Zn{8HcF^JA*Yb}0;o^koxPC@R zaNMQE#~Dy7>ubAyL-;vNJBdjBmStg$&nI^Bbu-OL`<_;-N;WNFNgZ-Iq4%c7A4sN0 z0X-v=aXO2@UjvlEgpwIQf!R;&`ro0RS%1|OJvAXugjW2@Y zd2L7(67F(WQ8^W-q})2rt^6a z!~KC&*Id=L+uTSUv^$=&9>eyV%h7uY#q4pQ3|eJ_2gv*8^Cc>UHfa z1EG?4&Jhj;q|^%!u23}!Vi7yU8vj{{z-{;P=4D{W@$}X>7hU)5PMgT5QNxz>=lTwI z<~NA{B=6!K%Z;0yjVN^|=X=b=yANvQSxPor0yL4B95Kyzg!!Q-2Ik`hmBV|%{RN*a@&BvDb%~ZkAPP%t z=?I(ZWSpku{7<6o2jf^N7ys6=-o36kuYw~Xwj?4VIJlXClx*I;`uQG6!v{-k$S;#~ z%!2#y=Q~Y&z{P?M@vFeg}g~6-G}Y%WZ$Hsl%@ar|A1FsR-Ubs<|VK|7hY7yZs6;&3mO`b6fZXt%JT23&DauS^Io=j`02RgZX}h%#Qdww zy;ucr?Xx(dweo;u8Yjt0Kb%kSr`$ysyNsKz9}b?ZYAZQhGn?ZTa2oR2FRFNOFtodsOcGwh3R z5)$ylpaTKK%U8+B`YNxa14j>Q6CAJ~0Xj8me1VHkb?-GCsYhoh?tdx8&p1YsE$Il^ zL+E{j&#?sUCC}a+vz%El?dRaVHX&84p*IE3 zMP(4zxWB-@XGg}6{Oe1GMgGy@X-!~&%}1-VrgM$ei*25UP}KYTWJ*dGZ$YCCu#Qr~ zqKu3$L8t}&5{)2cdju2{v>#5K?v=0K=Km_NLM{dQU*)y3JkhTW@xmeQyVBvchFWiG z4X-=lrsID%8|hE*GY$dNp!mKw9w^arQ9otj4WXRoPJOS2cR)xTe;^Ge$I zS^sf2fYVuS=Tc-p9r9EGk`e*8)$542OkJtzPihK=D39L1M6)u%adUB87uImr^)FZP|1FbEnJRtY-@LnBYAQGUkDK zHZ|_y!u>Y~WdnG_e{Q1C0pEa%qyiV~p@%X58XWR(h=6S%4+w~!Y|s8^Pv8v&R*uK7 z#*axa#~9tHM?KA-ZuqV(AZ91}L)Q5O;-Qa284Sz`SB8;PT#LvML^sUBOf(VdlBjlzOSbPAo+BPj$0?r&}%Z?ho*liq=^;eVFLTA3#a&;!oVR-z%a&E-0?mjNUE#)0FCi zR$?!l3dPiz0$JP|UVPg}GT{9O7chA9lNFH#Q+CI2aCF@ZyH0v(rSWTY-dB-rzMJW9 zV0Y8`K4Kl1MLpUhnT#E->{jp^reQ6MTDI93@3W>GcS`63;)bhSq5C{%b-1)`TnXf) zlbPZ%I<;QA(=nO`Sk^~*tHX1Zr_#?D0gaXROJ2gcRF^^VVVyrGyY{>KXO2YIHqZBW z*B*pM44jpRR3{9F2J1b7<|x)N=QegohNH{ugikGAkEVYPn~5l~;U;~jHqF~o zVgGL!i`P?ni$EP7&vb*KZ>T@ris;z+QcSDJwugc~&X@dRy`PnD*a+))2-a|f7PicO zjION?IiI38(l8aAjEqlMTE+7;{^BvL!cYW4e9tALh7*=gDflH*f0}_YD75{(1v#>5r11Rq z4iSw=A|Ne*M$Bw%y!_;Qg)sJrslzX0RDf}yS8DN3xQK>snU2Q5(IvCoEvWKArf$mDfsV$001Uyfmc;ZLYW) zS!l?6fcCr`G!eENTBik>MC(6Q=?z}%=(^GR#_hQ_tao=T6tUy7*k~OZjZ`%KaA#Zu z%8-F>1NVlX@NB_3x38n4o8kL*i{0bJmdX3WHu-4%W8PYHsa`n0BTQz|h6soizw;~b z&c!je^%0$jx^-^YkEcKM_8LfxK7b$$b(%x{qc3h$o%}R(qf};=7Jl4 z4wzM2?g_X4cx#bJjXHWdGcYv@5JxV~dg(l!fX!)&^yX-54He@-36$}yuIZ!aiW^z1#$rq1m; zZaQK6uNEK%&it17%idj0HZIlq@guv^Xtv=Z&C`*4K=*SZpm($VJ%7G3d8CZ5^>H9N zMpF0kPziq&^OnaK!@-Y|yy!;i_}>Jp=tjTU|I#GAAM1;FyBf!(he^90@Xf7ZSMf|I z-4+^K`=)!BfI_BiF^WUb&?88M;Jza4|23+<3TsNfm+XR0e@re*G?V`~m#1gicdtS% z{_<0N7(F=HsTgTk@#liaC{YM#>} z+6X9@0qZO(7jl4Skt*BPN%6vcv2_Y%fTz(p@3K8}@}AN{W}|IChbYsf2#Y*T;QhAu z_KaGcFmIgOqx$}6L*lK=1DDlP%*$jT+DJt&L>JGgoGavv^(aR{F$n=}ggBiVSX|vj zb{+Mojhat)q6j=+{%D4m47ljpNVx-(z)-n`gJ-z^68SZGt$e@qT~u7~fUaT1HJ^iVjP^z$|%YY7et=M^HPENdUeXajxKX;_l?Atc- z1%rFFiJwC`S0<8?zyH=NEiF4l6RO?9-Kr*roDBzfd=9V)M9R$C3Z!nLT5sO0n2BiX zNwIlf!)Nt-b0r%fYo_AvSdN}=UnS``s<8vrpvM_@qgtJD)tSb#;nvp-cFy98nd|2a zJEu(!AKX82q*i$NR6Q&BAQSeIh?+C11=*t25eRPMpWP~>=>+GU3b(Pvd<&bafjK$% zE8npGh=^sRv912>xqUX#j!d%Kd6ygP$o$ivbz#%{XAc@gBOH$%GPfUB%*3sLzkuF} znzHiL=WT}9M}dLOJf2f7PdmNeTFlo;GZX(o9X&GtL~u)_`KEEi-50RUc_bH^RKfdNl9aLhuzBeqKo)QUUI#1<@}C6HjC8xC%DwAkLp-(H0rO!kn|8%gy6>%u2d;AKP)gT2zZ&B zwNy$*Z=O^{FNvlsko|bsLyNRo;^w#J!oJDz2VW?aI~@y4<|=K6A*B1eva?N^MXQLb6_X^n>;LV1^Uc2|W-(b&_!YAy1w z<=tf$rgm&ddF{>{D`%|F#zO{n>j(sNCJ9^g&Pa7rr`PUNbJSfl@aZU_D!X#-72Pf*V6Hp6XM{J_b_EEvXlW#I`OeJ?4ZS`N8EPu>+ zS7m86;3{kPTSeJBZtDk9TKb8wA2V9--Gj{jHq;$2g3AN<2T(r8)bfnTrtI2n*3;vW zo5myK%IB&t%DYHWkg`5;d#6U6oR|KpO3Yccqx@U%3>G>5b%xe&GwTPXM-LJEuNbRE zmA^I!B6(O#Er=``)N#VzH0{+7a`)e z!E8Oty2AvQOCR%L6B~}W^gIgX_G7aon{tlh2XHnB{G>>Y`OiF zBDutwmpJNx>f(i&{!RH*OZ3``uG6Vw;83romFxgb&6wBu2Geb8;xuHHrtTb^zu|E( z6||c;cWJ2E@jK#{37(WUXG8O0@+o)dH*%K&JFrtf_*l9+KR4-UFsj(V^uX+#$ zv443vOO6EvJhWlHj^tr-w;z}mcVbMAWy*0$uKmo)MHe~ zpFBg?^HqouXp-@^RILTxSBK1KxrnAs&x6c#JRyMJ>J!Zl7?d z@3$0czHnEBeZswcBr#k3TK;~M3l_qCg@xev_?V&6)O!BN$WwdoSG}aft~jtPf4@`X zW=B8dpK4sUq^AX;@0Xss-xk|-r){ij!TQiL z`!l9zq_p2{gQZ@dv+);mIBIga`eOCVbQcOKo<~4!W1bSs0(O}+sHi0y2M#xnJxFDl zgixHG(^rBevmGW67N|W|y6({SM8P3m;NOJ!I$9~uMiT#dVk5CRM; zx0N^t2KT=PmoComk7!L1YYSh?W)kd7Sp5swaTe?OCAG>N;0`9{r99#u&N-!Amp0HqpPe&dHKnir<9+>O8f z(Hjr=@kAK9gtThCc(3AJfMzcpnY`~@0#gp}z7+OcBg6`gx|vds1`D*?SMk8wfEEhF z{!zMo+}7@eit(NWC`WuhVPgNIvuihM*5>6d@eim(d5N$qJrQD4QIaq*HVKp`e9MxV zFYQ2tA2t|xd7?IAgg0DC`&0)_yFU84#b4POCZbJtT;8VtahuK~>JL3z!gHJNDxTNd z5=VV=q`Hbfk}d7Dbxa;OyPq+WAS&%m)b%25Aeyh-^A?H-jxaJMAg@<0^q4a9e4i&+ zzc#*Y$p2Z+G5e2iZu6dhHbu?Fw~yY+(0j~;^IxH$2*F4jfqTQz&6CSkL*BnniP(e# zmBd)gIxc+dtm;z4+ut0kQ1x!OwT9k5>Z;hA3Df8*o=5JQTrI@W`kp{pC?iZ95)wkj z!yLzI81{%Luf$=6=|#0gy5O6TJvjYQFNn4NCTkTc|s8W!bSA)*SLOE$Mw5+WwN zJu)Bv8B&9OfD$i48<#5-in?_R?NJZUf=bP=@%5px_TBp4ey+~Hs$ESv(I&mO^qBqg zJZdvxTKJtzGI%L~kPXSodYM(@3&tFY{!J%Af0i0c&FRs~Z8kOuXexx$wX9Pt*>4QE zeJX<$@gTC!K);_Rw3jp_Kyo=m##a7|R*GC)-t?+=lTd1pItwc&7NX1noc31UvarN_ z?m^wsr5jl%sr^B=l(O`(#ZB5(-D2xL!V&e+-{z1sO0uWa)>QiN=m-hrJjCSk^6=82 zUhAq9%|=<*J6fI#;MN4H)(09I*EkI8!l1D4?lCW`u1;p)yQ>au>a?JSx)nl+Bnjdr z&$jsZwpj(WfYW*Q&bSx3E4`yMZS9&{ur?=(zz)*hTfKv{7G>06`;~ll5;aKsRMrA> zhj@_h-1FXJLrj9-U*M-tOl}+F;owd6VF0Wou7e3852mA3ug*t%P}JxvVv0yVLnV7( zOZRR)HDYyj)yTmizjR_~s8YY}!J_rZ(2%x6HSkY2*K-71o##v%Zk>2#I>DLNE4s?Q zf5z_~BykivdVaB!Ykex!amKvP;9;NGbVwIef=B;;TIVz|P@JAn?rdC@N%M1^FPXdb z&i&B{dBy}>LK0ZEhkP$aFriI4O7p5?eU{sfSRXdk?(QQ9}POh!xc60pNV#-oyAzNLgEUvgn zNOk26!$!>xA+&$KPD~6dAGc0a{;0+>H9PwP4A&@5h>i>ibNglU20edr-|9Ws)#%(% zY|fPp>^~iEx-&&`HyJ{r>tkqfdLljTRT`z^IcBYKmJHQ=zm~_xNDY<+oEHf{*n%^^w zT1efqjBXJzy_P*ueOS;E7W1`W>iX8;FU3;ky?R<@U9FLUr8f+6C40Hr#hD!gE-iT4 z=VN38F?tFFxbodKf8*ipJ+oFm(E?JL?44og%0)o+vv(N!?_YA8witm~d5SzL_e-*EMP9{$eMK>Rx!*6+wJtG0edNaDqdK zK^#+22}`DDXewUgSlVW&NR*P=Je9k~dhg!#hK7cF9-FuP4yG>Jj#a7CJ^MWh{)z!` z+Nmo`s<_0oV7X`ngj@;74rstg1<6*#-X6yTs2 zed-B5U0cgJ`FQ9YH5O0|SeZrjabt%EB+F)y$Y!W$QR5@_HYSJ=2jDq?v7M~-b&Hjo z)TgZO-8wzNQ&bnheh1PNnf(=C@k@n^90W1QJ|Zo)Hb zmDy7Gooq=@?N?#m2AIM%x;=b|4MK^QbiAkwmI-QwHx4u_`E{Ij> zTGpDJ!aZXK!wjW*!CxeMhFGlOv%va^>K;8P6mpu8yAl$atel)g%F6r8TWs1z=i%{@ zQWCLYa?he9uX7n8z~c&m0RQ*i`v#96`)|}8E1FIW7^1?#A@RebcbVxBh0`rXz79sq zW;8;=^bDG*e73%kHx?PaR8dxb23|ZGBS``-jQ%Y&jBr{OgnVN2B1CwphK}6P72>6Y z+>iY#$ale2FIBQ7Bqakk!ETpC5Nlo>-vk`QM;@tFT zZ*M>U>ma?Nipci|8CX5P2;$GE{eC5{VH*XVe7NDTcB88mWr0ZQ~(uU#XZ zo%0VLJix;2wFodpY=+JA#n4Ug6N5k`rK0jiV*<<_C|#Ar#lnx%wX5I}npl>bIUU zj0#>Hwg`*)|Btdafu_3s-iMDAnv9VQDT+cAN*NoDDX9#}oGBSH51A=4Wk`iY zG*Ahdhs?myBF) zR&`sI)E64q`}i^_ ze`9!*GBPrI1O)tU-)189Kt{ARR%;#xQ*5jl*AW>EZabBhs@JFs+IjoUen^mfqFcd4nfXv1fcdS?);lT>|&U+OK%)ezr+D z<5jD((7Pj2(Vy={+=skoJuxw{AkHX44)aqSDEZj9eh9UA97i11;_87ts!G$&IjgBjg=5v*0rsARM&fgeYx2Ce*MIr? z_3L4%o{|hfFy*{=4B|TLsi~>M?&%ygaWJ^AHTmn;x_5VPcIR8O8@T^Wc3BYwSF1;w zkWOes>YouM>eok+YT2lKiRq{4-jKXIjpwZT-N^w}Yyzgv#C7yiuZevhLu9OabIr|$ z0Uc2$$o3%IPns@*Shq1mymi(O!6b1yyyQ6Ae=7tRnQb@p=8yjoI2d&j4(iuFXX}R= z{5xYB@+>VbnweR)(o^p6tbw0q6x+}cBfPP8ZsZeBZpzs`Gs|%|=T-SiT7}iM??nWS z!6Q8EwU9eeWY>GGV<)jLvALyjbUcf~Zk5ATEB9fkh?Pm5ff8>p=NbkEXEiu^q#ye7 z0ys!0m10}e;AcjI-5`|P4V9QdW&?lG5qrtFbt@spTpGNH3lt1V znhgB^{-9E_+NpbD>v85QWt?T-GAXL1Y=P}2vBkVx%Vy=660`41p*@dpjZZ3!v5dx1 za_e9BbS=ruS2zr7!K`mrp*hYg><$V0aiC;oY5RUwQLZ3;F3$`y^doOIn#PoE_ z$+ORtb}{Y@hC81e*=ddgPJ7hk0}l#i5qFG2R{D*QtAg5z z5k!zlY)t&1y#4Dj_*D_&lz5qrVq$QLa*_=4Q;Ujp1}9M;ZsaDI2gkTH?|dr`pM6gS z1*rlTEr_QXbDeNqAP~G2S`gNGr$dTrLKfO|_QgH19#(!%qPMIjg^Ajrn?~=?pL>@U zahSsHtx6_;_-t5p-)>WldKk;mL`Y; zpWl{$;`s5Kk&zTVUvHTdK@*Co?Sc15=w6O1n5%*{wB2h)74xr@nxL!>e-IZV$royr z>qXUD8?IV^$yd3gvRdPeha6(%)x>_T6NJUwi694gO4q^rSNtDM!q-P7$qB;3t3+m$ zFSEfdvp&5azSsI+%1#zVHp)b?w?37#ya_$;rygL;z7bm}>O~K+5`t z$bTG3T=Vnut683!av;qOB|Njr!Eg)| zC!T%L6qbH+b`L(t4{P`E4CyX%P?s-X_P4roa`(rK3lSi?>|BrL3xTkE=DA&W%FAWp zF6_sB8s?LTJqdf4lg~G``DgEg}}ysQg8UYd3x z{iz;qL-U;EgY0~8-T_Zk59_GI`}pudjpUn}Du4%+Y$NK{h=IHW3?9^Yyyek5EY7Jk z`bZX>hSFNXKM(uF5v|znrOF-YRFr?x!Xm|vF1mqu&)?r{BYra|Nbnwf6o4`Uu%My`24NWj6!PpcmJvv70k>nvQcGtd&j3w!K~{eoh>Zh@H_5|RGdJw z)ElB*5_N5D=L)G87ZyS|Hm?rO{{G_Jy4JR@jQRRf_j@`MeU$I|fy4}Pl#?9>1ff~L zRE!w2HvC)$;FTiSn*P;aBzGP@e7C_T_5qq$atjNe>6rcXs~TBDxloKZs7@qa#(n$N zdQ1ON#9XV7%&YnAw#}o%&Jt?|=ELGnY}v!Fe3Vq4O}snw`-f!ZvwOBwy0paJ|NC^` z&DHMAH}3D75MP~$)jwhn;z8jtk~_8^x_me2{mtaRvqOADkYE!Oc~#XNZIzxvZ=s^0 zLAeUUxJ%GqK59G^dR?_)^=V^qImkg2D06gZh~HQYU-slDG@g&SyBB4ax=ouAr>btp z>X8;%cjZRp5EIROY|Y!9A>4O%ubrSi$nbO5?KeB1@J8zwq+_=*V-bJY{&r~_*UWyakl zW%J+Jvrgbpb8}Pn`epu|0N68o2zNhGt^17L+EwNl)-8anWV4;{0$s~pCyiZQU4vLR zGerI(Vm+d~Q0(KcyOLL4)U8fd-diL|s%fucX0|X1kWE>(Y`8ulbLfy}m10m(S_9PC z{5>-Dgti`GhOs0uW9d)vm33%%vh`s)4VruGIOiWCN5wV3M8SKmh zu=O$H6J@sDW!&<|$)@_AUS8KdGJ${By~AP4`r z(}jji)>PuX4JRp>lZtpW)fm>pY2_U|>9x}xSIT^gKI>NI-*`H3_f7D>TmYu{MP<2A zML=}KME~_OpCPcI+_XVq>fdC#vWEzS7RA zsBB*KFm@|PV|}zGbh9W|YlR=pzIprhdRSQ41jzhbh=_xDrM~*RGglW4565o5cmLmi zA^sGxf;V>z%|0^sMJkd*0|YrQ5vC#b+TxmW3}!DjWM&JV5k3S$==0PbwUs}+&cEk#l?kN;RHUV)djINBjRR%>l6(fMpK~;b9efVYlmfW zvL52#+0M>yjIRn=9ro&xyBbu-4;O{@IHn*{+ql;fTbEI+daHN8*rm`|{{JlZrpr(| z2H4Axznigzla-i#k#(gDGCN#otZV+A?#Qe5H7F@&h#W9pwXy#^&P+C@P;%`Jpq6|t zG_ADx#?(iNNB-w!Dg=x`V!+0p-*e5tVM-D!o!t9&MH)N$BmYPe65o|;eW}?+`+_JH z9TjP0ejr9@*zsh!H_7*!P`or_<)@=&!J_}YGlM<{;qP^V&{?M$mzI`>wZ>8h)w%D9 zI;r>4VI9fv(j{tSnj(3!1pzaITU_YNthQ$2L*2>A@u?+0=TAmPiKYTn~LM}^aHSG=3hiL9ng z?V=t1e7)q1EHhv#;`KF(!#G^-=NTiw*sxt=}*Km-- zLue4aF^|1Ml9pS+WZONyb1WG;*JYZTj04+jJj$0C-4eY+cJj#gGzK#n2V&oF|ETBw zNZP2a-frhGo}6XfeZz#FoD{aY-}H3+gA_S{1<}ybvPf>aVWgxKr7~U~f#2WJi~P8- z$~|mhQ@O&mk(2iGmg&veP>#Zn_m?$igt?9UT=lW^2@L*oLe+ zxsgiQtw|xRZRbXAu5O&VHCx8^R)-&?_HXw&tr5(5%OIZcl1$fJPU4w-e*9`Ni9{WG zXG%dVa<`G%^}2~7%k|v9KAbS#=hhna=lLRW<{m}cw+6t>uXSSI64K6iyc$TGg1AWi7JAu*FMN*^Nr^V8R=c0*faj0k0uBz9m}tFP$b>fzN(W>e^Y-bgG4L*#m5 z1^(CLIMe^#;%EU1*z#2vSqn5L<(5A|HkAfOOGpxsd^0kHzc<|%a3DVk`_E_B zVrcbUeHy>l*4tB&_HPe)lo3hav%^8dH2DAZ)@cDIw`%huoqN;_F>Kxnc?rf0{w?qW z&hAO5R@|HDwL^sO)N}gS%mudiChhAN{isc9dS2a~?Bw_KDWUo$KRQGEf^%iVr)KGo z9fLh?bxnI;9enJ5xgE~0n) zNc}OF`-qpmHz!6wRkFgQj$Uf+scf%!)Q0kSSz#CRQMHBsh*QsRt}D9QGW?ai?RRtvF<(0OUcY#WJ{DMXcrgM#G8cfE3@)a!6j&X%_I5wBC@t`?VS2RyzI zwT9-kzmm+4^}2>thflHQuq0E5*ngKTn0%*5NyixUo=|CwygDDjCG@YE{<~fOm%#}7 zY;v5uc01j{X6nAB zx*|48SNuU5h3{9p%$5E#Ho9oOJGa)3Veq*X#RiP)hB@srIJd`cE2+mfQf)a12UXv1u*l&t<&$4UhspCOEcK+Wn1h~cmK zRB2M}RXb%Wnbcn_9bfebVW zvJ@3EOFT;HC zr{n&b#9reWB{EoO6gJ$`wf`CY@gtR1%N~mCHv= z3&x~xEIGc_Q0d1S!JpZuiyt@Fot27W3wf%x@8#+w4p$Mk)pcBvy`@i|J`IYbXV8v; zR`SL9@E+OWN`Nho1N<;cx+xuGosG-ivN73ragLP5ZKFu zeUzO~X1*1(%B4}TWMfZG{*B&=r+L(~>g}6`-_?3}x-ht}^(W1pL2(;e)d$Z6DJYhn z6MKtWL^*x4gYNY0DP!qaVa;-~_4}xQKdR-`PP^6j5Pt|hKq;1dplgZ|8Kvj{bG48bPSvgjS=ZQ`$Nkq;SX!?yywlsvN8npz?%wPC%Ms< zBmkLsAc|C|n{AoD(hYFeZu+|lfp)=duJl$=P#_Qz6K9nOilZp=;NajOT5*}Ye zkiNaSJvrSh+keJqfeGDlsPS!~+ojn6ou5t7kjMZyypJdnCRLQUP1}urK8R8>bdX|( zw*HnTb*|}&3F03}BuM*JL60{AAenOyQyeeu5No0D#tC7YFN+z_bqeUwkuH6s8Tq;t zzg}@)*ki2v``sv z0FuXHUg&)33i+%_bQRjD?0^|1+IE^)WWeQJLxO_ygSbUpkka|JrO>o&5Ok0y#- z+yL#ryul7OG{4qlRbWP+(`d}7-PMX$r~C>1SSv*`g;-q)aWj)i-Yk* zfc<}i7B`hpO|{i5kg1{AR1SV9#V89EbLx%yt|%6@JCQ1Pa(#82Vf099 z|B^|zG>3~H8ym~%K7`uNb*ieWEC-&QXzj!nre|UK_;B|%iAT?$Zy?z|MfXe(tT!+_wxKD(oy7*?9xk1 zOXZC^kwcJL9LYJp2tn=R8X8-`==v;HK{h=N{pPht=PJyt2=p4~A3|@MzYW~cQZ5T( zD@4M?_SMhPF9jRN@=*Re@`p_m05>XDtCcC-+AW>vL zP|r*RQ0QOFR(tQGr0U8hYavW3_7>aX#~1oH-o1OrvKWQr-pZdj26}p55P40|*^F~( z?ROv`L=5A+b*tmn^>Rbk&(9sLYwnaB4wa(sic9Q|3NhBqg@To3;{RXgG;CGfNjp2~ zL_1{X4N*%5KwA)aGEO^LM@Q#|pGczD>^3ORZzkagMrMwzC!tLo7m^Hz4;fXiB~@Ue zdwP2*5D_AOX@oR4XGm<_mc3CY)AWm3kewba(@a*|iR3gG6Xc^uNklgO{Q1Da1P@ve z9xFc_D|(@e9gHrrBr)%Z>Z&Rd37a_b=FJ`P9wQwGNEPU0MJT|LDw33L+d(F~REeG2 zvK)|6U-i}tRaP0LPekogmfd0jqC1a3paLno4|m_E2Puoj_UFX^EJio%J?N=`Ro1`GrbwDlgSD}|D&z4^0NJnz1{0haly6%c6w!*A? zAM(g2hC#O(4#?xlErO)HQL$wrt6R(AtS16IZzB`b(4_~QKRsZ+*mpy?FEyiVsOKqf_GuiJ*GL=X&ibJ9p6ic?f%_qUMwowy z_P?&>@=3FAf^`Qizz;nDu#q1oC9TB{CE68$i{n3jArB}$(LzDT3;k_2fLHJuWU@z* z9Guebxizn8RZ@JY?Hn8|=Pn(R``1;7yjbM6hPr)}az91$Am{7+oZ6eS-`74c>y!W?H%XOokLS+Y9o2pcUmUZuU;MNH=+(EUxUJvCu~Nc z%P1RR3<2Cj3vpeu^jy5W3JY>E*g1w^>F69lCi^jl{OtMj4-0O^7?t3KG7jXS*cJu& z`5~r~E0juc5tKwAO?XAFdtRH~Po0%PRdM%hC|fU01p^V~aQQl1+WXu`{CI(QgWXK3 z8tLlY{cotHjcz3H)EHH=Zhi2C_0qEA7m}hy z;~q*bbJEYSF~KJLo4vFB8VYgPpCvVD|Et)6i!ZmDq6={14}Ft_x=!Ruwl_63u`R-h zBr@%U?MqgBh)V%!9Hf4js1C)^79J|!ZqDJ~Rqj*%F)bGkLoeVRHor_2C>V=e&|kK%zyEqtNEt=P z>|tCxot>SzRKfQwi#EN1=XKERjo1~C08iJFP3z$i&~tJU%}F*WMManSd>%s1?gWsx z8-vecIQWHxYLJSshYMCZcu1f3W{}Py2pJ=n{Q$yj&;Ag?nr)AMSto1oXCZ$?+jdpt z9QMdxz{J4w*7cxg!*Hz57OvQIWFCWC7$lLDSRlz!T+~8ASNSO=ZeVVG1vcxTH;ngM zDk^SCNp?!AP46UL7z`<2=;OiNgk)q}#~d1c8=-kadQH;yck3!H2Gm*pNYzCuJ_7lr z8Fa-Mj(;MmI`g)NP0}T;rn`4Y+kC++JOw$`lKJm(G&D37sB65gZAor*gTMP4+R1#(Cv5vl}vp-+zx36#cb#~;!g6m4+AKDXB^a#AW>iH?rW_ohI&!ReJF zBeVS5B-SQAnd2J*s63hO5pqk(ewA{s$ReeKWg&!&i7ivS%>wtY;-t+3>l#c_dgV-jjSt)kDl1#G{ice2X?gNL*UF7qWw(PiPR>tjbSxXI7Mz@%K#WkO zn-$c_r2%q>0b_El%;Cu3^)xi^+-b5bydD!iGNiL4ZVTYTCBy{s zZM(y9=Med1@TmZ#zrxl#04>-s7uor5OpOWBx&i^X2KxTFFQ3_>FgCDRX7SXe&LNNE z(`-WIR*4i1%iL`{7=x=G$bH|Owf133@5#~s0b+3v_YDsVbo%M*>&t})1U-|!{O)y@ zcoOMOjMc;E)C(PJemUnA(z4oq5|mU>)F-v-)xIq%CKXZqDzKZLvL^ZMe^(lFab`YH zVY}N}=pRLCzS0vG7ACUJ9h!XS@5yfF!tsDKQ!jBYV71Wgi$o&&$-8Geqn25MX*ZN- z*S$NuUsppTN!1gv!NcFPUu;#?)gRl3Axmj*pCv~-bJO|WA#1j9F4-4Zmm`2JLyqC# zY#8o5fC~tDDt*(y2|<_z9|WCoeW8{_3JY#QJYum+8m7^1vQO^!;-XbGdXMgk_m~~g z4jbzva668V&Zn2`b zkM%E$U-;jvw{KMj-QM1oc>7bw-4uIB3r!j2(tn-)xKB)M3rKA*YUcbj_}k{IUY6Zk zKcu~HAGm;$aEG0|$I<Zof zq4mK`>C=fuLt!bVgiy7@iYv>ebsV9SmkL?E4&74RrIlm0S!QL)@$oMTG1{{HWOFZF zP&^@^1g62q9it4fYv6MoK61oD@YO{kTtVX;n>@UUa8JM}VmW{1YLLX(%=_s*pY7FL z+cYfO!$p|?xl2_8_Xz7BAF|4zAW`pmL;j2SEdEeAWjAlq{_MKzzHw>)2q!VM#QYye z9B99}arMsAjLXi39ZNFa{B8P=Vf;%T;~BRz=#%5U@RJV;7_8|LGcz-XnA2@dK*>~)VYw&aWZpNK@%f3@bYY*p z0q(r|jC7uumM-}TnLmondA0+-(j*FxS(Ek!lZ|H#48x}p6Cu>pJb(B3$X#92~XlnSURwGzO zyDL}5?TnMbTmVI~3M{7Ho*rMw7Afvx1TTVT*DmtlL4u!)FbEX|5d_(2k$MyBj!h%{ zQ76Mp;5ht-ECDgV9RdQWC$bn-d3Zr%A;RC!2eORwmT%ms{xYdu<4`Al=g=5iVvw^> zLc}HB`ko!}SJrixFYih?JS$RvrHmANHtOki@f#~!TPT?eeY)m4=C7R*Sm)uCc;Uk2 z-Y4!pL4oC8uAgICWE;56h>L|o+Il15XV31~<$zX1H}Buyx9j9R+KB`yH?_mOps+y^2J}ust{C#I$FNRMWo07|8mkc; ziMk>$pSX!6cJADX=4SNas1#YR6#b+YY&8E}ZJczFyz4Y3p0JBj1@(M&e6CWh$H9tJU z&MLk#&XP|MCe32SIPW4aEC==JCOGW75s;wg-P&{$)C-W_-OaT4eBKc>8Ed=o%hmu8ycVMljpB9a>xwbh^4ThQS1m0@aGM*UGnc@zj1Z1 zFi%w~AL&7vF_ZC{L6ZpGEsXscJ9dw{-jL4q_CDi!T`G9*-H5PapGsXOzRLHRT<9km z+JoDbpypAgqM`+Jli{|8fDYqNnc0!6h75(t~Mt5(pAP1S*mK z2OZ>35RX;)3#)=oe*`UT63f=NG(YWb;)6KN4#KIW2lav!nTYgQQpA5_sK!woz0yMm z3Lmm=6|ZA>d5qR@17mx2Z)}P>eUA%jmX>2254$kf#fj4Y@qek()e~7rA(wHz|LXlL zMT@+QkIe<6;`DUI6dvLCUkm^89h!w2^U=d5VZbayouZzq{J+85pa0^ zkL9Yd7~*)NaJZVkD`Hu+yXuMfncm>J*`+L7I<@cP$2NE#xYEVqIdN_4^NlV>bff~_ z^PlU#8+GxM3d8aRYg%7S&y5^^^>a_1sq~k{t92Xhi0@^4VpS0pRAhke-%ew6>(?LC z*XINSjM(z&u{(#xd#&1E{46m5tc!JGYv=s)SnJ^m*Y&l(h<@D&>(4^s3pic=e9lep z|7Hc~qlOTmipqJG)q=L7ny+sI?H{JechGKP4`+zj%zOaAA);I@fiKHL{x8D4gcv+Z0d`$h5F|<{Gs)->+Z&GbU~Zf{E!45WVE(uFrBupg%eGB}4S&1}yxkQ=14^A#55m zNw6DHlYu%DkdzpR;E^Xn3SAS$!j5$Ul?NVd_4Xe4jz=vm`AIwQ7I0=OvjEJ)lK%+( zQy0lYvnAyne`HFrwr;~e=0jEBu2znnk0g(VNWx*C}lv%RPd8;^O_RYNtF;S<3=8fKNWRf^;HZY8oQt*58w&6t>{k&PsR zSe<^4ALky5tCz%P5jSDddl9M-o{v1l@4@8OBe>2BVeI0@U@Yq#*u*766p(?1{Tc=W z$}$(i(54^@e{Ugx4OEoTZ`sm1)_lrz^OVe=JOAXyA8BURgq#}+^ZkA1teBIe%*vue z(zg}W&MIr6E!&z+YHpjn?`An#e$};ObBE&yhj$7!N7$X|XDb67;rdRm?|gedVQg?6 zDG=Q5n4=z`&$Ymc#Ab&jFKl)GL+d5?vjO0qzJ7YtWeay}8oHy-nC$6tBb<{z7y+cXfF7kTWFd$F;fol+`8ek!ZF_A zPu~pB)EWHd*eq-=wxKrIN6x5epJ2(?lAh8R(-b|2PH!El+%C1|`UTn34{;WGFbAyS zHXP_(NdunGrz=nJbT%hXH`x6umvbl(|@h&LzbCjvq0rY#Oms$R%i=W|4a#lj~#Z=aHy5AC`YLDG|5CILRSlvSrp%W!*r_Ov;1 z!Vi=pOLjm$Ad04I3j}-{8w+30#LJqL4vo|_gHj!V^{olx(!Sk3NpIWRw<5z~9B4!j zAOyufggFd)29NaYjmsBBC*1o2UHcLP?Idcbvo*7K=V!ZVJ-xCaG=HHbaH3gyOmWFZ zKGpiRvz5-SFD)&%{bb0zl`SnT=1R;YFlgZU6-6^W{)kZc|K{q5NdKG34^kvR;^iT( z-x_69$)x?3I}LParD`Ia4)lf2OBT9#O6HdqZ#bf0NeVrd#JycKVd@0eL3vl8&2D9&rA=K1g;_w;e}zmlUf zoV0L#^rG$K_{-U*%UN3x;vT=IEEEHHLGBx#{Bu9m=?o91$??(Rg5f&0C9hZe6sK-Y z6k1*3nbD5;QY(I(A))hb9R-QwXm|;gI7jxxNpl|_UMJ*>8_#Ryd^@p+Vn$R)mKe&% zFvqp4vkAs$*Z-j2lTK>3gnk^z2^RkeDbP);xWy z=Z1r4vFFBmiD=R*AW6_lU zA%SPBru@Cs)zz%zz_oK!(YU-Ad@uS|^k?3XsMCSZma9K^ zg6T_z$yLSe@^VIL){}G8jdlC|uC1YbJ?&j=@95h6tL#O4N$ea=`>+Ha=I}#3hwzcN z$|6qddnTi|`%o6Z+NDdF*t2 zkpWfMcRSCv3pAT`Pfzu~reW*on|+E;)X!sYtyp~M9xYtJ_9C2CiOj!a-#T9IsB6)+ zj12an5MCS-)gtq!urJ+m-o|sZi;Z2hQ7^KKyyHPgwB&@d5*tmxY$Q4kUL&ls2lTebh)HaEIDO z{g-x87kuV320X;+C|}H-YxIha(tHNXxD)iK1-nk=(}Nuq-qP`90He zhG@b%prxh73UKEzJUbJBXD-7WV&?Q)g$;H=A?}zTm39Jw%Y%HrCew{@$ulihG~s{~ zh6R5G9s$x1r+K;ZLXh22Q(z@H_ zer2rl4c;|5Gn0fM$`hQznXxW*Up&<$%2WFW2QU5Vq?27bik2ZKxA@@Cv|F4+wb5IGE4%gYg4f_?Yov zg5z0RdKLEb!hZ6EV0Mz!-Yhja=2Op|M%(GcBOJQxC&Tq6d=fImZK--1V?}AhiPDX# zm(D*wtn&rF-P7Oy8aZeh^hhPTAcOG>-+=Vhd(nE$nl*xhT{aU9$P3mWD@B@^nIY7@ z)*2$yOSF~-9>;_XN<>7&z!4A8izEAZ%*5C*U27{0_iNoJatJz22imQ?FU!>G1->%G zPdoF+s&8zaMs4aX$kR>qzP5P(XdOskYYhkLqe_qgI{NkUFdPLWdaZ||MEbtoI?Yqe zBx=j&v+;66x8NBkzRWYqdJReM*?!OdJd-+*qm&@-E88r}m7$OtSvuj|uKAQW7g6`I zr_a7hs(%;E^i$h>y?@9^$Cd5_muAcx=0M7%4gEU>$;rvu+qa%F9O*7kgu_IXu@Z$y zhOsGX?|NSO1&4>{A4#}%izwXd`qY8~J>rcR9gzTF5jM~>^+bx!o`B%_&*3zBzAr%zM$ zAi@6>*D`ImV*Txi2s#wTSJl>18j8dUHV=IJHUZj%ZdpN$Aj*bbH#awb|BZ59R-oQp zhc;7D5~{8|Jbu8Ir|NhjCR)|ceA*`ok#8jKDpAG|C+d-U=F+Yz&h<2r>?09@B7)@vHU0X;o^1w;eTaM~== z`s6nI6onjLdfv7E`yY0){h`d$q26z3M51Jg)_pv$XTiewcH!of&3R(`51oYtu#Zlv zzoGtQLa{ddWSYi-b>g>Fl$2DBlS7lAKJ9k!x03^UT5cr9=7!Xl+w%M%Cug`~a!h>u z<@rst8#k)s6WCA`3*^13stOLaefuv&F@$J^kU@!-={Ce8*kwOHByR-wf**~1g|bI} zPxi0hxX}dFaX3vima`$!P%z9Eq;NsKLfj|5b?ery1<&Io%q3((vhS6uq4D7x)4TM7{y!-spbd>B(qO5k0TPRN7@_&fHn|GK8$iCTG{p2 zcsClUc}3wcAOs;`CH#BzHrY~-xfi*9ELaC}V*)bconJWme6Q|3w)?l2>T}-Rn$Jm> zl%FfMZ9&UDH@&B)IjQCQIydm1E1DfvNPKvLlT$70&s_Tj?UgrtOCGhfq`~`bcRa%T zhnH*kj2e^z)(ls*KW@ygbSB3w#V9Kr%Jv?UtQwJ2c$N3l%A&d30cB1C4VNa+K6|{! zyov#-J;Jj6{`oY~&e4%_$Nv5F@Rm`Lw(X$h7NF~+p}vkb(9K-bU8swJTq<{A6W*ZRx)JsdC(BJanb{qP=HZoPX07x9N9f1A-gg zyrP#43!htgrS!QG-KUyq=;H6k)KM7H9WWZKbGY!PgETI3>W88c)?YJcOVZHfMBSGj zbgEkxC$^ez8(IOIHTEE&Dp?px1(xwX&+0s6KD0qk5Vz^fJn4W(#6dh(>@u468A%l* zq_d8GH4K43urA}b8(W3H!*Ju!cJt<6TTHk+XLf*3rg4-lOx|UzWPTeo1X-FAWzWFA z?X$iYK^gr?5V0%KtDaDDz{zRYE`+LlAqTn`Tzw2&T+JwM7pzV2oKo5$yltSrU%l!a z3(Q$apK%Ry(~@1&l-D0#w$AkcCP#nJCvAAv^&p^a&gP&V=ax64DHke(_oi@jR}XAb ziqao$pZ->Hb?tzU%i&}zg-^wneDCgW?W4j>?jjEUPf3WxY)l@~XQ_J*4d zy&rn(ywv~AewjfwOfxCd*-Y$ByF)|LIfg7-oDH(Pe70@3jD*vV3f$<1d1r!PDc`?; zPdEaIIvM`A)}YTDEvDVM(H=fguYjG3UTTXu;;?&Nv6I2@Fd= zIyPn%$q=&-XGLgAYBj8+D7T?&5iNW?kjmZ6;#kvLa_tsBx0+|u9St|5`Yl2U(%4w_ zib6*eX0xX`-tG3S)%_l}!}fzHsoYIcY2m!cw%ZaPMy^Das`PxO+m)_NweYTV@PtO~ zIvtl}j~M1%<45X()!W^YoU1wWxce?|qB;>NDz+gS8Mz%hc08yPfwKV6rqR;vOb$#} zx5K;;)|ZeRnv?R#+9Ea9-*1vv+c4TBE?~(Ot$V-!=TD1*^heQjtF)%bdZl1yzNDm( zpe->uyU+0}k6igqRc@+ZLvyx(Dq!izQz4s!&(=@0M8uc>mc7>|@K!L8=kr>J?EMLp z&w`6}moxZ47+Xh=AQ%=a@QBS_h{4gh_q+> zG}wv-S`B7U{&LGa7WTnbo%kHQlJ1I`B;OLatKs(Of~;j*%IjAdWe#>4)sE79ff3!_ z>}S>FY%wf=rllf-80&Cv&6P`uP zn@>vD_68lIme;0ChfV$)5D0Pv4ZouQ>j+cWRt?cBMnzn`qs(VjDObRvPB<$KO z!&hsl75=GM>eIpn>+n5kL&eyy;ZLRBrIe3fik^HPbVqvkxp;pMWr?tn(~Twfm-c1u z^U0BVf4@RzpS^SRp_Hq(iOabjdmP}>z8>Or@nHP`f_+JnntESg)9$LkaWt#V^6Ve3ee3J zWG33H3}nFxrsPS{yQ5)$T6q8SC$xZ52a3hn!;NYe)1pKM~wxsDh+jx5EB z%0;hKn^xYrZ|yunb`Vki>iYW0$nW{-6z!+9<#$h!mKKIH0HL*I&w3bjdoS+uLAOxB zZWxd_qRRtlR8|q;C*@@`ZYiHRGl*-E_sEf0Sl(L+KFgvti9Rk)TGg{4dq!z6q>yk= zrc>=j?1bPvhs}A+(TRrpoaX9=nfAFqtUBrJ2VmEu=}E#66=i!)&P#(mSyK)SN^zZ?dMLBCoG$|f zX9*4ElI3o&3_aWWR2=;kPz_G;doG-l@Cc|CG#s$G{&{I^-YWXS?t7qP^!TuNN`Hm9 z4Sb-N$rmy%@L9g+cHhM2|HbR$wnf6{4gb} zFXozgQTe81eLW7%A$qEQ~f6Tlu*XzjN{A>8u8En@{xZ ziy;MDbhHh&`abUNu-SI@PKcBK$pz7U4Z~~RO+~!Dq5qMgePF2ivShNrllrz6-hrX^ z;dboI=lDznrZzO(>6s2y%>djAGvLx#p zriw^Wvqg7iF6l(KuR9s7m7>_5%f-=E9!7?}I_117&&hG&mtirhv^iuv@1lhM-powNfavD}+cSZ*oLV4jLv}3R zqX}*{;xcqejf9AYc6j;HRD-L>VAv0RfXGN5kWk}4)hODml^~D;W`k<6i?x*W4cWer z+i$<|e{WvWe|UokTNvvms!aiXVM)vfl+og8=gzB;3)nH9VD%|`H&`z@9?kIfL1jhz z4af}z5a7g=-YX9<)tVfnL`82SCE95pn(T(RJt=-c?bI9`G_7tdcbTIzuVL>keoV%9 z2s7l}OPN9jjERk{p72O3Xo%>XOg>p-DnhUsp}-~wF90s)Lz}K5NVLU3PL0$t`c383 zsU)zwL3=k5i8b%Y+=;^QwT3vvC>GuZ0^n_4mEWKTqUjMIvIAw0o8BF?`j}~4yp7X!>j7A1g|(_O)NpH?RE0|$(T7%HF@i?1cWm8oLy zA8`zL={UGX>&5-~gOWFJmMppldl{pIg~aJj1P{5S_Uepelin_|MVX7*iAVIUbk_g( zW=&4wuXNt~^Vgm;C)0w$6eL`BnbvF?I(S*@=WTvaki^X2RZJ}*o_`54ZsGYjqw^9_ z6pF5eyvyld%CU6|xA_{<_f3aJPF-$M9kp~h^>aU4m|meB1tFu%cIfhto***$`4jMr zuw)loln|>~C>3@fL^ulNCKA{&=yT6b%C%|_$J2>`XG(N!#r8?jEf4|;eP+D7ylQec zFRut#ZBW>G1sJUE-a#u?X?HP@O_DHayPpq(F;29%0Mq_M_C@8-`PL2Wwk5CNaw~JR zqf0g&LNtP}j&CrlySWoz_M+~SG`AViNlirL7C`v@9>qQb$CS4MD6DfSneEa*WMW zpjnuHOw$HBpk833kB7q9AK~nBgyQTDd@rbz??K z>|uCELurrW+-c~oO0IZP>4Gn6g842=zSpe$IMJilu(Mp{M3Lh z@3|xgtM`wt4+!kr_x63SA~P8Mr{Q+s;G1D!8mXFLkUzrc8$pk(KurV(=Oe|~MSw|y ziREyNU7QYcbD#T&!BDV@mOZgscEemrG zl0eN+NA|@A6kz6h+K%n;?zu`$5^MsHOShcLnpF~pKPw}cp&b`4`f&5GL!1Rl$&UQ&j#UuLY9~`VTiIA4R zd^zpVQ#2He6j9F<&4Z~r)La07W6U=KdT*k@ON$!}+&ny(xVY%P?Y2huT|LvqWW8|R zf4KngxcmbGjK$a}1Ud88#e9E$K4ZIKT<-qybtX2B6}}YFv}V(4%GYnp!E@iaZ(kTV za#h)ls=eVO03xz&x+Ihp#xc1BK8e65pI_Xpk@dre4~LzHwt$iT09#vXx=~cFOq0PE zdq8LV7v&9LvFWBiH_SJBO@&I6(HEKTo~W>+9E0|#q2YrzFMTZ}aqo&*+#0amG%bDJ z&f-O-eJoSpx_*%u@kHCQ!G)QhCe!Zt4$yuEVY;89RH$U;gR?Brp~P zQ#;oAGS~e5HQ;C;9-g2EdIsUDHSpYt-iZJm(V~$!-23<61of9`%N8;?=;;!)#1&G1 zyR?)Z7wC=nw`<(q1Y>sAxUqMx{O*r%X~0s5Uaa4Oq~B?<6;P#e$m8i^>@G8<=N(@ptC3uD9Bi`hty~9{vP-cq)!xCJYvZ~Fx`A~A`lR}eQ4t&{ z5;&B#Hu~Ihdo8zFdW`2id$z}&P$$#J;}h2cDHJS-TbuSac6TS@CL{Rv%4$gy(w9za zCOvs#ED{U6i_#Fe`X0A};=xT+egiTTf}-a)$k>i2c6P-x$h>#A`Vid#~0Ee{wy|7%8#%7Mg@22L9 z5#uNX@^Gu|X722+H&Cni`az~PoUC*4XP}T$2V2!6f>e@1Ezkm_XwduM? zJh)}+p148aq+pV?K0nvMA8TT3`vNXQrsLpgQZZ+V{NqT}Hvn7*Cj1T85-7=^1r^Np zv))B5)ro*jMiV`+TqKJkI3)>e08$i2Z*J`-E@g*rb&rIDXxtX-V?V`d<3w3UcfdXq z&O$-ggcq8rM@xq{DldKNA0I!1sX^OkLf7z6vxhr)q{Es7zKySarp{;U_Y+*@FLyX) zJP+fBl$xlZbQyn%3xMcq0xBH=1>w?9I-g+>t!-%ryVY*s5r&5&WZJ67q_2Q_4*&ku z-2*20j|y$JwgVk6C_z>#DiYB9og*pP1LHo_4-9sH4azrE8*ssHjTN~VA|WGJ6@tBw zDfhHMnTDUY_W^0SwzS{zHf#jk%mWJv9L`4rdBfSucd$a}3 zG~=2q>U7=H@L0rh56xv=^HA7wSrq+AK@$EfcnRqXi!b^6P`bn#Ca-*H9ubr6%T2d~ z3JSzQrC5jV-H#77+kVb{lO1vPl?kW}1?gW5_is7!ICaPLEnNUV1xx9wH{Y9ogVneM z+cxsG^h-8hh?{oVH3EzTzVoKOJ{w^04l%Ji2Bq$icki0#IT`l;QF*(_YTZ>7g+jw_ z-cN4eK;fz-hQfRMP4?giY+&0(cR4aYJ0R2tl}b@50-72{VM94n3Mvq9OX^T!_8l)@ zNkBcjH}J~rO=rmbu`mnSP%T|UN%<+yDyAzks=#tNWt&&_8EpEd@}|^bAOs;zWc>(E5p=Oy zVA&zcZErmSdR8FM&{QnHI7leDC@K*b=hm&YpnW&s@gNuc5M+5+c<2dkO5N=S z<{xPA{%=L3VXAVizp#+R#l=&#*|9;R!}2yRA`H+fw0k%(w`+QtZr$zeV5^njheVwr z-W`q7MtDstGPs1xtl+bNF+^HC;ZbOc8ZIvl$`bdt`>&zva0fB#Cb*ssWn}dj zFyO>v)*ED)%%CUv5PszE-@o_U_mSbgf+bL8{UTrStMpb*&bLS?ZWA%3!SMy1u~tO4 zw5KurAHN{ggoK2`V@RkG<2f{^_ewf^gR-JxX3-$XJ$}W-#pf7bfB6!3rQ0h82lajG zd10a+7mjZF&|c5x*f}L7yqW(}*&w`OWsu&?+h5#&I}!!QRK&E7URmt}ewi3$w)gji z7(s30mxFN7t5HWs1Z3*ZT?n^4oc8#bUY=zeNy}%-G^_qXW8*GB1Iwjel5~hH(}7Vp z|8X19ikqq}TMSQ<_P89r==}5ew8HkRBV|`wc$?xSE;^PB<}~+dn@bEm?d=^23QKND zT=v&}xHp$_^pv)2WPD?96)q_79k+1l$3OLiF9{JNH<7#cXxeb?Y-Y~ z&Nr{^{^2EyIoBNH8Bg4S{lQkL8x$nLbLsVk^Yq31MI~=`K-tWdvOqy)UvPN=9TMz{ zrcusWaX7EL07 zhc&3Iv@8B>eD3Qa+Z5tY>PQ>vF4cM1&JeTiO^Q35xgGMFiT3h5F=;4^H=l`rp+BZ3 zp8XmOx`M*P^T3G?ELz8MRDf0h4VW>00LL(32d&2j#YFb4T>aukO>u#$5!}XB(7r|% zyL-d8@ED+C)fZvC;c(w={tbC>P<9Pc8W3L!HK{8xvGT6To%;?D8=7hX>tKVx)Gfgj zYn@m*b@V`rspuwJEuukv+CoZ^z83;#lLh>6kBpb+|TIQ_TY1SQ4bD_&k(A#tFtU6j^+^WE<> zd_>?U%TQ%OIQm4s@@2EAxp_prF%jzQsOwRvy}-78MOF)#{{VP|4;UhX7tBOdx{v|` z0hw;{rprRYYx-psxVK+=FE*yUzGp}XktX?c(V+6NH^Ul!(v$p?9{X^>fgo8XAMz~Cl5`@0nH4yb17?weUC2I)c92%NBK0AHvb)&v42 zp!|X=Pk(or zn3er~c~H2eT=+YifixzTC2M4B%dSHjq`L4*;K$)5p*?)1eu1tmBP|{Xo|E@ZLeuu} z0=w|?+hhMi!Rh3i}A)cK){hcoeP; z)_H0He|JW?$?{MVJ>y`KB%*-#2MXb|cj+TTSXue*KEKndrC_d0ch8k01#4^!ErJNi z$488fT?gZ0-ZxRIge7v@7MtV-;(h{juCtwqU_PgvAMx>0&dyxmBsKys&81N>6`XIN z&;`X)R6;_Jj%`yXzmE9xm~lv zHhD$OcPUeV$TYczDXC_)W7B}~9+uL_Z__0vsX~KVr!@vlh9=?Fm1NhvcD{;f`%<^* ztU^_|-AlvU=xeb$<4dsF%=%Pn)=c&Y!g!J1%-DzQY|#H@N^9A0|4(t$h6%hypyCIA z1kQDx3nPn#MqV(j5VcQn9m-nvv_;!=hL$ z0eI$Ka7@4?{F2bm$v`w&tY-EG1q~2f>c&wN_zn95azB`K_dwmC2&hBWc5-C<-LFkI zn(oT8#K4A8D)hqs8Fm=VAU#bgDc8SQn0Oa`A5|}JrY?uUW=|AIeEj1V2V1Pb? zfV(l|NE$a}g@KF;jKS;-6b0|8*yN~j09&_arv^spg8K&ami2-I+hVeK06bX&pVKdOqd#V8@A*NZKVJ`; zgfd`D74;6L3MPT90j7@#0fGUR6)xkT>;kZn5P7`~Egmya5&@`l1n7>GgAOLB>ups3 zXwjBY#K0!$viHcOOD&Tn{Cv1{=0G9c(Gg|k8)$o=wgO>mbSjPh@~h>jyKI^JkwWdg zcJm>H)v<`LKABMr;8+EvI6Qzufi0-9svn;C8UD|yChNK=6MpwVbDJq`mT3j?2=&sA zkGbH|oN2M?(lM--*;3Ok`3+!AOn1aJ2C5sUU(P#ANH&@bzqM_5y`~f zVb&}XGL)w?l0FV44*Q5>=Y`S&SLBVbH+O+B*|UB#qPI5(#oVdN`n0-ZI{fpWK|r9? zHrvn*I7kEMH{+Oe-s$Ql4;;gi6+6&h04!juRBi%{LhUNpDC!h2qE2C$yQSq14ICCA z{RGK4CO)%nIv_%F4H1RDgSEf_T5Nl|f(8U2ST7qSqSGFNfctI^FwV~A%kjH1va;|Vq!PF=CZvmvH8GAJVxqbF>2F~ z(bh159C>Xb%_u!-rOE)Hd5|;k^*bUs13lA-d7poVmiLL3RE`S@>HIz(+AG@iMZCrG z7E7~v!bLoiCyj7-bGCL={*_%ZK)?TvFN`^{OhvL5Bc z5nPSRhGBwnwJ0n2=E3K-mOIAz-5Sfy9KFzK%fl%6)nK)ZAmB$fd958K_KIcLpPWl(MsWSYPP z9vDOb3+_7jqj{G_Y)};e--dsxpHW=^KtV7Bq}MlAQ^PiT8y$n-1n2p3RcfkL23FE+ zktL{VVyXV1(OC35fn>k;S8-f&C5yIuq1vmerbYrF3j~m@#dkM-EXhONOKsB?u&*S! zqhd&?544hj_c>1}A*az?tvz>|<7LidcFmTllRx^wzP_mw|7<--P5|Noveb0Bz|d*h zipFISZU*;C4h7|d==P+({mdHHxCKe8w;vqF`}a1X|2=jz>3K}nme%%2pm}>QUEhlsL{eoBMYK>PWW%ohyzWCa_4<*&?`a3#59AoZh%dD1Bc_5 zQc^uY?lIj~gV{?YD7`^p2kRz+b|WHy@|0@%wDIeM0MgTyU1>C5NE2vEC zKs$>h^c_C-CKnj~0_Y?pp3jLM#7rs>;mkO=I6y-JG$XbbTUtzS4nXt%edA~QX-2sJ zgNT0N8w-yUA(Qd{LqZVRYk){f0s6}zqTqmLx02E`2!K6;#`@?_Wl9*U3)0r!&a?@v zzI}iflbE!Qy$md|bAQFi7y_h@cz7uO!wz)8AjaS;?eXuH@|I}{YMM@aIHLiOZwiH6 z5S?N36OdnnHoiD$z=GD4b6*&ETp02Z49h;o{3&>cI-a?1k@tb17$I_$L7_w9gzS z3H&wdzh|=-fUTD);uoDXryFpk?w2;;7ThJzznl(mgH8(w;gyn-R9R_pxRZ4u7~q*# z)BsL^lVA4V<&q5nKi&oqDxh*-3irCB1k(~1wMpT}YsLR+;c;b_m2WDMk@5U)Zy=yY z>0tM!v*ux~$HB5sz&KlA)={k?kp!gg|6HcO0d^*EPG&h<2Bg%)#1VmNYIM@l{huFP zAuzP*>2>(OGga{0WunZ$Zoi!P)tMw4$Hy09^bg{uz)r;!Y-@mX{r3jN#gk(|f3h3Y zH=}Iits@_BWtF90WQ}wKb)zdVUf2RaKuR&(2sBZE`uXpo17k%gKWIS$Jvf|}fJg)q z4D$QxI7q591Av$QyP~=G%P3yRXt6w=|KFjn!LRf0QrECM`R^ir%K^S1+HgU2FeB|3 zyqs$XK}BcBNp@OBUcO4;;`sQtAuA6nq5T^GIO+`tokY-$hX55X7$pDy!Q24A{|jHP zUvaYlKmEUXSs;S?b+*g_Z&+7jdo;ED)?_y7{gamVFv`ttr)n-+E``BK^p_*qs4N~| zzCFgsCaDYq1gGisonGVTGLWnPd)f1V4&#py)w~nFj>I?ij08{jzOUfPqLoo3xzVIqF zX2TZj6)1E;qetEqH1}TwM$)%dW$o!z;cN|}9|wT;%rk6T=KyG0nZOBzcW{(?Z733T zvq=BLo`9xC=zkv>7@d6a-u`*S>E>c}e-(qKj9PP{M}vFKy1l*mFAy8qfyJAHLvJC2 zBK=P=6X4-Pv?m9AV}~Bza&DHMfADW^kl}1|i07$ur7;2d9c zbN_2s0QTCwt&x$cOanGu?td(if8HK!aVNtztEqM~qxE8Q(_HN1cK}78qVfa(%%X=a zLI$jw3K*Y+*H*f)o|AQLh}X%!;H|uOn&;YG=i^AB{wFhD;t{jv#j16`9M!GA1$6kD zp|5k#bp9oYfr^b1hNhyU>m>W_4sgSu+LHOAujSz6lmjBm`ridmy$%6BS_!CYsqA-d z4_!f5EBzOZdZBC8NACdDnr)d1e1p7~5MEuz8t4D5IvW5Cml>R#tkE69!3L}O*Z;mv zDTyo)f`GI|0q3a1uXMl=aCStYx=^+FwO$rUU(K${-kr%=mE0%~)<(pyU2gVOu}_4J zXav&ZK`8J|rO?9H^L*PK0cX@aXues^Ypbm%I)ZI%Xu9oxpi(?%gq}6^x-C>?KdsGk zQ!R95CiA}SYpUgV>VZutW_l+TN6#oIm;$TEA0IAT8t*S=se~SZrMl^}7^zOK!}T~4 zk~WegVXx*$dc29+$t>zr?_(HhPN@&c0S22(|F=YRPvOY~H<<6pzKZ&ZP!8AS@Aiex zD8-C(YHvP;ERU3N!b!_9aHN!@k|d)stF}tSD{zp6L$uMBOKT33DzaN zw!XnHBkQL&QZ#$`9g8@W&_CR)I8vqMdiX^9uS1Vea~uatI#?=B|3_|yy>UedD%iUz&NX9p2DC^U2(XkV$A7pbBCTlA>R%;}7NGI255 z*k7~tvA#}P4>~}+_!Lx7QAr02t}jHGr@LH^j`>yN37v3{GG(`{HbS4a4eh3iu3sE= z?zp&88M!}{!S1b>;c;<{yHA@hS+bmZS&`WD^hMjHNO<^z#GIWb*EjI`cW^^DtycSr z^Ryl|DjUOeN(?u?-0{6qE(Y_f)j%}{B`&R2LXSr zhYtZd<7V}Su|H|5WZKdG@G2!{*ZI=cR-~>N`7IB>kY~U%Xn=j3l14vKpP?{|jfd9W zeZTv&n-Ot;tQ}E~npu6d{BI5%E=PX@pS3ZezNp9&2hw`u<86oAz0AR@$Jin0m|c7m zrk+hr2~kI=CD#*nN?%^I+DbDXd{RhnT-y5Bn*wbdlCa4FIR-2^gA4*d=v=|T&;>Au z|DKq>Aq0$qz_0&e6l0sEFWs&KUUOq!cyi z;g;kx`-8Kx;h!{HP$)aoZ{W_|IZ#A*uaOstzUCz7DI%rH4fK}mpu1gXRmk1_OmiCG zZPt|0u9e+6$Zrb@CT8~=*y3F?1xXb3pHF#KX-9Y1#!iBvv zBU(oOHQ#ya;7qoh6?03|r2QBCg1k!xyU<%Uk8|cQ^Th`%I`nH)Z!Vwf9z^fuhH>Wq zVFBbW#6vQnd6PjywXP*=W>(~k>54v>&fUA8F>+63M~G{#u|4}vxM?{<11g+`TaQ!>M{`D~fDv#4Hd$xo^3S?GW1mPZLyMXAwk$>w6Zh3jd#wa;EP zk(E&4-;fNVf)=tLfRn)JI83EWiRUzmHMHcMjDs_nkbV4bvN-=D(#k=k{A?qN}_o zmmIp+_<8a=?7C5Uw64I!V7`rr#6n9jscw_>E-R8JE@fcCSQ+E8m)~4(RMEAke{Rf5 zuPRken_XZ>Sa)C$d=?Ft-wj-XmEslFrj`DWl*zZ$?zzk>!K;(9%Y1VSkL+B}F3x1d zP2EOJ2PGK^A4*Lxqz;aG%oOgQZvk~eWAGsxJ3&vsIUQ3#op@v~bs5!ks27PXe}`mO zn3x+ZH*k~YE&a%w)fX#<-UUm@%}1f?<(6-EP?cA(*c*+h)!Ri+WTchmbq}s22}A1} z#oEAQm>aC?w(&dqP^`o}M-N;1HX!oVs=NY!lV$RZDB-wdgDO*pi6Xz%8g|xbuhR^y za-c7IxvXfiR~MP~q{^L`S$TBiwwp7t=?RtvzsL|g`EFKhKJj<#I_(dU|0~>ru#NoQvhGPZcKOHIffKEU_=Puz zR}6j+!UKZMiJn}Om9=bBs=k-%W&*D``8FRhq2GTl;nmiin<=X}`~0RWLJ3l2ncZC# z+4)o~3Lr2aVf;MpO298#2iC}m!1fP@ga;SBpE@FUk$qCaE3;~_)(+wsZ6xzeD|6~7 zsY;3knqE#+p|<2*kz{iBP46x-)s60FH}!?tIF0h9%taaCR0!f+;jo0eQrObb$31a; zNhpp*&S60#tyL%Dl=##@3^b-`ggz&yad+ah*s$RkU<@5Dy>YnKUgn<)U&?4Yc7np; zYtHGS-#3v8M3(t9*TOMBI{m$hKaEQ^R4-wBWF)S#a4KxD zp}ky_G|9Svv2W%|q9;c4du;T~N3xyrnoh$9|{_>ZJ=ggAzU+3fO{6P$%F_6nYvnJ=;aHUuOgkf2fh zy%ax^NrU)4)URHk{+Oi`&kE_$O>SNpyl}o zXu$N*@zKcwPsZ31FmT`jBZ&z5EFiiAMii~BA~1MOWQkqZUI|z|jagx%b7@mYe~GR+ z_+X(yQ2)H(?J>VNw9a`0S8^GTq>)N#C#BM5dZb7}J1@%p{5g$J8|u*QOk?EbLhqe_ zHcoCM5c}&;JPerikl()3W&JIdhZj$`E-ioAHhWvII-8|Lk?#G6iOBwxrFrM`xHIz7 z_()o}tj}7chd}CfQ<8(h*q{JDasRL{N6tY>ko)pNG0pwQW#y%GN!1zQ=~~B<_97F{ z_Eg&wN&&aPERB?a$JL#jyEO&1qk){WIg7E47$?`f64@2;jJxQJYRQOOl7$Px4KwJr z2{pH5!e)(Y8d-_ePzRsA_Isy9#K!ovj|&PN3}UDUWBzV7HgBG4b?_x6JaLdLTtMF_ zxtoTp@7J6r-`wC1$I~FpjI`?8mg~6d-(HnqU@;nnr`U#E^-rb6r9U!_2zr~W^rVSM{K+D2gg@Yg3BCNN5we1NIT7LzIum?o8wN7Icy@BvvU`zuK98%HYv&SrI{sZSmQ?+6~n#*boM z1DGy7p3a=@OJaHN>rA_|3)}QPHtC`39nH3Tjzd`3DsjzQdb^W>wPof_Kow82SY znhrKi^u)P6F|54+z`}2A7m~rS{)HCID-Wgz?!B4jMG9oPPS6y4he1b*$>1j8dtfw~ zfq_BarY)@chaGFpZ6MSf#xuG~Zi6FDk^HmMLoNVqPzaPNKah=eT64!G_x))MTjbwc zs#5tstA!>?R^hMd_XuVPbGhY1FruW@kPfrCJg#yQW>f@gK<46v(@&>GJ;tNNs(@>_ z-{N~c9Sol_Ei)embKAS5;>U8fpnC&Gbw!c70Y+OV&oh2A?K8e|PALqYlzE?kFK93fGUL=pa zH+)&_YYi)xJ^ z+``$;;EN$Fs#=1I2}VNh4CR!zo@ELX5(?*@IB&8H+c28a1mq=OoeFalcPN2AE@$7q zVxz!?;x!vr_AS(dR$!qmM_SU??K2#Rz}$xqhsG~MO`rS*H1|An&{eH+Q==$8{S^#n5v!F3P)5jqk^^3A*WCD zOv-SQTCHK-!^{>>_W0hJBFHJhwM?Q>FbvMeV|!+AL8s*~Jat9xHxbJ&BC>Nbyv2(8 zm{Nx{RV`-CDra&y-jLDXUE@=;KN4U1`T9P(ayKRk#$T5H^x%v%Xdl{%d|BI)yPM*& zQ#YBXCCg$H#$IDR_F!%cXEU%xcm;3k1x}#tmT$Bhh&6~|i^t9vY}7}1 zg_N~C^iFj0%ehaO=I{bi9EZMX=**uhk5;8ih5H8RT~~bzB;_&uW}QEY=cR{)-v*1}at#S}3L%fb-P35oR z0^`rE796x(hKnubhZ?bCC7h39Me=+_GUyI%mt-1ufd0E4wCtS@$EUE*!YvmXnm}?=*inZN_l8j_F4*D5a*) z-^xr#V`KRuwqVv(mq2{wD8JxfsxP>`ty$1LCgVx+-SB8Vf||7U&F)YkZfOw~Ryz%}@UUb_8oe*g_VuF*X8vEX>I|*KF5o|Tp z!*4BWXph66a$Qq0V?Tsu^|a1Pyg@Y3;>-2N^i|_S$xt1WKh?{o`JfSBu?%M`J`R-` zgLdnoTr)l7P7dn)A!obfA(w3pu2{!7bFTNS{nX7m_QQPufB5tC$uG|rn+j>(0oykk zbG~fh0wy<)^s=3W*>Y=^POKtmt}3t2+yoOXgn#pOqHH#lCf#ni%{fTMuVNzC2L3`D zo9iu?Tu0eQ22!mi9flB*)1lB>#zJ?}yzmAoT5hj^G2!q2eYkua7@c3mY@HL2Y_AK! zchh4Tp*6?OnDbWC$K|1(IEa`2HT?#;t7ho-X(yA5VKxRtA!Eb+m^}8$8;wuO7?AQs zQPQ14nZc@9-a(;uVKt)TaEcT?huVAVt;XA56+_|NtYxDC7^DIOz~2)lYu+>;&1Gq0 z^9P832PY;H7OaD03#Q2cWETE4%BI-)I)^D&|B|*zTQ7{sG&V%?)hNZ+BKHePt8W*- zZo6U-!zD+9QFEoC`(d*h7^5oYb)@C?ePwz-iP;l`E(* zgC!%KqQ#Ub0e;&ZTE@0aT6^$#c;IT6_L_$fJvJUEbI0Q+2jmB$@m#QNh5+}xz#{@A z#G678e|;8T^xz}=k#l4>^-|}4!w&{s{`f)J17<4&zL|B`2*fUmU6H!;>L1{iIM6Qc zpQ5&3lUWu;@e^&K9WCUU4@jSREr(7%PX9)(CH)=s@QrFCgV3q&lajc9o55M?78xIE ze%(f0_q(|#j~bVBZ@s@XZhPWuMrUAiUMC&>(ndF*AgG_4zp5OJY+dx3gz9~}b#gzt z*?k;(TQwv0*`%L|IT7Dq%QE&=ucJt|JjcMjsax@CsgkwlA>NSf^JhNNVCAsxXmY=5 z$;I}DyGd+PYO2TKgRpmg?$)D%>JcJdXG`Y}Vb>idEf~ZJ7^M&&baT~04NxcK2CkOd zOeaguQ#?KE_4zG4g6bDw7)?OkLVyqw$={a&4tP-Z=G`hbc91+7SD_;DSW*`iMW#^e z^Z4kN;DMe`xvi-0L?TlCJA@zJ;>K4Z%1AEF4{S^I31YV5(yG%uV2=qrjjs2YgJ39L z5ncGreRV=ti6}rY`R>%M(2Q&##P#%(_1+T;)X|M>kHEO`@Z}7k;n*;r8)l3;+PgR( zvR0|9x}=mVQqPC&l}zozAjL1y$Yc^IrBeRDeWtEk_X0(mCLN1pvlSm*QQ+*Jri7`ta4Jl?}`Rw9A=Gsj3SCA+mDNrs|MyM z7j}B2$)6^D%ifdb+9$NG@tQs59JC?A&f6RrI5lh$>zYJIAXgln5}<)Rf4NpB-5nU|c|j6D?IFmhMJ;vepg zs7x!CaKJ=+@TIR&H|*!n43UHiZsnA(9^u|Aok;N}ntt@uK5C@l{R5AG$eu%!lly{{ zY*dXBOVfz3tG1|Uu~@u+$su)0#hmXb@0RXf|8#c5Eq$G(wjnc#e7r`9&9zy7Z+*1a ze9|d0EdrrYj;0OpGQu70k?Nmzm#n1I8u^YA`h>iW4qqsalD!|K8N^ z4L_##uUi$y5`u~Q=TS7v@%mUzLO5mR8aEH9T@K~NRIFN-FT)?6l}8!9ikp6-$mlaF z);4usH7y+&)Ax;~hiTv8gfca+V}JDtxmBCdho+gm&Um{^#MdMhf?k+I(Y#WY{F2{! zr3xmqoS}@qOp2{3Ty+9z8{|dvceH~gMO4G|{pdQoGoi!Fq9|sLk^4GAzIDeJf!6ErP~(MetN3f%1;3LSz4y0yBY#V-nf0)y zYd14^wF7H9Clr-?rgTfO5?|Z<{)yh|o@pq~`Ncs0(l*AntB;L&fj=NOtMV7FEtTS% z`+essLc^VB5q>PzvjNyj*_-K0TeI&4nWyM$nZYl#7!bm3WGWU)3S1jN;`t?Q<<;fy zy=b@*NpNaI);9IwVj_Lt=Bwo81bK+UdnWBmYK)VX!R=!H`#VQAvaFGhXU>#?bLx6} zp}@0y`4Gq)0~g$mU?z$k9uS2gkY+|4C&fE5s?38Wm^6b9jBUhH34?Y2e1b}zWeG6YsD2vB0N@ zl9hGX#uZr1x32=<^D!GOCnruYp){+x18kE{0H7eLmM8$W*%gR&KQCp0MX;v@}&Ee)&n%=ML!&_W**Z0&&Sgqd37<_BQl!X&)`<1KjJm@xFu2O}zB zVKVxdUK>|n5z*cu15i8d#{4_;Fkg~@UEo3=5cFcU+G?gU2xsE*)rzIC*TWZ<>TiKR zZLh%%f15PSQQ2Pq``-x5l?;c$qaSe0h@VK`ID@^XM)Ds@w8SDx&WH`Mb&) zyo>mph5i&7MgYbbw|{^CzZq@n5;24LIHek}r*8pToUM~J9JxlP%!Z3FOxCGG8&a=dSph|N5R-2oC}=au46Ej2*Y6X1qeG9pIE@YF`%q zr<4f{yrB=OAp+`a|6JqyFBK?-k3FTt;$F2Jpm|qx8$5%{S3}$O{jxPvK2)G>74k!r zKD5>Mu7W9G^wY8OpmyPNCWNzLn~+bZ$Hf-h6r%KgYW29+^#uxXPN5fq_$AMawJ^9W z&TWbI|+XXQ!fy*SWnjVWA@7bG#eN??7W_{D>XP6 zPK3e98_yg=@rI4e$zQ>O3_Ak-e|8wkHHJU?B#l1K!kdbEPonY4izNoY*U)ACKxEIX1~pf;yFUi(Si{1i!xC!@i@^!qgkYZ1g(I ztVt3R_xL|neB)1bJ4P;D$R%k4R)VAuU9M}?1;d&fo}*7lFa;N120WI8v3KwLED-Gp zgnw^zQGUXU8%6PKSh-=JMsk!*@a)F8JIvael!I*D z0=`^2{x#WnU6%s^xYw~Rd4ny}9;Ba>yBUj7-mIRM7eC^BQ&ResPO%@twb7S^LNLje zjO2GkG&{BIUyR?sFFnQ?-;x+1oAr)lCPRNBPO<+Qk}O_Kq5Ebnx`Nz<(n1DWN>5#x zGehqP$F*UZVM#S?LZT!v%S-W^>0=wltG>57Ga9;p z%al>__EQ)Sgid11H?(_lXV`%U;fyn<8(T9)I?q^LA^)7$rT4dMh?ZaSC?OBY(XO^& z%iEtu1>5#1XsTcDUg?!$65$DWcfWx?l`V$PAk}Ps znLcTjFf`&=$XtYzLgZ2$L-qEV4-%QD|LDZVDUTpB=M#I*1#_N)d&xdmpwAxKi8&b2 z{G^izpIpt6d9kcspLt5}P^qJ^_ig^woT#t29WOOxIKSff!vKp-T7I?hI-wJ>MsXGJ z<$xYhQeZ=hG=ly8pV)GL4g5LFZ?^<78%#z8-ZVgh$*qAGsIFVy`6gmjWc-DTCzt%} zy;bl_2ad~f(ouU29Zrz@>-4A{t%D*w#BnDdCGwr&Z+|Cd-?@W&l>I+EP{ZRF(L2TO z1#2`A!t1{Rs&RV_kMca=P~FjLr{IiVJEh zsn^Y>GyAYSXmJTYP1*o%A&<>Lo8G~%9q(mFd)_g>eu250-$5yg>Ac|h~ z9e6A3QW7J7`7Qo*=*2q zbJnY0BlV8IC*UOsCP|e&R<(C*a-vnGG1`f4Nh}cWx2YqFz%hk{rQcogx+tjeJ1MLu zO2!zIs@FNS9rr*Bb$7)V_WOY);W?jn5nd9PHH^v%G#^WWm=b_%Jpq(>g&KeZdD?t? zz^|sR{x)j_MHqMmwDDDkyCw#f&Fg24q&GIsEjt|B&(_;&-dYcpfwKmX!aIR77aT;V z+UhM3jE;jT_cyik60-=yi}(jcxUAy!87abB;lWXryqkuY3t^Ao~NVL1}`e48s7$(|G|5f1e=;f0WV z?``=LPAZ^Uu>9xD4SbY@k3(jTePAM4(DFS*Y{2G@v*=l?I4yd!M3jDb?o5-?yB<)v zFQ2oYdYJzNog5q1`^R@V8R-`SXE&!mnWV&`lbG0(uW)ssVF=}Z-S-!b`FiI_Qn7GM zms2b}$H&Os09K_Pa6*=pKFPh@b>b8VUpTvVA^`GV{qJPwZd>P0w2I+yunKop>F>u| z1J~!K@!#gM&i@YO?@>l;@E7cnhD_~I{v1d#zkz<_>t)%=7*gmg-}_3d$es2=g4yES zjaW9aJ%#nMs=i6-;lnEjCwB21+dqH4xf|9Q&oyhnlL$R>5wlqAW=tA%#0?1>#)u5Z z=!Gw?TO4PBN3?}TkRw2tgvL|3G$%nM&?Ab_$c5Ssq@?uWwVl7i8137Yo4oB($(HPa z%9$WeP8F<kh%%Tbc0WRB&Nt~8=pp)$f2!lFcLb0>M3S{A(tH#O?fqzrOeYN@G zibvpO6X3A}c?Wbrs;#sP_}p|*Twkw!wR|KdzEA0cj3BODHu`i=NFDX2-IwS_$E!|ZNmCT zn5{}|L!yl0W!N{ts^ML%SGzuG%0JS=vABi8>nz4Db?@xp;%0OO?2(+@)tO?@Q7x== z_y|?*d~pzHYux{b1wa8}j5ukNKkC`R~Ebvm3X%QULmT>l6xl^aGaW~dq3AbQy z)?!Kff$#17ryjpT^j5@5btyjtQlFJ~WSobGR^~9EKM5AC!U372O(J{*`lAow*Mjpo z5LS;o!!$^jYcFAllaeyEa9_0YlhgJAS$Ho{?zh+Iy|{%tS(1;Cq{YvP1Gl^<87f1a;8@jg>bIO zmTsp`u7^ZXJM+XFL|MoZVd7xYSIrI5iQI(_ZX=VG0EoCcZybwA9>Sjc6_&`=*6o~? zETzSXCgnTO+Kk}HP!eGJRbQ?fMZ{{=t4o_@!iuz*>T9$kHD{C>ye_7Bnho(@!<4)3 z6M%LG5e9vyVRbV3QFnRGOw%;6&(I~uEaH-Z&X2GoBssmg!Qgp^5~g#$aJi%%bhSVL z5vB#G?9nK{l9g=CAgqIeq_99|PugGbTg&_BD?6P^ zv_`BacwVaES6F>kZUvWOk3Jhy{XwT6cg80Zh1BY(G4xDt%G7ugIt(9bKWqgQ7wTF{ zAM`zUIJS-g={e30dUURdlQLD<~{cNrAxJv3>R zZv8+D9_Sol*1&q1y)g_hoRC-TMTHZDK2e6FMdw_(R;`Pl9jF(LS_(7$NfWQvqP>+lX zKp9TM@g}7U6(U0Z@%JrN0i@km=3WVZJ}kWAG2KHR&Vc7-8MI|@Kx2h5|K5U zz(rRm++df!Ez{JrLs*R{HlGMj?qj#ODwfs!=I~!W^e66wl?T0s=46xa{afUfMf7sN z%0-0LKo`Y+kJ#$KL#<7QV??Ujh*4sw454NMYbvrR+xTxDzVx&UaxJyxRKJeG_{gYk z{9V*^$0y~%Wo-j*<)dCc@7A0sMUwYKq6cmFfT)9-to09O?x%{pDKwocZry(bu?9v& z*K8EriAuz$G9W(wX#m-tb0|lDxf*4Exv8mh9(~S?blH{*kzSd=lXlfMCdzXHzktd-q zCvC+-y6%2t#qmlgV5f;7X>6`60I$?(W2-90a=wuR8HZt<;SOkjw;j67JH^ef0_NS- zMw0Db?BlM%qpwQ7<9iPP*@v&v20p5wB>~6}n`c)rGfpr}@#~NP*1f>9?Vw!646p#& z1ZV&k-lcv4=pvK>CCyiL4nX*TQ6CUC0BU|$A)XZu0@@hiK$jvN7%c*~R?!I=dwVvB zAs{SjsI!ZUr=nqCh=VqXx&w^hM_&gNGO&RjLI=?RC8+H(nc%nQbllCD=a=!{g9U!hwxu_8tS>Hq4sZzMo?i}J_sUXjRm zo1)rB?ff)eP?uQ23e`xNiOD~#&x0+#opNVf^Z4vlj$c+8fm=~2(}UC{+p^++wk zze+lsl8X!NgOFR-qu3~GNU#T?CAy`2Q&t}|qL=_~iN`@`w0hLi0RGc^TqB&niM}rK zRkTC$0isVtF4=_m_NJ{k_1?vL4fC>Q#wF?>D}#P( zT)luG4EeBX6jACNUT2g^T(^zZ4cT(|ZgjTHkBy?^U}gtMV07U!gQp0H z6-MB_1IZ5lH-t}tT6PE^1OgwasUo81&naFjJ0C8D0%03tATz8H!w3omK=BeZLt#bF z8lk-dGTL*q1Ft9`K*gh4wwO_;S}r~yD?PoncqPm&6*S7xN?O40xdf-qPsJU7I41cx)&~m6noTFs zMo+}kdZWTHR6jMs@7uf^yd*bRom+I2kdGOj=klQNgn%F3PWr6A|A8o2)~@sb&2Tuw zsB1PeogQ)*GO8W{yfabsjxc|nKY>h&aos7rH=~T~dBXSfd1e`If#?8^;^y5fZe`S* z@3PCHmHr2E6NK5v`-Q5@Z477N9(%P+-^rLOo+Y!kG4XAduz3W77TxYQwj{p=YWC?Wxw z;=Fe`Y*Rm-=7#DQkEHs;BjI?$h&$(x;xI+GYR`G>H*MwHpL#eyKTqvoD@hgEjuky6 zStjEfP+Naqg<)ytmjJI2`8ytnF{(~T{=Wm# z<%Q^pW&)uD?6G0p`kM4w=rgd73F2-z4?+mhmR<|-U*i<7yb~A96Zgd!UT6Mx2ab4m z+m~NE=2k)B%Q6_tPw=OUap|oM;nK?Y;fI!TB!+^Cm)UXKA-$Yp^N;Pa(1FLiazCXK z*ZwzMap~v`lf|k27h+7HX#V;5JzLTko8N}uOR~CAbpejZ&|d!t1H+`7h<~;gzwK(FGE_r&O!7?{D^7UJ%}z`*+^H%>Hk zbe;K{oD{&EerIRL3KX}V!J<(>waq;JYi-avZv)NsB6?LIV-^Br`Ut$~GA#2Aw-pEp z3DbdkR%Kt?HVUsf8K=`1bn3MN*cL8sY_@B98t9D$-q7X_Jjz$uKly~2UrR>WOZ~rD` zI??=Z#u^WS&@ddW=ZDFU!m*z3c^((VW|Tu9l<87K64w`gnb+@M|G@NmPIS3mQ>mOQ za|zXI&X1+EJ=j**6J^5(gl2=%%2Tk-2&7)oejYVF*dq3*Ofxb zvz%T|4Bai5Fj#2OP{qo-XFrnZzyZk*pPr1>*th|lvD;pwrajw0A}A* z9W<}~TE{!qRgqE5ao+QGALcU!lFspi<<>;-FM$RpZHx>M)>=t*Kd|Q|eh-eaXc;Os z`WSW7ULX%x3WUr-VZLbEiH@zT6GFm|M;Q79=<#0i0A;BV*$-AbAPMyvRUNsRPKQ>{U+#LlQ96CF4*9-h=DFd{_k7uzvCIum{T& z%vGd6TXh6t1Czp|pVliLIzY>c1gI>Q=^Sjc>Qvv7vbEtN@&KRpc~7W=Lt!jbiiKjw z8J>bw`c;6oUU*iXr~ik!(2a$I4ajV?OBt`$n^ZS7cCHes)TwR2nQXq zynKd74#!GRHr3J5L6Y>%YLbD^W)*REb43o)M$P!ndEaPv zwR?Z4LY!LCN`=eFS}|FtI6#gxID7AX!>LW@GAFcrZn=K&5L>F9^%WgaRZ;cgw9pfg z)a)|h5*s}R$xEnZxHQRJRIFINJyUXutji(O2bD8qY-b&s7NYm`liw>hdaIUG?qD;HzQ3xT}!Bs$mWc1#m9FV>B!dx_NiFA#%!PBdHM z38j2v+puFanY8bm?o;(_c6G7*j$QGhiW1$~nrC&U+wp{n2h;gm+!(7HU64q_LvjfB*1tJOuqTNt@?ZYn9^~4+wNjO|yUa9C!@{yh6;+_5x zmAYI8nGUH(aab!TLSvJvoK>^fnqEANkBE#~!24S%(YM|zjS}^MGDq@j4EhGk1#RT# ziX~Z>e9*HiPfBq-Q1SD4+`IwHALtb=ZEhk1uUWv;N3*D!vG`aF{3>DMe$2l?3k#lH@fc?YnZFM3V_#L(VXe#C~+JOgf@csCr>qk|(Jj2G!Y7`x8_4K_nC z$!z;!3iEyJ?QH{sY$>VeeT{4&N5lbAa9W^;w(iJJky*{>e!&O?S!~bijYksNeE`K6 z6`&%>Kt#r<(hjw4zJ3Cn<%xl5Z@Nmp-FD>a$tBRHlPB=EUubmY@p=$|xltDDqQWYW z+U?w=Z(ShBKl16OE}ev0I%EQ4|*p4*o601y-kjQxSNDfmh28E(jjMI36mRv-+* z3b^Uu^Z@^TNCC>KhCs$*gPySqbhcbA0V z5e_CxzRcb8ox+Krw$XTglE4z@FSofM-*4Xg=1tSKJ#H`y@Jg; zk`^NV3;kf2)LM5SE3ByzrWW#%$kn(E^?{}>YK9u@18oOu;e-JQ7O3pE->?R60>cR9 zzm=uR^)2y8oxH|K>$U%u*k|SNByf+~3NJ#l4P>yd5ud)WAp8eua^#PUGL|U3em|vZ z{|n{RT2}jR!DRbuHd~oK3DjMP`#f{$PK^9&$hjxqW;2pBv|sE7duQYii88Vj+Z+uA zcVex|jGRz}xj(Vlf_`yt3u{mkWv49weQ4lV>{biCh&%z7%Gy2PMKjVsOA8+e>^5Ao z$8MX{3=M%UiPu1&_6kte(ZUM>K>en}%GMVO#{8H8sj``uy0aG2L2@!KQ2#atI02xH z>kWYFzzZvF>mv_8|B@yh9}my`@0y}N)?tD_`%q1|_8GjzL4|clZ$j zX-SVOLeS5jTV0x!s?0_YBiluH3})E6KF;CD+V&;!cZ zke4*}MKp_tIGzKPQb8k|;CAcG+WWB|V3DUIWpQ-`Bve2Stsx;Wk*;=+>llGA>haL& zr4V4Jv&bO;uiA^iIpC)%QeULst$}Omq6YZ4i{klKw(PEsrB`ZktcEUty{x<(4vJLR zLs3UdPmigtqOvjp5JEgy9qkRSq0TE7#yDokm6)@QfUdR9xR8AT#^SSA4YH&3KZ-=C zxYU25dwr&_u?q}CX;osmiyIg;TgFG@9k>Fo_2-O?g_C9#07`iS_(q^a7Y%?e(q%K$ zqANbj%j}&GKYJ5()zx93ly^H90j`{t2POc#)@gR38%U%8J7of_H-LwQ>H>UWHoYA1 z9&%WXky15JE-$l;23mZmp>}WtxbsiVK6X|B^8kR5Jvo4#V_mlco*7vGU}bL*kP#RL z+*v?LC?|ZZUI(ZlO#z}{s33r-r2qiw`}_ORljLM%R$?te+*n=21ub)&QhZ3+;e=b` z%n?obDMC6tczsK8ygzgalvm9BZDeUZ0{!74B?J{mwIF~!cGkA8rgs$qq(S{7m~gj| z{ny9{PC#Npf(LOEEj1YO+c6*%^svM41xVij=}Is_WkJKvjsf5ks}96sK-k#^@QP4r0LesXRV9OEb%~cAolcVasa~D zPfgIqymP4)0ONuwP*eawFcg5$QcYVsGVo!O0#N^ff_eZ@l^)xw_8m33S{--ydR2JW z!-~cinkM^246M(>wB0rH`eipB+$Ex;-DCBu4hUFkkvK|DIlxmMeoe0%-6pp;`uQ+r zjPwCqEXF`f8zy;24yXnz1Esr@tQS<)0TC6o573LP0cQOHEg1LPr^3QQXef~1MSSld z5U!{i8amY50f5U3bL7b5{r$aE;U6fd2D=5A6!~qpl^50e;@p5974b*7X8jYFPJq@z z3Rv9fCX30YHK;P8DtTlZz~)e)rj}8F){_X}k#cc!Lqh>$A&BVc4)y+HFK5^5@%Q++ z;=;`6d^-};!S)HF4> zuSIA8#{%erx;7_RM6ngAzmVd-;1Bj*_+#z28?o;c6~okj)MbwMr&^>}0enk;5pd%x z5ek4f65XEUZ<{Zcn$bWXGS(HMe3AO?*~P`h3%)=CpyDzBGwn-Cz>w>Qy}i9%Qd%1F zwy+x@tppHt8{XVmfO@0G`VV#MBT&wKaW5rhWwl>PSAPb|_Fd!v5hgVi6*Sb*7v@xR zbYtTCG62kaDe`ba=T%ms14dG7>BY+d)UVw@w1^4Ni}SLi(*VRCP*8mX1Jr=veULld z2;i5p9G1QUyj+@IkHA2@^+muxbKE{C|F$auKUkFi-=k4ZVE70iTtPYn>?@$=g#lQl z+7+iyfMM+c1B@h?UuaX0r)_v&WLtQXXMuft;a^$M>;!m-jTh@a_Hgz=8qxuhApof{ zYxH}(zk*Vn;RCqf>unIA0L*9eC3+Uh+75w70c37~L0?{CG=N9z^-*S&Psd+-{6c`# zHi7-pfmHCqu@5vtiDYCZM*|Lo`rryMdyxRU2bHk!(o0K*4FSE@-*qikwMXNj!@sb8 zwXXtX^G8e)|ExD^5fD>-`Roi3QiK9*CwfZefLQL|Yg+4Xzl>THJ~nnpPmfet^wB>} zKT(S@|J*T4=~nrlU*7`SuK)ekm;aahfam{T*XPW8?^b9TnG-+->E9kJ@}qvB*XfE3 zfSDx%0>q#wsi|QAdtm7B&&NJ{z6j5Yh5*q|KrS%7PVfOhD;ggFQivYgYV{wNF1G*N zuq{zK_`hxi%>GB?{cU^F)I@q|d-AHGlacXP0OYz(iH`u+`@eKp0qs$LF)}4e>VqVJ z;T4OJaPQdipB5~45>n*2|F)_jrGI;f{&TzL=zni~_2RQGJaGR0@;$Cr`9I(A_xGBk z|L)hzWBYsYzpU%Ot}XhPMk`S%z$%^k0zBeCI@3N+OkL3Ng8TsX0u~D3n0etc{%<>T z2XKfKHj+rnOcMh_LF+fArA#l&h^?TaJ`e_qMwl+ie;Azb@zB zM_MQPyr{ z?Y46GC2kOWr}Db&^-^r^rH58c{BnhY#m`CFi{k=}@9|kVh`7OncH4vYqA#jDWR?q_ zyOm&zK0$FzQ%ETvm?7r2K^qwy7Fc@ss3s0);icn~!)|ML)^!BPl3hbqZe1^BMn80d z?t?R5_2lNt{PXgaM4AWy4NfZDYwFv|9*PvWx{^>zsPYgLdKbP!tAbgeiSWmqr^mXys|AT4S|D^~ zoS9>g&wIjN|IOnGFQKTFsC>(9lQ`+Jqx>?oL>)1n(ws35v09@83`|QM>%XtV@gQK| z)N*Hoq`{qL$aM%x1Id4a$?8B7aXDN>l2EGW=&Rz>Yfs`4dD%lAN7&! zq_6cpUN3=oq`6c#LG7_^rJ&5ZWy0k#^n@Z>81nuA4#2l4q2y#FHDbjBE(c4tbCKs7 zE$?1?wg39}?`7ivY|L~dQR$8G%Dp_4#Ke&tA=%o!eYdJnw8&W&!{+;%-|PAe*l=+< zVGF?DAANOrowvABiv0+`7xuYffcjcxij!&YK6Ma+F)00u`Sjde!DbsJnH=)#N(}9) zWOPJAs@ftTk@4M%R-Da}Jh8TGIpL*sNj=Xf1wTfUWS#D-9=`}m2iXd5IaZH8G|poN zs&NOlB>Y{~ETKiewmIDj4@?6~qvJ_Nx){Zcn?*LbVC)sT;)Y8KM9@zg-)5<(B1r^!i&kZX!Gnu}$G00=ab^jc34p>Q*K zo{Gm$e0DrD%DOQEiyPr7ke66qVHJ)}HR0Nm#(9!h%>sj|#ub!iEvKs=e4?Q=(s6iW zW)xm>zI)(#D`h4h<8D{~Ih-7X*N)u3C-B;nw3Y{k?r_({^b%zV@+4p8%R%S;z^S*u zb*oe1!V@rKBZUyOQCr@MacbtSY6v+I~Y6&;PDuPwm zm?%vci45Y)KfzZhoMvtumE77STie^d8k}ma8=QRt8C69AOUy$og1e_Rl~k2S&!L<1?4jYZ#^7e_QJga8@*CR62U^UI1?xF82 zusv0Z17&mx{H37$h{a!K|D2KO#=mctwn3@%jCQJovp@tqXwAi)66Wl{W!iwd$GR=z zI}@6E0qZv0VD<5D>S-MdWe15<4h7R9awE+dK|-$4&%uOON1$q6u^!82#$VV3{IEE^ z2wogA?=cJB^OV@MSlZmoEn%^1^l3<4^m{s~@k5)Se|pxEz_ZcCN7H_+?@R8bgP=AW3*4*Ib!%f-~i8$10`6A*@v)NOu z&~HF9YlF9ho7jY>BRE4+*^)Qf5L#*G&BZdGk*-0K&u@a;*{f*o@tesoWX-y277fkd z=LQe`?yDwy7m+XFkR#Y~{aQH2SR-!jb2uu!E9x9FUe&taFK&cdqZY2;YCX>)A;;ET zprm1R+{}NR*e2%m`=@d&5cgaCGUmv|lYoEZ?+Q9zqRIlX;XL7Rn$#wLYeI+41@}+F z)+fYm=esqCU!a2E9wW!QN>S;;J~gj689h2(9Gg^sBQ7uH)SD8AaeeNfz#~q1jbtiK zSipz?njcFsojDcMN#TR-g(xTI&P3bd43rRo!@zQe3o!LE+sGOqe zG8UB~Chr~jc;VD(kw7kodGcIq9YDUG(;h>SKo+7phg%^tz%(KX`z~Z)W4tOVg6TxJ5!!Vv{GdA(`0v1-JHvGVW_L zsh~TsWo2Cs@vkUKHjZH+SHfCr<6v!JGRx6`^l}o8HOoK@;>iUE2_17(dRQnMfCA0& z&+8l`y4Ua&exFQzRTG z*ze{&vze?Q6%uhcApOH>>y3U8H#ec7iI~E{^Ir72^Bk*A+2h#r0*aj$R)hu#LYBj! ztu_sQfWsqDt{bg#aTEx6T!ZyOgi;MpOw1X8&;Lq?n3Q`<)+4mJvdoSN`_M8n7#93V zCHJGUSVs6;vxlMJF+Qg$_&qkBMpue|U*b7H!T|{YCT-L5Tk|{}&%LcefST^&;?kHP zZgB#iHUXU3aDyW$>HCnU-eO8YdtHURb~3q42T2zM>f9)vN5f~Lj@M75MUX=(TIGQCVG z?kqW1Ihkp%tZ`p$N3l>{k(l~?%P z1MK>rI4p?vMh2dDNryRFgWz?$389_vT!ePL#w{V6flJxFBy}rnC#TZ4kZ0CA zql*WoRBz?V$fE>~3lZk$*e}n#GiCGR6r0d1@Kag*5hG1*%?9=FvWJ2cQUV8Ewt=ur z*7yYB&8=~z1z}U5RPzJ41eZbbekB32@iybRr0>4?DFiK&&j| zS@OBtq-pMFA~s%X)rx(`9JKT!^aF_CDaQT^$YK9pFPTzFl?~EX@9+G&1GS%G=<82& z-Ge}66FF$&A5AwYg3S11igWqEpx=i)Z6flmX*vm5=*tqlOnA>d|y2JfO`+z z7A&TiAdzqwRJr4YS$4=(N|}7}M(i9z5S#nm4Y8_fTAc7@(_BMSJ7;^busp6X zmK}B9>F%@&dd~ToWTZn@!uGtQS$q3tz!K-MsSqoulbpuiB5`_fJ8T(9&4N@6L}EBq zCFBiuv@LV~P6hx){xOr~zu|h-xes9}GZ7$_*k%l5H6jW2Go5v2vLNH7WaHc0`#$_h3*PiH`B%ZQJ^gnuMck?H8()G_-Q_v(7zER5t_vVco+jHZZVnpe zHw>Bl(uSfJR-Q)QZI3PCvP9#>X#4q2ABZ!Wk*jb6+1n@-BE-Xw-;`x9S3zNh?cv$9 ziEMiOLCF7~{{I&}H)fU7IU$x>l?RYSvGQp`lolcmJa7exOB+pM5;6Qj2x!2N28Ju& z9jgFXHchbf+qc1<9ZLokGH=t1>^DEF?Hi~5RG7IHpuxGj(iR2HnjJTj`%CzfV~6?f z>uxO=;%EzP`(U{@j0Gq;VSDbYJ+p7P;zoqEbr4E#_#(Ko`@gPnL8r^8N{={8Ck-8{ zCed5zVKga+n9VobDlu$6zn^Ofx!>STCln#(CVwB}^D{H0e6X$Q43VM(YN_Mn(N8U+ z4p6+ftV&T~PiLri(g-^z9bf?SWnzZ|u;KrA%Dw_ydHm@F}V<@=bxR0EeG$d z8@|sY3>Chw*1S;Bm_F`r$?#mDSYoC{j4}*qC&t?d-+BYLK_D7s+_-9QU#8x3HZj!A z>NvgOtu--V(gj2PxlS84<+V2^t~g33#)-p4od6*Wi$XL}qwb=&s6%GHOezQMd_dd% zblE&B+OrU4aW@_qGsZb#z13nXsDs#(68QXfBq?| z1jCv|c4uQw)iLwb5ms&4~nfJuYGR6|Qn>+mS^au~sGHPL_dd%`3O3BC`gnr{q zYoEv*)LAQPJ&`=+c@`QM`w2Wjt++hI94v3u_xI&|D+lzJRl$}E#-KcJ2q=w zyzU%$3H%1*wMdx1Rz^4AfiUt1yngRr=OR;M7zmefj-hd_6iPC_8Hgooc3pSJ9>{AZ z-dwP)aD2h7R(^S#g&&w)Snc5r6vQ6;b9Y*{>D2WQ!Vv~X#+SxiklQbDi(f2>oK%24 zo+~&?rC4_v7E4Mo{X;9J2sguBZ{pP6-x%FA+Sgv|CyM3O+iu7g>$4Y(&FWSmRrDG7 zOh3ool3vXaVuOTBeD`Van9&3-pM<}2E-rDn#Yp$)++Mv_0}oI&mTF0Ha2LONTc~z9 z1q7!GMvJPN@K3f^O;`h284jqCQ)$ta?27H5dGXwv=(BobOBSmf_Wkv9Bl&N#PmK}z zweQWQ&sD;0HEaEntxF1DQfkTvJh$g}%L^6sbM!E@jgRDkT;qpoofkM7ZaVNef8#|f zQK-0{Bk@P_#)SN51F9_o~4Xm3}1srT;o>|&~f^{_Op>Lcn!AM zn&sjCSf{b9B~+}g)e@vkU|&bfe6G7SWAxU4TXxp$IYFhrVZ%m%{LN3SnSL-8&AK6^ zCia3^4Sb1YR3n}+j{D64f|zoJKA?`DNI{YsENz8u9O^X6`0h7kKn}w4)mhTB`@#1$ zd5k{{w=8_L!wD2>;GW>O_J{QCpn0Qv$A>kWv%;IA-5*wc?>cESa-3>F5tLz(ivo4Zq`vw>=)aqdk8|c@p@b@;(2{ z0g$%7k+vmi`T>mxxz0S<-V;rqqnoaxtffyQn&Q`|VIp?=k zAOT1%4BbZJ@t(hWZZnsO5o&os=;v-cVML_uVVysd_Oy4?sMq-*a{rg z`2Kfziz387`gip}0Ehsyvx`R>N!D}iNX>SuU6BBC1U5Y9Rybw^oMOMdej{JJ)U>E9 zf^pzwPFgyUkCwWN7kBpKC0OAI48-{zY*Qj@5x}QDh!A^nXaBm=BbDj0&LE*-9LJyE z@z|@<8&}(D5C9QkcSVtvB?bm(nzn3|5mh#!(n{5`7{qpWHjiu$+vM5E37$K{Eb`7{ ziszQ%FDxMX%gqELq6qdeNJLIQT%%(A-L0ti zR?QMQ(OT}W5Y$q1&Jf8=H*u1Bf_j$L+167%JIhXZ9o09HrNt<0!d0vJ0#@ScRxM@IVCC30Wb@}4X-dA17FP&sA zd5wTv)8&@do_l>S7c|4iE}gxt<|PcPt=s#@Mkxzacb}6S&W#O2FFd$@zdx}{u>&+Y)XU}$U z%Mflh23T<0xg3JVNe{hq?|6&Far`Mg|6(FQm7Ex3UQ^OMP z_3^#9@hh_>YadF-rdZ!1Oo(W*m2NGMfN{Mt2>9vz=8x{-#hQzCAzvS!UVE|;QKOIu zh2+2<9t9z9l@L+O(6K-lui4bxl0n_V!p+94DJyVXa(gMmIq4P_4zofpKry!NknD%& zCLcC?5d`~qB;EEW;d?QL05Z?hultudm@8HuU^E9q4B1|HLGR^l+d8_F$pckmf_Njx z?8EctIW@a-|0<#}0V3ql>vjR3`kImxajg%AWz77g2Kq^Pw=A38LgPjxOL(4kQ-_~p zA>S&T6$?D}9;5Nf_~8)PzsxBU@w(E45kRji{kf*#(y%D6eq6S_g4x&_d0V!uP+phw zz}dd1AHRLK)7}fl4MW0bgxsnBWZsZaD1=#;d$Oe!{&XfzQ3%)wn!5)ZX;vm+83ps zsqMsApebi}%P^BHD>6a8+{;g&;43<@X5|;AREo^zuZw=@iw~W)Ndh&;e!EO(rg&x- zTVjU^(RlnuvBuBsjiOaVYz~wN(Ri7CiG^^PnR9*jf=xGz^Eo$>4ejKDttyMegS0le ztKzuxMM4_>7DPIXq`e`I)jqe+wVvQJrPQ0}TO*_gLQ}?a*lqN@0D1dv+0W9pqCvzl z--HItqq}6}?r7h;Wz~Vmwa~}nrDT^BjJc9I?Q1akooXArg2waePuJ5q z{va2@P}6pbyMTUW^L$L=vqx^rNkm9QP&(;Nf%qAL4_j6f?&ZrFMc3}7xzV_1U=3D& zrNEwja)60=heKXDSi>!5P~Qp)ndh9ul~wiSY9q@P?Fez7;YyAXm!3#lqgnE-Dgd$*gSrkh1rZSRiLa5&&4;ublH z$L%Ne-5r(8Kjd5a$NN^>jM+GM$n3@5ba~A1YHe#Sk>eiX^t;z{t=1R^?XL;WfooGF zgsWwlmt><$XlV?2iN5X@)ZllOOiA*KLAT@eel|2mD#)yda&I82->vG|Z;QD=nDZX6 zd5bm*NuW|K_LsZ)rZ|l-ntMU~{UbrasyC@+yW0b5@T%W3bMaUT`*ruxDpDxto|d!l zYxr-3Q~fnRpf%beMX$Qi^Ch-&UGnhhGjWu6@d-D48^okzeW+Kf;gySV_>xkaH33^x zDTvOKT|OAFKh9aB>VA_UlNwmGy}P^9tkF_t%K7%*EKpSWo@`)nuKs4Uip-CK>##HO zx5x;0(kg1^W&2vI+P1m0iWvqUSdghhoOj*)7z-@NTB0qa0f*X+*%V#R!tnoNf&bRgXY-*;NV=l+mkRHn8LdZ`WEk>?j)KnL)LurlZDuk_$G5 zl*puNf8^b1yVTA)_>>>emUsvBWg!rkHRR7TJ*MN2(Hzp-{rD1LjlRo=*q~g(urV2c z9(r5k$fjI%7^h8chCp0l%OP88CQW@A4vroS12+SQ$`!fhSYr^)@ucN#qds_&y2=)d zaxYemD(9wSY25JMwyo}1XKj;m&-U$Ww#{S z!goJcjl9}{amdzeVo;~4O4hy{co~ZiJ6cAZ?_Z0hjFnS4H??=(^p0h8 z{bb#^>H^PUI76KFO{OAL5(8#9y|pSyd&O!mtGVF4QR3fWnWr3GxPC6iV%LObUVtw_ zNi(kTcwO-AZY$-&u%*ybG4Sl!LxV6ff2oNyS&zl5bw@l(-hjRX)yt8)N+M|I4NI2z zs}P73->VCP4#fDn(I5gY=&x-oqofCcaJyXvoYSXFHl@E=McT+DbW_oP$&D9Ys-kS_ zAamDvt(*7BGD5$`;&r2*?03!+PWtH?$55?pA|urZ@F#S@k1X+4%NCh7E6G>mC&W1Y zMJj$-WQpm4EAt4s9y~5@?pK2c05#X{$D`ax-aEa8iwho>QEmyNCZrwvnUY^BS7YOo z&mO30&+f>-?}0#H?cobkDZe$w&dbu+hnYr0+teQ?&_MT45q zy*3Gcx>l?DRLSr}h@EK!-3&K;T=Fd{Hc6cNDBWyQQvS1$L8Arj)Xda9?Hy;w1y1y#e5_f_2S zWAI1De%$hyvq0ioT{$2mo;fG z`4)Pg?Txmudr@%nO{*ul*_|U?*iniX9k-GQz5XsZwoK`@h63+h_p2i6?p-m4Ez?cr z3rcqpl6OSnUrgw99ooLRYG3N#nyIZB!zj+)R_kkY8h})s}7%3U9udz)@Klc&TMdrH$mGHk-i@Cw9@rU(tqK}F=#sX2?p*>P>LZP89Wpba|moy5lRR=_aJ`#JcGpibB z!K`eVm$Y!+;lH#PxZ{Guj(&S17>0fJG!B}B^;791QPjy5BwHLzT29$`%9iZCQ~i2i zXf*!7dgenhuNxm4kFML>4Lna)=>{k-pZOtX-a*sFd10ZoaB(E=$&+jJWO%P&i-foha}dcZ-PPR3D>_Y2;C#8H)0NEzb33`lnf71*@_8 z#nAZ)^q+?uXdYnKh?3le_P(3v zkFNUZIj*uQ>Yb=B>yB+)F2n|if#aY2L%=h6ae>5#Oh(skj#s9U^=rC{%E~>r@WM-4 zHI9y53yzP!=P5YbKOA6F&=v)K8?2uY`y746$B?yatETq)Fhr*Y8tk|6+_PL3nCr2+ z)*~Z`%RN^iTPf5PT2c=+@avaq{4<(Iz0frD%h^z?-ooRQ=AggE_Y%+dMKF{K2)HIz zzk|D`fPA;_ZzIpS`%usZYgQcZ{s=M*K0kQ>Gj*fpT@%D`S-88N3dSc%#{flOVmeDaZ6ih_l^0E(|TovKv zKAya$yzdBJXveyjEV^8tPk7fu&imoaKb{gCR(hCMP{9qYb62#NE{$x8OQ17WVsr)H zw)kDO)&|LvLk()7J1kE}SZ$Sb6zjTFlg}FKD;w_g6ZdV0e~yaBHV(=4@GbK&7>mAnN55R*MvT+rw3WICiZBx z!&<&?cqR#RM@zN4uZwLse}T6P4io)`(AIh~T&;bz;yVZ@ZoX@MZ|=ywgH3AestEQ5 zMc!_O`d3!*B%0bS+rRVksyhV7F!^;Iv%T)*z3dCf&B_TKMGS4o~xNg&a@?o8aht?Z%-UNqGRx#>(Im64RIB^LaY<&sK5= z2NbHP6gy298VE#kA1fYDA27iz?^ezy7*}0JVup6`d+vm52MKwSDH2V7vOlcex;nr= zh%gtlgn7Kk^!-j#8Sk>*LSA1>o>YQX87W(V?*UuVxi(z>^mUQ>c6<$q&`^=C(OohLLjrjKNsP@I>Bjraa^s^O{09(Q--esB{$x zJ~>_#HE$!(_-DX&;3P`CwUg%&;%4vL$U|tV{lN+1RI|pZ=&}YIJMPW|J5LpS;c|!y zb-Jw7ix)4L{pBi0KCnt-bWiI74uF#5 zQ#)49-D464g2yd;)p~t)V;t-$;JQIrJ9?-Tfi>eIrNfW-e+qag{D}>}fA% z8{WkX?Zr*td|l^ujy#dxu#uQCl|R!mQ0F#8GhTt*V5?7ZyPSob^AxC~Mi-AVA0=J% zR^_n5nOSwyGj0J>06m{ai7vrDJub^&QXy8OTO7gl>UU%54VpNG%D6wC=A?qg6m;@; z41%;DJxv9r)mPQ31M!0_p~-EN_5Lv|=gTzcJTobU)(u#?TKf(pW0CPrO+iyu27*4M zN=i*Z3MI_h2joWTDYYa17w?hfy!0U;FOw4$8eQX;Gt%PVee>?)m~Rx}{G7?JN&6BU zkTfZfksX(+Yb0Bk#5hoYv2s97Kct<{52{ME3VK0J?6Q5|!q z`E40~7#g5tg@TGSsgLOmy8GRW$@0Uq508g8To}pAY4OtV?pQa=L%Uo#_*cuT3>EAA znI}TIklr#$^I~L$=A#mhG1!gN6wM#H0pVB)AKC4pmt-y)Rr`FqU%y6 z9nA;&;h#An4(GI^`kq6YvmW-L*GUMT$NkMic#Rnx(y_9yuC2HE#|D=RTo&3**tLeL z{yc?n2cS@akKc!)9rDM{!JP?Y)(<6l{&>@I#l~7Wy(^ZMSiD==HzrhLIbb3?6LXio zC5C}xlFr+Km9Tt6KoQJK7uGr7cO&_zZA1_#TJru$q23-(xm)>exp2rtH!K?M$5O8WgD9sWGg^*e2;^{Uz6Lhf-?Z zWfr+JFf!|?qsF>jbXm-ot#&V&Dlj4@Zk+k{%L-IE6a=-~p`U0zcDb7zijuzlaafzz zzsw*TG0&7=bdDZD&pee>J!u%hlAXS0kRK%V2dy24JjJ~oKaXv+Z~FFKA{vXM;F=uu ztWqO91DPmR+O=!VOfXoQV68eZOuUmd{1My4OXSBD!pFb1EYIua-C3prmk-Z(c|5`D zUcEeNDX>H3)<$W~kdwGCta(EQ9;2)2I}ZC>1(O^Xq7R*JivNd|y{0jb^A_iT-Os(n$dI*Jt?rdQ&7>!Oh zeVIjIvkLWmRqWhWiepe$;fk%IoZp9KCuQ^+j&7JMPi~KfUR!&86;(wZy8D#m!Q=cG ztJM5B_S>$ZRKAzp0!qwTi?Bq2Or0J(3H1fkFxNoL&6vZUsNHwSEf(r45y4W&+9J<5 z4x_|Hy+pZb4%#1+dp41vfVCDTbyk_wQ_2E&>ThIW-zN}96FLp zM}tMy^JJzc7|vSl>2e4vg5XMO6{>fdw@%?b7DrpRgO=7`WqCpk2a8MQK=^-Av}|F} zt}laSrrmk+zguUu>o^q4fy=^q@KLsC@fpiNQ|{ymu9m)K>2NuJQIMm884At}|+H zu|Vds+FbF|lO5kTE~v{l>H}Z3avmSW%Z3NP5x5mPTd6YQSIt-j zO$Dj+?7c>nk4o_;D(R^$f*JmRu5cu@6C zpY4SraLlCJ*xzY{X}TIPQ8|w9@zg_6zlC=icDG73(s*?eAW#w-FV>^#Rr$OE$p?VE z_2w%LvGd1s$c!_?bvm(9LgM)6Xd3&EXZ$kkL9f==c8RCes|2=>)3a`fW3HeZgrO(_ zj3&2Qo#e=Q2S@*$YLD9-n%RhTuC;Eo*ntH~vJ<^kOBvl!f>}e2=4?x!vAP zm|(LcIQ{ioD%al(B?kouYVh+oCA^4m082j*YZ93G9-mmsjl%m=HE8M8_%FaAt}}(G zOAN=_s=aTA{ea@{NIiMIkYMoxwjG0dTjCqrQp}=!?Kq!OSjXvjN%_j6UrzNNG?fM4 z?A%PjB=d7r+vtayik4R?BlS_>K4*5=_tbi#1WUiee^_ut&@7R%VkH9`! zybyoc&%5-9?tYK9XBiX{mpX0LD{)e~Zwm7QVK9D#l+T~-r*OSwh%JF%MG#;X1yFUw zON?}2YaiNGCd{s-ONTTG!yXJ5U}5V=j4OD&DF_bi(i=2;uOB7TzilpbkY%ol|B;g{ zzf+}rC9p2cGkzuHJ< zXD&E)8YIxNKa_cXwC{&eH+-NufXU&mFZqz0kdM^~y6o!u<+?2T{-|iAT0S+FWzCs^ zOnixeMsx4TSUMd59x4Ff0U>;9-|cM+CfRT2;Sj5nKl#(>hzltKbt1fV_##hfF#`s% z9BzJMNAJSAAGFKSgcgAjk?Ak=)3{1fE~&Pkf~mr11d=nt@`x`R_TX6dH}jZEV zcUE+&$XFm9g|kaoTNYP09~|K3CZDJaY{xCKewwe5uh`6g4m%pYsTQd>B20zgd2EZs zoWb)3aggjJ#tP?!^J2LpB}l*aXVDzBD0pjf5oUd}C#0m)X_`>SxOiX`Zm#Avt;I>i)PC61 zzKkgIesq+Bu_(tWR)xTW0vca(Ae%zO68a0;70Udp<#}sR#;w9>I)z$Eo})rl!lG{I z?VYvEN&}aj6GId@F@4qVCoPaU4WePAL`e=$7wfMKAK|^Oa_u7-mB?({<1<2>~t2GjO8=aHYl0VuwP26Gz0V1G$KQhzRft{%QfRn z&msdpscUk!=zv@@8GEV~WR|z!46ZKRvA^qhZ=$dKk)+{Go{}3>(aD7@bbk|G$(bnq z*Az*S1W;vg`vO}BOzXDbg2zHEj%L~C$}c+~*5nhsie9~Op5*gJ$A^SZjHi4Wo*@R= zs`;kL%J7rwhTNa>sJiCW-22;A!*!f$3!AQ%2h<3&yE)+wUzSVYfnF$jOmH}i;5aTOq z++aNljD`1|}rt=U#>tGqVm^E2pVcxN#SDAzP*Q%NNM6 zYA?R|kz|3uJo`A(5Aoe6iEB68H#6ZmX5%-x5FI=F1y)kfBzUgMm0SeukLgwML3AmD z%*j{L4PPq|=hO+QO*~TIYG-rf>0I#pG`ldfJ;?jF_e{f}?sAV9)+OCoV%yH$>PPPJ zb3btdaMp?Yk)rcg8+M^=khU;N3^WBpkg<&pxV(wo9qJ(5_gUdB5cu8$R;7nMQ&Kl5fqFt5FsR`J0f|sz8MD07Ym}FU+j?u z_h+HNOglnEirJahh)tp%d0rzO9;m!iQPPKoJyVmMbcDt}S8u>FaS1@P)t;bvUA4-Q zg)4{mA0ybOSCC8#ulEgDaJ}Q7XUpL&;bTx%QL8I}oYhe}rES}jaG34`A#p`n|1qUR z_6O)C&AC$tZF^r;7J9?_v~AO;)E2gYWh}M6H;MgiUluS`LqoQ~d6i@YXtFE9I&3>y zj2Zl??V3@Q-oZ&KuzOj32SBA2%SHMPTrzAu$3m8qP-7P+D1ohHIG-bVY0d2~9G&Y<&ec~G7i^YV3hNxye7P%`tZ z_Sb-EuY-ZujCwPsBhNQr0$#1~`ax45Tidx~HqNfTZUgqU!TacY)cy>tV3jk#?%a2FalA(25g!?2sdUM9g zKQz>G5dGJEH}2b*n}T6qXTOiKC&NZ{-Oovm_Stn#zmo1#iI8viSRlRxoDq{T&%)Hv0qcz7&VYV{P6{+0Y zBLaIFo@uZ#WhJXG)0iv{2Gvo7kN8%APNqVU1EEDGjI{ zh1_yX!%D?qpok4-xj|u!G^# zX|lp3S-aVN>~mw`3$8w}oi}aTy~O)0sd2!i4gZmlN$#JqSO*!u6nbjpB<2R1dFDr| z<@i6I_i%5M8>yW~t0_~HgOF%m@wQ4B-I-F1p2XODk0ah7WAbiLDJBcit|8i}G_Yp- z8N={QkxOK$tS8sdaCEn?a$5_4^wL5{1pMn(aoh;K5ng$*)-r6M(U*^Bp&xI`VfKN0 zn$g0Nv6`mJOxqalFTrGaZJh6vr=n7x|1B*T_68|Q=A1!~SJP`JnB*?tzv2{; z9wA|dHLGLxn2SOwQOW^*D@$E7I6E-J6&5?cVtm22uoquELo3x*yXX zFLnJ$+%l*cCK?VaWBLjAF??ai0uGB8#U=t!n1z|}Q@R)DJE|qS9yw`WwSRa-3cmJ+ zz`JI>-pn0n8BWVgbU)F9DTg07b#cKSV4p`4F8p_RmCD2zXa%Ryx9)02>8MZ9c6zc4 z1^sI8&vUd5#_JqGaN1TNUGUX;C}e+i+0Gbs1>HrLCA?V`-dWW<@4KZ?#|R%maHsmF zE1Y}RDL?$jBQk`~`pqRQhY#AI21;h@T>Nv62swawXLVBjV(a$!Hv5>yk;m@f;3*lp zl4eg}9q4_t7$XVF6u#h;{@;*oACDoIQMh}8*Egd<9g=Wbi=|}S=aaBf2URtYQnZ<+ zhMwe#Gwyh@*@u+*%U=tp&j4xHUxen65EfXT$;OJ_v+EJ0;EylNV4#yRxVwSs2WyE7>FSxM-wtgQyE_C9?(R-+?tQOccmMTIkKThMj3kGB z&f2xAR#nZK6T5cWpv|Uq)n>pnBfhrapK9?08aV6A#};StUs&Kh7|I{&{+ui&bsYt8 zi-ADhuMj@9_m&M{j+ zxPLsV-LzefBo}g|05kgf9)ppVA!z1-&~lDjkKJg*t%jic)sXOG@PB4{n%5Wsqs63e zSPKYZQ=Gd({$YgOsYsz3#ZKr;cBio~iSozuVal1*DzGTGef{7qC^y5=AnbXhO06w) zDUSKCEBSk9-z7>NZV3v0FJqSWKEuld=?!I|(jG?h+ z(GSFqLOkAJspDZl&|^rBY7*J00X5>#7=Mg0!fI&gSP$3TSWd#ReLQZk1+!&ktD80) zboSoaI%uM)R^n*n7 ze3=wM@g6D|e%J6cv~5#f9hsF-Gs+<$eqoz}vh<)llR%$7X$w_yMtSpkXmIH!;a&vg zg9LxzJR?vR7t+**dhY@P7j%CoFlpOJxy9tDkyu35$VS}k&sQ-#w$_tPQ*3H>`sv!w zEfW}n_i01aNQJsqrObYB?YZw|k7nq2{HGA7yVK?#-1$8)++C#tYUy**7_!ALWVp5# zft>xoH8?Iz@vdL;)U$bFhNa5jr*+cM%_aRLdD8HLLrF`SR;Vz;E<7888k)bf6#nO^l{x%YgJ_z+ z)shB(XB_VuyYdkrLXmCf6-2@FjJf_RMX4MHUgc}hdWtMeiS~P*bb=75FV%zts3E1s z$Q^x_)qyBI#`PfuPwtXYV8NKN&1&;Ey3OUQ@)t3-`~EG~D&nwgDDZfl{nmdI0nTmj z*8&R+Fn!f68d9A9CaSQ}J5OPCgb(uy<+>u7Z9~=NtLJ03z--z^ec(y+;JKF)d5q}& z757=XbmCj!vMxAO@z1ar9ESim-7iMv0!G$SM^^2l^)`OC=Lb#TV7@SBLrmc09fWaL z--W9AI-Ov_z6jbpVyK$?ty%+HZjG1pFEYovM;Y9xyWaYCz@loo4O2%@wr-FP4Mh+~ zHdbkIjEj8*ruyQq&9|ihrRg&zUJR*zS0zqS&?+3HDL zkq}qEg+c=#p%6DyL#Q_|qwOVuGYYEv0dqOf2Yglir_?jwIWTbxK$^Mu7g6W!si5;) z8?o8uxU1?WIdBUF>dm-ItyZdO9X}Dn{O2qpm~YFKF)ohd8@%6d3+Gti1|R_-zydK< zx8#k{HKneITxE)>QvJ7S)plboivIp*U4?}=21G-F-!~H&HNgYSk!g$QrF3&kPHh;i z7D->}^u$NUT0da?yDibsbPN~QlY=R><6mqC#IfW*8>iG)23k)Zf?-7U{i$|-cZdJE z93u2Hh|m-kul*hao)dut!hep$kn;39r*vzYW#omD6DOlmX_oxF~?pt zXt6tHp3+ov2uG9Ef`p8YU;D>!sH}?5Wv2+f023GNz#4Hs4poQvUrT*f5nZXkb?nx=js)xjQi(D z)&AEw9sB@JrXC>_UjIy9_hvt8Fn~yc$@B5rcxIrt_g-h5|Mem&d!at2(WsVp0tyE`@}=ir9S<>K zkO_i)eSNFwYRk(J0b-sHE0^6HBMcqF($a{`%*>3YliA`pLGN#kOG82eZg)H*EQVC< zogZp{rJ?ePTL4v1Q`OSaa&iVBIjWsI0LTIn!Q{*4sx*J^uVqx0z8lo69okjh$TC~hgNTar}M%A@j**Z#7+OCl(QTH*m+YCVz1$ky%=&X&?+Qj z2M#0vZU3{}!;~kq$AoJHsl+OIK9LM9=(S zoq&e=N*&LG4FMkyvQ#2ZRGRgp0B7hj{aNdkbNTl+vhtDmjw<5{?U2{c_0LBi#4Ic> z4mbN^=waTszDV#h9vg7iw-?YG;Rd=ZXND{#Cj9johSdu+F zK3ST$wgHrXpUBDkZM+hI@9uRXB?|;6GI`thS{x40E!nkd&1{+v z$Uk@mcJl&^mjJ;qK=vz}-g$jc0izADzjm!UyQ2g=_Yl9L0+d@qmEYTZ?-Kws1lZL< zo;U+h#CK1t6JED0e>Z1*ZUIy8)qTCh>6n>7KMLOFdpc%$XO1(!eek?n4MHOoh0-DN zHUjryvzY(WLff$F^pVK@n5kprb0{l}D%VmSy0SvaV}q+JVySRqM>gOpMdrD|sc9h} z%q%U_b}c4ar#*nBEiNzboh?yH^K5rI(R{ui7=!FZ;k(ZU?Eq|bZ{Nx%Zn}(XA2MDa z_Ob?YMZ!`&UjcQ%O+Xv*;*pk@m(Y35)g-Lr7x1t|ou2RQj#nBc&YXckWx&+nIotT( z3Fklu80hGN)NLZAp|h**mU4^)4#PiIh z%gD%h6-9)GUbY-3Cnp#ZfwyC&q!`1W?x(Eja*=rz=j55AWLE z(9rNj_G~3v&>rM@_kh%VPlMo76~7b2|Exbb^6AhLvD^V2Muj9u;2)l`(08B;CKfcZ zi}1$$HFumG={Tuh@zt#81)b~B9Sqj|jV8dEbSR<7bz?GeQ|scL zg8M%|b~8F`>S1|R{H|WQAb0@qW$>Tgg<(DdPVPH+20p+X+=-1#FueiIF%cTKa>X}p zvplj{F`r6VoQBt5K1plpzqNioOkn7m3?85=| z!E&Atb=wD#}7e^Xi^>WpkNeh#vmuW ze~y4Z)82X2=&y{#<-T)KamUpu>=L6sby{z$SI`8luGAjxPk8RJ&DnRAQ7rSUtoOY(f(humJ7cqn%)~Ih z?hVF*_D+ljQ<;(B;u7_ecnJhh08oFWp1mj@PZTYvtA1~SvdW7%a7T&Lj z9d5E7aG4NFR(OaPyge!^P}qt9k(Vh)F+@o_OAP;Z1b*gjL_n z4W@=1OYb^|Ctnogq9$R~3ce#NlpiMGK-lcxOeZo}^ZMbjo8MsLCk86kOkPnajT<8Kwj1|SOi?%89r*Ie;JuMt~b(DMCa3s^!OZZ9xV+T z%$07nsyjEREV$xlmggrJKi1|ai>;7VCzYd@<|^~nMj%9ClHfz?3J z)_|W5f!n9&_VYaEF{CtMGeA~XF{BVghXAjy(h)w)@iT_{I@%L2;vVj*+Ktrd^Y0V#BvyT3Jc)%~=M|t(qj3lFy|0Y2DlIgDyd6hK$ElBOugNKX5M_iw zb3(fVbwVcC0}>{8(7bzSnbe07?qI^rml`Y^Q!%=o5%z73kq7`J4s_u0eg$g}RtEbFR2OK~KHN#OJ(Yi{e@tzPmNR-rNuh$-?9r zi%>Dn=mMSeqOftqgcs`HiJPBpPk!#1h9SbH%FY||$1;+722uc)F9|MjprQVJCK(Po z=PSi2^~4YHgmoW-DM!zmN`p1lp12g<&T$%mTx4Ow>W5d;#WL(x#bpaqNWSOzfwj=c zuNAL@=LQzU1qDfy@rgz%>giM}+<^%UjD1BdnY#fDg^!b(RsgHX^NIa4y|t}+(voTz zPDf}0&6|IhAFRLUQd4Dn=+n$}cl+P^dlT2Mms#FK95;uhW{l9Lt<=F^lJqN=!ufyf zX6wn2*^`ISJ(6_kjtG*Fz|)Am1TAWVn@Z1QV?V3-00S)4gf_1x?EYH$XAC{2Y{*#+B^gTd>ID`OG%|A9w_nu|&>uq;+C2GUe_-_%Q~OtUhN7&B z&=cO{X=jLh zgB+deqfw736weo&OPIT%A)wPXn}({qA-Vq!uA_;CT6%q~Fsmqfcek#o{i$M0)_u8>Y6 z(h7@`2R^JYDc_vWvw!>jVdhtLB|g|VB%z#md?w3GpF=F(s>7HR%38Vj)mlHBVm;x^ zJNKNkJ(-qh76%^o(c;d5{wsAhi%4}1&EQy9Ieq)s&hMgZ?E-anzx-UT!E2Nt!+vd2vb3or)?lA4R9IhOm zu=+Uco!|$0;sy~qE;94u7)9%vwELapq3>Jh_Rn}Pl4dp}$-kXyZfki%wJkh&@<%2y zSs=LntC$T19{`aj8sRHj)C17(DyXXm10=6N>=i1SdFL7h4DeT zw=}I6`&Ydvshv(@L!(u@_$T)D7R$cUrKXDY5L;LS*lT+>WpzeqxKu=qPqh%x{TJfN zf6&?JzQbzTKJsFQ31D?5)Jh~hBZk_gWHJP>6ZV ziY#W+XPb}H1{bz-qH52#q`$gEh(Tj+w|3xvbts{{YYqmwL%Wj&T_}<}RfL_gG(dB; z?-{e?#)NgVjzK@d3|{_%=yrAlaz-h-VKNvq2NsMhcazv2`uu&KZaG0*5$_JH(9E*N zJs2`#?#$57leRFT4RVqzncQt4-fLio46BV>R)J~ed#^4S85!MAMR{$H!#>_`MHvG5 z7bOFOn3WZsxrK#3d)mb?P31bkdfWx%mxvj%LGMB_SXkgJ2BLwSsXmNbXkQu@V_PV4 zbDt4A4OSzz?kb(3KU=*KC_>BV**{Om+!~V^|Y*r(1&Z?9)?t(yzkr1 zd&K%Mt~-6WH$VMp<}te`#xvt&yaVXz zV2%~+aI0*~ISBI8QSBNHeI_Q&{u!~zBFbvdRTjskcd%p%;p%)(Zvo9{!ODdo*P*Fk zIZp!39{XeLtd!CQs{pDUrBUhm^^_|1V6za1j1qya`&Yh+L5|N|jdK{SW;HoZ9fbP} zIBjk8;$9Ut4n1Z-`rhh#6`h%h{Ev8D`|G2HP`M=Wu{jxtB#4f&+kr*!C zGgPBAttiIMG}}_epev%=iOJ2FXmtGM-7-}B>WhRuUKEfdI2ADSOJQ?RP5>{|gj9bs zu~l(J+&paIiqVJQ6`|;T26;mAjYTLk4d^HUVJRMcYA8xC5LJ4F7B&@`__UMAnXl*9 z12UwjFbDGc>|B=5=Qqb>B-D?+!p-u+UGEE;7sVF}6w4rix(W)geX8}kAOH=pKU_8* z9z63EI$@WW_F$cWD`&Dv1%aw4x-RQlQ7dcZBQVPx)COad1f;+` zs9)bj{6Nl^cJsc-6? z6EIFo%(dbE4&d8djN9yK;3eLAa=5ZaBil8+KrGw*rj!BwbqglPxtmkX)ltqB1z}!a zkP7g={vt?SZBZ{Du)-v(PU7D_I}qHqsmEmcN_aouwQ7o6e8}q^&L5i_s;LX1`?nLNnGGd#_i)z0ac2Q=N$%@y$okAtBi_aLRTVQ zVqg-m0fe%w-Gt9|z!e9;Qdv%kCf45S0gTj)($MpqM*1DKrd9=wL)&|q)85|x{9=H3 z3#a2Add>Zew|8J5sFff>)DJNHzdt8<-;-H+Ma60G0;Cw+<0>`JK!(=wfy`hI%Zqf< z>0(G7#g$CC;O;(sP>9G3g?>#n*!QKza%jd#HN$BL{+>V%&rtq0gI_wy{zXK1e@}-E zjGpCU;xeGz&8S|lC7v#kZw_W)-)mKmK=o!^vCi+Gt}FP}9mMKXiw&#bQI6aKB)^{` zI+|m2u`sS`+9abHv%{fiGCzIb{Ayb7uR?qb6kVCA(ogC7bI8?caXBq(^kV1AKKExlMS{|aRJ zV)bTNrzd4l%>dCJF<%h>UpAtJwc=d|I(f=iZqK#bau!TK*tf=+J*x>Wp^KTtdZeZ4 z`G;k0n?)*Ep(`oK*#f*tUQZV3u!!VT>PWWZsyyQr^77QU0Orv^*Cp|Vy;5Omc}R`0 z%WCEeXM^@Q(OC_zAdUXtKK);iL0AT5jDT;-n(uE?pOOCxKbZWalaIqeZq`4m`j9Hw-QH8?&Ra-L&D1Cy?e_3NG;wI zhjjO3OUDeq935ShJ+}vw>8A9kO}eLZ%W1YuOC1kyA3HSTo$q}JO5VN_ zr-9u7FyW;4=%}HGURqGoex-8A;Y6Q>gXB;f0KTio!A5xgLj|GHFbSh zr9Ww&GiUyCZH^`q)jzu@t3L)>>w``ET+bdUV86V|n533_nIVao%GQn~)DnyW5~Qb| z(76GHR{iyHDY!n*5p>!ir{&-Q|E-Du0HSJ`JXc5-v4gu3Yk7@;W+Dz*Zfv;A+z%f; zIv+a^2)7pZrIP6K5y2E4zrPVp$+Xaa^F%jG`f9W5lRj^KPe`sTLqT_VsOshxQ#0+| z=mY~3ywdMnZe9BqXXr~f?}4Pe+WW9eAS4;s@2x-`E{@9zn`qqT5+97uh86acttx4( ztF4r{v0mj&e-cX>?2wi=4SxdG6}}h{r~qONp!N{qpgdqn%-kFLf-?jp?>zhXez}UUr-qDm~+aRVM^Pz$sbG8L3R@)+(w; zmQl6eC*xhpIEllkeev8i%!{kA!V**Ejd0Ey-T^0AAF1#8V3jTVxsIq7xYCfjY8<}8 zKmRT@fKIIVOH==BBb>3*kZkl99surTVCNSA#7bVbwWvW|Tv3KkDBxi4$VVQAIV|nI z2fw3i956j%CoiYvpWnY8p3h%8RvCUE|Lb0~_kA%krxQ5*29X&;fVp>BxRjl05)+mE zlLN)QidA9rgbmfWH~c$HCZdX`N0|cc7?k;@r7zt$z@q(8gaGJwDikU8TU3`%`fis4 zAk7d7^|CfXNoR{({8nA7ATG!3vVe10jKspd9^|f~7#j5M< z94<*Gd3lNOw{tJ$wVJCWx6T;4V+(pF_X5le%K8Cp&hNfTa)!Q(aI3}46cXgEDrA*2 zZ-^E*2&jUxf^G{b79A8&kCqnBxhqvGWE{;v%Vu|qrb!&a*d zIX)Z8wXf*Q(R7M7z<&Wc0)(I*GJGMV%3NcAWOrwq{?>A4CT~@s`V|)aIx`TB&rmsk z4E~u7$3_)ppird)J4gdFdwjgdU<-q9CQuZQgQylUq?nSB{3A^H%aIE5Gu&l;8k2OY zTn55bDo%8xNu)D_Xm#$L-z-oTctaqbV>h_WHbxLKU*l4y2y1ga2Fn(xr-JP-F=x`C zkMRb2em=5ALVy|-paz9;u<4)Q-cA&ROxSJJu!>z+LxaY~O6XlK;qP>2t-d=Hlrr~e zWqT!zZ1g$(Z28vQPOW%<**}x$IaMjbM1OPy1kq3BiH_+F6fsoGCw~YGo5O@`wRK(6 zVya4n(nE~zCmN9zW-C+N5wl>B4}D3IAm9FV_H?s(<4d!r{nL0*d%cpAv77Wg(`e*X&eOBdibEICrK#HldC$d2d~%= z#R2^_&Q~1EUHuqtXEnxt{iol4E9I3}Zm!my=;!3LOK*!mu%+@JAh>N>g+veRzAxR; zI|3AV9~-Uyiv?(&cYuU14;IJ4{q~$rLA99T%UkP14BF8_AMH4nSob@|vW`?~DK>QI z8S7y*N3W0R(C_j0q0QU3iQ!?%l=;K2v@f|%5#j&*r=Op7tl+qdd}MZ;9Brnx3(3MU z?c?%Be+*M#j{7iY)zsmL<(j0Op63i=4G#H+<>U5Rj8kZ^!^brwqN4t{;1Z3oW=FdC zhFBGYf}PEF#|5h#q5*DGC5Q0GT=5QTgqu;B5$L18%f+V4>V6?E7T9F-<+~Z{fy{Z; zDvhSM>{?v((_?Kfw<|n=DhwJ5Jf8H0bPE1Ne93Q*EFaqnDwv;fXI7JEI#PZbFyXtx zmaZX-m&?{IY-Lau>j6d{2n!qsbMO5-u-(xV48a4I_#%*u`9VvxYG7Hfq*P1n_0a-K z%j!5Fth3ba>AnE_Bf@S`@|Kb5g{_pDofV4s1u{8`%scDLTWqcs+*gGh6d}dLsys{o z%5*rXTQ_!EJej#aIB8kV`#sy-MT`zkpZ=w=IA|_Lw&=b;gOYy5Jy> z{Nu}vOa#A()6bb1kk+7>jJ+T~6R+AizbeM5&iZ?*um|Q!c^-3#5&TpQSy5-tY|xVa ze4&9hceE)ryaT~esUCHO>L0uc?=lddz>=AbB!v^fEX+rfnZPhHF>Mc~3xc!wJ*JW| zelK29LnLxLUAV2~si#4!Jg2SLbQzznJS)EnLnpoQU~MmWFe@r0V{)gq{2VSRxk4$wzlHIw zzxxQEW}|{`%9n@%Q#3OKU={4RGSDp3#DAFf0|pwJn0p0I#@NrWe)9+oKJciA&!2?8 z@OL-GU!c|+Ntl99(k*R3(?V1VuMK$9R@-FDrgR~bda0ehv4*s!^Xr9pFjL|6SQ|Ca zg8oXO2|epFsAjoym#Qite1n zcKsWX>oyut8u^b2pBhxS|QbRA`l=1yNw$eyg=G9HaYu<*w%>Eaz~u|NOh z`}&4+76pT{-X9ErwD8khI6%T8Z=b!ro;AI_KD9Jc zk?=;2>_F%NCBH6&SuTw_PTShM_UpId2pI$gB@Nk&%{t|Ib~)m=$Au2$PM|fO6kMkz zynNR2dereQbcsW+{h^~~N;=oE)MkDGy3{#IAwC1D(GJ_%&^y|~C)i)?7uG*_j`{wD zo<0%~8Z4AfnVyqDi}~;scsUrLoAu#R38fB}5Oeo6KHeXD@jJ$5FhHdmzH64y*~x!aXlrL0mx5%QGR=@d>fvT;~xVQy|5Hr%i2fo~$C-|9*%B8FQy?GFivV5nBuwWmV1n-1#`YaOHllQ~bT zlWjSpl$vcx3J|m?lUXwxD|Jw`fz|g!fcCm)%5v$PT^8xmk#&=%E>NfBZ1gL4F{BCL z-;0a#1pjM;7=F%dNV4h&LG#b{Aep8M$7c&&TvWGi+z5PsCk^O;kW=Ty)_@m+5a;U!=)Q3(6CRv)36s|e2eRVhxbx}9Rodbj=d0S6XH7&Na@#7mbvK7U`+!NIFNs7kdD^326!IbM~T8wLie(;JZK3wT(JUY<*+{V6n01F%&=L{Wt=UfP{A9_$1HTfm|}=} zTAUmZhx#b?6=;OqW#!WegrsH3>U37IW9aPx%m|V9vt6dkW=PpnHxb8^S`h{YmWXnZ z4!?N`mF{T%EM5AE0uIFi6`-w%(g|n+&WjFd%3?nGQWq{^TIoavY{eV%4F28Rnyr&R z0z88ys6B)GthIK4o@_AzSQ72yL(yP>#on}DuWskU&6D>A$(wqxcJ(8w@&!{rD)&58 ztJuww4^8jQ#gB~gqW0G>Wb^uKhU7G4-rV9{9PQnmA6EwFDt{_?jv|GBaWb{|yh^|A z&KD&~U)Yba4N|N8JUbU3$8w-hpWa5$YBfzqRrRlRkYt>0_JsjzvY`O{M7vMzM*c`! zY`A-x=1I1v$&J!tie#_rNz2|O5pq_Hp(1K11YGDb>$ ziTxNFnLD0evVZlxJl#P?1B#1od57l3v>@^ERVHB(5i~3;5$Q*2FI|lp1F$0Z$N1FE z1K~c}!W#C!XrrG5RFHxtmW%E&Ekg4(=AU9EuK)#KZpEOmDmxUIhXDKSpD=V$%qO$n@u6@Xns0YG^1 ziHY?(jSE*chrAKFhf=c(EyY!AAT7as3YX`L0dN;UqShCun7cddXt+&4I4ncuCpsgu z&;3_9MLj0)0jlq6<64dp#E%R*&Ar13G~mfxj^-ceE{xPbCi;qpazoDF;k25iPNdU* zY_zL9xvSe2WMC>M$g%>0fb5owlS5Ma4@r=acZCa_i_7W~CjyzEul}uj#Qm1%@>)&F z$**yP&XB!vT-J>?6Cqaw<+kgm>&$v;8TzdC@HjVE>>wgm^RPd%Z)_yf>=RFx?)HSE z_4Ywi&P&C=Hy5Z<;+@P7b$_`2ZPAEPLCpzT8)>9jh&BS@#nd{|LH6ILY$Gmr#;y38 zRD}dPm}H_14+V#ikhl3`Ao+<99hy^9jZ54bP4(M4kCP)eF~H7V8x@n=Y)`I`wg33# zuHm@f6F54jLvgD(Z5vsgUs;-6SaFb0lbAZZ=@Y*C!(Q@s%lgPyQ>~{$<#i_{H@F#a z&qPT(G^>jWTg*pZJ`NZ zhAycH9Nr{2MQ&7$C$K+CIl*Ujz5H?7dL;`F4{yuqYbk3(AUBUp5$Q`oseOa7`Qpi8 z2=P;uS60&rZ;pFc_v>k`+l@Ig0jJNZHHsBpRkPpo)v@$thT#zXvdj&I?tLQuqpw`4 zZo#J$< zZO;7sa`^MMQ|BHop`_Lr5+Y~kBA%Wc-lpXR#tY_N=vl%QED$l-&G=5g-Qw>hIu1or zB>bv=@N_PXLezUsI(!ol&VRaWbgsVMkpAAZ=SrQGGGv+uelG89fbo+qZgB7pg{R4G zw4Q!?SYiG583^*Q=pq)~#j2VDu()!46RuzQulzkyUAg=ZeQl z=&J@1hx)S}j(MhqhNVWcZCesDarIEPREw;p5HG0;2`l z*RLr+KE}@QgY~D}yb^6NF{%y7fct(D7fuouHl?m8puSZgR-SLMwi9m zX`Q-+?OrGtRw2A##7m;EA`C3HjLlRzExt8DdA55+J$%%J({dD{@*}%B;x7zLv)_Va z?#mZE1?CLnX_I}1ys3g^zf7n^l?@I@BS&In@Ok0`hf4r4$8DPkY}%hGG12qqt*7*3 z+Z91quB7oBQF@*M(PtBDWcYr!Snxe5OU`)CJItqHFQ0D}y*I-@ns~v)8JK9p-Lift zASNZ8vkDRr$xk~^@486C*=PA#V^be`r+?PGh)B?A_al6xx%dEc!Q-#n7ZA>0Q*|y{ z>Xh`&VNsMIB$TNHVklY`_QdNs_f|+HM+(Y2e(nDJS~qXX6gR*kCBCqi;2tA8@pIFO zdv7i}Z8i-Z?aLdo-!ajt#wuh%EDukP*(#u7l#|V-eA8lBa zzsTe|SXEb67F_gR*5W{~#EaDL@xr{#x}A^cwFumLjUnxMoLO@tELkC)J1Mdi<(dG+ z0^t&zhs`pjBUo{o^6%ayIoPaspasZny41U`r=!CBZ;oyI_`zBH`eSaU+k#uUkVl$Z zGbrC}7X7w~@5*Q+F~*9CO_RJ!=?YL&z!X|`(`|A)?69q_JSQssiF09La{eh~Z`+z3 z^Nl0X*VAKjMfn;b$xj4Z?Zc5)n7BA1kVCeLIZm;jGeE2A_ed8n1j~KZxZn=`m{3;q z8m1J#v}ud;78x3sf1xQ)=QOW7Xs#ca0zShKfxqlOzvw z8osP`q4?3Q-Bv{*d6(pF!^BqfhpX0sM7b&rfM>I~cOQBB{by{$Haa~W@f#pkYg((q zQ&j9$0v}7HmuMt@Evf1b9#G~mqa11&dxX!NJe#OfDIfEIX)r=Fn!|w@UJb9c{rF@78=I^)x3AHc zkhJLW@TZxywW@r`y}09>;}Qw&ac_HLtKBDVf3I+dbl}uFO?}omArA60``{~b$xAHX zDP-|!9_n}n;vA1yb(?vM{*BpifJ%omOZRLIa200xkHqw=1+=Xe zd=nhQpWw+;nP#$#oo|RFu|1-47NBXibe-=R13F5sjflKPbG*HPO-%qDQ8*Q)|H$7a z>o{hk!RUo6Ah&?7>tufw9ws2orJ8X3*LQvoJ!>;Bi*L%{L82sGGj6>zc<=Q+%kM@qunX3p_J>_6_lnf z2Nas`&d_JlA=eN+fk;~!&TAXz8$CM9k&~5Zo=hwC@@LfgUB9!|X&H)IThl=}d=kcX z6tuPT4%y2bK32m(dD2H(&(93vDv9>PWjMt`Xm~i{dpZb&v2OqZ7SK)BpX&gy&j5Dc z^h0U6RzoBl2D!g#)40eD6G!2S7-M4}vH@|sIX>>>#C>wZcXgqPt6d)f@wacpoF`?A z)5W@X^y7ye7Cd078BpLISAhzkonOXx8lZM$iS~%P9>QQmwc__PUZ?}rndh6a0O^3vy>VfF(We-H25sJ3MB)D+Rsugy7sfy8&VMKv0iaCx$Iz%gA%R$Q}v zf7tyKe(j9}JEjceK$&s|VryjmTvUvBV|&@hPb8};-kqkHU;RA&MB0&eaWKMC2wE^h zsa^Zn@gcJml>#_oJBpzePTf5?a8MkB>Z@oMeo;LZgD2z3skTul;G>NN{WFB0&^hJ+NMIMK-$@C+&$28m5|Na9a= zp>qA(?)-Gj85wXL+e5^luEUL$!5ZRz#j1#}zh?H4$Ty4bPh0hQXWWV%tv}V? zcU1pKs@@2}9POX5I|B`FQKev7e;t+EqQhN-->Y@QF>%BXcye;FDM#8NP$tk8H`x57 z8)Qf&Mf2JlEBy8?qoe2Ir%h1aF9y`O3u-YPe$utS4NEQ26>7TPjK^HBcwaW=t!&yl zn>RRr?t;22wz34!tygd75z0SCCiRR~T~2(0Yxpj9cw4SPV@+_&N&r^q?E2Qd*ZcA1 zjta%mM9w~3h?Cqi;5qxI$dwyYUyLCfF#_p1{g6}Zg{ZNCxy0KV!BO@ir|3ZnZ&Xzk zGk&XTFK!CeDvI>?I&sR~WLxi(A1g_lc!$@^{Vqqx5CHyZslwXOCVhnA34&gl$gO>V zsalPcxJFr)$4KW23KAGjZtVw(WKj_xIqX-g8ZH(MqW~fAVL*JlYUL#SBS)my%Omt} z=htV~bXf`-wTkV|Uywe|g_45;2{7dS{r!4~b&Y#Mk*8dU5+fSSApQ?#KvosovSAq6 zOK-Km@Gt=~J)bn)g&n#`zRcPSesf-9^bJ9g?rpnfL#D5Gfu*o`6Ye9&kr?S1p%m); z_CulS*I-<)ajWFq5S~A?LJ?`Vjo7*mB@$%r!+4xpg^axnr`t8<+ZF#?4}iG?vVE=Q z=C8c*Z|!d#jh>xJA3+QeOudmvKe5n1Y`t1;_b5@=Vf2im5jLqkfrP5AuJzA@6_Rb` zJ?oK2>2y-kZVkVnUq6$P{60s*jUeokH!MyHE7a&nvLk#U9VbT#!WA#|M-;MpmQbJ)=hcm@s!~19z7!M|qwnCd|Kuow zXN-S_aYpq>SXjKa-HAOJBeJAI%GQ!H{#H+v=Jfm;S=a!3CXDPnCif270tZZMs)*4A zsv)h^rQ|R^5fUTjbnM60l3G?@Kg$okhoIoopSF&OpZF|T=2}K5hh;Abxn)au6a4We zSW|K+(TT$P01;}otKG4q!@_G@;-C9jwc=y^fn-k_!^6XrG%G^_3mQ%)1I~_H!h@ru z`K6_yR7!v1)fUs%X)sjRD`vl^KV z?~`UYS21}9V``Kb*6=np|A2@a6lp&FX2HeXaZvtD0~yoMz=`^h>HMiiNhFsLAGJ;O zWVNMXYeX+Zyl5&M3(YKLkDw^BaXEQ+6%d*8F$R#YYfr;x8n^$Q?TRv)!}B@Oed6l4+R~ zaZPIqQr9p1n%?nhifUE2Id3OgUOnD);U>GMYAcI-*}r$btZaVVXC$kB>b;yVx`d60 z6E>9nV*q@OT*<3ly}8`%fS4ydfonT zoCL@KVtW|C3k(3i77QMWvb<7Dl!^lDvm_a(KqRilJP%?XEX-O*^mA=;V-)10y4E16 zx`K=2XB)PZgi0uAv|luLFNEn&_mvSQu8+R$`X(oVfE&N}EmBc4UUA&#ADL$N-?6bj$9>qSyt zi_>1Q2F88bAI5B$9rh<>-6Nta(b|7u+`W45WxqY?yeFz}ojnghf*x!fkunS$4!STv zl4ZGdU^Iczt=gn!OtiOm;V|R{s)IOhT5;6$Kp~8Bb5%FdPPJZ+U1RQ-iZdcJcx9%lbCr){gBr!nVqEIqTNfVdo*7 za5LrW9wh?1pr${`y6eZ!EbmKyMjVWoJO;{cgN$hxZal|df;)+}kO6M-UOatdd7pcc zV|@Q!^LBqKPhf5c>57*;^BIPqtinY_Fm6ajBChQ5i54~3_eGJV` z6YjpzvF*q)aU0T@h8IZ{?~x0fth$FU)v5tgg}37$pMOEVb;VP?fw^!T9sM5nzD6ta zxvU54Y!edP13pvo$|)Y~tu7PQu9|@CwpKfZtuB`sOtlb- zl2bP7QL)5mecuKpayhY>W<6FIOZ-^>lR;*tNEZM^tvw~_uoGfh8g@C41n(*vW-HU} z@Jb%rMTU{noC*3YVMhBW-cas^$}iM@FxmQo&d~$!E{FfTds)|j0a|NGNv2(@%+*bX zmS#_`^T#<1e$v?YP`?n&2jiKbq}z2l+d;i)x~9%QfmfXgzr>%WwdZ?(U(@AiOUXP) zg1-HTvH4U}fLE?!>GldrX?-S=4%9RsM$ky~{_w#@qaw0FsKPM_h1eKqSOQ~+9ZM76 zJudpP9ci(pY7PIfB(J}Xc7L5#ti~eGR$G#Kf>1cPU)TLmU{hM{ z!Wnhn+rE{g)}Y`B6MPS!KJMM#e#od6f09f|Q-1$0JI$Ww?w$8tLoC`8vitCBXMa37 zgIQ}vP-gPjxI~BfHBqaVbQe60am0nTBYe3yi~AiBDU})hIuhp>GO{{_ygf5~<)P8h z<4tVG$U=dHI*Wz+#u$D1c0C{Nc(XOSL!nVCP*=BLBHxSWW~$|2=7vvx?kVG-cM3{9 zRdD+8H~a4anVI$oIuX|&_v{($|LGC; zrjc-3tu&|&H-eP@SW-R6a(uQDw84#Zl);N+l8duuxG}1vh&lO~eR%IFmjCqi=PsgQ ze>iw{eLcHr3IH{A^3sDA3SI~X?`8Nq*nUJrVU%;`ZZ4UpcOut#cjRsC)y)9OKF!YJ zDMN4bWjuGbEy;7PPCW>b!sy{DK0-sPunm(#;z!bNeTlzm(jzEjRS>uXadkaIjdUWk zBZC76Ha(B7Jn`tnRh2n|DnF$4#`$;bY3;Bd@Q^QAQn4BJHI%zA<2R5%1>8ib6S)}& z+w4-5jQUiA2F*>LDf4U64j6#2m21CK3oOYKGxfup9*b20Cr1eGn|iSs%o0MJEzHLN zB*aqoRRk@_+-X_R>up0wL))Wy^H`kDQ3(4qte(4PVXlvHm~9uxcm)Hl zMxd72f?ihFF1}=Roa%@5#lSl-pm9CoN@7SIVoZm-jD@KlBbo}M;%3+>Adp~tZ!CX* zd&Ag3Q)AHSGT@M@eoY-`&(c)(XK2rg>PMf$PwtvHl98(}Vi)Gx^hIB*(GX&=FaJB$ z57bU^wfgzlf-em{l=SYxzS1IVEm_h|Eg0_SPn6Cfi-Dafd%Oikk&vuLby?=+uFY@n zgKgHne)Ck#i^UxSTE^(rJ9Q5A?a5YJ|Hm@Qc5Uc)2UhtLr)MlaI^C$}SlGiwfuW0M zR&VkuNS(SR#QVvt4{tV~FM4ys5V$7uHmBp%Y5TS>j8SH2?)=E@RiK;k%XVu(;Qx%r zpL_k5ADQasx%kz`h|OLb%zn-5&#RH;F0188F`1lkT6yEuwyqf8d-uQJm+Lyb>v`#^ z=QlOK>Ml?A(oV?z_4kj##XA~-rxSLyKb>7Z;X{-C1&#>d1hP`|OW#v%*QZQWIlnEb zXo~T-#$}!vZ{<5ocy>;IYJE!L@%r>gmz(?J`^*>^*i1cL97EdT1;VF#E?yV2VL{gA z16^z`OXoVxTq&4i=HdP8`+NDYp9Se%C27%C>-d*dXh*7sG3B3pEPc0r_Pze-sfUyY~#QDcY*i2K3f;ZwkDC&z?%KJ$`83$%ti~8x2nw0x32u&($Le^cCJOg z;Bw^r(ABbh`+=h~U$y#{$Zzt?F7E2+_!0r^2LoG{N!xFqJbylax086)x0~rFPknN8 zeZT*I-I}m$@$DWiPN@b*jZ?F1f|sQUdUZK`a7dnPHs`INF?N?uabDkN28uuM{;iG-v}t}ihOo4{Mzc=Zwa@L9iDg4 zWshmMQ1)s5y9ec`u}_>)KH=A%fK%I+wwg(`CF@$b)o%WD&}aek>#Y-GC44j_dEfq9 zV|D2v18BtOrGY2E%~jrMX~3g2Cf?ICSg|SZt`%!2aC+Ef$?*#pW@-S>%5!PJl_ z;b~vrae8*#!?nBC#jNqRn*IFA>^&tpR+hnMcUb~=@_H=Kk_vgb_WX0u1koky%r|eO zmM`#ne^C>-+hVtS*VN-~`_AOcr0*(`7kTOPyg+R4kqcipZ`_itFAJJRyC7>_#`EGX zR5x(7=!WbYTLnTa%if&-^Cn%p@!oGa##eeVFP1Fm>QA)L^tV0c7j2oZdRBek>hCTS zIX(xJX9!n5PYa%76eCy;G%xNAaJCG%?0@6UkB-f3h6N7}q#e)B%4(W-Jjcx3x(rxL z11GaDzxe^`DFCOa3}>IM0q$`IYMA)zSJm5<;7KmqX-wMJHMakbSc$ zZ2fC%Ki_=`nmymL=Wd?5z5V`&_iKNDd+HtkYf_UIIJ}ZIHx!BPh83q%UTweEb>pYip|A7*b6$Aq zC@T2UZqXv4byau!_M};~@&3LTy8iaW>paK*D!a#Bt&&})q`o3?bUS3`v-rm{Y zHt*PB@usZ$g4ID5?c0;2^L8j^{M@l)N8A4R^1G!mK&&`F7@Q8QyH@c}%erz?UrO}q zi~F$`T2?Otjul}zw7`oi^73Nhe!lWKZxd>2%GQ*8=<5KpK}H~QpE+hJP8T301xy+(mqiDJ|PNm zff8_19|<@up{nICeyz)6a0m$r2{(5{vSo?ytc?)YLr5VKT@g4vCoVod{=TR_bnYK) j%q2z2Or>qWe)-R6E4A#IOa8(e3_#%N>gTe~DWM4fLl2@1 diff --git a/cv/classification/acmix/pytorch/run.sh b/cv/classification/acmix/pytorch/run.sh deleted file mode 100644 index 71a65f586..000000000 --- a/cv/classification/acmix/pytorch/run.sh +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2022, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -NGPU=$1 -CONFIG=$2 -DATA_PATH=$3 - -cd Swin-Transformer - -python3 -m torch.distributed.launch --nproc_per_node ${NGPU} \ - --master_port 12345 main.py --cfg configs/${CONFIG} \ - --data-path ${DATA_PATH} --batch-size 128 diff --git a/cv/classification/acnet/pytorch/README.md b/cv/classification/acnet/pytorch/README.md index 12bbcacc9..3a6b90535 100755 --- a/cv/classification/acnet/pytorch/README.md +++ b/cv/classification/acnet/pytorch/README.md @@ -7,8 +7,8 @@ As designing appropriate Convolutional Neural Network (CNN) architecture in the ```bash git clone https://github.com/DingXiaoH/ACNet.git -pip3 install urllib3==1.26.6 cd ACNet +git checkout 748fb0c734b41c48eacaacf7fc5e851e33a63ce8 ``` Sign up and login in [ImageNet official website](https://www.image-net.org/index.php), then choose 'Download' to download the whole ImageNet dataset. Specify `/path/to/imagenet` to your ImageNet path in later training process. @@ -37,6 +37,8 @@ rm -rf acnet/acb.py rm -rf utils/misc.py mv ../acb.py acnet/ mv ../misc.py utils/ +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' acnet/do_acnet.py export PYTHONPATH=$PYTHONPATH:. ``` diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index 1232ebd87..cfa2c15de 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -14,6 +14,9 @@ We propose a simple yet fast and effective partial convolution (**PConv**), as w Clone this repo and install the required packages: ```bash pip install -r requirements.txt +git clone https://github.com/JierunChen/FasterNet.git +cd FasterNet +git checkout e8fba4465ae912359c9f661a72b14e39347e4954 ``` ## Step 2: Preparing datasets diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml deleted file mode 100644 index 8932f6cdc..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.05 -momentum: 0.9 -epochs: 300 -clip_grad: 0.01 -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.002 # for bs=2048 -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 192 -depths: [3, 4, 18, 3] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0.3 -norm_layer: BN -act_layer: RELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: rand-m7-mstd0.5-inc1 # Use AutoAugment policy, Rand Augment -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.7 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml deleted file mode 100644 index 651976879..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.05 -momentum: 0.9 -epochs: 300 -clip_grad: 1 -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.002 # for bs=2048 -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 144 -depths: [3, 4, 18, 3] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0.2 -norm_layer: BN -act_layer: RELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: rand-m7-mstd0.5-inc1 # Use AutoAugment policy, Rand Augment -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.5 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml deleted file mode 100644 index 80b17d2eb..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.03 -momentum: 0.9 -epochs: 300 -clip_grad: null -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.004 # for bs=4096 RELU -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 128 -depths: [1, 2, 13, 2] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0.1 -norm_layer: BN -act_layer: RELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: rand-m7-mstd0.5-inc1 # Use AutoAugment policy, Rand Augment -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.3 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml deleted file mode 100644 index 9a2c2915e..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.005 -momentum: 0.9 -epochs: 300 -clip_grad: null -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.004 # for bs=4096 -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 40 -depths: [1, 2, 8, 2] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0. -norm_layer: BN -act_layer: GELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: null -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.05 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml deleted file mode 100644 index d9af3f8b1..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.01 -momentum: 0.9 -epochs: 300 -clip_grad: null -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.004 # for bs=4096 -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 64 -depths: [1, 2, 8, 2] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0.02 -norm_layer: BN -act_layer: GELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: rand-m3-mstd0.5-inc1 # Use AutoAugment policy, Rand Augment -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.1 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml deleted file mode 100644 index 17d3eb5d9..000000000 --- a/cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml +++ /dev/null @@ -1,72 +0,0 @@ -strategy: ddp -benchmark: True -pretrained: False -sync_batchnorm: False -dataset_name: imagenet -image_size: 224 -#multi_scale: null -multi_scale: !!str 192_280 # image_size 192 before epoch 280 -test_crop_ratio: 0.9 -# -------------------------------------- -# Optimizer parameters -# -------------------------------------- -opt: adamw -weight_decay: 0.02 -momentum: 0.9 -epochs: 300 -clip_grad: null -precision: 16 -# -------------------------------------- -# Learning rate schedule parameters -# -------------------------------------- -sched: cosine -lr: 0.004 # for bs=4096 -warmup_lr: 0.000001 -min_lr: 0.00001 -warmup_epochs: 20 -# -------------------------------------- -# Distillation parameters -# -------------------------------------- -teacher_model: regnety_160 -distillation_type: none # do not use KD by default -#distillation_type: hard # should be better than soft -#distillation_type: soft -distillation_alpha: 0.5 -distillation_tau: 1.0 -# -------------------------------------- -# Model parameters -# -------------------------------------- -model_name: fasternet -mlp_ratio: 2 -embed_dim: 96 -depths: [1, 2, 8, 2] -feature_dim: 1280 -patch_size: 4 -patch_stride: 4 -patch_size2: 2 -patch_stride2: 2 -layer_scale_init_value: 0 # no layer scale -drop_path_rate: 0.05 -norm_layer: BN -act_layer: RELU -n_div: 4 -# -------------------------------------- -# Augmentation parameters -# -------------------------------------- -color_jitter: 0 -aa: rand-m5-mstd0.5-inc1 # Use AutoAugment policy, Rand Augment -train_interpolation: bicubic # Training interpolation (random, bilinear, bicubic default: "bicubic") -smoothing: 0.1 # Label smoothing -# Random Erase params -reprob: 0 -remode: pixel -recount: 1 -# -------------------------------------- -# MixUp/CutMix parameters -# -------------------------------------- -mixup: 0.1 -cutmix: 1.0 -cutmix_minmax: null # cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None) -mixup_prob: 1.0 # Probability of performing mixup or cutmix when either/both is enabled -mixup_switch_prob: 0.5 # Probability of switching to cutmix when both mixup and cutmix enabled -mixup_mode: batch # How to apply mixup/cutmix params. Per "batch", "pair", or "elem" \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/data/__init__.py b/cv/classification/fasternet/pytorch/data/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/cv/classification/fasternet/pytorch/data/custom_imagenet_data.py b/cv/classification/fasternet/pytorch/data/custom_imagenet_data.py deleted file mode 100644 index 5ed8ed9c2..000000000 --- a/cv/classification/fasternet/pytorch/data/custom_imagenet_data.py +++ /dev/null @@ -1,237 +0,0 @@ -# type: ignore[override] -import os -from typing import Any, Callable, Optional - -import torch -from pytorch_lightning import LightningDataModule -from torch.utils.data import DataLoader -from torchvision import datasets -from utils.utils import * - -from pl_bolts.datasets import UnlabeledImagenet -from pl_bolts.transforms.dataset_normalizations import imagenet_normalization -from pl_bolts.utils import _TORCHVISION_AVAILABLE -from pl_bolts.utils.warnings import warn_missing_pkg - -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data import create_transform - -if _TORCHVISION_AVAILABLE: - from torchvision import transforms -else: # pragma: no cover - warn_missing_pkg("torchvision") - - -class custom_ImagenetDataModule(LightningDataModule): - """ - The train set is the imagenet train. - The val/test set are the official imagenet validation set. - - """ - - name = "imagenet" - - def __init__( - self, - data_dir: str, - meta_dir: Optional[str] = None, - image_size: int = 224, - num_workers: int = 0, - batch_size: int = 32, - batch_size_eva: int = 32, - # dist_eval: bool = True, - pin_memory: bool = True, - drop_last: bool = False, - train_transforms_multi_scale = None, - scaling_epoch = None, - *args: Any, - **kwargs: Any, - ) -> None: - """ - Args: - data_dir: path to the imagenet dataset file - meta_dir: path to meta.bin file - image_size: final image size - num_workers: how many data workers - batch_size: batch_size - pin_memory: If true, the data loader will copy Tensors into CUDA pinned memory before - returning them - drop_last: If true drops the last incomplete batch - """ - super().__init__(*args, **kwargs) - - if not _TORCHVISION_AVAILABLE: # pragma: no cover - raise ModuleNotFoundError( - "You want to use ImageNet dataset loaded from `torchvision` which is not installed yet." - ) - - self.image_size = image_size - self.dims = (3, self.image_size, self.image_size) - self.data_dir = data_dir - self.num_workers = num_workers - self.meta_dir = meta_dir - self.batch_size = batch_size - self.batch_size_eva = batch_size_eva - self.pin_memory = pin_memory - self.drop_last = drop_last - self.num_samples = 1281167 - self.num_tasks = get_world_size() - self.global_rank = get_rank() - self.train_transforms_multi_scale = train_transforms_multi_scale - self.scaling_epoch = scaling_epoch - # self.dist_eval = dist_eval - - @property - def num_classes(self) -> int: - return 1000 - - def _verify_splits(self, data_dir: str, split: str) -> None: - dirs = os.listdir(data_dir) - - if split not in dirs: - raise FileNotFoundError( - f"a {split} Imagenet split was not found in {data_dir}," - f" make sure the folder contains a subfolder named {split}" - ) - - def prepare_data(self) -> None: - """This method already assumes you have imagenet2012 downloaded. It validates the data using the meta.bin. - - .. warning:: Please download imagenet on your own first. - To get imagenet: - 1. download yourself from http://www.image-net.org/challenges/LSVRC/2012/downloads - 2. download the devkit (ILSVRC2012_devkit_t12.tar.gz) - """ - self._verify_splits(self.data_dir, "train") - self._verify_splits(self.data_dir, "val") - - def setup(self, stage: Optional[str] = None) -> None: - """Creates train, val, and test dataset.""" - if stage == "fit" or stage is None: - train_transforms = self.train_transform() if self.train_transforms is None else self.train_transforms - val_transforms = self.val_transform() if self.val_transforms is None else self.val_transforms - - self.dataset_train = datasets.ImageFolder(os.path.join(self.data_dir, 'train'), transform=train_transforms) - self.dataset_val = datasets.ImageFolder(os.path.join(self.data_dir, 'val'), transform=val_transforms) - - if self.train_transforms_multi_scale is not None: - self.dataset_train_multi_scale = datasets.ImageFolder(os.path.join(self.data_dir, 'train'), - transform=self.train_transforms_multi_scale) - else: - self.dataset_train_multi_scale = None - - if stage == "test" or stage is None: - val_transforms = self.val_transform() if self.val_transforms is None else self.val_transforms - self.dataset_test = datasets.ImageFolder(os.path.join(self.data_dir, 'val'), transform=val_transforms) - - def train_dataloader(self) -> DataLoader: - if self.dataset_train_multi_scale is not None and \ - self.trainer.current_epoch < self.scaling_epoch: - dataset = self.dataset_train_multi_scale - print("load dataset_train_multi_scale") - else: - dataset = self.dataset_train - print("load dataset_train") - - loader: DataLoader = DataLoader( - dataset, - batch_size=self.batch_size, - shuffle=True, - num_workers=self.num_workers, - drop_last=self.drop_last, - pin_memory=self.pin_memory - ) - return loader - - def val_dataloader(self) -> DataLoader: - loader: DataLoader = DataLoader( - self.dataset_val, - batch_size=self.batch_size_eva, - # persistent_workers=True, - shuffle=False, - num_workers=self.num_workers, - drop_last=False, - pin_memory=self.pin_memory - ) - return loader - - def test_dataloader(self) -> DataLoader: - """Uses the validation split of imagenet2012 for testing.""" - loader: DataLoader = DataLoader( - self.dataset_test, - batch_size=self.batch_size_eva, - # persistent_workers=True, - shuffle=False, - num_workers=self.num_workers, - drop_last=False, - pin_memory=self.pin_memory - ) - return loader - - def train_transform(self) -> Callable: - preprocessing = transforms.Compose( - [ - transforms.RandomResizedCrop(self.image_size), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - imagenet_normalization(), - ] - ) - - return preprocessing - - def val_transform(self) -> Callable: - - preprocessing = transforms.Compose( - [ - transforms.Resize(self.image_size + 32), - transforms.CenterCrop(self.image_size), - transforms.ToTensor(), - imagenet_normalization(), - ] - ) - return preprocessing - - -def build_imagenet_transform(is_train, args, image_size): - resize_im = image_size > 32 - if is_train: - # this should always dispatch to transforms_imagenet_train - transform = create_transform( - input_size=image_size, - is_training=True, - # use_prefetcher=args.use_prefetcher, - color_jitter=args.color_jitter, - auto_augment=args.aa, - interpolation=args.train_interpolation, - re_prob=args.reprob, - re_mode=args.remode, - re_count=args.recount, - ) - if not resize_im: - # replace RandomResizedCropAndInterpolation with - # RandomCrop - transform.transforms[0] = transforms.RandomCrop( - image_size, padding=4) - return transform - - t = [] - if resize_im: - # warping (no cropping) when evaluated at 384 or larger - if image_size >= 384: - t.append( - transforms.Resize((image_size, image_size), - interpolation=transforms.InterpolationMode.BICUBIC), - ) - print(f"Warping {image_size} size input images...") - else: - # size = int((256 / 224) * image_size) - size = int(1.0*image_size/args.test_crop_ratio) - t.append( - transforms.Resize(size, interpolation=transforms.InterpolationMode.BICUBIC), # to maintain same ratio w.r.t. 224 images - ) - t.append(transforms.CenterCrop(image_size)) - - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - return transforms.Compose(t) \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/data/data_api.py b/cv/classification/fasternet/pytorch/data/data_api.py deleted file mode 100644 index 082c5a27c..000000000 --- a/cv/classification/fasternet/pytorch/data/data_api.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import sys -import inspect -currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) -parentdir = os.path.dirname(currentdir) -sys.path.insert(0, parentdir) - -from utils.utils import str2list -from data.custom_imagenet_data import custom_ImagenetDataModule -from data.custom_imagenet_data import build_imagenet_transform - - -__all__ = ['LitDataModule'] - - -def LitDataModule(hparams): - dm =None - CLASS_NAMES = None - drop_last = True - bs = hparams.batch_size - bs_eva = hparams.batch_size_eva - n_gpus = len(str2list(hparams.gpus)) if hparams.gpus is not None else hparams.devices - n_nodes = hparams.num_nodes - batch_size = int(1.0*bs / n_gpus / n_nodes) if hparams.strategy == 'ddp' else bs - batch_size_eva = int(1.0*bs_eva / n_gpus / n_nodes) if hparams.strategy == 'ddp' else bs_eva - - if hparams.dataset_name == "imagenet": - dm = custom_ImagenetDataModule( - image_size=hparams.image_size, - data_dir=hparams.data_dir, - train_transforms=build_imagenet_transform(is_train=True, args=hparams, image_size=hparams.image_size), - train_transforms_multi_scale=None if hparams.multi_scale is None else build_imagenet_transform( - is_train=True, args=hparams, image_size=int(hparams.multi_scale.split('_')[0])), - scaling_epoch=None if hparams.multi_scale is None else int(hparams.multi_scale.split('_')[1]), - val_transforms=build_imagenet_transform(is_train=False, args=hparams, image_size=hparams.image_size), - num_workers=hparams.num_workers, - pin_memory=hparams.pin_memory, - # dist_eval= True if len(str2list(hparams.gpus))>1 else False, - batch_size=batch_size, - batch_size_eva=batch_size_eva, - drop_last=drop_last - ) - else: - print("Invalid dataset name, exiting...") - exit() - - return dm, CLASS_NAMES \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/detection/README.MD b/cv/classification/fasternet/pytorch/detection/README.MD deleted file mode 100644 index fb0355c05..000000000 --- a/cv/classification/fasternet/pytorch/detection/README.MD +++ /dev/null @@ -1,75 +0,0 @@ -# COCO Object detection with FasterNet - -## Dependency Setup - -After setting up dependency for [Image Classification](https://github.com/JierunChen/FasterNet), install the following packages -``` -pip install mmcv-full==1.6.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.11.0/index.html -pip install mmdet==2.25.0 -``` - -## Data preparation - -Prepare COCO according to the guidelines in [MMDetection v2.25.0](https://mmdetection.readthedocs.io/en/v2.25.0/). - -## Results and models on COCO - -| Method | Backbone | Pretrain | Lr schd | Aug | box AP | mask AP | Config | Download | -|------------|----------|-------------|:-------:|:---:|:------:|:-------:|------------------------------------------------------|----------| -| Mask R-CNN | FasterNet-S | ImageNet-1K | 1x | No | 39.9 | 36.9 | [config](configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py) | [log](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_s_fpn_1x_coco_20221111_063428.log) & [model](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_s_fpn_1x_coco_20221111_063419.pth) | -| Mask R-CNN | FasterNet-M | ImageNet-1K | 1x | No | 43.0 | 39.1 | [config](configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py) | [log](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_m_fpn_1x_coco_20221107_124415.log) & [model](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_m_fpn_1x_coco_20221107_124408.pth) | -| Mask R-CNN | FasterNet-L | ImageNet-1K | 1x | No | 44.0 | 39.9 | [config](configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py) | [log](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_l_fpn_1x_coco_20221107_004515.log) & [model](https://github.com/JierunChen/FasterNet/releases/download/v1.0/mask_rcnn_fasternet_l_fpn_1x_coco_20221107_004433.pth) | - -## Evaluation - -To evaluate FasterNet-T0 + Mask R-CNN on COCO val2017 on a single node with 8 GPUs, run -``` -bash ./dist_test.sh configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py \ - ckpts/mask_rcnn_fasternet_s_fpn_1x_coco_20221111_063419.pth 8 --eval bbox segm -``` - -To measure its FLOPs, run -``` -python get_flops.py configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py -``` - -To measure its throughput on a GPU, run -``` -CUDA_VISIBLE_DEVICES=0 python -m torch.distributed.launch --nproc_per_node=1 --master_port=29500 \ -benchmark.py configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py \ -ckpts/mask_rcnn_fasternet_s_fpn_1x_coco_20221111_063419.pth --launcher pytorch --fuse-conv-bn -``` - -**Note**: There are an issue related to throughput measurement in the [paper v1](https://arxiv.org/abs/2303.03667). -Although it do not affect the conclusion that FasterNet achieves higher accuracy-latency efficiency, we clarify that: - -- PConv and FasterNet use `"slicing"` type for faster inference and throughput measurement. -However, it implicitly modifies the shortcut, making a computation inconsistency to using `"split_cat"`. -To fix that, we may - - clone the input via `x = x.clone()` before applying partial convolution, but it introduces additional latency and can defeat the benefits of using `"slicing"` over `"split_cat"`. - - move the shortcut after the PConv operator, which resolves the issue and is likely to maintain the effectiveness. Models modified are under retraining and will be released once finished. - - -## Training - -To train FasterNet-T0 + Mask R-CNN on COCO train2017 on a single node with 8 GPUs for 12 epochs, run -``` -CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 bash ./dist_train.sh \ -configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py 8 \ ---work-dir work_dirs/mask_rcnn_fasternet_s_fpn_1x_coco/$(date +'%Y%m%d_%H%M%S') \ ---cfg-options model.pretrained=../model_ckpt/fasternet_t0-epoch=281-val_acc1=71.9180.pth -``` - -## Acknowledgement -This repository is mainly based on [mmdetection](https://github.com/open-mmlab/mmdetection) library. - -## Citation -If you find this repository helpful, please consider citing: -``` -@article{chen2023run, - title={Run, Don't Walk: Chasing Higher FLOPS for Faster Neural Networks}, - author={Chen, Jierun and Kao, Shiu-hong and He, Hao and Zhuo, Weipeng and Wen, Song and Lee, Chul-Ho and Chan, S-H Gary}, - journal={arXiv preprint arXiv:2303.03667}, - year={2023} -} -``` diff --git a/cv/classification/fasternet/pytorch/detection/backbones/__init__.py b/cv/classification/fasternet/pytorch/detection/backbones/__init__.py deleted file mode 100644 index 2249d1d23..000000000 --- a/cv/classification/fasternet/pytorch/detection/backbones/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .fasternet import * \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/detection/backbones/fasternet.py b/cv/classification/fasternet/pytorch/detection/backbones/fasternet.py deleted file mode 100644 index a8ab981c9..000000000 --- a/cv/classification/fasternet/pytorch/detection/backbones/fasternet.py +++ /dev/null @@ -1,59 +0,0 @@ -from mmdet.models.builder import BACKBONES as det_BACKBONES -import os -import sys -import inspect -currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) -parent_parentdir = os.path.dirname(os.path.dirname(currentdir)) -sys.path.insert(0, parent_parentdir) -from models.fasternet import FasterNet - - -@det_BACKBONES.register_module() -def fasternet_s(**kwargs): - model = FasterNet( - mlp_ratio=2.0, - embed_dim=128, - depths=(1, 2, 13, 2), - drop_path_rate=0.15, - act_layer='RELU', - fork_feat=True, - pconv_fw_type='split_cat', - # pconv_fw_type='slicing', # TODO: move the residual connect after the pconv, retrain the model, and then use slicing for inference - **kwargs - ) - - return model - - -@det_BACKBONES.register_module() -def fasternet_m(**kwargs): - model = FasterNet( - mlp_ratio=2.0, - embed_dim=144, - depths=(3, 4, 18, 3), - drop_path_rate=0.2, - act_layer='RELU', - fork_feat=True, - pconv_fw_type='split_cat', - # pconv_fw_type='slicing', # TODO: move the residual connect after the pconv, retrain the model, and then use slicing for inference - **kwargs - ) - - return model - - -@det_BACKBONES.register_module() -def fasternet_l(**kwargs): - model = FasterNet( - mlp_ratio=2.0, - embed_dim=192, - depths=(3, 4, 18, 3), - drop_path_rate=0.3, - act_layer='RELU', - fork_feat=True, - pconv_fw_type='split_cat', - # pconv_fw_type='slicing', # TODO: move the residual connect after the pconv, retrain the model, and then use slicing for inference - **kwargs - ) - - return model diff --git a/cv/classification/fasternet/pytorch/detection/benchmark.py b/cv/classification/fasternet/pytorch/detection/benchmark.py deleted file mode 100644 index d1629070d..000000000 --- a/cv/classification/fasternet/pytorch/detection/benchmark.py +++ /dev/null @@ -1,197 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import argparse -import copy -import os -import time - -import torch -from mmcv import Config, DictAction -from mmcv.cnn import fuse_conv_bn -from mmcv.parallel import MMDistributedDataParallel -from mmcv.runner import init_dist, load_checkpoint, wrap_fp16_model - -from mmdet.datasets import (build_dataloader, build_dataset, - replace_ImageToTensor) -from mmdet.models import build_detector -from mmdet.utils import replace_cfg_vals, update_data_root - -import backbones - - -def parse_args(): - parser = argparse.ArgumentParser(description='MMDet benchmark a model') - parser.add_argument('config', help='test config file path') - parser.add_argument('checkpoint', help='checkpoint file') - parser.add_argument( - '--repeat-num', - type=int, - default=1, - help='number of repeat times of measurement for averaging the results') - parser.add_argument( - '--max-iter', type=int, default=2000, help='num of max iter') - parser.add_argument( - '--log-interval', type=int, default=50, help='interval of logging') - parser.add_argument( - '--fuse-conv-bn', - action='store_true', - help='Whether to fuse conv and bn, this will slightly increase' - 'the inference speed') - parser.add_argument( - '--cfg-options', - nargs='+', - action=DictAction, - help='override some settings in the used config, the key-value pair ' - 'in xxx=yyy format will be merged into config file. If the value to ' - 'be overwritten is a list, it should be like key="[a,b]" or key=a,b ' - 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ' - 'Note that the quotation marks are necessary and that no white space ' - 'is allowed.') - parser.add_argument( - '--launcher', - choices=['none', 'pytorch', 'slurm', 'mpi'], - default='none', - help='job launcher') - parser.add_argument('--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) - return args - - -def measure_inference_speed(cfg, checkpoint, max_iter, log_interval, - is_fuse_conv_bn): - # set cudnn_benchmark - if cfg.get('cudnn_benchmark', False): - torch.backends.cudnn.benchmark = True - cfg.model.pretrained = None - cfg.data.test.test_mode = True - - # build the dataloader - samples_per_gpu = cfg.data.test.pop('samples_per_gpu', 1) - if samples_per_gpu > 1: - # Replace 'ImageToTensor' to 'DefaultFormatBundle' - cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline) - dataset = build_dataset(cfg.data.test) - data_loader = build_dataloader( - dataset, - samples_per_gpu=1, - # Because multiple processes will occupy additional CPU resources, - # FPS statistics will be more unstable when workers_per_gpu is not 0. - # It is reasonable to set workers_per_gpu to 0. - workers_per_gpu=0, - dist=True, - shuffle=False) - - # build the model and load checkpoint - cfg.model.train_cfg = None - model = build_detector(cfg.model, test_cfg=cfg.get('test_cfg')) - fp16_cfg = cfg.get('fp16', None) - if fp16_cfg is not None: - wrap_fp16_model(model) - load_checkpoint(model, checkpoint, map_location='cpu') - if is_fuse_conv_bn: - model = fuse_conv_bn(model) - - model = MMDistributedDataParallel( - model.cuda(), - device_ids=[torch.cuda.current_device()], - broadcast_buffers=False) - model.eval() - - # the first several iterations may be very slow so skip them - num_warmup = 5 - pure_inf_time = 0 - fps = 0 - - # benchmark with 2000 image and take the average - for i, data in enumerate(data_loader): - - torch.cuda.synchronize() - start_time = time.perf_counter() - - with torch.no_grad(): - model(return_loss=False, rescale=True, **data) - - torch.cuda.synchronize() - elapsed = time.perf_counter() - start_time - - if i >= num_warmup: - pure_inf_time += elapsed - if (i + 1) % log_interval == 0: - fps = (i + 1 - num_warmup) / pure_inf_time - print( - f'Done image [{i + 1:<3}/ {max_iter}], ' - f'fps: {fps:.1f} img / s, ' - f'times per image: {1000 / fps:.1f} ms / img', - flush=True) - - if (i + 1) == max_iter: - fps = (i + 1 - num_warmup) / pure_inf_time - print( - f'Overall fps: {fps:.1f} img / s, ' - f'times per image: {1000 / fps:.1f} ms / img', - flush=True) - break - return fps - - -def repeat_measure_inference_speed(cfg, - checkpoint, - max_iter, - log_interval, - is_fuse_conv_bn, - repeat_num=1): - assert repeat_num >= 1 - - fps_list = [] - - for _ in range(repeat_num): - # - cp_cfg = copy.deepcopy(cfg) - - fps_list.append( - measure_inference_speed(cp_cfg, checkpoint, max_iter, log_interval, - is_fuse_conv_bn)) - - if repeat_num > 1: - fps_list_ = [round(fps, 1) for fps in fps_list] - times_pre_image_list_ = [round(1000 / fps, 1) for fps in fps_list] - mean_fps_ = sum(fps_list_) / len(fps_list_) - mean_times_pre_image_ = sum(times_pre_image_list_) / len( - times_pre_image_list_) - print( - f'Overall fps: {fps_list_}[{mean_fps_:.1f}] img / s, ' - f'times per image: ' - f'{times_pre_image_list_}[{mean_times_pre_image_:.1f}] ms / img', - flush=True) - return fps_list - - return fps_list[0] - - -def main(): - args = parse_args() - - cfg = Config.fromfile(args.config) - - # replace the ${key} with the value of cfg.key - cfg = replace_cfg_vals(cfg) - - # update data root according to MMDET_DATASETS - update_data_root(cfg) - - if args.cfg_options is not None: - cfg.merge_from_dict(args.cfg_options) - - if args.launcher == 'none': - raise NotImplementedError('Only supports distributed mode') - else: - init_dist(args.launcher, **cfg.dist_params) - - repeat_measure_inference_speed(cfg, args.checkpoint, args.max_iter, - args.log_interval, args.fuse_conv_bn, - args.repeat_num) - - -if __name__ == '__main__': - main() diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py deleted file mode 100644 index 149f590bb..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py +++ /dev/null @@ -1,49 +0,0 @@ -# dataset settings -dataset_type = 'CocoDataset' -data_root = 'data/coco/' -img_norm_cfg = dict( - mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) -train_pipeline = [ - dict(type='LoadImageFromFile'), - dict(type='LoadAnnotations', with_bbox=True), - dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), - dict(type='RandomFlip', flip_ratio=0.5), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='DefaultFormatBundle'), - dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), -] -test_pipeline = [ - dict(type='LoadImageFromFile'), - dict( - type='MultiScaleFlipAug', - img_scale=(1333, 800), - flip=False, - transforms=[ - dict(type='Resize', keep_ratio=True), - dict(type='RandomFlip'), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='ImageToTensor', keys=['img']), - dict(type='Collect', keys=['img']), - ]) -] -data = dict( - samples_per_gpu=2, - workers_per_gpu=2, - train=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_train2017.json', - img_prefix=data_root + 'train2017/', - pipeline=train_pipeline), - val=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_val2017.json', - img_prefix=data_root + 'val2017/', - pipeline=test_pipeline), - test=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_val2017.json', - img_prefix=data_root + 'val2017/', - pipeline=test_pipeline)) -evaluation = dict(interval=1, metric='bbox') diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py deleted file mode 100644 index 9901a8584..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py +++ /dev/null @@ -1,49 +0,0 @@ -# dataset settings -dataset_type = 'CocoDataset' -data_root = 'data/coco/' -img_norm_cfg = dict( - mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True) -train_pipeline = [ - dict(type='LoadImageFromFile'), - dict(type='LoadAnnotations', with_bbox=True, with_mask=True), - dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), - dict(type='RandomFlip', flip_ratio=0.5), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='DefaultFormatBundle'), - dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks']), -] -test_pipeline = [ - dict(type='LoadImageFromFile'), - dict( - type='MultiScaleFlipAug', - img_scale=(1333, 800), - flip=False, - transforms=[ - dict(type='Resize', keep_ratio=True), - dict(type='RandomFlip'), - dict(type='Normalize', **img_norm_cfg), - dict(type='Pad', size_divisor=32), - dict(type='ImageToTensor', keys=['img']), - dict(type='Collect', keys=['img']), - ]) -] -data = dict( - samples_per_gpu=2, - workers_per_gpu=2, - train=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_train2017.json', - img_prefix=data_root + 'train2017/', - pipeline=train_pipeline), - val=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_val2017.json', - img_prefix=data_root + 'val2017/', - pipeline=test_pipeline), - test=dict( - type=dataset_type, - ann_file=data_root + 'annotations/instances_val2017.json', - img_prefix=data_root + 'val2017/', - pipeline=test_pipeline)) -evaluation = dict(metric=['bbox', 'segm']) diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py deleted file mode 100644 index 5b0b1452c..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py +++ /dev/null @@ -1,27 +0,0 @@ -checkpoint_config = dict(interval=1) -# yapf:disable -log_config = dict( - interval=50, - hooks=[ - dict(type='TextLoggerHook'), - # dict(type='TensorboardLoggerHook') - ]) -# yapf:enable -custom_hooks = [dict(type='NumClassCheckHook')] - -dist_params = dict(backend='nccl') -log_level = 'INFO' -load_from = None -resume_from = None -workflow = [('train', 1)] - -# disable opencv multithreading to avoid system being overloaded -opencv_num_threads = 0 -# set multi-process start method as `fork` to speed up the training -mp_start_method = 'fork' - -# Default setting for scaling LR automatically -# - `enable` means enable scaling LR automatically -# or not by default. -# - `base_batch_size` = (8 GPUs) x (2 samples per GPU). -auto_scale_lr = dict(enable=False, base_batch_size=16) diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py deleted file mode 100644 index d903e55e2..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py +++ /dev/null @@ -1,120 +0,0 @@ -# model settings -model = dict( - type='MaskRCNN', - backbone=dict( - type='ResNet', - depth=50, - num_stages=4, - out_indices=(0, 1, 2, 3), - frozen_stages=1, - norm_cfg=dict(type='BN', requires_grad=True), - norm_eval=True, - style='pytorch', - init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')), - neck=dict( - type='FPN', - in_channels=[256, 512, 1024, 2048], - out_channels=256, - num_outs=5), - rpn_head=dict( - type='RPNHead', - in_channels=256, - feat_channels=256, - anchor_generator=dict( - type='AnchorGenerator', - scales=[8], - ratios=[0.5, 1.0, 2.0], - strides=[4, 8, 16, 32, 64]), - bbox_coder=dict( - type='DeltaXYWHBBoxCoder', - target_means=[.0, .0, .0, .0], - target_stds=[1.0, 1.0, 1.0, 1.0]), - loss_cls=dict( - type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0), - loss_bbox=dict(type='L1Loss', loss_weight=1.0)), - roi_head=dict( - type='StandardRoIHead', - bbox_roi_extractor=dict( - type='SingleRoIExtractor', - roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0), - out_channels=256, - featmap_strides=[4, 8, 16, 32]), - bbox_head=dict( - type='Shared2FCBBoxHead', - in_channels=256, - fc_out_channels=1024, - roi_feat_size=7, - num_classes=80, - bbox_coder=dict( - type='DeltaXYWHBBoxCoder', - target_means=[0., 0., 0., 0.], - target_stds=[0.1, 0.1, 0.2, 0.2]), - reg_class_agnostic=False, - loss_cls=dict( - type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0), - loss_bbox=dict(type='L1Loss', loss_weight=1.0)), - mask_roi_extractor=dict( - type='SingleRoIExtractor', - roi_layer=dict(type='RoIAlign', output_size=14, sampling_ratio=0), - out_channels=256, - featmap_strides=[4, 8, 16, 32]), - mask_head=dict( - type='FCNMaskHead', - num_convs=4, - in_channels=256, - conv_out_channels=256, - num_classes=80, - loss_mask=dict( - type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))), - # model training and testing settings - train_cfg=dict( - rpn=dict( - assigner=dict( - type='MaxIoUAssigner', - pos_iou_thr=0.7, - neg_iou_thr=0.3, - min_pos_iou=0.3, - match_low_quality=True, - ignore_iof_thr=-1), - sampler=dict( - type='RandomSampler', - num=256, - pos_fraction=0.5, - neg_pos_ub=-1, - add_gt_as_proposals=False), - allowed_border=-1, - pos_weight=-1, - debug=False), - rpn_proposal=dict( - nms_pre=2000, - max_per_img=1000, - nms=dict(type='nms', iou_threshold=0.7), - min_bbox_size=0), - rcnn=dict( - assigner=dict( - type='MaxIoUAssigner', - pos_iou_thr=0.5, - neg_iou_thr=0.5, - min_pos_iou=0.5, - match_low_quality=True, - ignore_iof_thr=-1), - sampler=dict( - type='RandomSampler', - num=512, - pos_fraction=0.25, - neg_pos_ub=-1, - add_gt_as_proposals=True), - mask_size=28, - pos_weight=-1, - debug=False)), - test_cfg=dict( - rpn=dict( - nms_pre=1000, - max_per_img=1000, - nms=dict(type='nms', iou_threshold=0.7), - min_bbox_size=0), - rcnn=dict( - score_thr=0.05, - nms=dict(type='nms', iou_threshold=0.5), - max_per_img=100, - mask_thr_binary=0.5))) diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py deleted file mode 100644 index 13b3783cb..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py +++ /dev/null @@ -1,11 +0,0 @@ -# optimizer -optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) -# learning policy -lr_config = dict( - policy='step', - warmup='linear', - warmup_iters=500, - warmup_ratio=0.001, - step=[8, 11]) -runner = dict(type='EpochBasedRunner', max_epochs=12) diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py deleted file mode 100644 index 00e859022..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py +++ /dev/null @@ -1,11 +0,0 @@ -# optimizer -optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) -# learning policy -lr_config = dict( - policy='step', - warmup='linear', - warmup_iters=500, - warmup_ratio=0.001, - step=[16, 19]) -runner = dict(type='EpochBasedRunner', max_epochs=20) diff --git a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py deleted file mode 100644 index 69dc9ee80..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py +++ /dev/null @@ -1,11 +0,0 @@ -# optimizer -optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) -# learning policy -lr_config = dict( - policy='step', - warmup='linear', - warmup_iters=500, - warmup_ratio=0.001, - step=[16, 22]) -runner = dict(type='EpochBasedRunner', max_epochs=24) diff --git a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py b/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py deleted file mode 100644 index 1c2134bc4..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py +++ /dev/null @@ -1,22 +0,0 @@ -_base_ = [ - '../_base_/models/mask_rcnn_r50_fpn.py', - '../_base_/datasets/coco_instance.py', - '../_base_/schedules/schedule_1x.py', - '../_base_/default_runtime.py' -] - -# optimizer -model = dict( - backbone=dict( - type='fasternet_l', - style='pytorch', - init_cfg=dict( - type='Pretrained', - checkpoint='../model_ckpt/fasternet_l-epoch=299-val_acc1=83.5060.pth', - ), - # init_cfg=None, - ), - neck=dict(in_channels=[192, 384, 768, 1536])) -# optimizer -optimizer = dict(_delete_=True, type='AdamW', lr=0.0001, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) diff --git a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py b/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py deleted file mode 100644 index 20a896271..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py +++ /dev/null @@ -1,22 +0,0 @@ -_base_ = [ - '../_base_/models/mask_rcnn_r50_fpn.py', - '../_base_/datasets/coco_instance.py', - '../_base_/schedules/schedule_1x.py', - '../_base_/default_runtime.py' -] - -# optimizer -model = dict( - backbone=dict( - type='fasternet_m', - style='pytorch', - init_cfg=dict( - type='Pretrained', - checkpoint='../model_ckpt/fasternet_m-epoch=291-val_acc1=82.9620.pth', - ), - # init_cfg=None, - ), - neck=dict(in_channels=[144, 288, 576, 1152])) -# optimizer -optimizer = dict(_delete_=True, type='AdamW', lr=0.0001, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) diff --git a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py b/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py deleted file mode 100644 index f5f84c30a..000000000 --- a/cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py +++ /dev/null @@ -1,22 +0,0 @@ -_base_ = [ - '../_base_/models/mask_rcnn_r50_fpn.py', - '../_base_/datasets/coco_instance.py', - '../_base_/schedules/schedule_1x.py', - '../_base_/default_runtime.py' -] - -# optimizer -model = dict( - backbone=dict( - type='fasternet_s', - style='pytorch', - init_cfg=dict( - type='Pretrained', - checkpoint='../model_ckpt/fasternet_s-epoch=299-val_acc1=81.2840.pth', - ), - # init_cfg=None, - ), - neck=dict(in_channels=[128, 256, 512, 1024])) -# optimizer -optimizer = dict(_delete_=True, type='AdamW', lr=0.0002, weight_decay=0.0001) -optimizer_config = dict(grad_clip=None) diff --git a/cv/classification/fasternet/pytorch/detection/dist_test.sh b/cv/classification/fasternet/pytorch/detection/dist_test.sh deleted file mode 100755 index dea131b43..000000000 --- a/cv/classification/fasternet/pytorch/detection/dist_test.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -CONFIG=$1 -CHECKPOINT=$2 -GPUS=$3 -NNODES=${NNODES:-1} -NODE_RANK=${NODE_RANK:-0} -PORT=${PORT:-29500} -MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"} - -PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ -python -m torch.distributed.launch \ - --nnodes=$NNODES \ - --node_rank=$NODE_RANK \ - --master_addr=$MASTER_ADDR \ - --nproc_per_node=$GPUS \ - --master_port=$PORT \ - $(dirname "$0")/test.py \ - $CONFIG \ - $CHECKPOINT \ - --launcher pytorch \ - ${@:4} diff --git a/cv/classification/fasternet/pytorch/detection/dist_train.sh b/cv/classification/fasternet/pytorch/detection/dist_train.sh deleted file mode 100755 index aa71bf4ae..000000000 --- a/cv/classification/fasternet/pytorch/detection/dist_train.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -CONFIG=$1 -GPUS=$2 -NNODES=${NNODES:-1} -NODE_RANK=${NODE_RANK:-0} -PORT=${PORT:-29500} -MASTER_ADDR=${MASTER_ADDR:-"127.0.0.1"} - -PYTHONPATH="$(dirname $0)/..":$PYTHONPATH \ -python -m torch.distributed.launch \ - --nnodes=$NNODES \ - --node_rank=$NODE_RANK \ - --master_addr=$MASTER_ADDR \ - --nproc_per_node=$GPUS \ - --master_port=$PORT \ - $(dirname "$0")/train.py \ - $CONFIG \ - --seed 0 \ - --launcher pytorch ${@:3} diff --git a/cv/classification/fasternet/pytorch/detection/get_flops.py b/cv/classification/fasternet/pytorch/detection/get_flops.py deleted file mode 100644 index 8b99dfd30..000000000 --- a/cv/classification/fasternet/pytorch/detection/get_flops.py +++ /dev/null @@ -1,112 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import argparse -import numpy as np -import torch -from mmcv import Config, DictAction -from mmdet.models import build_detector - -try: - from mmcv.cnn import get_model_complexity_info -except ImportError: - raise ImportError('Please upgrade mmcv to >0.6.2') -import backbones - - -@torch.no_grad() -def get_complexity_info(model, input_size): - model.eval() - - # using ptflops - macs, params = get_model_complexity_info(model, (3, input_size, input_size), as_strings=True, print_per_layer_stat=False, verbose=False) - - print('{:<30} {:<8}'.format('Computational complexity: ', macs)) - print('{:<30} {:<8}'.format('Number of parameters: ', params)) - macs = float(macs[:-5]) - params = float(params[:-2]) - - return macs, params - - -def parse_args(): - parser = argparse.ArgumentParser(description='Train a detector') - parser.add_argument('config', help='train config file path') - parser.add_argument( - '--shape', - type=int, - nargs='+', - default=[1280, 800], - help='input image size') - parser.add_argument( - '--cfg-options', - nargs='+', - action=DictAction, - help='override some settings in the used config, the key-value pair ' - 'in xxx=yyy format will be merged into config file. If the value to ' - 'be overwritten is a list, it should be like key="[a,b]" or key=a,b ' - 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ' - 'Note that the quotation marks are necessary and that no white space ' - 'is allowed.') - parser.add_argument( - '--size-divisor', - type=int, - default=32, - help='Pad the input image, the minimum size that is divisible ' - 'by size_divisor, -1 means do not pad the image.') - args = parser.parse_args() - return args - - -def main(): - - args = parse_args() - - if len(args.shape) == 1: - h = w = args.shape[0] - elif len(args.shape) == 2: - h, w = args.shape - else: - raise ValueError('invalid input shape') - ori_shape = (3, h, w) - divisor = args.size_divisor - if divisor > 0: - h = int(np.ceil(h / divisor)) * divisor - w = int(np.ceil(w / divisor)) * divisor - - input_shape = (3, h, w) - - cfg = Config.fromfile(args.config) - if args.cfg_options is not None: - cfg.merge_from_dict(args.cfg_options) - - model = build_detector( - cfg.model, - train_cfg=cfg.get('train_cfg'), - test_cfg=cfg.get('test_cfg')) - if torch.cuda.is_available(): - model.cuda() - model.eval() - - if hasattr(model, 'forward_dummy'): - model.forward = model.forward_dummy - else: - raise NotImplementedError( - 'FLOPs counter is currently not currently supported with {}'. - format(model.__class__.__name__)) - - flops, params = get_model_complexity_info(model, input_shape) - - split_line = '=' * 30 - - if divisor > 0 and \ - input_shape != ori_shape: - print(f'{split_line}\nUse size divisor set input shape ' - f'from {ori_shape} to {input_shape}\n') - print(f'{split_line}\nInput shape: {input_shape}\n' - f'Flops: {flops}\nParams: {params}\n{split_line}') - print('!!!Please be cautious if you use the results in papers. ' - 'You may need to check if all ops are supported and verify that the ' - 'flops computation is correct.') - - -if __name__ == '__main__': - main() diff --git a/cv/classification/fasternet/pytorch/detection/test.py b/cv/classification/fasternet/pytorch/detection/test.py deleted file mode 100644 index d9c5c3706..000000000 --- a/cv/classification/fasternet/pytorch/detection/test.py +++ /dev/null @@ -1,276 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import argparse -import os -import os.path as osp -import time -import warnings - -import mmcv -import torch -from mmcv import Config, DictAction -from mmcv.cnn import fuse_conv_bn -from mmcv.runner import (get_dist_info, init_dist, load_checkpoint, - wrap_fp16_model) - -from mmdet.apis import multi_gpu_test, single_gpu_test -from mmdet.datasets import (build_dataloader, build_dataset, - replace_ImageToTensor) -from mmdet.models import build_detector -from mmdet.utils import (build_ddp, build_dp, compat_cfg, get_device, - replace_cfg_vals, setup_multi_processes, - update_data_root) -import backbones - - -def parse_args(): - parser = argparse.ArgumentParser( - description='MMDet test (and eval) a model') - parser.add_argument('config', help='test config file path') - parser.add_argument('checkpoint', help='checkpoint file') - parser.add_argument( - '--work-dir', - help='the directory to save the file containing evaluation metrics') - parser.add_argument('--out', help='output result file in pickle format') - parser.add_argument( - '--fuse-conv-bn', - action='store_true', - help='Whether to fuse conv and bn, this will slightly increase' - 'the inference speed') - parser.add_argument( - '--gpu-ids', - type=int, - nargs='+', - help='(Deprecated, please use --gpu-id) ids of gpus to use ' - '(only applicable to non-distributed training)') - parser.add_argument( - '--gpu-id', - type=int, - default=0, - help='id of gpu to use ' - '(only applicable to non-distributed testing)') - parser.add_argument( - '--format-only', - action='store_true', - help='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') - parser.add_argument( - '--eval', - type=str, - nargs='+', - help='evaluation metrics, which depends on the dataset, e.g., "bbox",' - ' "segm", "proposal" for COCO, and "mAP", "recall" for PASCAL VOC') - parser.add_argument('--show', action='store_true', help='show results') - parser.add_argument( - '--show-dir', help='directory where painted images will be saved') - parser.add_argument( - '--show-score-thr', - type=float, - default=0.3, - help='score threshold (default: 0.3)') - parser.add_argument( - '--gpu-collect', - action='store_true', - help='whether to use gpu to collect results.') - parser.add_argument( - '--tmpdir', - help='tmp directory used for collecting results from multiple ' - 'workers, available when gpu-collect is not specified') - parser.add_argument( - '--cfg-options', - nargs='+', - action=DictAction, - help='override some settings in the used config, the key-value pair ' - 'in xxx=yyy format will be merged into config file. If the value to ' - 'be overwritten is a list, it should be like key="[a,b]" or key=a,b ' - 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ' - 'Note that the quotation marks are necessary and that no white space ' - 'is allowed.') - parser.add_argument( - '--options', - nargs='+', - action=DictAction, - help='custom options for evaluation, the key-value pair in xxx=yyy ' - 'format will be kwargs for dataset.evaluate() function (deprecate), ' - 'change to --eval-options instead.') - parser.add_argument( - '--eval-options', - nargs='+', - action=DictAction, - help='custom options for evaluation, the key-value pair in xxx=yyy ' - 'format will be kwargs for dataset.evaluate() function') - parser.add_argument( - '--launcher', - choices=['none', 'pytorch', 'slurm', 'mpi'], - default='none', - help='job launcher') - parser.add_argument('--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) - - if args.options and args.eval_options: - raise ValueError( - '--options and --eval-options cannot be both ' - 'specified, --options is deprecated in favor of --eval-options') - if args.options: - warnings.warn('--options is deprecated in favor of --eval-options') - args.eval_options = args.options - return args - - -def main(): - args = parse_args() - - assert args.out or args.eval or args.format_only or args.show \ - or args.show_dir, \ - ('Please specify at least one operation (save/eval/format/show the ' - 'results / save the results) with the argument "--out", "--eval"' - ', "--format-only", "--show" or "--show-dir"') - - if args.eval and args.format_only: - raise ValueError('--eval and --format_only cannot be both specified') - - if args.out is not None and not args.out.endswith(('.pkl', '.pickle')): - raise ValueError('The output file must be a pkl file.') - - cfg = Config.fromfile(args.config) - - # replace the ${key} with the value of cfg.key - cfg = replace_cfg_vals(cfg) - - # update data root according to MMDET_DATASETS - update_data_root(cfg) - - if args.cfg_options is not None: - cfg.merge_from_dict(args.cfg_options) - - cfg = compat_cfg(cfg) - - # set multi-process settings - setup_multi_processes(cfg) - - # set cudnn_benchmark - if cfg.get('cudnn_benchmark', False): - torch.backends.cudnn.benchmark = True - - if 'pretrained' in cfg.model: - cfg.model.pretrained = None - elif 'init_cfg' in cfg.model.backbone: - cfg.model.backbone.init_cfg = None - - if cfg.model.get('neck'): - if isinstance(cfg.model.neck, list): - for neck_cfg in cfg.model.neck: - if neck_cfg.get('rfp_backbone'): - if neck_cfg.rfp_backbone.get('pretrained'): - neck_cfg.rfp_backbone.pretrained = None - elif cfg.model.neck.get('rfp_backbone'): - if cfg.model.neck.rfp_backbone.get('pretrained'): - cfg.model.neck.rfp_backbone.pretrained = None - - if args.gpu_ids is not None: - cfg.gpu_ids = args.gpu_ids[0:1] - warnings.warn('`--gpu-ids` is deprecated, please use `--gpu-id`. ' - 'Because we only support single GPU mode in ' - 'non-distributed testing. Use the first GPU ' - 'in `gpu_ids` now.') - else: - cfg.gpu_ids = [args.gpu_id] - cfg.device = get_device() - # init distributed env first, since logger depends on the dist info. - if args.launcher == 'none': - distributed = False - else: - distributed = True - init_dist(args.launcher, **cfg.dist_params) - - test_dataloader_default_args = dict( - samples_per_gpu=1, workers_per_gpu=2, dist=distributed, shuffle=False) - - # in case the test dataset is concatenated - if isinstance(cfg.data.test, dict): - cfg.data.test.test_mode = True - if cfg.data.test_dataloader.get('samples_per_gpu', 1) > 1: - # Replace 'ImageToTensor' to 'DefaultFormatBundle' - cfg.data.test.pipeline = replace_ImageToTensor( - cfg.data.test.pipeline) - elif isinstance(cfg.data.test, list): - for ds_cfg in cfg.data.test: - ds_cfg.test_mode = True - if cfg.data.test_dataloader.get('samples_per_gpu', 1) > 1: - for ds_cfg in cfg.data.test: - ds_cfg.pipeline = replace_ImageToTensor(ds_cfg.pipeline) - - test_loader_cfg = { - **test_dataloader_default_args, - **cfg.data.get('test_dataloader', {}) - } - - rank, _ = get_dist_info() - # allows not to create - if args.work_dir is not None and rank == 0: - mmcv.mkdir_or_exist(osp.abspath(args.work_dir)) - timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime()) - json_file = osp.join(args.work_dir, f'eval_{timestamp}.json') - - # build the dataloader - dataset = build_dataset(cfg.data.test) - data_loader = build_dataloader(dataset, **test_loader_cfg) - - # build the model and load checkpoint - cfg.model.train_cfg = None - model = build_detector(cfg.model, test_cfg=cfg.get('test_cfg')) - fp16_cfg = cfg.get('fp16', None) - if fp16_cfg is not None: - wrap_fp16_model(model) - checkpoint = load_checkpoint(model, args.checkpoint, map_location='cpu') - if args.fuse_conv_bn: - model = fuse_conv_bn(model) - # old versions did not save class info in checkpoints, this walkaround is - # for backward compatibility - if 'CLASSES' in checkpoint.get('meta', {}): - model.CLASSES = checkpoint['meta']['CLASSES'] - else: - model.CLASSES = dataset.CLASSES - - if not distributed: - model = build_dp(model, cfg.device, device_ids=cfg.gpu_ids) - outputs = single_gpu_test(model, data_loader, args.show, args.show_dir, - args.show_score_thr) - else: - model = build_ddp( - model, - cfg.device, - device_ids=[int(os.environ['LOCAL_RANK'])], - broadcast_buffers=False) - outputs = multi_gpu_test( - model, data_loader, args.tmpdir, args.gpu_collect - or cfg.evaluation.get('gpu_collect', False)) - - rank, _ = get_dist_info() - if rank == 0: - if args.out: - print(f'\nwriting results to {args.out}') - mmcv.dump(outputs, args.out) - kwargs = {} if args.eval_options is None else args.eval_options - if args.format_only: - dataset.format_results(outputs, **kwargs) - if args.eval: - eval_kwargs = cfg.get('evaluation', {}).copy() - # hard-code way to remove EvalHook args - for key in [ - 'interval', 'tmpdir', 'start', 'gpu_collect', 'save_best', - 'rule', 'dynamic_intervals' - ]: - eval_kwargs.pop(key, None) - eval_kwargs.update(dict(metric=args.eval, **kwargs)) - metric = dataset.evaluate(outputs, **eval_kwargs) - print(metric) - metric_dict = dict(config=args.config, metric=metric) - if args.work_dir is not None and rank == 0: - mmcv.dump(metric_dict, json_file) - - -if __name__ == '__main__': - main() diff --git a/cv/classification/fasternet/pytorch/detection/train.py b/cv/classification/fasternet/pytorch/detection/train.py deleted file mode 100644 index db062a9ad..000000000 --- a/cv/classification/fasternet/pytorch/detection/train.py +++ /dev/null @@ -1,243 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import argparse -import copy -import os -import os.path as osp -import time -import warnings - -import mmcv -import torch -import torch.distributed as dist -from mmcv import Config, DictAction -from mmcv.runner import get_dist_info, init_dist -from mmcv.utils import get_git_hash - -from mmdet import __version__ -from mmdet.apis import init_random_seed, set_random_seed, train_detector -from mmdet.datasets import build_dataset -from mmdet.models import build_detector -from mmdet.utils import (collect_env, get_device, get_root_logger, - replace_cfg_vals, setup_multi_processes, - update_data_root) -import backbones - - -def parse_args(): - parser = argparse.ArgumentParser(description='Train a detector') - parser.add_argument('config', help='train config file path') - parser.add_argument('--work-dir', help='the dir to save logs and models') - parser.add_argument( - '--resume-from', help='the checkpoint file to resume from') - parser.add_argument( - '--auto-resume', - action='store_true', - help='resume from the latest checkpoint automatically') - parser.add_argument( - '--no-validate', - action='store_true', - help='whether not to evaluate the checkpoint during training') - group_gpus = parser.add_mutually_exclusive_group() - group_gpus.add_argument( - '--gpus', - type=int, - help='(Deprecated, please use --gpu-id) number of gpus to use ' - '(only applicable to non-distributed training)') - group_gpus.add_argument( - '--gpu-ids', - type=int, - nargs='+', - help='(Deprecated, please use --gpu-id) ids of gpus to use ' - '(only applicable to non-distributed training)') - group_gpus.add_argument( - '--gpu-id', - type=int, - default=0, - help='id of gpu to use ' - '(only applicable to non-distributed training)') - parser.add_argument('--seed', type=int, default=None, help='random seed') - parser.add_argument( - '--diff-seed', - action='store_true', - help='Whether or not set different seeds for different ranks') - parser.add_argument( - '--deterministic', - action='store_true', - help='whether to set deterministic options for CUDNN backend.') - parser.add_argument( - '--options', - nargs='+', - action=DictAction, - help='override some settings in the used config, the key-value pair ' - 'in xxx=yyy format will be merged into config file (deprecate), ' - 'change to --cfg-options instead.') - parser.add_argument( - '--cfg-options', - nargs='+', - action=DictAction, - help='override some settings in the used config, the key-value pair ' - 'in xxx=yyy format will be merged into config file. If the value to ' - 'be overwritten is a list, it should be like key="[a,b]" or key=a,b ' - 'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" ' - 'Note that the quotation marks are necessary and that no white space ' - 'is allowed.') - parser.add_argument( - '--launcher', - choices=['none', 'pytorch', 'slurm', 'mpi'], - default='none', - help='job launcher') - parser.add_argument('--local_rank', type=int, default=0) - parser.add_argument( - '--auto-scale-lr', - action='store_true', - help='enable automatically scaling LR.') - args = parser.parse_args() - if 'LOCAL_RANK' not in os.environ: - os.environ['LOCAL_RANK'] = str(args.local_rank) - - if args.options and args.cfg_options: - raise ValueError( - '--options and --cfg-options cannot be both ' - 'specified, --options is deprecated in favor of --cfg-options') - if args.options: - warnings.warn('--options is deprecated in favor of --cfg-options') - args.cfg_options = args.options - - return args - - -def main(): - args = parse_args() - - cfg = Config.fromfile(args.config) - - # replace the ${key} with the value of cfg.key - cfg = replace_cfg_vals(cfg) - - # update data root according to MMDET_DATASETS - update_data_root(cfg) - - if args.cfg_options is not None: - cfg.merge_from_dict(args.cfg_options) - - if args.auto_scale_lr: - if 'auto_scale_lr' in cfg and \ - 'enable' in cfg.auto_scale_lr and \ - 'base_batch_size' in cfg.auto_scale_lr: - cfg.auto_scale_lr.enable = True - else: - warnings.warn('Can not find "auto_scale_lr" or ' - '"auto_scale_lr.enable" or ' - '"auto_scale_lr.base_batch_size" in your' - ' configuration file. Please update all the ' - 'configuration files to mmdet >= 2.24.1.') - - # set multi-process settings - setup_multi_processes(cfg) - - # set cudnn_benchmark - if cfg.get('cudnn_benchmark', False): - torch.backends.cudnn.benchmark = True - - # work_dir is determined in this priority: CLI > segment in file > filename - if args.work_dir is not None: - # update configs according to CLI args if args.work_dir is not None - cfg.work_dir = args.work_dir - elif cfg.get('work_dir', None) is None: - # use config filename as default work_dir if cfg.work_dir is None - cfg.work_dir = osp.join('./work_dirs', - osp.splitext(osp.basename(args.config))[0]) - - if args.resume_from is not None: - cfg.resume_from = args.resume_from - cfg.auto_resume = args.auto_resume - if args.gpus is not None: - cfg.gpu_ids = range(1) - warnings.warn('`--gpus` is deprecated because we only support ' - 'single GPU mode in non-distributed training. ' - 'Use `gpus=1` now.') - if args.gpu_ids is not None: - cfg.gpu_ids = args.gpu_ids[0:1] - warnings.warn('`--gpu-ids` is deprecated, please use `--gpu-id`. ' - 'Because we only support single GPU mode in ' - 'non-distributed training. Use the first GPU ' - 'in `gpu_ids` now.') - if args.gpus is None and args.gpu_ids is None: - cfg.gpu_ids = [args.gpu_id] - - # init distributed env first, since logger depends on the dist info. - if args.launcher == 'none': - distributed = False - else: - distributed = True - init_dist(args.launcher, **cfg.dist_params) - # re-set gpu_ids with distributed training mode - _, world_size = get_dist_info() - cfg.gpu_ids = range(world_size) - - # create work_dir - mmcv.mkdir_or_exist(osp.abspath(cfg.work_dir)) - # dump config - cfg.dump(osp.join(cfg.work_dir, osp.basename(args.config))) - # init the logger before other steps - timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime()) - log_file = osp.join(cfg.work_dir, f'{timestamp}.log') - logger = get_root_logger(log_file=log_file, log_level=cfg.log_level) - - # init the meta dict to record some important information such as - # environment info and seed, which will be logged - meta = dict() - # log env info - env_info_dict = collect_env() - env_info = '\n'.join([(f'{k}: {v}') for k, v in env_info_dict.items()]) - dash_line = '-' * 60 + '\n' - logger.info('Environment info:\n' + dash_line + env_info + '\n' + - dash_line) - meta['env_info'] = env_info - meta['config'] = cfg.pretty_text - # log some basic info - logger.info(f'Distributed training: {distributed}') - logger.info(f'Config:\n{cfg.pretty_text}') - - cfg.device = get_device() - # set random seeds - seed = init_random_seed(args.seed, device=cfg.device) - seed = seed + dist.get_rank() if args.diff_seed else seed - logger.info(f'Set random seed to {seed}, ' - f'deterministic: {args.deterministic}') - set_random_seed(seed, deterministic=args.deterministic) - cfg.seed = seed - meta['seed'] = seed - meta['exp_name'] = osp.basename(args.config) - - model = build_detector( - cfg.model, - train_cfg=cfg.get('train_cfg'), - test_cfg=cfg.get('test_cfg')) - model.init_weights() - - datasets = [build_dataset(cfg.data.train)] - if len(cfg.workflow) == 2: - val_dataset = copy.deepcopy(cfg.data.val) - val_dataset.pipeline = cfg.data.train.pipeline - datasets.append(build_dataset(val_dataset)) - if cfg.checkpoint_config is not None: - # save mmdet version, config file content and class names in - # checkpoints as meta data - cfg.checkpoint_config.meta = dict( - mmdet_version=__version__ + get_git_hash()[:7], - CLASSES=datasets[0].CLASSES) - # add an attribute for visualization convenience - model.CLASSES = datasets[0].CLASSES - train_detector( - model, - datasets, - cfg, - distributed=distributed, - validate=(not args.no_validate), - timestamp=timestamp, - meta=meta) - - -if __name__ == '__main__': - main() diff --git a/cv/classification/fasternet/pytorch/models/__init__.py b/cv/classification/fasternet/pytorch/models/__init__.py deleted file mode 100644 index 30c636589..000000000 --- a/cv/classification/fasternet/pytorch/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .registry import * \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/models/fasternet.py b/cv/classification/fasternet/pytorch/models/fasternet.py deleted file mode 100644 index 5abc16d46..000000000 --- a/cv/classification/fasternet/pytorch/models/fasternet.py +++ /dev/null @@ -1,360 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -import torch -import torch.nn as nn -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ -from functools import partial -from typing import List -from torch import Tensor -import copy -import os - -try: - from mmdet.models.builder import BACKBONES as det_BACKBONES - from mmdet.utils import get_root_logger - from mmcv.runner import _load_checkpoint - has_mmdet = True -except ImportError: - print("If for detection, please install mmdetection first") - has_mmdet = False - - -class Partial_conv3(nn.Module): - - def __init__(self, dim, n_div, forward): - super().__init__() - self.dim_conv3 = dim // n_div - self.dim_untouched = dim - self.dim_conv3 - self.partial_conv3 = nn.Conv2d(self.dim_conv3, self.dim_conv3, 3, 1, 1, bias=False) - - if forward == 'slicing': - self.forward = self.forward_slicing - elif forward == 'split_cat': - self.forward = self.forward_split_cat - else: - raise NotImplementedError - - def forward_slicing(self, x: Tensor) -> Tensor: - # only for inference - x = x.clone() # !!! Keep the original input intact for the residual connection later - x[:, :self.dim_conv3, :, :] = self.partial_conv3(x[:, :self.dim_conv3, :, :]) - - return x - - def forward_split_cat(self, x: Tensor) -> Tensor: - # for training/inference - x1, x2 = torch.split(x, [self.dim_conv3, self.dim_untouched], dim=1) - x1 = self.partial_conv3(x1) - x = torch.cat((x1, x2), 1) - - return x - - -class MLPBlock(nn.Module): - - def __init__(self, - dim, - n_div, - mlp_ratio, - drop_path, - layer_scale_init_value, - act_layer, - norm_layer, - pconv_fw_type - ): - - super().__init__() - self.dim = dim - self.mlp_ratio = mlp_ratio - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.n_div = n_div - - mlp_hidden_dim = int(dim * mlp_ratio) - - mlp_layer: List[nn.Module] = [ - nn.Conv2d(dim, mlp_hidden_dim, 1, bias=False), - norm_layer(mlp_hidden_dim), - act_layer(), - nn.Conv2d(mlp_hidden_dim, dim, 1, bias=False) - ] - - self.mlp = nn.Sequential(*mlp_layer) - - self.spatial_mixing = Partial_conv3( - dim, - n_div, - pconv_fw_type - ) - - if layer_scale_init_value > 0: - self.layer_scale = nn.Parameter(layer_scale_init_value * torch.ones((dim)), requires_grad=True) - self.forward = self.forward_layer_scale - else: - self.forward = self.forward - - def forward(self, x: Tensor) -> Tensor: - shortcut = x - x = self.spatial_mixing(x) - x = shortcut + self.drop_path(self.mlp(x)) - return x - - def forward_layer_scale(self, x: Tensor) -> Tensor: - shortcut = x - x = self.spatial_mixing(x) - x = shortcut + self.drop_path( - self.layer_scale.unsqueeze(-1).unsqueeze(-1) * self.mlp(x)) - return x - - -class BasicStage(nn.Module): - - def __init__(self, - dim, - depth, - n_div, - mlp_ratio, - drop_path, - layer_scale_init_value, - norm_layer, - act_layer, - pconv_fw_type - ): - - super().__init__() - - blocks_list = [ - MLPBlock( - dim=dim, - n_div=n_div, - mlp_ratio=mlp_ratio, - drop_path=drop_path[i], - layer_scale_init_value=layer_scale_init_value, - norm_layer=norm_layer, - act_layer=act_layer, - pconv_fw_type=pconv_fw_type - ) - for i in range(depth) - ] - - self.blocks = nn.Sequential(*blocks_list) - - def forward(self, x: Tensor) -> Tensor: - x = self.blocks(x) - return x - - -class PatchEmbed(nn.Module): - - def __init__(self, patch_size, patch_stride, in_chans, embed_dim, norm_layer): - super().__init__() - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_stride, bias=False) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = nn.Identity() - - def forward(self, x: Tensor) -> Tensor: - x = self.norm(self.proj(x)) - return x - - -class PatchMerging(nn.Module): - - def __init__(self, patch_size2, patch_stride2, dim, norm_layer): - super().__init__() - self.reduction = nn.Conv2d(dim, 2 * dim, kernel_size=patch_size2, stride=patch_stride2, bias=False) - if norm_layer is not None: - self.norm = norm_layer(2 * dim) - else: - self.norm = nn.Identity() - - def forward(self, x: Tensor) -> Tensor: - x = self.norm(self.reduction(x)) - return x - - -class FasterNet(nn.Module): - - def __init__(self, - in_chans=3, - num_classes=1000, - embed_dim=96, - depths=(1, 2, 8, 2), - mlp_ratio=2., - n_div=4, - patch_size=4, - patch_stride=4, - patch_size2=2, # for subsequent layers - patch_stride2=2, - patch_norm=True, - feature_dim=1280, - drop_path_rate=0.1, - layer_scale_init_value=0, - norm_layer='BN', - act_layer='RELU', - fork_feat=False, - init_cfg=None, - pretrained=None, - pconv_fw_type='split_cat', - **kwargs): - super().__init__() - - if norm_layer == 'BN': - norm_layer = nn.BatchNorm2d - else: - raise NotImplementedError - - if act_layer == 'GELU': - act_layer = nn.GELU - elif act_layer == 'RELU': - act_layer = partial(nn.ReLU, inplace=True) - else: - raise NotImplementedError - - if not fork_feat: - self.num_classes = num_classes - self.num_stages = len(depths) - self.embed_dim = embed_dim - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_stages - 1)) - self.mlp_ratio = mlp_ratio - self.depths = depths - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - patch_size=patch_size, - patch_stride=patch_stride, - in_chans=in_chans, - embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None - ) - - # stochastic depth decay rule - dpr = [x.item() - for x in torch.linspace(0, drop_path_rate, sum(depths))] - - # build layers - stages_list = [] - for i_stage in range(self.num_stages): - stage = BasicStage(dim=int(embed_dim * 2 ** i_stage), - n_div=n_div, - depth=depths[i_stage], - mlp_ratio=self.mlp_ratio, - drop_path=dpr[sum(depths[:i_stage]):sum(depths[:i_stage + 1])], - layer_scale_init_value=layer_scale_init_value, - norm_layer=norm_layer, - act_layer=act_layer, - pconv_fw_type=pconv_fw_type - ) - stages_list.append(stage) - - # patch merging layer - if i_stage < self.num_stages - 1: - stages_list.append( - PatchMerging(patch_size2=patch_size2, - patch_stride2=patch_stride2, - dim=int(embed_dim * 2 ** i_stage), - norm_layer=norm_layer) - ) - - self.stages = nn.Sequential(*stages_list) - - self.fork_feat = fork_feat - - if self.fork_feat: - self.forward = self.forward_det - # add a norm layer for each output - self.out_indices = [0, 2, 4, 6] - for i_emb, i_layer in enumerate(self.out_indices): - if i_emb == 0 and os.environ.get('FORK_LAST3', None): - raise NotImplementedError - else: - layer = norm_layer(int(embed_dim * 2 ** i_emb)) - layer_name = f'norm{i_layer}' - self.add_module(layer_name, layer) - else: - self.forward = self.forward_cls - # Classifier head - self.avgpool_pre_head = nn.Sequential( - nn.AdaptiveAvgPool2d(1), - nn.Conv2d(self.num_features, feature_dim, 1, bias=False), - act_layer() - ) - self.head = nn.Linear(feature_dim, num_classes) \ - if num_classes > 0 else nn.Identity() - - self.apply(self.cls_init_weights) - self.init_cfg = copy.deepcopy(init_cfg) - if self.fork_feat and (self.init_cfg is not None or pretrained is not None): - self.init_weights() - - def cls_init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, (nn.Conv1d, nn.Conv2d)): - trunc_normal_(m.weight, std=.02) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, (nn.LayerNorm, nn.GroupNorm)): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - # init for mmdetection by loading imagenet pre-trained weights - def init_weights(self, pretrained=None): - logger = get_root_logger() - if self.init_cfg is None and pretrained is None: - logger.warn(f'No pre-trained weights for ' - f'{self.__class__.__name__}, ' - f'training start from scratch') - pass - else: - assert 'checkpoint' in self.init_cfg, f'Only support ' \ - f'specify `Pretrained` in ' \ - f'`init_cfg` in ' \ - f'{self.__class__.__name__} ' - if self.init_cfg is not None: - ckpt_path = self.init_cfg['checkpoint'] - elif pretrained is not None: - ckpt_path = pretrained - - ckpt = _load_checkpoint( - ckpt_path, logger=logger, map_location='cpu') - if 'state_dict' in ckpt: - _state_dict = ckpt['state_dict'] - elif 'model' in ckpt: - _state_dict = ckpt['model'] - else: - _state_dict = ckpt - - state_dict = _state_dict - missing_keys, unexpected_keys = \ - self.load_state_dict(state_dict, False) - - # show for debug - print('missing_keys: ', missing_keys) - print('unexpected_keys: ', unexpected_keys) - - def forward_cls(self, x): - # output only the features of last layer for image classification - x = self.patch_embed(x) - x = self.stages(x) - x = self.avgpool_pre_head(x) # B C 1 1 - x = torch.flatten(x, 1) - x = self.head(x) - - return x - - def forward_det(self, x: Tensor) -> Tensor: - # output the features of four stages for dense prediction - x = self.patch_embed(x) - outs = [] - for idx, stage in enumerate(self.stages): - x = stage(x) - if self.fork_feat and idx in self.out_indices: - norm_layer = getattr(self, f'norm{idx}') - x_out = norm_layer(x) - outs.append(x_out) - - return outs \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/models/model_api.py b/cv/classification/fasternet/pytorch/models/model_api.py deleted file mode 100644 index b4021b6ab..000000000 --- a/cv/classification/fasternet/pytorch/models/model_api.py +++ /dev/null @@ -1,158 +0,0 @@ -import os -import sys -import inspect -currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) -parentdir = os.path.dirname(currentdir) -sys.path.insert(0, parentdir) - -from torch.optim.lr_scheduler import * -from models import * -from utils.utils import * -import torch -import pytorch_lightning as pl - -from timm.data import Mixup -from timm.models import create_model -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.scheduler import create_scheduler -from timm.optim import create_optimizer -from timm.utils import accuracy -from pl_bolts.optimizers.lr_scheduler import LinearWarmupCosineAnnealingLR -from utils.loss import DistillationLoss - - -def build_criterion(args): - if args.mixup > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif args.smoothing: - criterion = LabelSmoothingCrossEntropy(smoothing=args.smoothing) - else: - criterion = torch.nn.CrossEntropyLoss() - return criterion - - -def build_mixup_fn(args, num_classes): - mixup_fn = None - mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None - if mixup_active: - mixup_fn = Mixup( - mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax, - prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode, - label_smoothing=args.smoothing, num_classes=num_classes) - return mixup_fn - - -class LitModel(pl.LightningModule): - def __init__(self, num_classes, hparams): - super().__init__() - - self.save_hyperparameters(hparams) - if 'fasternet' in hparams.model_name: - self.model = create_model( - hparams.model_name, - mlp_ratio=hparams.mlp_ratio, - embed_dim=hparams.embed_dim, - depths=hparams.depths, - pretrained=hparams.pretrained, - n_div=hparams.n_div, - feature_dim=hparams.feature_dim, - patch_size=hparams.patch_size, - patch_stride=hparams.patch_stride, - patch_size2=hparams.patch_size2, - patch_stride2=hparams.patch_stride2, - num_classes=num_classes, - layer_scale_init_value=hparams.layer_scale_init_value, - drop_path_rate=hparams.drop_path_rate, - norm_layer=hparams.norm_layer, - act_layer=hparams.act_layer, - pconv_fw_type=hparams.pconv_fw_type - ) - else: - self.model = create_model( - hparams.model_name, - pretrained=hparams.pretrained, - num_classes=num_classes - ) - - base_criterion = build_criterion(hparams) - self.distillation_type = hparams.distillation_type - if hparams.distillation_type == 'none': - self.criterion = base_criterion - else: - # assert hparams.teacher_path, 'need to specify teacher-path when using distillation' - print(f"Creating teacher model: {hparams.teacher_model}") - teacher_model = create_model( - hparams.teacher_model, - pretrained=True, - num_classes=num_classes, - global_pool='avg', - ) - for param in teacher_model.parameters(): - param.requires_grad = False - teacher_model.eval() - self.criterion = DistillationLoss(base_criterion, - teacher_model, - hparams.distillation_type, - hparams.distillation_alpha, - hparams.distillation_tau - ) - self.criterion_eva = torch.nn.CrossEntropyLoss() - self.mixup_fn = build_mixup_fn(hparams, num_classes) - - def forward(self, x): - return self.model(x) - - def on_train_epoch_start(self): - if self.hparams.multi_scale is not None: - if self.current_epoch == int(self.hparams.multi_scale.split('_')[1]): - # image_size = self.hparams.image_size - self.trainer.reset_train_dataloader(self) - - def _calculate_loss(self, batch, mode="train"): - imgs, labels = batch - if mode == "train" and self.mixup_fn is not None: - imgs, labels = self.mixup_fn(imgs, labels) - preds = self.model(imgs) - - if mode == "train": - if self.distillation_type == 'none': - loss = self.criterion(preds, labels) - else: - loss = self.criterion(imgs, preds, labels) - self.log("%s_loss" % mode, loss) - else: - loss = self.criterion_eva(preds, labels) - acc1, acc5 = accuracy(preds, labels, topk=(1, 5)) - sync_dist = True if torch.cuda.device_count() > 1 else False - self.log("%s_loss" % mode, loss, sync_dist=sync_dist) - self.log("%s_acc1" % mode, acc1, sync_dist=sync_dist) - self.log("%s_acc5" % mode, acc5, sync_dist=sync_dist) - - return loss - - def training_step(self, batch, batch_idx): - loss = self._calculate_loss(batch, mode="train") - return loss - - def validation_step(self, batch, batch_idx): - self._calculate_loss(batch, mode="val") - - def test_step(self, batch, batch_idx): - self._calculate_loss(batch, mode="test") - - def configure_optimizers(self): - optimizer = create_optimizer(self.hparams, self.parameters()) - if self.hparams.sched == 'cosine': - scheduler = LinearWarmupCosineAnnealingLR(optimizer, - warmup_epochs=self.hparams.warmup_epochs, - max_epochs=self.hparams.epochs, - warmup_start_lr=self.hparams.warmup_lr, - eta_min=self.hparams.min_lr - ) - else: - # scheduler, _ = create_scheduler(self.hparams, optimizer) - raise NotImplementedError - - return [optimizer], [scheduler] - diff --git a/cv/classification/fasternet/pytorch/models/registry.py b/cv/classification/fasternet/pytorch/models/registry.py deleted file mode 100644 index 169a6645a..000000000 --- a/cv/classification/fasternet/pytorch/models/registry.py +++ /dev/null @@ -1,9 +0,0 @@ -import torch.nn as nn -from timm.models.registry import register_model -from .fasternet import FasterNet - - -@register_model -def fasternet(**kwargs): - model = FasterNet(**kwargs) - return model \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/requirements.txt b/cv/classification/fasternet/pytorch/requirements.txt index e02c51aab..44e79f6bd 100644 --- a/cv/classification/fasternet/pytorch/requirements.txt +++ b/cv/classification/fasternet/pytorch/requirements.txt @@ -1,20 +1,6 @@ -# conda create -n fasternet python=3.9.12 -y -# conda activate fasternet -# pip install -r requirements.txt - -# ---------------------------------------- ---extra-index-url https://download.pytorch.org/whl/cu113 - -#torch==1.11.0 -#torchvision==0.12.0 pytorch-lightning==1.6.5 lightning-bolts==0.5.0 timm==0.6.5 wandb>=0.12.21 -matplotlib==3.5.2 -fvcore>=0.1.5.post20220512 - -# ---------------------------------------- -# install the following packages for mmdet -# pip install mmcv-full==1.6.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.11.0/index.html -# pip install mmdet==2.25.0 +matplotlib +fvcore>=0.1.5.post20220512 \ No newline at end of file diff --git a/cv/classification/fasternet/pytorch/train_test.py b/cv/classification/fasternet/pytorch/train_test.py deleted file mode 100644 index 127e13b6c..000000000 --- a/cv/classification/fasternet/pytorch/train_test.py +++ /dev/null @@ -1,152 +0,0 @@ -import os -import sys -import torch -from torch import nn -from argparse import ArgumentParser -import wandb - -import pytorch_lightning as pl -from pytorch_lightning.callbacks import ModelCheckpoint, TQDMProgressBar, StochasticWeightAveraging -from pytorch_lightning.loggers import WandbLogger -from pytorch_lightning import seed_everything -from pytorch_lightning.plugins import DDPPlugin - -from utils.utils import * -from utils.fuse_conv_bn import fuse_conv_bn -from data.data_api import LitDataModule -from models.model_api import LitModel - - -def main(args): - # Init data pipeline - dm, _ = LitDataModule(hparams=args) - - # Init LitModel - if args.checkpoint_path is not None: - PATH = args.checkpoint_path - if PATH[-5:]=='.ckpt': - model = LitModel.load_from_checkpoint(PATH, map_location='cpu', num_classes=dm.num_classes, hparams=args) - print('Successfully load the pl checkpoint file.') - if args.pl_ckpt_2_torch_pth: - device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - model = model.model.to(device) - torch.save(model.state_dict(), PATH[:-5]+'.pth') - exit() - elif PATH[-4:] == '.pth': - model = LitModel(num_classes=dm.num_classes, hparams=args) - missing_keys, unexpected_keys = model.model.load_state_dict(torch.load(PATH), False) - # show for debug - print('missing_keys: ', missing_keys) - print('unexpected_keys: ', unexpected_keys) - else: - raise TypeError - else: - model = LitModel(num_classes=dm.num_classes, hparams=args) - - flops, params = get_flops_params(model.model, args.image_size) - - if args.fuse_conv_bn: - fuse_conv_bn(model.model) - - if args.measure_latency: - dm.prepare_data() - dm.setup(stage="test") - for idx, (images, _) in enumerate(dm.test_dataloader()): - model = model.model.eval() - throughput, latency = measure_latency(images[:1, :, :, :], model, GPU=False, num_threads=1) - if torch.cuda.is_available(): - throughput, latency = measure_latency(images, model, GPU=True) - exit() - - print_model(model) - - # Callbacks - MONITOR = 'val_acc1' - checkpoint_callback = ModelCheckpoint( - monitor=MONITOR, - dirpath=args.model_ckpt_dir, - filename=args.model_name+'-{epoch}-{val_acc1:.4f}', - save_top_k=1, - save_last=True, - mode='max' if 'acc' in MONITOR else 'min' - ) - refresh_callback = TQDMProgressBar(refresh_rate=20) - callbacks = [ - checkpoint_callback, - refresh_callback - ] - - # Initialize wandb logger - WANDB_ON = True if args.dev+args.test_phase==0 else False - if WANDB_ON: - wandb_logger = WandbLogger( - project=args.wandb_project_name, - save_dir=args.wandb_save_dir, - offline=args.wandb_offline, - log_model=False, - job_type='train') - wandb_logger.log_hyperparams(args) - wandb_logger.log_hyperparams({"flops": flops, "params": params}) - - # Initialize a trainer - find_unused_para = False if args.distillation_type == 'none' else True - trainer = pl.Trainer( - fast_dev_run=args.dev, - logger=wandb_logger if WANDB_ON else None, - max_epochs=args.epochs, - gpus=args.gpus, - accelerator="gpu", - sync_batchnorm=args.sync_batchnorm, - num_nodes=args.num_nodes, - gradient_clip_val=args.clip_grad, - strategy=DDPPlugin(find_unused_parameters=find_unused_para) if args.strategy == 'ddp' else args.strategy, - callbacks=callbacks, - precision=args.precision, - benchmark=args.benchmark - ) - - if bool(args.test_phase): - trainer.test(model, datamodule=dm) - else: - trainer.fit(model, dm) - if args.dev==0: - trainer.test(ckpt_path="best", datamodule=dm) - - # Close wandb run - if WANDB_ON: - wandb.finish() - - -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument('-c', '--cfg', type=str, default='cfg/fasternet_t0.yaml') - parser.add_argument('-g', "--gpus", type=str, default=None, - help="Number of GPUs to train on (int) or which GPUs to train on (list or str) applied per node.") - parser.add_argument('-d', "--dev", type=int, default=0, help='fast_dev_run for debug') - parser.add_argument("--num_nodes", type=int, default=1) - parser.add_argument('-n', "--num_workers", type=int, default=4) - parser.add_argument('-b', "--batch_size", type=int, default=2048) - parser.add_argument('-e', "--batch_size_eva", type=int, default=1000, help='batch_size for evaluation') - parser.add_argument("--model_ckpt_dir", type=str, default="./model_ckpt/") - parser.add_argument("--data_dir", type=str, default="../../data/imagenet") - parser.add_argument('--pin_memory', action='store_true') - parser.add_argument("--checkpoint_path", type=str, default=None) - parser.add_argument("--pconv_fw_type", type=str, default='split_cat', - help="use 'split_cat' for training/inference and 'slicing' only for inference") - parser.add_argument('--measure_latency', action='store_true', help='measure latency or throughput') - parser.add_argument('--test_phase', action='store_true') - parser.add_argument('--fuse_conv_bn', action='store_true') - parser.add_argument("--wandb_project_name", type=str, default="fasternet") - parser.add_argument('--wandb_offline', action='store_true') - parser.add_argument('--wandb_save_dir', type=str, default='./') - parser.add_argument('--pl_ckpt_2_torch_pth', action='store_true', - help='convert pl .ckpt file to torch .pth file, and then exit') - - args = parser.parse_args() - cfg = load_cfg(args.cfg) - args = merge_args_cfg(args, cfg) - - # please change {WANDB_API_KEY} to your personal api_key before using wandb - # os.environ["WANDB_API_KEY"] = "{WANDB_API_KEY}" - - main(args) diff --git a/cv/classification/fasternet/pytorch/utils/__init__.py b/cv/classification/fasternet/pytorch/utils/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py b/cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py deleted file mode 100644 index 8f1b7686a..000000000 --- a/cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) OpenMMLab. All rights reserved. -import torch -import torch.nn as nn - - -def _fuse_conv_bn(conv: nn.Module, bn: nn.Module) -> nn.Module: - """Fuse conv and bn into one module. - - Args: - conv (nn.Module): Conv to be fused. - bn (nn.Module): BN to be fused. - - Returns: - nn.Module: Fused module. - """ - conv_w = conv.weight - conv_b = conv.bias if conv.bias is not None else torch.zeros_like( - bn.running_mean) - - factor = bn.weight / torch.sqrt(bn.running_var + bn.eps) - conv.weight = nn.Parameter(conv_w * - factor.reshape([conv.out_channels, 1, 1, 1])) - conv.bias = nn.Parameter((conv_b - bn.running_mean) * factor + bn.bias) - return conv - - -def fuse_conv_bn(module: nn.Module) -> nn.Module: - """Recursively fuse conv and bn in a module. - - During inference, the functionary of batch norm layers is turned off - but only the mean and var alone channels are used, which exposes the - chance to fuse it with the preceding conv layers to save computations and - simplify network structures. - - Args: - module (nn.Module): Module to be fused. - - Returns: - nn.Module: Fused module. - """ - last_conv = None - last_conv_name = None - - for name, child in module.named_children(): - if isinstance(child, - (nn.modules.batchnorm._BatchNorm, nn.SyncBatchNorm)): - if last_conv is None: # only fuse BN that is after Conv - continue - fused_conv = _fuse_conv_bn(last_conv, child) - module._modules[last_conv_name] = fused_conv - # To reduce changes, set BN as Identity instead of deleting it. - module._modules[name] = nn.Identity() - last_conv = None - elif isinstance(child, nn.Conv2d): - last_conv = child - last_conv_name = name - else: - fuse_conv_bn(child) - return module - diff --git a/cv/classification/fasternet/pytorch/utils/loss.py b/cv/classification/fasternet/pytorch/utils/loss.py deleted file mode 100644 index ed725e0aa..000000000 --- a/cv/classification/fasternet/pytorch/utils/loss.py +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2015-present, Facebook, Inc. -# All rights reserved. -""" -Implements the knowledge distillation loss -""" -import torch -from torch.nn import functional as F - - -class DistillationLoss(torch.nn.Module): - """ - This module wraps a standard criterion and adds an extra knowledge distillation loss by - taking a teacher model prediction and using it as additional supervision. - """ - def __init__(self, base_criterion: torch.nn.Module, teacher_model: torch.nn.Module, - distillation_type: str, alpha: float, tau: float): - super().__init__() - self.base_criterion = base_criterion - self.teacher_model = teacher_model - assert distillation_type in ['none', 'soft', 'hard'] - self.distillation_type = distillation_type - self.alpha = alpha - self.tau = tau - - def forward(self, inputs, outputs, labels): - """ - Args: - inputs: The original inputs that are feed to the teacher model - outputs: the outputs of the model to be trained. It is expected to be - either a Tensor, or a Tuple[Tensor, Tensor], with the original output - in the first position and the distillation predictions as the second output - labels: the labels for the base criterion - """ - outputs_kd = outputs - # outputs_kd = None - # if not isinstance(outputs, torch.Tensor): - # # assume that the model outputs a tuple of [outputs, outputs_kd] - # outputs, outputs_kd = outputs - base_loss = self.base_criterion(outputs, labels) - # if self.distillation_type == 'none': - # return base_loss - - # if outputs_kd is None: - # raise ValueError("When knowledge distillation is enabled, the model is " - # "expected to return a Tuple[Tensor, Tensor] with the output of the " - # "class_token and the dist_token") - # don't backprop throught the teacher - with torch.no_grad(): - teacher_outputs = self.teacher_model(inputs) - - if self.distillation_type == 'soft': - T = self.tau - # taken from https://github.com/peterliht/knowledge-distillation-pytorch/blob/master/model/net.py#L100 - # with slight modifications - distillation_loss = F.kl_div( - F.log_softmax(outputs_kd / T, dim=1), - #We provide the teacher's targets in log probability because we use log_target=True - #(as recommended in pytorch https://github.com/pytorch/pytorch/blob/9324181d0ac7b4f7949a574dbc3e8be30abe7041/torch/nn/functional.py#L2719) - #but it is possible to give just the probabilities and set log_target=False. In our experiments we tried both. - F.log_softmax(teacher_outputs / T, dim=1), - reduction='sum', - log_target=True - ) * (T * T) / outputs_kd.numel() - #We divide by outputs_kd.numel() to have the legacy PyTorch behavior. - #But we also experiments output_kd.size(0) - #see issue 61(https://github.com/facebookresearch/deit/issues/61) for more details - elif self.distillation_type == 'hard': - distillation_loss = F.cross_entropy(outputs_kd, teacher_outputs.argmax(dim=1)) - - loss = base_loss * (1 - self.alpha) + distillation_loss * self.alpha - return loss diff --git a/cv/classification/fasternet/pytorch/utils/utils.py b/cv/classification/fasternet/pytorch/utils/utils.py deleted file mode 100644 index a4970342c..000000000 --- a/cv/classification/fasternet/pytorch/utils/utils.py +++ /dev/null @@ -1,188 +0,0 @@ -import torch -from torch import nn -import os -import numpy as np -import yaml -import time -from argparse import Namespace -import torch.distributed as dist -from pytorch_lightning.utilities import rank_zero_only -from fvcore.nn import FlopCountAnalysis, parameter_count - - -def load_cfg(cfg): - hyp = None - if isinstance(cfg, str): - with open(cfg, errors='ignore') as f: - hyp = yaml.safe_load(f) # load hyps dict - return Namespace(**hyp) - - -def merge_args_cfg(args, cfg): - dict0 = vars(args) - dict1 = vars(cfg) - dict = {**dict0, **dict1} - - return Namespace(**dict) - - -def str2list(string, sperator=','): - li = list(map(int, string.split(sperator))) - return li - -# def check_dir_format(dir): -# if dir.endswith(os.path.sep): -# return dir -# else: -# return dir+os.path.sep -# -# -# -# -# -# def append_path_by_date(model_ckpt_dir): -# os.environ['TZ'] = 'Asia/Hong_Kong' -# time.tzset() -# timestr = time.strftime("%Y%m%d-%H%M%S") -# -# return check_dir_format(model_ckpt_dir) + timestr + os.path.sep -# -@torch.no_grad() -@rank_zero_only -def print_model(model): - print(model) - - -@torch.no_grad() -def replace_layers(model, old, new): - for n, module in model.named_children(): - if len(list(module.children())) > 0: - ## compound module, go inside it - replace_layers(module, old, new) - - if isinstance(module, old): - ## simple module - setattr(model, n, new()) - -# @torch.no_grad() -# @rank_zero_only -# def mk_model_ckpt_dir(model_ckpt_dir): -# if not os.path.exists(model_ckpt_dir): -# os.makedirs(model_ckpt_dir) -# -@torch.no_grad() -def get_flops_params(model, input_size): - model.eval() - - tensor = (torch.rand(1, 3, input_size, input_size), ) - flops = FlopCountAnalysis(model, tensor) - flops = flops.total() / 1000000. - print("FVcore FLOPs(M): ", flops) - - params = parameter_count(model) - params = params[""] / 1000000. - print("FVcore params(M): ", params) - - return flops, params - - -@torch.no_grad() -def measure_latency(images, model, GPU=True, chan_last=False, half=False, num_threads=None, iter=200): - """ - :param images: b, c, h, w - :param model: model - :param GPU: whther use GPU - :param chan_last: data_format - :param half: half precision - :param num_threads: for cpu - :return: - """ - - if GPU: - model.cuda() - model.eval() - torch.backends.cudnn.benchmark = True - - images = images.cuda(non_blocking=True) - batch_size = images.shape[0] - if chan_last: - images = images.to(memory_format=torch.channels_last) - model = model.to(memory_format=torch.channels_last) - if half: - images = images.half() - model = model.half() - - for i in range(50): - model(images) - torch.cuda.synchronize() - tic1 = time.time() - for i in range(iter): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - throughput = iter * batch_size / (tic2 - tic1) - latency = 1000 * (tic2 - tic1) / iter - print(f"batch_size {batch_size} throughput on gpu {throughput}") - print(f"batch_size {batch_size} latency on gpu {latency} ms") - - return throughput, latency - else: - model.eval() - if num_threads is not None: - torch.set_num_threads(num_threads) - - batch_size = images.shape[0] - - if chan_last: - images = images.to(memory_format=torch.channels_last) - model = model.to(memory_format=torch.channels_last) - if half: - images = images.half() - model = model.half() - for i in range(10): - model(images) - tic1 = time.time() - for i in range(iter): - model(images) - tic2 = time.time() - throughput = iter * batch_size / (tic2 - tic1) - latency = 1000 * (tic2 - tic1) / iter - print(f"batch_size {batch_size} throughput on cpu {throughput}") - print(f"batch_size {batch_size} latency on cpu {latency} ms") - - return throughput, latency -# -# -# def setup_for_distributed(is_master): -# """ -# This function disables printing when not in master process -# """ -# import builtins as __builtin__ -# builtin_print = __builtin__.print -# -# def print(*args, **kwargs): -# force = kwargs.pop('force', False) -# if is_master or force: -# builtin_print(*args, **kwargs) -# -# __builtin__.print = print -# -# -def is_dist_avail_and_initialized(): - if not dist.is_available(): - return False - if not dist.is_initialized(): - return False - return True - - -def get_world_size(): - if not is_dist_avail_and_initialized(): - return 1 - return dist.get_world_size() - - -def get_rank(): - if not is_dist_avail_and_initialized(): - return 0 - return dist.get_rank() \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/LICENSE b/cv/classification/repmlp/pytorch/LICENSE deleted file mode 100644 index d87546195..000000000 --- a/cv/classification/repmlp/pytorch/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 DingXiaoH - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/cv/classification/repmlp/pytorch/README.md b/cv/classification/repmlp/pytorch/README.md index 97a1fba4c..99d354727 100644 --- a/cv/classification/repmlp/pytorch/README.md +++ b/cv/classification/repmlp/pytorch/README.md @@ -7,6 +7,9 @@ RepMLP, a multi-layer-perceptron-style neural network building block for image r ```bash pip3 install timm yacs +git clone https://github.com/DingXiaoH/RepMLP.git +cd RepMLP +git checkout 3eff13fa0257af28663880d870f327d665f0a8e2 ``` ## Step 2: Preparing datasets @@ -32,6 +35,12 @@ imagenet ## Step 3: Training ```bash +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' main_repmlp.py + +# change dataset load +sed -i "s@dataset = torchvision.datasets.ImageNet(root=config.DATA.DATA_PATH, split='train' if is_train else 'val', transform=transform)@dataset = datasets.ImageFolder(os.path.join(config.DATA.DATA_PATH, prefix), transform=transform)@" data/build.py + python3 -m torch.distributed.launch --nproc_per_node 8 --master_port 12349 main_repmlp.py --arch RepMLPNet-B256 --batch-size 32 --tag my_experiment --opts TRAIN.EPOCHS 100 TRAIN.BASE_LR 0.001 TRAIN.WEIGHT_DECAY 0.1 TRAIN.OPTIMIZER.NAME adamw TRAIN.OPTIMIZER.MOMENTUM 0.9 TRAIN.WARMUP_LR 5e-7 TRAIN.MIN_LR 0.0 TRAIN.WARMUP_EPOCHS 10 AUG.PRESET raug15 AUG.MIXUP 0.4 AUG.CUTMIX 1.0 DATA.IMG_SIZE 256 --data-path [/path/to/imagenet] ``` diff --git a/cv/classification/repmlp/pytorch/config.py b/cv/classification/repmlp/pytorch/config.py deleted file mode 100644 index eb153be28..000000000 --- a/cv/classification/repmlp/pytorch/config.py +++ /dev/null @@ -1,215 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import yaml -from yacs.config import CfgNode as CN - -_C = CN() - -# Base config files -_C.BASE = [''] - -# ----------------------------------------------------------------------------- -# Data settings -# ----------------------------------------------------------------------------- -_C.DATA = CN() -# Batch size for a single GPU, could be overwritten by command line argument -_C.DATA.BATCH_SIZE = 128 -# Path to dataset, could be overwritten by command line argument -_C.DATA.DATA_PATH = '/path/to/imgnet/' - -# Dataset name -_C.DATA.DATASET = 'imagenet' -# Input image size -_C.DATA.IMG_SIZE = 224 -_C.DATA.TEST_SIZE = None -_C.DATA.TEST_BATCH_SIZE = None -# Interpolation to resize image (random, bilinear, bicubic) -_C.DATA.INTERPOLATION = 'bilinear' -# Use zipped dataset instead of folder dataset -# could be overwritten by command line argument -_C.DATA.ZIP_MODE = False -# Cache Data in Memory, could be overwritten by command line argument -_C.DATA.CACHE_MODE = 'part' -# Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU. -_C.DATA.PIN_MEMORY = True -# Number of data loading threads -_C.DATA.NUM_WORKERS = 8 - -# ----------------------------------------------------------------------------- -# Model settings -# ----------------------------------------------------------------------------- -_C.MODEL = CN() -# Model type -_C.MODEL.ARCH = 'RepMLPNet-B224' -# Checkpoint to resume, could be overwritten by command line argument -_C.MODEL.RESUME = '' -# Number of classes, overwritten in data preparation -_C.MODEL.NUM_CLASSES = 1000 -# Label Smoothing -_C.MODEL.LABEL_SMOOTHING = 0.1 - -# ----------------------------------------------------------------------------- -# Training settings -# ----------------------------------------------------------------------------- -_C.TRAIN = CN() -_C.TRAIN.START_EPOCH = 0 -_C.TRAIN.EPOCHS = 3 #100 -_C.TRAIN.WARMUP_EPOCHS = 10 -_C.TRAIN.WEIGHT_DECAY = 0.1 -_C.TRAIN.BASE_LR = 0.002 -_C.TRAIN.WARMUP_LR = 0.0 -_C.TRAIN.MIN_LR = 0.0 -# Clip gradient norm -_C.TRAIN.CLIP_GRAD = 5.0 -# Auto resume from latest checkpoint -_C.TRAIN.AUTO_RESUME = True -# Gradient accumulation steps -# could be overwritten by command line argument -_C.TRAIN.ACCUMULATION_STEPS = 0 -# Whether to use gradient checkpointing to save memory -# could be overwritten by command line argument -_C.TRAIN.USE_CHECKPOINT = False - -# LR scheduler -_C.TRAIN.LR_SCHEDULER = CN() -_C.TRAIN.LR_SCHEDULER.NAME = 'cosine' -# Epoch interval to decay LR, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_EPOCHS = 30 -# LR decay rate, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_RATE = 0.1 - -# Optimizer -_C.TRAIN.OPTIMIZER = CN() -_C.TRAIN.OPTIMIZER.NAME = 'adamw' -# Optimizer Epsilon -_C.TRAIN.OPTIMIZER.EPS = 1e-8 -# Optimizer Betas -_C.TRAIN.OPTIMIZER.BETAS = (0.9, 0.999) -# SGD momentum -_C.TRAIN.OPTIMIZER.MOMENTUM = 0.9 - -# For EMA model -_C.TRAIN.EMA_ALPHA = 0.0 -_C.TRAIN.EMA_UPDATE_PERIOD = 8 - -# ----------------------------------------------------------------------------- -# Augmentation settings -# ----------------------------------------------------------------------------- -_C.AUG = CN() -# Mixup alpha, mixup enabled if > 0 -_C.AUG.MIXUP = 0.0 -# Cutmix alpha, cutmix enabled if > 0 -_C.AUG.CUTMIX = 0.0 -# Cutmix min/max ratio, overrides alpha and enables cutmix if set -_C.AUG.CUTMIX_MINMAX = None -# Probability of performing mixup or cutmix when either/both is enabled -_C.AUG.MIXUP_PROB = 1.0 -# Probability of switching to cutmix when both mixup and cutmix enabled -_C.AUG.MIXUP_SWITCH_PROB = 0.5 -# How to apply mixup/cutmix params. Per "batch", "pair", or "elem" -_C.AUG.MIXUP_MODE = 'batch' - -_C.AUG.PRESET = None # If use AUG.PRESET (e.g., 'raug15'), use the pre-defined preprocessing, ignoring the following settings. -# Color jitter factor -_C.AUG.COLOR_JITTER = 0.4 -# Use AutoAugment policy. "v0" or "original" -_C.AUG.AUTO_AUGMENT = 'rand-m9-mstd0.5-inc1' -# Random erase prob -_C.AUG.REPROB = 0.25 -# Random erase mode -_C.AUG.REMODE = 'pixel' -# Random erase count -_C.AUG.RECOUNT = 1 - - -# ----------------------------------------------------------------------------- -# Testing settings -# ----------------------------------------------------------------------------- -_C.TEST = CN() -# Whether to use center crop when testing -_C.TEST.CROP = False - -# ----------------------------------------------------------------------------- -# Misc -# ----------------------------------------------------------------------------- -# Mixed precision opt level, if O0, no amp is used ('O0', 'O1', 'O2') -# overwritten by command line argument -_C.AMP_OPT_LEVEL = '' -# Path to output folder, overwritten by command line argument -_C.OUTPUT = '' -# Tag of experiment, overwritten by command line argument -_C.TAG = 'default' -# Frequency to save checkpoint -_C.SAVE_FREQ = 20 -# Frequency to logging info -_C.PRINT_FREQ = 10 -# Fixed random seed -_C.SEED = 0 -# Perform evaluation only, overwritten by command line argument -_C.EVAL_MODE = False -# Test throughput only, overwritten by command line argument -_C.THROUGHPUT_MODE = False -# local rank for DistributedDataParallel, given by command line argument -_C.LOCAL_RANK = 0 - - -def update_config(config, args): - config.defrost() - if args.opts: - config.merge_from_list(args.opts) - # merge from specific arguments - if args.arch: - config.MODEL.ARCH = args.arch - if args.batch_size: - config.DATA.BATCH_SIZE = args.batch_size - if args.data_path: - config.DATA.DATA_PATH = args.data_path - if args.zip: - config.DATA.ZIP_MODE = True - if args.cache_mode: - config.DATA.CACHE_MODE = args.cache_mode - if args.resume: - config.MODEL.RESUME = args.resume - if args.accumulation_steps: - config.TRAIN.ACCUMULATION_STEPS = args.accumulation_steps - if args.use_checkpoint: - config.TRAIN.USE_CHECKPOINT = True - if args.amp_opt_level: - config.AMP_OPT_LEVEL = args.amp_opt_level - if args.output: - config.OUTPUT = args.output - if args.tag: - config.TAG = args.tag - if args.eval: - config.EVAL_MODE = True - if args.throughput: - config.THROUGHPUT_MODE = True - - if config.DATA.TEST_SIZE is None: - config.DATA.TEST_SIZE = config.DATA.IMG_SIZE - if config.DATA.TEST_BATCH_SIZE is None: - config.DATA.TEST_BATCH_SIZE = config.DATA.BATCH_SIZE - # set local rank for distributed training - config.LOCAL_RANK = args.local_rank - # output folder - config.OUTPUT = os.path.join(config.OUTPUT, config.MODEL.ARCH, config.TAG) - config.freeze() - - -def get_config(args): - """Get a yacs CfgNode object with default values.""" - # Return a clone so that the defaults will not be altered - # This is for the "local variable" use pattern - config = _C.clone() - update_config(config, args) - - return config diff --git a/cv/classification/repmlp/pytorch/convert.py b/cv/classification/repmlp/pytorch/convert.py deleted file mode 100644 index 5fcb55809..000000000 --- a/cv/classification/repmlp/pytorch/convert.py +++ /dev/null @@ -1,33 +0,0 @@ -import argparse -import os -import torch -from repmlpnet import get_RepMLPNet_model - -parser = argparse.ArgumentParser(description='RepMLPNet Conversion') -parser.add_argument('load', metavar='LOAD', help='path to the source weights file') -parser.add_argument('save', metavar='SAVE', help='path to the target weights file') -parser.add_argument('-a', '--arch', metavar='ARCH', default='RepMLPNet-B224') - -def convert(): - args = parser.parse_args() - model = get_RepMLPNet_model(args.arch, deploy=False) - - if os.path.isfile(args.load): - print("=> loading checkpoint '{}'".format(args.load)) - checkpoint = torch.load(args.load, map_location='cpu') - if 'state_dict' in checkpoint: - checkpoint = checkpoint['state_dict'] - elif 'model' in checkpoint: - checkpoint = checkpoint['model'] - ckpt = {k.replace('module.', ''): v for k, v in checkpoint.items()} # strip the names - print(ckpt.keys()) - model.load_state_dict(ckpt) - else: - raise ValueError("=> no checkpoint found at '{}'".format(args.load)) - - model.locality_injection() - - torch.save(model.state_dict(), args.save) - -if __name__ == '__main__': - convert() \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/cutout.py b/cv/classification/repmlp/pytorch/cutout.py deleted file mode 100644 index 8592ffc08..000000000 --- a/cv/classification/repmlp/pytorch/cutout.py +++ /dev/null @@ -1,55 +0,0 @@ -import numpy as np - -class Cutout: - - def __init__(self, size=16) -> None: - self.size = size - - def _create_cutout_mask(self, img_height, img_width, num_channels, size): - """Creates a zero mask used for cutout of shape `img_height` x `img_width`. - Args: - img_height: Height of image cutout mask will be applied to. - img_width: Width of image cutout mask will be applied to. - num_channels: Number of channels in the image. - size: Size of the zeros mask. - Returns: - A mask of shape `img_height` x `img_width` with all ones except for a - square of zeros of shape `size` x `size`. This mask is meant to be - elementwise multiplied with the original image. Additionally returns - the `upper_coord` and `lower_coord` which specify where the cutout mask - will be applied. - """ - # assert img_height == img_width - - # Sample center where cutout mask will be applied - height_loc = np.random.randint(low=0, high=img_height) - width_loc = np.random.randint(low=0, high=img_width) - - size = int(size) - # Determine upper right and lower left corners of patch - upper_coord = (max(0, height_loc - size // 2), max(0, width_loc - size // 2)) - lower_coord = ( - min(img_height, height_loc + size // 2), - min(img_width, width_loc + size // 2), - ) - mask_height = lower_coord[0] - upper_coord[0] - mask_width = lower_coord[1] - upper_coord[1] - assert mask_height > 0 - assert mask_width > 0 - - mask = np.ones((img_height, img_width, num_channels)) - zeros = np.zeros((mask_height, mask_width, num_channels)) - mask[upper_coord[0]: lower_coord[0], upper_coord[1]: lower_coord[1], :] = zeros - return mask, upper_coord, lower_coord - - def __call__(self, pil_img): - pil_img = pil_img.copy() - img_height, img_width, num_channels = (*pil_img.size, 3) - _, upper_coord, lower_coord = self._create_cutout_mask( - img_height, img_width, num_channels, self.size - ) - pixels = pil_img.load() # create the pixel map - for i in range(upper_coord[0], lower_coord[0]): # for every col: - for j in range(upper_coord[1], lower_coord[1]): # For every row - pixels[i, j] = (125, 122, 113, 0) # set the colour accordingly - return pil_img \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/data/__init__.py b/cv/classification/repmlp/pytorch/data/__init__.py deleted file mode 100644 index 70c633ce6..000000000 --- a/cv/classification/repmlp/pytorch/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .build import build_loader \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/data/build.py b/cv/classification/repmlp/pytorch/data/build.py deleted file mode 100644 index de5f46294..000000000 --- a/cv/classification/repmlp/pytorch/data/build.py +++ /dev/null @@ -1,195 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Copyright (c) 2023, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- -import os -import torch -import numpy as np -import torch.distributed as dist -from torchvision import datasets, transforms -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data import Mixup -from timm.data import create_transform -try: - from timm.data.transforms import str_to_pil_interp as _pil_interp -except: - from timm.data.transforms import _pil_interp -from .cached_image_folder import CachedImageFolder -from .samplers import SubsetRandomSampler - - -def build_loader(config): - config.defrost() - dataset_train, config.MODEL.NUM_CLASSES = build_dataset(is_train=True, config=config) - config.freeze() - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build train dataset") - dataset_val, _ = build_dataset(is_train=False, config=config) - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build val dataset") - - num_tasks = dist.get_world_size() - global_rank = dist.get_rank() - if config.DATA.ZIP_MODE and config.DATA.CACHE_MODE == 'part': - indices = np.arange(dist.get_rank(), len(dataset_train), dist.get_world_size()) - sampler_train = SubsetRandomSampler(indices) - else: - sampler_train = torch.utils.data.DistributedSampler( - dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - - if dataset_val is None: - sampler_val = None - else: - indices = np.arange(dist.get_rank(), len(dataset_val), dist.get_world_size()) #TODO - sampler_val = SubsetRandomSampler(indices) - - data_loader_train = torch.utils.data.DataLoader( - dataset_train, sampler=sampler_train, - batch_size=config.DATA.BATCH_SIZE, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=True, - ) - - if dataset_val is None: - data_loader_val = None - else: - data_loader_val = torch.utils.data.DataLoader( - dataset_val, sampler=sampler_val, - batch_size=config.DATA.TEST_BATCH_SIZE, - shuffle=False, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=False - ) - - # setup mixup / cutmix - mixup_fn = None - mixup_active = config.AUG.MIXUP > 0 or config.AUG.CUTMIX > 0. or config.AUG.CUTMIX_MINMAX is not None - if mixup_active: - mixup_fn = Mixup( - mixup_alpha=config.AUG.MIXUP, cutmix_alpha=config.AUG.CUTMIX, cutmix_minmax=config.AUG.CUTMIX_MINMAX, - prob=config.AUG.MIXUP_PROB, switch_prob=config.AUG.MIXUP_SWITCH_PROB, mode=config.AUG.MIXUP_MODE, - label_smoothing=config.MODEL.LABEL_SMOOTHING, num_classes=config.MODEL.NUM_CLASSES) - - return dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn - - -def build_dataset(is_train, config): - if config.DATA.DATASET == 'imagenet': - transform = build_transform(is_train, config) - prefix = 'train' if is_train else 'val' - if config.DATA.ZIP_MODE: - ann_file = prefix + "_map.txt" - prefix = prefix + ".zip@/" - dataset = CachedImageFolder(config.DATA.DATA_PATH, ann_file, prefix, transform, - cache_mode=config.DATA.CACHE_MODE if is_train else 'part') - else: - # Data source on our machines. You will never need it. - nori_root = os.path.join('/home/dingxiaohan/ndp/', 'imagenet.train.nori.list' if is_train else 'imagenet.val.nori.list') - if os.path.exists(nori_root): - # Data source on our machines. You will never need it. - from nori_dataset import ImageNetNoriDataset - dataset = ImageNetNoriDataset(nori_root, transform=transform) - else: - import torchvision - print('use raw ImageNet data') - root = os.path.join(config.DATA.DATA_PATH, prefix) - dataset = datasets.ImageFolder(root, transform=transform) - nb_classes = 1000 - - elif config.DATA.DATASET == 'cf100': - mean = [0.5070751592371323, 0.48654887331495095, 0.4409178433670343] - std = [0.2673342858792401, 0.2564384629170883, 0.27615047132568404] - if is_train: - transform = transforms.Compose([ - transforms.RandomCrop(32, padding=4), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - transforms.Normalize(mean, std) - ]) - dataset = datasets.CIFAR100(root=config.DATA.DATA_PATH, train=True, download=True, transform=transform) - else: - transform = transforms.Compose( - [transforms.ToTensor(), - transforms.Normalize(mean, std)]) - dataset = datasets.CIFAR100(root=config.DATA.DATA_PATH, train=False, download=True, transform=transform) - nb_classes = 100 - - else: - raise NotImplementedError("We only support ImageNet and CIFAR-100 now.") - - return dataset, nb_classes - - -def build_transform(is_train, config): - resize_im = config.DATA.IMG_SIZE > 32 - if is_train: - # this should always dispatch to transforms_imagenet_train - - if config.AUG.PRESET is None: - transform = create_transform( - input_size=config.DATA.IMG_SIZE, - is_training=True, - color_jitter=config.AUG.COLOR_JITTER if config.AUG.COLOR_JITTER > 0 else None, - auto_augment=config.AUG.AUTO_AUGMENT if config.AUG.AUTO_AUGMENT != 'none' else None, - re_prob=config.AUG.REPROB, - re_mode=config.AUG.REMODE, - re_count=config.AUG.RECOUNT, - interpolation=config.DATA.INTERPOLATION, - ) - print('=============================== original AUG! ', config.AUG.AUTO_AUGMENT) - if not resize_im: - # replace RandomResizedCropAndInterpolation with - # RandomCrop - transform.transforms[0] = transforms.RandomCrop(config.DATA.IMG_SIZE, padding=4) - - elif config.AUG.PRESET.strip() == 'raug15': - from randaug import RandAugPolicy - transform = transforms.Compose([ - transforms.RandomResizedCrop(config.DATA.IMG_SIZE), - transforms.RandomHorizontalFlip(), - RandAugPolicy(magnitude=15), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - print('---------------------- RAND AUG 15 distortion!') - elif config.AUG.PRESET.strip() == 'weak': - transform = transforms.Compose([ - transforms.RandomResizedCrop(config.DATA.IMG_SIZE), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - elif config.AUG.PRESET.strip() == 'none': - transform = transforms.Compose([ - transforms.Resize(config.DATA.IMG_SIZE, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - transforms.CenterCrop(config.DATA.IMG_SIZE), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - else: - raise ValueError('???' + config.AUG.PRESET) - print(transform) - return transform - - t = [] - if resize_im: - if config.TEST.CROP: - size = int((256 / 224) * config.DATA.TEST_SIZE) - t.append(transforms.Resize(size, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - # to maintain same ratio w.r.t. 224 images - ) - t.append(transforms.CenterCrop(config.DATA.TEST_SIZE)) - else: - # default for testing - t.append(transforms.Resize(config.DATA.TEST_SIZE, interpolation=_pil_interp(config.DATA.INTERPOLATION))) - t.append(transforms.CenterCrop(config.DATA.TEST_SIZE)) - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - trans = transforms.Compose(t) - return trans diff --git a/cv/classification/repmlp/pytorch/data/cached_image_folder.py b/cv/classification/repmlp/pytorch/data/cached_image_folder.py deleted file mode 100644 index 94fcde30a..000000000 --- a/cv/classification/repmlp/pytorch/data/cached_image_folder.py +++ /dev/null @@ -1,252 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import io -import os -import time -import torch.distributed as dist -import torch.utils.data as data -from PIL import Image - -from .zipreader import is_zip_path, ZipReader - - -def has_file_allowed_extension(filename, extensions): - """Checks if a file is an allowed extension. - Args: - filename (string): path to a file - Returns: - bool: True if the filename ends with a known image extension - """ - filename_lower = filename.lower() - return any(filename_lower.endswith(ext) for ext in extensions) - - -def find_classes(dir): - classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))] - classes.sort() - class_to_idx = {classes[i]: i for i in range(len(classes))} - return classes, class_to_idx - - -def make_dataset(dir, class_to_idx, extensions): - images = [] - dir = os.path.expanduser(dir) - for target in sorted(os.listdir(dir)): - d = os.path.join(dir, target) - if not os.path.isdir(d): - continue - - for root, _, fnames in sorted(os.walk(d)): - for fname in sorted(fnames): - if has_file_allowed_extension(fname, extensions): - path = os.path.join(root, fname) - item = (path, class_to_idx[target]) - images.append(item) - - return images - - -def make_dataset_with_ann(ann_file, img_prefix, extensions): - images = [] - with open(ann_file, "r") as f: - contents = f.readlines() - for line_str in contents: - path_contents = [c for c in line_str.split('\t')] - im_file_name = path_contents[0] - class_index = int(path_contents[1]) - - assert str.lower(os.path.splitext(im_file_name)[-1]) in extensions - item = (os.path.join(img_prefix, im_file_name), class_index) - - images.append(item) - - return images - - -class DatasetFolder(data.Dataset): - """A generic data loader where the samples are arranged in this way: :: - root/class_x/xxx.ext - root/class_x/xxy.ext - root/class_x/xxz.ext - root/class_y/123.ext - root/class_y/nsdf3.ext - root/class_y/asd932_.ext - Args: - root (string): Root directory path. - loader (callable): A function to load a sample given its path. - extensions (list[string]): A list of allowed extensions. - transform (callable, optional): A function/transform that takes in - a sample and returns a transformed version. - E.g, ``transforms.RandomCrop`` for images. - target_transform (callable, optional): A function/transform that takes - in the target and transforms it. - Attributes: - samples (list): List of (sample path, class_index) tuples - """ - - def __init__(self, root, loader, extensions, ann_file='', img_prefix='', transform=None, target_transform=None, - cache_mode="no"): - # image folder mode - if ann_file == '': - _, class_to_idx = find_classes(root) - samples = make_dataset(root, class_to_idx, extensions) - # zip mode - else: - samples = make_dataset_with_ann(os.path.join(root, ann_file), - os.path.join(root, img_prefix), - extensions) - - if len(samples) == 0: - raise (RuntimeError("Found 0 files in subfolders of: " + root + "\n" + - "Supported extensions are: " + ",".join(extensions))) - - self.root = root - self.loader = loader - self.extensions = extensions - - self.samples = samples - self.labels = [y_1k for _, y_1k in samples] - self.classes = list(set(self.labels)) - - self.transform = transform - self.target_transform = target_transform - - self.cache_mode = cache_mode - if self.cache_mode != "no": - self.init_cache() - - def init_cache(self): - assert self.cache_mode in ["part", "full"] - n_sample = len(self.samples) - global_rank = dist.get_rank() - world_size = dist.get_world_size() - - samples_bytes = [None for _ in range(n_sample)] - start_time = time.time() - for index in range(n_sample): - if index % (n_sample // 10) == 0: - t = time.time() - start_time - print(f'global_rank {dist.get_rank()} cached {index}/{n_sample} takes {t:.2f}s per block') - start_time = time.time() - path, target = self.samples[index] - if self.cache_mode == "full": - samples_bytes[index] = (ZipReader.read(path), target) - elif self.cache_mode == "part" and index % world_size == global_rank: - samples_bytes[index] = (ZipReader.read(path), target) - else: - samples_bytes[index] = (path, target) - self.samples = samples_bytes - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (sample, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - sample = self.loader(path) - if self.transform is not None: - sample = self.transform(sample) - if self.target_transform is not None: - target = self.target_transform(target) - - return sample, target - - def __len__(self): - return len(self.samples) - - def __repr__(self): - fmt_str = 'Dataset ' + self.__class__.__name__ + '\n' - fmt_str += ' Number of datapoints: {}\n'.format(self.__len__()) - fmt_str += ' Root Location: {}\n'.format(self.root) - tmp = ' Transforms (if any): ' - fmt_str += '{0}{1}\n'.format(tmp, self.transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - tmp = ' Target Transforms (if any): ' - fmt_str += '{0}{1}'.format(tmp, self.target_transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - return fmt_str - - -IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif'] - - -def pil_loader(path): - # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835) - if isinstance(path, bytes): - img = Image.open(io.BytesIO(path)) - elif is_zip_path(path): - data = ZipReader.read(path) - img = Image.open(io.BytesIO(data)) - else: - with open(path, 'rb') as f: - img = Image.open(f) - return img.convert('RGB') - - -def accimage_loader(path): - import accimage - try: - return accimage.Image(path) - except IOError: - # Potentially a decoding problem, fall back to PIL.Image - return pil_loader(path) - - -def default_img_loader(path): - from torchvision import get_image_backend - if get_image_backend() == 'accimage': - return accimage_loader(path) - else: - return pil_loader(path) - - -class CachedImageFolder(DatasetFolder): - """A generic data loader where the images are arranged in this way: :: - root/dog/xxx.png - root/dog/xxy.png - root/dog/xxz.png - root/cat/123.png - root/cat/nsdf3.png - root/cat/asd932_.png - Args: - root (string): Root directory path. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - loader (callable, optional): A function to load an image given its path. - Attributes: - imgs (list): List of (image path, class_index) tuples - """ - - def __init__(self, root, ann_file='', img_prefix='', transform=None, target_transform=None, - loader=default_img_loader, cache_mode="no"): - super(CachedImageFolder, self).__init__(root, loader, IMG_EXTENSIONS, - ann_file=ann_file, img_prefix=img_prefix, - transform=transform, target_transform=target_transform, - cache_mode=cache_mode) - self.imgs = self.samples - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (image, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - image = self.loader(path) - if self.transform is not None: - img = self.transform(image) - else: - img = image - if self.target_transform is not None: - target = self.target_transform(target) - - return img, target diff --git a/cv/classification/repmlp/pytorch/data/samplers.py b/cv/classification/repmlp/pytorch/data/samplers.py deleted file mode 100644 index 738da77f6..000000000 --- a/cv/classification/repmlp/pytorch/data/samplers.py +++ /dev/null @@ -1,30 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import torch - - -class SubsetRandomSampler(torch.utils.data.Sampler): - r"""Samples elements randomly from a given list of indices, without replacement. - - Arguments: - indices (sequence): a sequence of indices - """ - - def __init__(self, indices): - self.epoch = 0 - self.indices = indices - - def __iter__(self): - return (self.indices[i] for i in torch.randperm(len(self.indices))) - - def __len__(self): - return len(self.indices) - - def set_epoch(self, epoch): - self.epoch = epoch diff --git a/cv/classification/repmlp/pytorch/data/zipreader.py b/cv/classification/repmlp/pytorch/data/zipreader.py deleted file mode 100644 index 2476fdc2c..000000000 --- a/cv/classification/repmlp/pytorch/data/zipreader.py +++ /dev/null @@ -1,104 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import zipfile -import io -import numpy as np -from PIL import Image -from PIL import ImageFile - -ImageFile.LOAD_TRUNCATED_IMAGES = True - - -def is_zip_path(img_or_path): - """judge if this is a zip path""" - return '.zip@' in img_or_path - - -class ZipReader(object): - """A class to read zipped files""" - zip_bank = dict() - - def __init__(self): - super(ZipReader, self).__init__() - - @staticmethod - def get_zipfile(path): - zip_bank = ZipReader.zip_bank - if path not in zip_bank: - zfile = zipfile.ZipFile(path, 'r') - zip_bank[path] = zfile - return zip_bank[path] - - @staticmethod - def split_zip_style_path(path): - pos_at = path.index('@') - assert pos_at != -1, "character '@' is not found from the given path '%s'" % path - - zip_path = path[0: pos_at] - folder_path = path[pos_at + 1:] - folder_path = str.strip(folder_path, '/') - return zip_path, folder_path - - @staticmethod - def list_folder(path): - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - folder_list = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - len(os.path.splitext(file_foler_name)[-1]) == 0 and \ - file_foler_name != folder_path: - if len(folder_path) == 0: - folder_list.append(file_foler_name) - else: - folder_list.append(file_foler_name[len(folder_path) + 1:]) - - return folder_list - - @staticmethod - def list_files(path, extension=None): - if extension is None: - extension = ['.*'] - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - file_lists = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - str.lower(os.path.splitext(file_foler_name)[-1]) in extension: - if len(folder_path) == 0: - file_lists.append(file_foler_name) - else: - file_lists.append(file_foler_name[len(folder_path) + 1:]) - - return file_lists - - @staticmethod - def read(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - return data - - @staticmethod - def imread(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - try: - im = Image.open(io.BytesIO(data)) - except: - print("ERROR IMG LOADED: ", path_img) - random_img = np.random.rand(224, 224, 3) * 255 - im = Image.fromarray(np.uint8(random_img)) - return im diff --git a/cv/classification/repmlp/pytorch/logger.py b/cv/classification/repmlp/pytorch/logger.py deleted file mode 100644 index b08e312c0..000000000 --- a/cv/classification/repmlp/pytorch/logger.py +++ /dev/null @@ -1,42 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import sys -import logging -import functools -from termcolor import colored - - -@functools.lru_cache() -def create_logger(output_dir, dist_rank=0, name=''): - # create logger - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.propagate = False - - # create formatter - fmt = '[%(asctime)s %(name)s] (%(filename)s %(lineno)d): %(levelname)s %(message)s' - color_fmt = colored('[%(asctime)s %(name)s]', 'green') + \ - colored('(%(filename)s %(lineno)d)', 'yellow') + ': %(levelname)s %(message)s' - - # create console handlers for master process - if dist_rank == 0: - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setLevel(logging.DEBUG) - console_handler.setFormatter( - logging.Formatter(fmt=color_fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(console_handler) - - # create file handlers - file_handler = logging.FileHandler(os.path.join(output_dir, f'log_rank{dist_rank}.txt'), mode='a') - file_handler.setLevel(logging.DEBUG) - file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(file_handler) - - return logger diff --git a/cv/classification/repmlp/pytorch/lr_scheduler.py b/cv/classification/repmlp/pytorch/lr_scheduler.py deleted file mode 100644 index 490e32f32..000000000 --- a/cv/classification/repmlp/pytorch/lr_scheduler.py +++ /dev/null @@ -1,102 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import torch -from timm.scheduler.cosine_lr import CosineLRScheduler -from timm.scheduler.step_lr import StepLRScheduler -from timm.scheduler.scheduler import Scheduler - - -def build_scheduler(config, optimizer, n_iter_per_epoch): - num_steps = int(config.TRAIN.EPOCHS * n_iter_per_epoch) - warmup_steps = int(config.TRAIN.WARMUP_EPOCHS * n_iter_per_epoch) - decay_steps = int(config.TRAIN.LR_SCHEDULER.DECAY_EPOCHS * n_iter_per_epoch) - - lr_scheduler = None - if config.TRAIN.LR_SCHEDULER.NAME == 'cosine': - lr_scheduler = CosineLRScheduler( - optimizer, - t_initial=num_steps, - lr_min=config.TRAIN.MIN_LR, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - cycle_limit=1, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'linear': - lr_scheduler = LinearLRScheduler( - optimizer, - t_initial=num_steps, - lr_min_rate=0.01, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'step': - lr_scheduler = StepLRScheduler( - optimizer, - decay_t=decay_steps, - decay_rate=config.TRAIN.LR_SCHEDULER.DECAY_RATE, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - - return lr_scheduler - - -class LinearLRScheduler(Scheduler): - def __init__(self, - optimizer: torch.optim.Optimizer, - t_initial: int, - lr_min_rate: float, - warmup_t=0, - warmup_lr_init=0., - t_in_epochs=True, - noise_range_t=None, - noise_pct=0.67, - noise_std=1.0, - noise_seed=42, - initialize=True, - ) -> None: - super().__init__( - optimizer, param_group_field="lr", - noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, - initialize=initialize) - - self.t_initial = t_initial - self.lr_min_rate = lr_min_rate - self.warmup_t = warmup_t - self.warmup_lr_init = warmup_lr_init - self.t_in_epochs = t_in_epochs - if self.warmup_t: - self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] - super().update_groups(self.warmup_lr_init) - else: - self.warmup_steps = [1 for _ in self.base_values] - - def _get_lr(self, t): - if t < self.warmup_t: - lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] - else: - t = t - self.warmup_t - total_t = self.t_initial - self.warmup_t - lrs = [v - ((v - v * self.lr_min_rate) * (t / total_t)) for v in self.base_values] - return lrs - - def get_epoch_values(self, epoch: int): - if self.t_in_epochs: - return self._get_lr(epoch) - else: - return None - - def get_update_values(self, num_updates: int): - if not self.t_in_epochs: - return self._get_lr(num_updates) - else: - return None diff --git a/cv/classification/repmlp/pytorch/main_repmlp.py b/cv/classification/repmlp/pytorch/main_repmlp.py deleted file mode 100644 index b553fb607..000000000 --- a/cv/classification/repmlp/pytorch/main_repmlp.py +++ /dev/null @@ -1,417 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- -import time -import argparse -import datetime -import numpy as np -import torch -import torch.backends.cudnn as cudnn -import torch.distributed as dist -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.utils import accuracy, AverageMeter -from config import get_config -from data import build_loader -from lr_scheduler import build_scheduler -from logger import create_logger -from utils import load_checkpoint, save_checkpoint, get_grad_norm, auto_resume_helper, reduce_tensor, save_latest, update_model_ema, unwrap_model, load_weights -import copy -from optimizer import build_optimizer -from repmlpnet import get_RepMLPNet_model - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - - -def parse_option(): - parser = argparse.ArgumentParser('RepOpt-VGG training script built on the codebase of Swin Transformer', add_help=False) - parser.add_argument( - "--opts", - help="Modify config options by adding 'KEY VALUE' pairs. ", - default=None, - nargs='+', - ) - - # easy config modification - parser.add_argument('--arch', default=None, type=str, help='arch name') - parser.add_argument('--batch-size', default=128, type=int, help="batch size for single GPU") - parser.add_argument('--data-path', default='/path/to/imgnet/', type=str, help='path to dataset') - parser.add_argument('--zip', action='store_true', help='use zipped dataset instead of folder dataset') - parser.add_argument('--cache-mode', type=str, default='part', choices=['no', 'full', 'part'], - help='no: no cache, ' - 'full: cache all data, ' - 'part: sharding the dataset into nonoverlapping pieces and only cache one piece') - parser.add_argument('--resume', help='resume from checkpoint') - parser.add_argument('--accumulation-steps', type=int, help="gradient accumulation steps") - parser.add_argument('--use-checkpoint', action='store_true', - help="whether to use gradient checkpointing to save memory") - parser.add_argument('--amp-opt-level', type=str, default='O0', choices=['O0', 'O1', 'O2'], #TODO Note: use amp if you have it - help='mixed precision opt level, if O0, no amp is used') - parser.add_argument('--output', default='output', type=str, metavar='PATH', - help='root of output folder, the full path is // (default: output)') - parser.add_argument('--tag', help='tag of experiment') - parser.add_argument('--eval', action='store_true', help='Perform evaluation only') - parser.add_argument('--throughput', action='store_true', help='Test throughput only') - - # distributed training - parser.add_argument("--local_rank", type=int, default=0, help='local rank for DistributedDataParallel') - - args, unparsed = parser.parse_known_args() - - config = get_config(args) - - return args, config - - - - -def main(config): - dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn = build_loader(config) - - logger.info(f"Creating model:{config.MODEL.ARCH}") - - model = get_RepMLPNet_model(config.MODEL.ARCH, deploy=False) - - optimizer = build_optimizer(config, model) - - model.cuda() - - if torch.cuda.device_count() > 1: - if config.AMP_OPT_LEVEL != "O0": - model, optimizer = amp.initialize(model, optimizer, opt_level=config.AMP_OPT_LEVEL) - model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.LOCAL_RANK], - broadcast_buffers=False) - model_without_ddp = model.module - else: - if config.AMP_OPT_LEVEL != "O0": - model, optimizer = amp.initialize(model, optimizer, opt_level=config.AMP_OPT_LEVEL) - model_without_ddp = model - - n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params: {n_parameters}") - if hasattr(model_without_ddp, 'flops'): - flops = model_without_ddp.flops() - logger.info(f"number of GFLOPs: {flops / 1e9}") - - if config.THROUGHPUT_MODE: - throughput(data_loader_val, model, logger) - return - - if config.EVAL_MODE: - load_weights(model, config.MODEL.RESUME) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Only eval. top-1 acc, top-5 acc, loss: {acc1:.3f}, {acc5:.3f}, {loss:.5f}") - return - - - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train)) - - if config.AUG.MIXUP > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif config.MODEL.LABEL_SMOOTHING > 0.: - criterion = LabelSmoothingCrossEntropy(smoothing=config.MODEL.LABEL_SMOOTHING) - else: - criterion = torch.nn.CrossEntropyLoss() - - - - max_accuracy = 0.0 - max_ema_accuracy = 0.0 - - if config.TRAIN.EMA_ALPHA > 0 and (not config.EVAL_MODE) and (not config.THROUGHPUT_MODE): - model_ema = copy.deepcopy(model) - else: - model_ema = None - - if config.TRAIN.AUTO_RESUME: - resume_file = auto_resume_helper(config.OUTPUT) - if resume_file: - if config.MODEL.RESUME: - logger.warning(f"auto-resume changing resume file from {config.MODEL.RESUME} to {resume_file}") - config.defrost() - config.MODEL.RESUME = resume_file - config.freeze() - logger.info(f'auto resuming from {resume_file}') - else: - logger.info(f'no checkpoint found in {config.OUTPUT}, ignoring auto resume') - - if (not config.THROUGHPUT_MODE) and config.MODEL.RESUME: - max_accuracy = load_checkpoint(config, model_without_ddp, optimizer, lr_scheduler, logger, model_ema=model_ema) - - - - logger.info("Start training") - start_time = time.time() - for epoch in range(config.TRAIN.START_EPOCH, config.TRAIN.EPOCHS): - data_loader_train.sampler.set_epoch(epoch) - - train_one_epoch(config, model, criterion, data_loader_train, optimizer, epoch, mixup_fn, lr_scheduler, model_ema=model_ema) - if dist.get_rank() == 0: - save_latest(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, model_ema=model_ema) - if epoch % config.SAVE_FREQ == 0: - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, model_ema=model_ema) - - if epoch % config.SAVE_FREQ == 0 or epoch >= (config.TRAIN.EPOCHS - 10): - - if data_loader_val is not None: - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network at epoch {epoch}: {acc1:.3f}%") - max_accuracy = max(max_accuracy, acc1) - logger.info(f'Max accuracy: {max_accuracy:.2f}%') - if max_accuracy == acc1 and dist.get_rank() == 0: - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, - is_best=True, model_ema=model_ema) - - if model_ema is not None: - if data_loader_val is not None: - acc1, acc5, loss = validate(config, data_loader_val, model_ema) - logger.info(f"EMAAccuracy of the network at epoch {epoch} test images: {acc1:.3f}%") - max_ema_accuracy = max(max_ema_accuracy, acc1) - logger.info(f'EMAMax accuracy: {max_ema_accuracy:.2f}%') - if max_ema_accuracy == acc1 and dist.get_rank() == 0: - best_ema_path = os.path.join(config.OUTPUT, 'best_ema.pth') - logger.info(f"{best_ema_path} best EMA saving......") - torch.save(unwrap_model(model_ema).state_dict(), best_ema_path) - else: - latest_ema_path = os.path.join(config.OUTPUT, 'latest_ema.pth') - logger.info(f"{latest_ema_path} latest EMA saving......") - torch.save(unwrap_model(model_ema).state_dict(), latest_ema_path) - - total_time = time.time() - start_time - total_time_str = str(datetime.timedelta(seconds=int(total_time))) - logger.info('Training time {}'.format(total_time_str)) - - -def train_one_epoch(config, model, criterion, data_loader, optimizer, epoch, mixup_fn, lr_scheduler, model_ema=None): - model.train() - optimizer.zero_grad() - - num_steps = len(data_loader) - batch_time = AverageMeter() - loss_meter = AverageMeter() - norm_meter = AverageMeter() - - start = time.time() - end = time.time() - for idx, (samples, targets) in enumerate(data_loader): - samples = samples.cuda(non_blocking=True) - targets = targets.cuda(non_blocking=True) - - if mixup_fn is not None: - samples, targets = mixup_fn(samples, targets) - - outputs = model(samples) - - if config.TRAIN.ACCUMULATION_STEPS > 1: - - loss = criterion(outputs, targets) - loss = loss / config.TRAIN.ACCUMULATION_STEPS - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - if (idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0: - optimizer.step() - optimizer.zero_grad() - lr_scheduler.step_update(epoch * num_steps + idx) - - else: - if type(outputs) is dict: - loss = 0.0 - for name, pred in outputs.items(): - if 'aux' in name: - loss += 0.1 * criterion(pred, targets) - else: - loss += criterion(pred, targets) - else: - loss = criterion(outputs, targets) - - optimizer.zero_grad() - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - optimizer.step() - lr_scheduler.step_update(epoch * num_steps + idx) - - torch.cuda.synchronize() - - loss_meter.update(loss.item(), targets.size(0)) - norm_meter.update(grad_norm) - batch_time.update(time.time() - end) - - if model_ema is not None: - update_model_ema(config, dist.get_world_size(), model=model, model_ema=model_ema, cur_epoch=epoch, cur_iter=idx) - - end = time.time() - - if idx % config.PRINT_FREQ == 0: - lr = optimizer.param_groups[0]['lr'] - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - etas = batch_time.avg * (num_steps - idx) - logger.info( - f'Train: [{epoch}/{config.TRAIN.EPOCHS}][{idx}/{num_steps}]\t' - f'eta {datetime.timedelta(seconds=int(etas))} lr {lr:.6f}\t' - f'time {batch_time.val:.4f} ({batch_time.avg:.4f})\t' - f'loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'grad_norm {norm_meter.val:.4f} ({norm_meter.avg:.4f})\t' - f'mem {memory_used:.0f}MB') - epoch_time = time.time() - start - logger.info(f"EPOCH {epoch} training takes {datetime.timedelta(seconds=int(epoch_time))}") - - -@torch.no_grad() -def validate(config, data_loader, model): - criterion = torch.nn.CrossEntropyLoss() - model.eval() - - batch_time = AverageMeter() - loss_meter = AverageMeter() - acc1_meter = AverageMeter() - acc5_meter = AverageMeter() - - end = time.time() - for idx, (images, target) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - output = model(images) - - if type(output) is dict: - output = output['main'] - - # measure accuracy and record loss - loss = criterion(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - acc1 = reduce_tensor(acc1) - acc5 = reduce_tensor(acc5) - loss = reduce_tensor(loss) - - loss_meter.update(loss.item(), target.size(0)) - acc1_meter.update(acc1.item(), target.size(0)) - acc5_meter.update(acc5.item(), target.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - logger.info( - f'Test: [{idx}/{len(data_loader)}]\t' - f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' - f'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' - f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' - f'Mem {memory_used:.0f}MB') - logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') - return acc1_meter.avg, acc5_meter.avg, loss_meter.avg - - -@torch.no_grad() -def throughput(data_loader, model, logger): - model.eval() - - for idx, (images, _) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - - batch_size = images.shape[0] - for i in range(50): - model(images) - torch.cuda.synchronize() - logger.info(f"throughput averaged with 30 times") - tic1 = time.time() - for i in range(30): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - throughput = 30 * batch_size / (tic2 - tic1) - logger.info(f"batch_size {batch_size} throughput {throughput}") - return - - -import os - -if __name__ == '__main__': - args, config = parse_option() - - if config.AMP_OPT_LEVEL != "O0": - assert amp is not None, "amp not installed!" - - if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ: - rank = int(os.environ["RANK"]) - world_size = int(os.environ['WORLD_SIZE']) - else: - rank = -1 - world_size = -1 - torch.cuda.set_device(config.LOCAL_RANK) - torch.distributed.init_process_group(backend='nccl', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.barrier() - seed = config.SEED + dist.get_rank() - - torch.manual_seed(seed) - np.random.seed(seed) - cudnn.benchmark = True - - if not config.EVAL_MODE: - # linear scale the learning rate according to total batch size, may not be optimal - linear_scaled_lr = config.TRAIN.BASE_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - linear_scaled_warmup_lr = config.TRAIN.WARMUP_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - linear_scaled_min_lr = config.TRAIN.MIN_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - # gradient accumulation also need to scale the learning rate - if config.TRAIN.ACCUMULATION_STEPS > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_warmup_lr = linear_scaled_warmup_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_min_lr = linear_scaled_min_lr * config.TRAIN.ACCUMULATION_STEPS - config.defrost() - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_LR = linear_scaled_warmup_lr - config.TRAIN.MIN_LR = linear_scaled_min_lr - config.freeze() - - print('==========================================') - print('real base lr: ', config.TRAIN.BASE_LR) - print('==========================================') - - os.makedirs(config.OUTPUT, exist_ok=True) - - logger = create_logger(output_dir=config.OUTPUT, dist_rank=0 if torch.cuda.device_count() == 1 else dist.get_rank(), name=f"{config.MODEL.ARCH}") - - if torch.cuda.device_count() == 1 or dist.get_rank() == 0: - path = os.path.join(config.OUTPUT, "config.json") - with open(path, "w") as f: - f.write(config.dump()) - logger.info(f"Full config saved to {path}") - - # print config - logger.info(config.dump()) - - main(config) diff --git a/cv/classification/repmlp/pytorch/optimizer.py b/cv/classification/repmlp/pytorch/optimizer.py deleted file mode 100644 index a43e321c6..000000000 --- a/cv/classification/repmlp/pytorch/optimizer.py +++ /dev/null @@ -1,68 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -from torch import optim as optim - - -def build_optimizer(config, model): - """ - Build optimizer, set weight decay of normalization to 0 by default. - """ - skip = {} - skip_keywords = {} - if hasattr(model, 'no_weight_decay'): - skip = model.no_weight_decay() - if hasattr(model, 'no_weight_decay_keywords'): - skip_keywords = model.no_weight_decay_keywords() - echo = (config.LOCAL_RANK==0) - parameters = set_weight_decay(model, skip, skip_keywords, echo=echo) - opt_lower = config.TRAIN.OPTIMIZER.NAME.lower() - optimizer = None - if opt_lower == 'sgd': - optimizer = optim.SGD(parameters, momentum=config.TRAIN.OPTIMIZER.MOMENTUM, nesterov=True, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - if echo: - print('================================== SGD nest, momentum = {}, wd = {}'.format(config.TRAIN.OPTIMIZER.MOMENTUM, config.TRAIN.WEIGHT_DECAY)) - elif opt_lower == 'adamw': - optimizer = optim.AdamW(parameters, eps=config.TRAIN.OPTIMIZER.EPS, betas=config.TRAIN.OPTIMIZER.BETAS, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - - return optimizer - - -def set_weight_decay(model, skip_list=(), skip_keywords=(), echo=False): - has_decay = [] - no_decay = [] - - for name, param in model.named_parameters(): - if not param.requires_grad: - continue # frozen weights - if 'identity.weight' in name: - has_decay.append(param) - if echo: - print(f"{name} USE weight decay") - elif len(param.shape) == 1 or name.endswith(".bias") or (name in skip_list) or \ - check_keywords_in_name(name, skip_keywords): - no_decay.append(param) - if echo: - print(f"{name} has no weight decay") - else: - has_decay.append(param) - if echo: - print(f"{name} USE weight decay") - - return [{'params': has_decay}, - {'params': no_decay, 'weight_decay': 0.}] - - -def check_keywords_in_name(name, keywords=()): - isin = False - for keyword in keywords: - if keyword in name: - isin = True - return isin diff --git a/cv/classification/repmlp/pytorch/randaug.py b/cv/classification/repmlp/pytorch/randaug.py deleted file mode 100644 index 31600c33a..000000000 --- a/cv/classification/repmlp/pytorch/randaug.py +++ /dev/null @@ -1,407 +0,0 @@ -import math -import random - -import numpy as np -import PIL -from PIL import Image, ImageEnhance, ImageOps - -from cutout import Cutout - - -_PIL_VER = tuple([int(x) for x in PIL.__version__.split('.')[:2]]) - -_FILL = (128, 128, 128) - -# This signifies the max integer that the controller RNN could predict for the -# augmentation scheme. -_MAX_LEVEL = 10. - -_HPARAMS_DEFAULT = dict( - translate_const=250, - img_mean=_FILL, -) - -_RANDOM_INTERPOLATION = (Image.BILINEAR, Image.BICUBIC) - - -def _interpolation(kwargs): - interpolation = kwargs.pop('resample', Image.BILINEAR) - if isinstance(interpolation, (list, tuple)): - return random.choice(interpolation) - else: - return interpolation - - -def _check_args_tf(kwargs): - if 'fillcolor' in kwargs and _PIL_VER < (5, 0): - kwargs.pop('fillcolor') - kwargs['resample'] = _interpolation(kwargs) - - -def cutout(img, factor, **kwargs): - _check_args_tf(kwargs) - return Cutout(size=factor)(img) - - -def shear_x(img, factor, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, factor, 0, 0, 1, 0), **kwargs) - - -def shear_y(img, factor, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, factor, 1, 0), **kwargs) - - -def translate_x_rel(img, pct, **kwargs): - pixels = pct * img.size[0] - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, pixels, 0, 1, 0), **kwargs) - - -def translate_y_rel(img, pct, **kwargs): - pixels = pct * img.size[1] - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, pixels), **kwargs) - - -def translate_x_abs(img, pixels, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, pixels, 0, 1, 0), **kwargs) - - -def translate_y_abs(img, pixels, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, pixels), **kwargs) - - -def rotate(img, degrees, **kwargs): - _check_args_tf(kwargs) - if _PIL_VER >= (5, 2): - return img.rotate(degrees, **kwargs) - elif _PIL_VER >= (5, 0): - w, h = img.size - post_trans = (0, 0) - rotn_center = (w / 2.0, h / 2.0) - angle = -math.radians(degrees) - matrix = [ - round(math.cos(angle), 15), - round(math.sin(angle), 15), - 0.0, - round(-math.sin(angle), 15), - round(math.cos(angle), 15), - 0.0, - ] - - def transform(x, y, matrix): - (a, b, c, d, e, f) = matrix - return a * x + b * y + c, d * x + e * y + f - - matrix[2], matrix[5] = transform( - -rotn_center[0] - post_trans[0], - - rotn_center[1] - post_trans[1], matrix - ) - matrix[2] += rotn_center[0] - matrix[5] += rotn_center[1] - return img.transform(img.size, Image.AFFINE, matrix, **kwargs) - else: - return img.rotate(degrees, resample=kwargs['resample']) - - -def auto_contrast(img, **__): - return ImageOps.autocontrast(img) - - -def invert(img, **__): - return ImageOps.invert(img) - - -def identity(img, **__): - return img - - -def equalize(img, **__): - return ImageOps.equalize(img) - - -def solarize(img, thresh, **__): - return ImageOps.solarize(img, thresh) - - -def solarize_add(img, add, thresh=128, **__): - lut = [] - for i in range(256): - if i < thresh: - lut.append(min(255, i + add)) - else: - lut.append(i) - if img.mode in ("L", "RGB"): - if img.mode == "RGB" and len(lut) == 256: - lut = lut + lut + lut - return img.point(lut) - else: - return img - - -def posterize(img, bits_to_keep, **__): - if bits_to_keep >= 8: - return img - return ImageOps.posterize(img, bits_to_keep) - - -def contrast(img, factor, **__): - return ImageEnhance.Contrast(img).enhance(factor) - - -def color(img, factor, **__): - return ImageEnhance.Color(img).enhance(factor) - - -def brightness(img, factor, **__): - return ImageEnhance.Brightness(img).enhance(factor) - - -def sharpness(img, factor, **__): - return ImageEnhance.Sharpness(img).enhance(factor) - - -def _randomly_negate(v): - """With 50% prob, negate the value""" - return -v if random.random() > 0.5 else v - - -def _cutout_level_to_arg(level, _hparams): - # range [0, 40] - level = max(2, (level / _MAX_LEVEL) * 40.) - return level, - - -def _rotate_level_to_arg(level, _hparams): - # range [-30, 30] - level = (level / _MAX_LEVEL) * 30. - level = _randomly_negate(level) - return level, - - -def _enhance_level_to_arg(level, _hparams): - # range [0.1, 1.9] - return (level / _MAX_LEVEL) * 1.8 + 0.1, - - -def _shear_level_to_arg(level, _hparams): - # range [-0.3, 0.3] - level = (level / _MAX_LEVEL) * 0.3 - level = _randomly_negate(level) - return level, - - -def _translate_abs_level_to_arg(level, hparams): - translate_const = hparams['translate_const'] - level = (level / _MAX_LEVEL) * float(translate_const) - level = _randomly_negate(level) - return level, - - -def _translate_rel_level_to_arg(level, _hparams): - # range [-0.45, 0.45] - level = (level / _MAX_LEVEL) * 0.45 - level = _randomly_negate(level) - return level, - - -def _posterize_original_level_to_arg(level, _hparams): - # As per original AutoAugment paper description - # range [4, 8], 'keep 4 up to 8 MSB of image' - return int((level / _MAX_LEVEL) * 4) + 4, - - -def _posterize_research_level_to_arg(level, _hparams): - # As per Tensorflow models research and UDA impl - # range [4, 0], 'keep 4 down to 0 MSB of original image' - return 4 - int((level / _MAX_LEVEL) * 4), - - -def _posterize_tpu_level_to_arg(level, _hparams): - # As per Tensorflow TPU EfficientNet impl - # range [0, 4], 'keep 0 up to 4 MSB of original image' - return int((level / _MAX_LEVEL) * 4), - - -def _solarize_level_to_arg(level, _hparams): - # range [0, 256] - return int((level / _MAX_LEVEL) * 256), - - -def _solarize_add_level_to_arg(level, _hparams): - # range [0, 110] - return int((level / _MAX_LEVEL) * 110), - - -LEVEL_TO_ARG = { - 'AutoContrast': None, - 'Equalize': None, - 'Invert': None, - 'Identity': None, - 'Rotate': _rotate_level_to_arg, - 'PosterizeOriginal': _posterize_original_level_to_arg, - 'PosterizeResearch': _posterize_research_level_to_arg, - 'PosterizeTpu': _posterize_tpu_level_to_arg, - 'Solarize': _solarize_level_to_arg, - 'SolarizeAdd': _solarize_add_level_to_arg, - 'Color': _enhance_level_to_arg, - 'Contrast': _enhance_level_to_arg, - 'Brightness': _enhance_level_to_arg, - 'Sharpness': _enhance_level_to_arg, - 'ShearX': _shear_level_to_arg, - 'ShearY': _shear_level_to_arg, - 'TranslateX': _translate_abs_level_to_arg, - 'TranslateY': _translate_abs_level_to_arg, - 'TranslateXRel': _translate_rel_level_to_arg, - 'TranslateYRel': _translate_rel_level_to_arg, - 'Cutout': _cutout_level_to_arg, -} - - -NAME_TO_OP = { - 'AutoContrast': auto_contrast, - 'Equalize': equalize, - 'Invert': invert, - 'Identity': identity, - 'Rotate': rotate, - 'PosterizeOriginal': posterize, - 'PosterizeResearch': posterize, - 'PosterizeTpu': posterize, - 'Solarize': solarize, - 'SolarizeAdd': solarize_add, - 'Color': color, - 'Contrast': contrast, - 'Brightness': brightness, - 'Sharpness': sharpness, - 'ShearX': shear_x, - 'ShearY': shear_y, - 'TranslateX': translate_x_abs, - 'TranslateY': translate_y_abs, - 'TranslateXRel': translate_x_rel, - 'TranslateYRel': translate_y_rel, - 'Cutout': cutout, -} - - -class AutoAugmentTransform(object): - """ - AutoAugment from Google. - Implementation adapted from: - https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py - """ - - def __init__(self, name, prob=0.5, magnitude=10, hparams=None): - """ - Args: - name (str): any type of transforms list in _RAND_TRANSFORMS. - prob (float): probability of perform current augmentation. - magnitude (int): intensity / magnitude of each augmentation. - hparams (dict): hyper-parameters required by each augmentation. - """ - hparams = hparams or _HPARAMS_DEFAULT - self.aug_fn = NAME_TO_OP[name] - self.level_fn = LEVEL_TO_ARG[name] - self.prob = prob - self.magnitude = magnitude - self.hparams = hparams.copy() - self.kwargs = dict( - fillcolor=hparams['img_mean'] if 'img_mean' in hparams else _FILL, - resample=hparams['interpolation'] if 'interpolation' in hparams - else _RANDOM_INTERPOLATION, - ) - - # If magnitude_std is > 0, we introduce some randomness - # in the usually fixed policy and sample magnitude from a normal distribution - # with mean `magnitude` and std-dev of `magnitude_std`. - # NOTE This is my own hack, being tested, not in papers or reference impls. - self.magnitude_std = self.hparams.get('magnitude_std', 0) - - def __call__(self, img: PIL.Image) -> PIL.Image: - if random.random() > self.prob: - return img - magnitude = self.magnitude - if self.magnitude_std and self.magnitude_std > 0: - magnitude = random.gauss(magnitude, self.magnitude_std) - # NOTE: magnitude fixed and no boundary - # magnitude = min(_MAX_LEVEL, max(0, magnitude)) # clip to valid range - level_args = self.level_fn( - magnitude, self.hparams) if self.level_fn is not None else tuple() - return self.aug_fn(img, *level_args, **self.kwargs) - # return np.array(self.aug_fn(Image.fromarray(img), *level_args, **self.kwargs)) - - # def apply_coords(self, coords: np.ndarray) -> np.ndarray: - # return coords - - -_RAND_TRANSFORMS = [ - 'AutoContrast', - 'Equalize', - 'Invert', - 'Rotate', - 'PosterizeTpu', - 'Solarize', - 'SolarizeAdd', - 'Color', - 'Contrast', - 'Brightness', - 'Sharpness', - 'ShearX', - 'ShearY', - 'TranslateXRel', - 'TranslateYRel', - 'Cutout' # FIXME I implement this as random erasing separately -] - -_RAND_TRANSFORMS_CMC = [ - 'AutoContrast', - 'Identity', - 'Rotate', - 'Sharpness', - 'ShearX', - 'ShearY', - 'TranslateXRel', - 'TranslateYRel', - # 'Cutout' # FIXME I implement this as random erasing separately -] - - -# These experimental weights are based loosely on the relative improvements mentioned in paper. -# They may not result in increased performance, but could likely be tuned to so. -_RAND_CHOICE_WEIGHTS_0 = { - 'Rotate': 0.3, - 'ShearX': 0.2, - 'ShearY': 0.2, - 'TranslateXRel': 0.1, - 'TranslateYRel': 0.1, - 'Color': .025, - 'Sharpness': 0.025, - 'AutoContrast': 0.025, - 'Solarize': .005, - 'SolarizeAdd': .005, - 'Contrast': .005, - 'Brightness': .005, - 'Equalize': .005, - 'PosterizeTpu': 0, - 'Invert': 0, -} - - -class RandAugPolicy(object): - def __init__(self, layers=2, magnitude=10): - self.layers = layers - self.magnitude = magnitude - - def __call__(self, img): - for _ in range(self.layers): - trans = np.random.choice(_RAND_TRANSFORMS) - # NOTE: prob apply, fixed magnitude - # trans_op = AutoAugmentTransform(trans, prob=np.random.uniform(0.2, 0.8), magnitude=self.magnitude) - # NOTE: always apply, random magnitude - trans_op = AutoAugmentTransform(trans, prob=1.0, magnitude=np.random.choice(self.magnitude)) - img = trans_op(img) - assert img is not None, trans - return img diff --git a/cv/classification/repmlp/pytorch/repmlpnet.py b/cv/classification/repmlp/pytorch/repmlpnet.py deleted file mode 100644 index 8bc9af923..000000000 --- a/cv/classification/repmlp/pytorch/repmlpnet.py +++ /dev/null @@ -1,325 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- - -import torch.nn.functional as F -import torch.nn as nn -import torch.utils.checkpoint as checkpoint -import torch - -def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - return result - -def conv_bn_relu(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups) - result.add_module('relu', nn.ReLU()) - return result - -def fuse_bn(conv_or_fc, bn): - std = (bn.running_var + bn.eps).sqrt() - t = bn.weight / std - t = t.reshape(-1, 1, 1, 1) - - if len(t) == conv_or_fc.weight.size(0): - return conv_or_fc.weight * t, bn.bias - bn.running_mean * bn.weight / std - else: - repeat_times = conv_or_fc.weight.size(0) // len(t) - repeated = t.repeat_interleave(repeat_times, 0) - return conv_or_fc.weight * repeated, (bn.bias - bn.running_mean * bn.weight / std).repeat_interleave( - repeat_times, 0) - - -class GlobalPerceptron(nn.Module): - - def __init__(self, input_channels, internal_neurons): - super(GlobalPerceptron, self).__init__() - self.fc1 = nn.Conv2d(in_channels=input_channels, out_channels=internal_neurons, kernel_size=1, stride=1, bias=True) - self.fc2 = nn.Conv2d(in_channels=internal_neurons, out_channels=input_channels, kernel_size=1, stride=1, bias=True) - self.input_channels = input_channels - - def forward(self, inputs): - x = F.adaptive_avg_pool2d(inputs, output_size=(1, 1)) - x = self.fc1(x) - x = F.relu(x, inplace=True) - x = self.fc2(x) - x = F.sigmoid(x) - x = x.view(-1, self.input_channels, 1, 1) - return x - -class RepMLPBlock(nn.Module): - - def __init__(self, in_channels, out_channels, - h, w, - reparam_conv_k=None, - globalperceptron_reduce=4, - num_sharesets=1, - deploy=False): - super().__init__() - - self.C = in_channels - self.O = out_channels - self.S = num_sharesets - - self.h, self.w = h, w - - self.deploy = deploy - - assert in_channels == out_channels - self.gp = GlobalPerceptron(input_channels=in_channels, internal_neurons=in_channels // globalperceptron_reduce) - - self.fc3 = nn.Conv2d(self.h * self.w * num_sharesets, self.h * self.w * num_sharesets, 1, 1, 0, bias=deploy, groups=num_sharesets) - if deploy: - self.fc3_bn = nn.Identity() - else: - self.fc3_bn = nn.BatchNorm2d(num_sharesets) - - self.reparam_conv_k = reparam_conv_k - if not deploy and reparam_conv_k is not None: - for k in reparam_conv_k: - conv_branch = conv_bn(num_sharesets, num_sharesets, kernel_size=k, stride=1, padding=k//2, groups=num_sharesets) - self.__setattr__('repconv{}'.format(k), conv_branch) - - - def partition(self, x, h_parts, w_parts): - x = x.reshape(-1, self.C, h_parts, self.h, w_parts, self.w) - x = x.permute(0, 2, 4, 1, 3, 5) - return x - - def partition_affine(self, x, h_parts, w_parts): - fc_inputs = x.reshape(-1, self.S * self.h * self.w, 1, 1) - out = self.fc3(fc_inputs) - out = out.reshape(-1, self.S, self.h, self.w) - out = self.fc3_bn(out) - out = out.reshape(-1, h_parts, w_parts, self.S, self.h, self.w) - return out - - def forward(self, inputs): - # Global Perceptron - global_vec = self.gp(inputs) - - origin_shape = inputs.size() - h_parts = origin_shape[2] // self.h - w_parts = origin_shape[3] // self.w - - partitions = self.partition(inputs, h_parts, w_parts) - - # Channel Perceptron - fc3_out = self.partition_affine(partitions, h_parts, w_parts) - - # Local Perceptron - if self.reparam_conv_k is not None and not self.deploy: - conv_inputs = partitions.reshape(-1, self.S, self.h, self.w) - conv_out = 0 - for k in self.reparam_conv_k: - conv_branch = self.__getattr__('repconv{}'.format(k)) - conv_out += conv_branch(conv_inputs) - conv_out = conv_out.reshape(-1, h_parts, w_parts, self.S, self.h, self.w) - fc3_out += conv_out - - fc3_out = fc3_out.permute(0, 3, 1, 4, 2, 5) # N, O, h_parts, out_h, w_parts, out_w - out = fc3_out.reshape(*origin_shape) - out = out * global_vec - return out - - - def get_equivalent_fc3(self): - fc_weight, fc_bias = fuse_bn(self.fc3, self.fc3_bn) - if self.reparam_conv_k is not None: - largest_k = max(self.reparam_conv_k) - largest_branch = self.__getattr__('repconv{}'.format(largest_k)) - total_kernel, total_bias = fuse_bn(largest_branch.conv, largest_branch.bn) - for k in self.reparam_conv_k: - if k != largest_k: - k_branch = self.__getattr__('repconv{}'.format(k)) - kernel, bias = fuse_bn(k_branch.conv, k_branch.bn) - total_kernel += F.pad(kernel, [(largest_k - k) // 2] * 4) - total_bias += bias - rep_weight, rep_bias = self._convert_conv_to_fc(total_kernel, total_bias) - final_fc3_weight = rep_weight.reshape_as(fc_weight) + fc_weight - final_fc3_bias = rep_bias + fc_bias - else: - final_fc3_weight = fc_weight - final_fc3_bias = fc_bias - return final_fc3_weight, final_fc3_bias - - def local_inject(self): - self.deploy = True - # Locality Injection - fc3_weight, fc3_bias = self.get_equivalent_fc3() - # Remove Local Perceptron - if self.reparam_conv_k is not None: - for k in self.reparam_conv_k: - self.__delattr__('repconv{}'.format(k)) - self.__delattr__('fc3') - self.__delattr__('fc3_bn') - self.fc3 = nn.Conv2d(self.S * self.h * self.w, self.S * self.h * self.w, 1, 1, 0, bias=True, groups=self.S) - self.fc3_bn = nn.Identity() - self.fc3.weight.data = fc3_weight - self.fc3.bias.data = fc3_bias - - def _convert_conv_to_fc(self, conv_kernel, conv_bias): - I = torch.eye(self.h * self.w).repeat(1, self.S).reshape(self.h * self.w, self.S, self.h, self.w).to(conv_kernel.device) - fc_k = F.conv2d(I, conv_kernel, padding=(conv_kernel.size(2)//2,conv_kernel.size(3)//2), groups=self.S) - fc_k = fc_k.reshape(self.h * self.w, self.S * self.h * self.w).t() - fc_bias = conv_bias.repeat_interleave(self.h * self.w) - return fc_k, fc_bias - - -# The common FFN Block used in many Transformer and MLP models. -class FFNBlock(nn.Module): - def __init__(self, in_channels, hidden_channels=None, out_channels=None, act_layer=nn.GELU): - super().__init__() - out_features = out_channels or in_channels - hidden_features = hidden_channels or in_channels - self.ffn_fc1 = conv_bn(in_channels, hidden_features, 1, 1, 0) - self.ffn_fc2 = conv_bn(hidden_features, out_features, 1, 1, 0) - self.act = act_layer() - - def forward(self, x): - x = self.ffn_fc1(x) - x = self.act(x) - x = self.ffn_fc2(x) - return x - - -class RepMLPNetUnit(nn.Module): - - def __init__(self, channels, h, w, reparam_conv_k, globalperceptron_reduce, ffn_expand=4, - num_sharesets=1, deploy=False): - super().__init__() - self.repmlp_block = RepMLPBlock(in_channels=channels, out_channels=channels, h=h, w=w, - reparam_conv_k=reparam_conv_k, globalperceptron_reduce=globalperceptron_reduce, - num_sharesets=num_sharesets, deploy=deploy) - self.ffn_block = FFNBlock(channels, channels * ffn_expand) - self.prebn1 = nn.BatchNorm2d(channels) - self.prebn2 = nn.BatchNorm2d(channels) - - def forward(self, x): - y = x + self.repmlp_block(self.prebn1(x)) # TODO use droppath? - z = y + self.ffn_block(self.prebn2(y)) - return z - - -class RepMLPNet(nn.Module): - - def __init__(self, - in_channels=3, num_class=1000, - patch_size=(4, 4), - num_blocks=(2,2,6,2), channels=(192,384,768,1536), - hs=(64,32,16,8), ws=(64,32,16,8), - sharesets_nums=(4,8,16,32), - reparam_conv_k=(3,), - globalperceptron_reduce=4, use_checkpoint=False, - deploy=False): - super().__init__() - num_stages = len(num_blocks) - assert num_stages == len(channels) - assert num_stages == len(hs) - assert num_stages == len(ws) - assert num_stages == len(sharesets_nums) - - self.conv_embedding = conv_bn_relu(in_channels, channels[0], kernel_size=patch_size, stride=patch_size, padding=0) - - stages = [] - embeds = [] - for stage_idx in range(num_stages): - stage_blocks = [RepMLPNetUnit(channels=channels[stage_idx], h=hs[stage_idx], w=ws[stage_idx], reparam_conv_k=reparam_conv_k, - globalperceptron_reduce=globalperceptron_reduce, ffn_expand=4, num_sharesets=sharesets_nums[stage_idx], - deploy=deploy) for _ in range(num_blocks[stage_idx])] - stages.append(nn.ModuleList(stage_blocks)) - if stage_idx < num_stages - 1: - embeds.append(conv_bn_relu(in_channels=channels[stage_idx], out_channels=channels[stage_idx + 1], kernel_size=2, stride=2, padding=0)) - - self.stages = nn.ModuleList(stages) - self.embeds = nn.ModuleList(embeds) - self.head_norm = nn.BatchNorm2d(channels[-1]) - self.head = nn.Linear(channels[-1], num_class) - - self.use_checkpoint = use_checkpoint - - def forward(self, x): - x = self.conv_embedding(x) - for i, stage in enumerate(self.stages): - for block in stage: - if self.use_checkpoint: - x = checkpoint.checkpoint(block, x) - else: - x = block(x) - if i < len(self.stages) - 1: - embed = self.embeds[i] - if self.use_checkpoint: - x = checkpoint.checkpoint(embed, x) - else: - x = embed(x) - x = self.head_norm(x) - x = F.adaptive_avg_pool2d(x, 1) - x = x.view(x.size(0), -1) - x = self.head(x) - return x - - def locality_injection(self): - for m in self.modules(): - if hasattr(m, 'local_inject'): - m.local_inject() - -def create_RepMLPNet_T224(deploy=False): - return RepMLPNet(channels=(64, 128, 256, 512), hs=(56,28,14,7), ws=(56,28,14,7), - num_blocks=(2,2,6,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,16,128), - deploy=deploy) -def create_RepMLPNet_T256(deploy=False): - return RepMLPNet(channels=(64, 128, 256, 512), hs=(64,32,16,8), ws=(64,32,16,8), - num_blocks=(2,2,6,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,16,128), - deploy=deploy) -def create_RepMLPNet_B224(deploy=False): - return RepMLPNet(channels=(96, 192, 384, 768), hs=(56,28,14,7), ws=(56,28,14,7), - num_blocks=(2,2,12,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,32,128), - deploy=deploy) -def create_RepMLPNet_B256(deploy=False): - return RepMLPNet(channels=(96, 192, 384, 768), hs=(64,32,16,8), ws=(64,32,16,8), - num_blocks=(2,2,12,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,32,128), - deploy=deploy) -def create_RepMLPNet_D256(deploy=False): - return RepMLPNet(channels=(80, 160, 320, 640), hs=(64,32,16,8), ws=(64,32,16,8), - num_blocks=(2,2,18,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,16,128), - deploy=deploy) -def create_RepMLPNet_L256(deploy=False): - return RepMLPNet(channels=(96, 192, 384, 768), hs=(64,32,16,8), ws=(64,32,16,8), - num_blocks=(2,2,18,2), reparam_conv_k=(1, 3), sharesets_nums=(1,4,32,256), - deploy=deploy) - -model_map = { - 'RepMLPNet-T256': create_RepMLPNet_T256, - 'RepMLPNet-T224': create_RepMLPNet_T224, - 'RepMLPNet-B224': create_RepMLPNet_B224, - 'RepMLPNet-B256': create_RepMLPNet_B256, - 'RepMLPNet-D256': create_RepMLPNet_D256, - 'RepMLPNet-L256': create_RepMLPNet_L256, -} - -def get_RepMLPNet_model(name, deploy=False): - if name not in model_map: - raise ValueError('Not yet supported. You may add some code to create the model here.') - model = model_map[name](deploy=deploy) - return model - - -# Verify the equivalency -if __name__ == '__main__': - model = create_RepMLPNet_B224() - model.eval() - - x = torch.randn(1, 3, 224, 224) - origin_y = model(x) - - model.locality_injection() - - print(model) - new_y = model(x) - print((new_y - origin_y).abs().sum()) \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/test.py b/cv/classification/repmlp/pytorch/test.py deleted file mode 100644 index d501e510f..000000000 --- a/cv/classification/repmlp/pytorch/test.py +++ /dev/null @@ -1,135 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- -import argparse -import os -import time -import torch -import torch.nn as nn -import torch.nn.parallel -import torch.backends.cudnn as cudnn -import torch.optim -import torch.utils.data -import torch.utils.data.distributed -import torchvision.transforms as transforms -import torchvision.datasets as datasets -from utils import load_weights, ProgressMeter, AverageMeter -from repmlpnet import get_RepMLPNet_model -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.utils import accuracy - -parser = argparse.ArgumentParser(description='PyTorch ImageNet Test') -parser.add_argument('data', metavar='DATA', help='path to dataset') -parser.add_argument('mode', metavar='MODE', default='train', choices=['train', 'deploy', 'check'], help='train, deploy, or check the equivalency?') -parser.add_argument('weights', metavar='WEIGHTS', help='path to the weights file') -parser.add_argument('-a', '--arch', metavar='ARCH', default='RepMLPNet-B224') -parser.add_argument('-b', '--batch-size', default=100, type=int, - metavar='N', - help='mini-batch size (default: 100) for test') -parser.add_argument('-r', '--resolution', default=224, type=int, - metavar='R', - help='resolution (default: 224) for test') -parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', - help='number of data loading workers (default: 4)') - -def test(): - args = parser.parse_args() - model = get_RepMLPNet_model(name=args.arch, deploy=args.mode == 'deploy') - - num_params = 0 - for k, v in model.state_dict().items(): - print(k, v.shape) - num_params += v.nelement() - print('total params: ', num_params) - - if os.path.isfile(args.weights): - print("=> loading checkpoint '{}'".format(args.weights)) - load_weights(model, args.weights) - else: - raise ValueError("=> no checkpoint found at '{}'".format(args.weights)) - - if args.mode == 'check': # Note this. In "check" mode, we load the trained weights and convert afterwards. - model.locality_injection() - - if not torch.cuda.is_available(): - print('using CPU, this will be slow.') - use_gpu = False - criterion = nn.CrossEntropyLoss() - else: - model = model.cuda() - use_gpu = True - criterion = nn.CrossEntropyLoss().cuda() - cudnn.benchmark = True - - t = [] - t.append(transforms.Resize(args.resolution)) - t.append(transforms.CenterCrop(args.resolution)) - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - trans = transforms.Compose(t) - - if os.path.exists('/home/dingxiaohan/ndp/imagenet.val.nori.list'): - # This is the data source on our machine. For debugging only. You will never need it. - from noris_dataset import ImageNetNoriDataset - val_dataset = ImageNetNoriDataset('/home/dingxiaohan/ndp/imagenet.val.nori.list', trans) - else: - # Your ImageNet directory - valdir = os.path.join(args.data, 'val') - val_dataset = datasets.ImageFolder(valdir, trans) - - val_loader = torch.utils.data.DataLoader( - val_dataset, - batch_size=args.batch_size, shuffle=False, - num_workers=args.workers, pin_memory=True) - - validate(val_loader, model, criterion, use_gpu) - - -def validate(val_loader, model, criterion, use_gpu): - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - progress = ProgressMeter( - len(val_loader), - [batch_time, losses, top1, top5], - prefix='Test: ') - - # switch to evaluate mode - model.eval() - - with torch.no_grad(): - end = time.time() - for i, (images, target) in enumerate(val_loader): - if use_gpu: - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - output = model(images) - loss = criterion(output, target) - - # measure accuracy and record loss - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - losses.update(loss.item(), images.size(0)) - top1.update(acc1.item(), images.size(0)) - top5.update(acc5.item(), images.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if i % 10 == 0: - progress.display(i) - - print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}'.format(top1=top1, top5=top5)) - - return top1.avg - - -if __name__ == '__main__': - test() \ No newline at end of file diff --git a/cv/classification/repmlp/pytorch/utils.py b/cv/classification/repmlp/pytorch/utils.py deleted file mode 100644 index f7caac85b..000000000 --- a/cv/classification/repmlp/pytorch/utils.py +++ /dev/null @@ -1,193 +0,0 @@ -# -------------------------------------------------------- -# RepMLPNet: Hierarchical Vision MLP with Re-parameterized Locality (https://arxiv.org/abs/2112.11081) -# CVPR 2022 -# Github source: https://github.com/DingXiaoH/RepMLP -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import torch -import torch.distributed as dist -import numpy as np - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - - -def unwrap_model(model): - """Remove the DistributedDataParallel wrapper if present.""" - wrapped = isinstance(model, torch.nn.parallel.distributed.DistributedDataParallel) - return model.module if wrapped else model - - -def load_checkpoint(config, model, optimizer, lr_scheduler, logger, model_ema=None): - logger.info(f"==============> Resuming form {config.MODEL.RESUME}....................") - if config.MODEL.RESUME.startswith('https'): - checkpoint = torch.hub.load_state_dict_from_url( - config.MODEL.RESUME, map_location='cpu', check_hash=True) - else: - checkpoint = torch.load(config.MODEL.RESUME, map_location='cpu') - msg = model.load_state_dict(checkpoint['model'], strict=False) - logger.info(msg) - max_accuracy = 0.0 - if not config.EVAL_MODE and 'optimizer' in checkpoint and 'lr_scheduler' in checkpoint and 'epoch' in checkpoint: - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['lr_scheduler']) - config.defrost() - config.TRAIN.START_EPOCH = checkpoint['epoch'] + 1 - config.freeze() - if 'amp' in checkpoint and config.AMP_OPT_LEVEL != "O0" and checkpoint['config'].AMP_OPT_LEVEL != "O0": - amp.load_state_dict(checkpoint['amp']) - logger.info(f"=> loaded successfully '{config.MODEL.RESUME}' (epoch {checkpoint['epoch']})") - if 'max_accuracy' in checkpoint: - max_accuracy = checkpoint['max_accuracy'] - if model_ema is not None: - unwrap_model(model_ema).load_state_dict(checkpoint['ema']) - print('=================================================== EMAloaded') - - del checkpoint - torch.cuda.empty_cache() - return max_accuracy - -def load_weights(model, path): - checkpoint = torch.load(path, map_location='cpu') - if 'model' in checkpoint: - checkpoint = checkpoint['model'] - unwrap_model(model).load_state_dict(checkpoint, strict=False) - print('=================== loaded from', path) - - -def save_latest(config, epoch, model, max_accuracy, optimizer, lr_scheduler, logger, model_ema=None): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'epoch': epoch, - 'config': config} - if config.AMP_OPT_LEVEL != "O0": - save_state['amp'] = amp.state_dict() - if model_ema is not None: - save_state['ema'] = unwrap_model(model_ema).state_dict() - - save_path = os.path.join(config.OUTPUT, 'latest.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - -def save_checkpoint(config, epoch, model, max_accuracy, optimizer, lr_scheduler, logger, is_best=False, model_ema=None): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'epoch': epoch, - 'config': config} - if config.AMP_OPT_LEVEL != "O0": - save_state['amp'] = amp.state_dict() - if model_ema is not None: - save_state['ema'] = unwrap_model(model_ema).state_dict() - - if is_best: - best_path = os.path.join(config.OUTPUT, 'best_ckpt.pth') - torch.save(save_state, best_path) - - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - - -def get_grad_norm(parameters, norm_type=2): - if isinstance(parameters, torch.Tensor): - parameters = [parameters] - parameters = list(filter(lambda p: p.grad is not None, parameters)) - norm_type = float(norm_type) - total_norm = 0 - for p in parameters: - param_norm = p.grad.data.norm(norm_type) - total_norm += param_norm.item() ** norm_type - total_norm = total_norm ** (1. / norm_type) - return total_norm - - -def auto_resume_helper(output_dir): - checkpoints = os.listdir(output_dir) - checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith('pth') and 'ema' not in ckpt] - print(f"All checkpoints founded in {output_dir}: {checkpoints}") - if len(checkpoints) > 0: - latest_checkpoint = max([os.path.join(output_dir, d) for d in checkpoints], key=os.path.getmtime) - print(f"The latest checkpoint founded: {latest_checkpoint}") - resume_file = latest_checkpoint - else: - resume_file = None - return resume_file - - -def reduce_tensor(tensor): - rt = tensor.clone() - dist.all_reduce(rt, op=dist.ReduceOp.SUM) - rt /= dist.get_world_size() - return rt - - - - -def update_model_ema(cfg, num_gpus, model, model_ema, cur_epoch, cur_iter): - """Update exponential moving average (ema) of model weights.""" - update_period = cfg.TRAIN.EMA_UPDATE_PERIOD - if update_period is None or update_period == 0 or cur_iter % update_period != 0: - return - # Adjust alpha to be fairly independent of other parameters - total_batch_size = num_gpus * cfg.DATA.BATCH_SIZE - adjust = total_batch_size / cfg.TRAIN.EPOCHS * update_period - # print('ema adjust', adjust) - alpha = min(1.0, cfg.TRAIN.EMA_ALPHA * adjust) - # During warmup simply copy over weights instead of using ema - alpha = 1.0 if cur_epoch < cfg.TRAIN.WARMUP_EPOCHS else alpha - # Take ema of all parameters (not just named parameters) - params = unwrap_model(model).state_dict() - for name, param in unwrap_model(model_ema).state_dict().items(): - param.copy_(param * (1.0 - alpha) + params[name] * alpha) - - -class ProgressMeter(object): - def __init__(self, num_batches, meters, prefix=""): - self.batch_fmtstr = self._get_batch_fmtstr(num_batches) - self.meters = meters - self.prefix = prefix - - def display(self, batch): - entries = [self.prefix + self.batch_fmtstr.format(batch)] - entries += [str(meter) for meter in self.meters] - print('\t'.join(entries)) - - def _get_batch_fmtstr(self, num_batches): - num_digits = len(str(num_batches // 1)) - fmt = '{:' + str(num_digits) + 'd}' - return '[' + fmt + '/' + fmt.format(num_batches) + ']' - -class AverageMeter(object): - """Computes and stores the average and current value""" - def __init__(self, name, fmt=':f'): - self.name = name - self.fmt = fmt - self.reset() - - def reset(self): - self.val = 0 - self.avg = 0 - self.sum = 0 - self.count = 0 - - def update(self, val, n=1): - self.val = val - self.sum += val * n - self.count += n - self.avg = self.sum / self.count - - def __str__(self): - fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})' - return fmtstr.format(**self.__dict__) \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/LICENSE b/cv/classification/repvgg/pytorch/LICENSE deleted file mode 100755 index 9b7d31a34..000000000 --- a/cv/classification/repvgg/pytorch/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 DingXiaoH - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/cv/classification/repvgg/pytorch/README.md b/cv/classification/repvgg/pytorch/README.md index 583d5d179..be5907217 100755 --- a/cv/classification/repvgg/pytorch/README.md +++ b/cv/classification/repvgg/pytorch/README.md @@ -6,6 +6,9 @@ ```bash pip3 install timm yacs +git clone https://github.com/DingXiaoH/RepVGG.git +cd RepVGG +git checkout eae7c5204001eaf195bbe2ee72fb6a37855cce33 ``` ## Step 2: Download data @@ -31,7 +34,14 @@ imagenet ## Step 3: Run RepVGG ```bash -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12349 main.py --arch [model name] --data-path [/path/to/imagenet] --batch-size 32 --tag train_from_scratch --output ./ --opts TRAIN.EPOCHS 300 TRAIN.BASE_LR 0.1 TRAIN.WEIGHT_DECAY 1e-4 TRAIN.WARMUP_EPOCHS 5 MODEL.LABEL_SMOOTHING 0.1 AUG.PRESET weak AUG.MIXUP 0.0 DATA.DATASET imagenet DATA.IMG_SIZE 224 +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' main.py + +# change dataset load +# Tips: "import os" into data/build.py +sed -i "s@dataset = torchvision.datasets.ImageNet(root=config.DATA.DATA_PATH, split='train' if is_train else 'val', transform=transform)@dataset = datasets.ImageFolder(os.path.join(config.DATA.DATA_PATH, prefix), transform=transform)@" data/build.py + +python3 -m torch.distributed.launch --nproc_per_node 4 --master_port 12349 main.py --arch RepVGG-A0 --data-path ./imagenet --batch-size 32 --tag train_from_scratch --output ./ --opts TRAIN.EPOCHS 300 TRAIN.BASE_LR 0.1 TRAIN.WEIGHT_DECAY 1e-4 TRAIN.WARMUP_EPOCHS 5 MODEL.LABEL_SMOOTHING 0.1 AUG.PRESET weak AUG.MIXUP 0.0 DATA.DATASET imagenet DATA.IMG_SIZE 224 ``` The original RepVGG models were trained in 120 epochs with cosine learning rate decay from 0.1 to 0. We used 8 GPUs, global batch size of 256, weight decay of 1e-4 (no weight decay on fc.bias, bn.bias, rbr_dense.bn.weight and rbr_1x1.bn.weight) (weight decay on rbr_identity.weight makes little difference, and it is better to use it in most of the cases), and the same simple data preprocssing as the PyTorch official example: @@ -54,9 +64,6 @@ RepVGGplus-L2pse, RepVGG-A0, RepVGG-A1, RepVGG-A2, RepVGG-B0, RepVGG-B1, RepVGG- |----------| ----------- | ------------------------------------ | | RepVGG-A0| 8 cards | Acc@1=0.7241 | +## Reference - - - - - +- [RepMLP](https://github.com/DingXiaoH/RepVGG/tree/eae7c5204001eaf195bbe2ee72fb6a37855cce33) \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/data/__init__.py b/cv/classification/repvgg/pytorch/data/__init__.py deleted file mode 100755 index 70c633ce6..000000000 --- a/cv/classification/repvgg/pytorch/data/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .build import build_loader \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/data/build.py b/cv/classification/repvgg/pytorch/data/build.py deleted file mode 100755 index faf093957..000000000 --- a/cv/classification/repvgg/pytorch/data/build.py +++ /dev/null @@ -1,188 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- -import torch -import numpy as np -import torch.distributed as dist -from torchvision import datasets, transforms -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data import Mixup -from timm.data import create_transform -try: - from timm.data.transforms import str_to_pil_interp as _pil_interp -except: - from timm.data.transforms import _pil_interp -from .cached_image_folder import CachedImageFolder -from .samplers import SubsetRandomSampler -import os - - -def build_loader(config): - config.defrost() - dataset_train, config.MODEL.NUM_CLASSES = build_dataset(is_train=True, config=config) - config.freeze() - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build train dataset") - dataset_val, _ = build_dataset(is_train=False, config=config) - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build val dataset") - - num_tasks = dist.get_world_size() - global_rank = dist.get_rank() - if config.DATA.ZIP_MODE and config.DATA.CACHE_MODE == 'part': - indices = np.arange(dist.get_rank(), len(dataset_train), dist.get_world_size()) - sampler_train = SubsetRandomSampler(indices) - else: - sampler_train = torch.utils.data.DistributedSampler( - dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - - if dataset_val is None: - sampler_val = None - else: - indices = np.arange(dist.get_rank(), len(dataset_val), dist.get_world_size()) #TODO - sampler_val = SubsetRandomSampler(indices) - - data_loader_train = torch.utils.data.DataLoader( - dataset_train, sampler=sampler_train, - batch_size=config.DATA.BATCH_SIZE, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=True, - ) - - if dataset_val is None: - data_loader_val = None - else: - data_loader_val = torch.utils.data.DataLoader( - dataset_val, sampler=sampler_val, - batch_size=config.DATA.TEST_BATCH_SIZE, - shuffle=False, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=False - ) - - # setup mixup / cutmix - mixup_fn = None - mixup_active = config.AUG.MIXUP > 0 or config.AUG.CUTMIX > 0. or config.AUG.CUTMIX_MINMAX is not None - if mixup_active: - mixup_fn = Mixup( - mixup_alpha=config.AUG.MIXUP, cutmix_alpha=config.AUG.CUTMIX, cutmix_minmax=config.AUG.CUTMIX_MINMAX, - prob=config.AUG.MIXUP_PROB, switch_prob=config.AUG.MIXUP_SWITCH_PROB, mode=config.AUG.MIXUP_MODE, - label_smoothing=config.MODEL.LABEL_SMOOTHING, num_classes=config.MODEL.NUM_CLASSES) - - return dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn - - -def build_dataset(is_train, config): - if config.DATA.DATASET == 'imagenet': - transform = build_transform(is_train, config) - prefix = 'train' if is_train else 'val' - if config.DATA.ZIP_MODE: - ann_file = prefix + "_map.txt" - prefix = prefix + ".zip@/" - dataset = CachedImageFolder(config.DATA.DATA_PATH, ann_file, prefix, transform, - cache_mode=config.DATA.CACHE_MODE if is_train else 'part') - else: - import torchvision - print('use raw ImageNet data') - #dataset = torchvision.datasets.ImageNet(root=config.DATA.DATA_PATH, split='train' if is_train else 'val', transform=transform) - root = os.path.join(config.DATA.DATA_PATH, prefix) - dataset = datasets.ImageFolder(root, transform=transform) - - nb_classes = 1000 - - elif config.DATA.DATASET == 'cf100': - mean = [0.5070751592371323, 0.48654887331495095, 0.4409178433670343] - std = [0.2673342858792401, 0.2564384629170883, 0.27615047132568404] - if is_train: - transform = transforms.Compose([ - transforms.RandomCrop(32, padding=4), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - transforms.Normalize(mean, std) - ]) - dataset = datasets.CIFAR100(root=config.DATA.DATA_PATH, train=True, download=True, transform=transform) - else: - transform = transforms.Compose( - [transforms.ToTensor(), - transforms.Normalize(mean, std)]) - dataset = datasets.CIFAR100(root=config.DATA.DATA_PATH, train=False, download=True, transform=transform) - nb_classes = 100 - - else: - raise NotImplementedError("We only support ImageNet and CIFAR-100 now.") - - return dataset, nb_classes - - -def build_transform(is_train, config): - resize_im = config.DATA.IMG_SIZE > 32 - if is_train: - # this should always dispatch to transforms_imagenet_train - - if config.AUG.PRESET is None: - transform = create_transform( - input_size=config.DATA.IMG_SIZE, - is_training=True, - color_jitter=config.AUG.COLOR_JITTER if config.AUG.COLOR_JITTER > 0 else None, - auto_augment=config.AUG.AUTO_AUGMENT if config.AUG.AUTO_AUGMENT != 'none' else None, - re_prob=config.AUG.REPROB, - re_mode=config.AUG.REMODE, - re_count=config.AUG.RECOUNT, - interpolation=config.DATA.INTERPOLATION, - ) - print('=============================== original AUG! ', config.AUG.AUTO_AUGMENT) - if not resize_im: - # replace RandomResizedCropAndInterpolation with - # RandomCrop - transform.transforms[0] = transforms.RandomCrop(config.DATA.IMG_SIZE, padding=4) - - elif config.AUG.PRESET.strip() == 'raug15': - from train.randaug import RandAugPolicy - transform = transforms.Compose([ - transforms.RandomResizedCrop(config.DATA.IMG_SIZE), - transforms.RandomHorizontalFlip(), - RandAugPolicy(magnitude=15), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - print('---------------------- RAND AUG 15 distortion!') - - elif config.AUG.PRESET.strip() == 'weak': - transform = transforms.Compose([ - transforms.RandomResizedCrop(config.DATA.IMG_SIZE), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - elif config.AUG.PRESET.strip() == 'none': - transform = transforms.Compose([ - transforms.Resize(config.DATA.IMG_SIZE, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - transforms.CenterCrop(config.DATA.IMG_SIZE), - transforms.ToTensor(), - transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), - ]) - else: - raise ValueError('???' + config.AUG.PRESET) - print(transform) - return transform - - t = [] - if resize_im: - if config.TEST.CROP: - size = int((256 / 224) * config.DATA.TEST_SIZE) - t.append(transforms.Resize(size, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - # to maintain same ratio w.r.t. 224 images - ) - t.append(transforms.CenterCrop(config.DATA.TEST_SIZE)) - else: - # default for testing - t.append(transforms.Resize(config.DATA.TEST_SIZE, interpolation=_pil_interp(config.DATA.INTERPOLATION))) - t.append(transforms.CenterCrop(config.DATA.TEST_SIZE)) - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - trans = transforms.Compose(t) - return trans diff --git a/cv/classification/repvgg/pytorch/data/cached_image_folder.py b/cv/classification/repvgg/pytorch/data/cached_image_folder.py deleted file mode 100755 index 2f3d013a6..000000000 --- a/cv/classification/repvgg/pytorch/data/cached_image_folder.py +++ /dev/null @@ -1,244 +0,0 @@ -import io -import os -import time -import torch.distributed as dist -import torch.utils.data as data -from PIL import Image - -from .zipreader import is_zip_path, ZipReader - - -def has_file_allowed_extension(filename, extensions): - """Checks if a file is an allowed extension. - Args: - filename (string): path to a file - Returns: - bool: True if the filename ends with a known image extension - """ - filename_lower = filename.lower() - return any(filename_lower.endswith(ext) for ext in extensions) - - -def find_classes(dir): - classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))] - classes.sort() - class_to_idx = {classes[i]: i for i in range(len(classes))} - return classes, class_to_idx - - -def make_dataset(dir, class_to_idx, extensions): - images = [] - dir = os.path.expanduser(dir) - for target in sorted(os.listdir(dir)): - d = os.path.join(dir, target) - if not os.path.isdir(d): - continue - - for root, _, fnames in sorted(os.walk(d)): - for fname in sorted(fnames): - if has_file_allowed_extension(fname, extensions): - path = os.path.join(root, fname) - item = (path, class_to_idx[target]) - images.append(item) - - return images - - -def make_dataset_with_ann(ann_file, img_prefix, extensions): - images = [] - with open(ann_file, "r") as f: - contents = f.readlines() - for line_str in contents: - path_contents = [c for c in line_str.split('\t')] - im_file_name = path_contents[0] - class_index = int(path_contents[1]) - - assert str.lower(os.path.splitext(im_file_name)[-1]) in extensions - item = (os.path.join(img_prefix, im_file_name), class_index) - - images.append(item) - - return images - - -class DatasetFolder(data.Dataset): - """A generic data loader where the samples are arranged in this way: :: - root/class_x/xxx.ext - root/class_x/xxy.ext - root/class_x/xxz.ext - root/class_y/123.ext - root/class_y/nsdf3.ext - root/class_y/asd932_.ext - Args: - root (string): Root directory path. - loader (callable): A function to load a sample given its path. - extensions (list[string]): A list of allowed extensions. - transform (callable, optional): A function/transform that takes in - a sample and returns a transformed version. - E.g, ``transforms.RandomCrop`` for images. - target_transform (callable, optional): A function/transform that takes - in the target and transforms it. - Attributes: - samples (list): List of (sample path, class_index) tuples - """ - - def __init__(self, root, loader, extensions, ann_file='', img_prefix='', transform=None, target_transform=None, - cache_mode="no"): - # image folder mode - if ann_file == '': - _, class_to_idx = find_classes(root) - samples = make_dataset(root, class_to_idx, extensions) - # zip mode - else: - samples = make_dataset_with_ann(os.path.join(root, ann_file), - os.path.join(root, img_prefix), - extensions) - - if len(samples) == 0: - raise (RuntimeError("Found 0 files in subfolders of: " + root + "\n" + - "Supported extensions are: " + ",".join(extensions))) - - self.root = root - self.loader = loader - self.extensions = extensions - - self.samples = samples - self.labels = [y_1k for _, y_1k in samples] - self.classes = list(set(self.labels)) - - self.transform = transform - self.target_transform = target_transform - - self.cache_mode = cache_mode - if self.cache_mode != "no": - self.init_cache() - - def init_cache(self): - assert self.cache_mode in ["part", "full"] - n_sample = len(self.samples) - global_rank = dist.get_rank() - world_size = dist.get_world_size() - - samples_bytes = [None for _ in range(n_sample)] - start_time = time.time() - for index in range(n_sample): - if index % (n_sample // 10) == 0: - t = time.time() - start_time - print(f'global_rank {dist.get_rank()} cached {index}/{n_sample} takes {t:.2f}s per block') - start_time = time.time() - path, target = self.samples[index] - if self.cache_mode == "full": - samples_bytes[index] = (ZipReader.read(path), target) - elif self.cache_mode == "part" and index % world_size == global_rank: - samples_bytes[index] = (ZipReader.read(path), target) - else: - samples_bytes[index] = (path, target) - self.samples = samples_bytes - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (sample, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - sample = self.loader(path) - if self.transform is not None: - sample = self.transform(sample) - if self.target_transform is not None: - target = self.target_transform(target) - - return sample, target - - def __len__(self): - return len(self.samples) - - def __repr__(self): - fmt_str = 'Dataset ' + self.__class__.__name__ + '\n' - fmt_str += ' Number of datapoints: {}\n'.format(self.__len__()) - fmt_str += ' Root Location: {}\n'.format(self.root) - tmp = ' Transforms (if any): ' - fmt_str += '{0}{1}\n'.format(tmp, self.transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - tmp = ' Target Transforms (if any): ' - fmt_str += '{0}{1}'.format(tmp, self.target_transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - return fmt_str - - -IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif'] - - -def pil_loader(path): - # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835) - if isinstance(path, bytes): - img = Image.open(io.BytesIO(path)) - elif is_zip_path(path): - data = ZipReader.read(path) - img = Image.open(io.BytesIO(data)) - else: - with open(path, 'rb') as f: - img = Image.open(f) - return img.convert('RGB') - - -def accimage_loader(path): - import accimage - try: - return accimage.Image(path) - except IOError: - # Potentially a decoding problem, fall back to PIL.Image - return pil_loader(path) - - -def default_img_loader(path): - from torchvision import get_image_backend - if get_image_backend() == 'accimage': - return accimage_loader(path) - else: - return pil_loader(path) - - -class CachedImageFolder(DatasetFolder): - """A generic data loader where the images are arranged in this way: :: - root/dog/xxx.png - root/dog/xxy.png - root/dog/xxz.png - root/cat/123.png - root/cat/nsdf3.png - root/cat/asd932_.png - Args: - root (string): Root directory path. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - loader (callable, optional): A function to load an image given its path. - Attributes: - imgs (list): List of (image path, class_index) tuples - """ - - def __init__(self, root, ann_file='', img_prefix='', transform=None, target_transform=None, - loader=default_img_loader, cache_mode="no"): - super(CachedImageFolder, self).__init__(root, loader, IMG_EXTENSIONS, - ann_file=ann_file, img_prefix=img_prefix, - transform=transform, target_transform=target_transform, - cache_mode=cache_mode) - self.imgs = self.samples - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (image, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - image = self.loader(path) - if self.transform is not None: - img = self.transform(image) - else: - img = image - if self.target_transform is not None: - target = self.target_transform(target) - - return img, target diff --git a/cv/classification/repvgg/pytorch/data/lmdb_dataset.py b/cv/classification/repvgg/pytorch/data/lmdb_dataset.py deleted file mode 100755 index 640d1824d..000000000 --- a/cv/classification/repvgg/pytorch/data/lmdb_dataset.py +++ /dev/null @@ -1,164 +0,0 @@ -import os -import os.path as osp -from PIL import Image -import six -import lmdb -import warnings -warnings.simplefilter(action='ignore', category=FutureWarning) -import pyarrow as pa -import numpy as np -import torch.utils.data as data -from torch.utils.data import DataLoader -from torchvision.datasets import ImageFolder - -train_lmdb_path = '/apdcephfs/share_1290939/0_public_datasets/imageNet_2012/train.lmdb' -val_lmdb_path = '/apdcephfs/share_1290939/0_public_datasets/imageNet_2012/val.lmdb' - -# from data.lmdb_dataset import ImageFolderLMDB, train_lmdb_path, val_lmdb_path -# lmdb_path = train_lmdb_path if is_train else val_lmdb_path -# dataset = ImageFolderLMDB(db_path=lmdb_path, transform=transform) - -def loads_pyarrow(buf): - """ - Args: - buf: the output of `dumps`. - """ - return pa.deserialize(buf) - - -class ImageFolderLMDB(data.Dataset): - def __init__(self, db_path, transform=None, target_transform=None): - self.db_path = db_path - self.env = lmdb.open(db_path, subdir=osp.isdir(db_path), - readonly=True, lock=False, - readahead=False, meminit=False) - with self.env.begin(write=False) as txn: - self.length = loads_pyarrow(txn.get(b'__len__')) - self.keys = loads_pyarrow(txn.get(b'__keys__')) - - self.transform = transform - self.target_transform = target_transform - - def __getstate__(self): - state = self.__dict__ - state["env"] = None - return state - - def __setstate__(self, state): - self.__dict__ = state - self.env = lmdb.open(self.db_path, subdir=osp.isdir(self.db_path), - readonly=True, lock=False, - readahead=False, meminit=False) - with self.env.begin(write=False) as txn: - self.length = loads_pyarrow(txn.get(b'__len__')) - self.keys = loads_pyarrow(txn.get(b'__keys__')) - - def __getitem__(self, index): - env = self.env - with env.begin(write=False) as txn: - byteflow = txn.get(self.keys[index]) - - unpacked = loads_pyarrow(byteflow) - - # load img - imgbuf = unpacked[0] - buf = six.BytesIO() - buf.write(imgbuf) - buf.seek(0) - img = Image.open(buf).convert('RGB') - if self.transform is not None: - img = self.transform(img) - - # load label - target = unpacked[1] - if self.target_transform is not None: - target = self.transform(target) - - return img, target -# if self.transform is not None: -# img = self.transform(img) -# -# # im2arr = np.array(img) -# -# if self.target_transform is not None: -# target = self.target_transform(target) -# -# return img, target - # return im2arr, target - - def __len__(self): - return self.length - - def __repr__(self): - return self.__class__.__name__ + ' (' + self.db_path + ')' - - -def raw_reader(path): - with open(path, 'rb') as f: - bin_data = f.read() - return bin_data - - -def dumps_pyarrow(obj): - """ - Serialize an object. - Returns: - Implementation-dependent bytes-like object - """ - return pa.serialize(obj).to_buffer() - - -def folder2lmdb(dpath, name="train", write_frequency=5000): - directory = osp.expanduser(osp.join(dpath, name)) - print("Loading dataset from %s" % directory) - dataset = ImageFolder(directory, loader=raw_reader) - data_loader = DataLoader(dataset, num_workers=4, collate_fn=lambda x: x) - - lmdb_path = osp.join(dpath, "%s.lmdb" % name) - isdir = os.path.isdir(lmdb_path) - - print("Generate LMDB to %s" % lmdb_path) - db = lmdb.open(lmdb_path, subdir=isdir, - map_size=1099511627776 * 2, readonly=False, - meminit=False, map_async=True) - - txn = db.begin(write=True) - for idx, data in enumerate(data_loader): - image, label = data[0] - - txn.put(u'{}'.format(idx).encode('ascii'), dumps_pyarrow((image, label))) - if idx % write_frequency == 0: - print("[%d/%d]" % (idx, len(data_loader))) - txn.commit() - txn = db.begin(write=True) - - # finish iterating through dataset - txn.commit() - keys = [u'{}'.format(k).encode('ascii') for k in range(idx + 1)] - with db.begin(write=True) as txn: - txn.put(b'__keys__', dumps_pyarrow(keys)) - txn.put(b'__len__', dumps_pyarrow(len(keys))) - - print("Flushing database ...") - db.sync() - db.close() - - - - -if __name__ == "__main__": - # lmdb_path = '/apdcephfs/share_1016399/0_public_datasets/imageNet_2012/train.lmdb' - # from lmdb_dataset import ImageFolderLMDB - # dataset = ImageFolderLMDB(db_path=lmdb_path) - # for x, y in dataset: - # print(type(x), type(y)) - # exit() - - import argparse - parser = argparse.ArgumentParser() - parser.add_argument('--dir', type=str, required=True, help="The dataset directory to process") - args = parser.parse_args() - # generate lmdb - path = args.dir - folder2lmdb(path, name="train") - folder2lmdb(path, name="val") diff --git a/cv/classification/repvgg/pytorch/data/samplers.py b/cv/classification/repvgg/pytorch/data/samplers.py deleted file mode 100755 index fed54b4e2..000000000 --- a/cv/classification/repvgg/pytorch/data/samplers.py +++ /dev/null @@ -1,21 +0,0 @@ -import torch - -class SubsetRandomSampler(torch.utils.data.Sampler): - r"""Samples elements randomly from a given list of indices, without replacement. - - Arguments: - indices (sequence): a sequence of indices - """ - - def __init__(self, indices): - self.epoch = 0 - self.indices = indices - - def __iter__(self): - return (self.indices[i] for i in torch.randperm(len(self.indices))) - - def __len__(self): - return len(self.indices) - - def set_epoch(self, epoch): - self.epoch = epoch diff --git a/cv/classification/repvgg/pytorch/data/zipreader.py b/cv/classification/repvgg/pytorch/data/zipreader.py deleted file mode 100755 index 9d773c3c4..000000000 --- a/cv/classification/repvgg/pytorch/data/zipreader.py +++ /dev/null @@ -1,96 +0,0 @@ -import os -import zipfile -import io -import numpy as np -from PIL import Image -from PIL import ImageFile - -ImageFile.LOAD_TRUNCATED_IMAGES = True - - -def is_zip_path(img_or_path): - """judge if this is a zip path""" - return '.zip@' in img_or_path - - -class ZipReader(object): - """A class to read zipped files""" - zip_bank = dict() - - def __init__(self): - super(ZipReader, self).__init__() - - @staticmethod - def get_zipfile(path): - zip_bank = ZipReader.zip_bank - if path not in zip_bank: - zfile = zipfile.ZipFile(path, 'r') - zip_bank[path] = zfile - return zip_bank[path] - - @staticmethod - def split_zip_style_path(path): - pos_at = path.index('@') - assert pos_at != -1, "character '@' is not found from the given path '%s'" % path - - zip_path = path[0: pos_at] - folder_path = path[pos_at + 1:] - folder_path = str.strip(folder_path, '/') - return zip_path, folder_path - - @staticmethod - def list_folder(path): - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - folder_list = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - len(os.path.splitext(file_foler_name)[-1]) == 0 and \ - file_foler_name != folder_path: - if len(folder_path) == 0: - folder_list.append(file_foler_name) - else: - folder_list.append(file_foler_name[len(folder_path) + 1:]) - - return folder_list - - @staticmethod - def list_files(path, extension=None): - if extension is None: - extension = ['.*'] - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - file_lists = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - str.lower(os.path.splitext(file_foler_name)[-1]) in extension: - if len(folder_path) == 0: - file_lists.append(file_foler_name) - else: - file_lists.append(file_foler_name[len(folder_path) + 1:]) - - return file_lists - - @staticmethod - def read(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - return data - - @staticmethod - def imread(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - try: - im = Image.open(io.BytesIO(data)) - except: - print("ERROR IMG LOADED: ", path_img) - random_img = np.random.rand(224, 224, 3) * 255 - im = Image.fromarray(np.uint8(random_img)) - return im diff --git a/cv/classification/repvgg/pytorch/example_pspnet.py b/cv/classification/repvgg/pytorch/example_pspnet.py deleted file mode 100755 index 19ff9abdc..000000000 --- a/cv/classification/repvgg/pytorch/example_pspnet.py +++ /dev/null @@ -1,161 +0,0 @@ -import torch -from torch import nn -import torch.nn.functional as F -from repvgg import get_RepVGG_func_by_name - -# The PSPNet parts are from -# https://github.com/hszhao/semseg - -class PPM(nn.Module): - def __init__(self, in_dim, reduction_dim, bins, BatchNorm): - super(PPM, self).__init__() - self.features = [] - for bin in bins: - self.features.append(nn.Sequential( - nn.AdaptiveAvgPool2d(bin), - nn.Conv2d(in_dim, reduction_dim, kernel_size=1, bias=False), - BatchNorm(reduction_dim), - nn.ReLU(inplace=True) - )) - self.features = nn.ModuleList(self.features) - - def forward(self, x): - x_size = x.size() - out = [x] - for f in self.features: - out.append(F.interpolate(f(x), x_size[2:], mode='bilinear', align_corners=True)) - return torch.cat(out, 1) - - -class PSPNet(nn.Module): - def __init__(self, - backbone_name, backbone_file, deploy, - bins=(1, 2, 3, 6), dropout=0.1, classes=2, - zoom_factor=8, use_ppm=True, criterion=nn.CrossEntropyLoss(ignore_index=255), BatchNorm=nn.BatchNorm2d, - pretrained=True): - super(PSPNet, self).__init__() - assert 2048 % len(bins) == 0 - assert classes > 1 - assert zoom_factor in [1, 2, 4, 8] - self.zoom_factor = zoom_factor - self.use_ppm = use_ppm - self.criterion = criterion - - repvgg_fn = get_RepVGG_func_by_name(backbone_name) - backbone = repvgg_fn(deploy) - if pretrained: - checkpoint = torch.load(backbone_file) - if 'state_dict' in checkpoint: - checkpoint = checkpoint['state_dict'] - ckpt = {k.replace('module.', ''): v for k, v in checkpoint.items()} # strip the names - backbone.load_state_dict(ckpt) - - self.layer0, self.layer1, self.layer2, self.layer3, self.layer4 = backbone.stage0, backbone.stage1, backbone.stage2, backbone.stage3, backbone.stage4 - - # The last two stages should have stride=1 for semantic segmentation - # Note that the stride of 1x1 should be the same as the 3x3 - # Use dilation following the implementation of PSPNet - secondlast_channel = 0 - for n, m in self.layer3.named_modules(): - if ('rbr_dense' in n or 'rbr_reparam' in n) and isinstance(m, nn.Conv2d): - m.dilation, m.padding, m.stride = (2, 2), (2, 2), (1, 1) - print('change dilation, padding, stride of ', n) - secondlast_channel = m.out_channels - elif 'rbr_1x1' in n and isinstance(m, nn.Conv2d): - m.stride = (1, 1) - print('change stride of ', n) - last_channel = 0 - for n, m in self.layer4.named_modules(): - if ('rbr_dense' in n or 'rbr_reparam' in n) and isinstance(m, nn.Conv2d): - m.dilation, m.padding, m.stride = (4, 4), (4, 4), (1, 1) - print('change dilation, padding, stride of ', n) - last_channel = m.out_channels - elif 'rbr_1x1' in n and isinstance(m, nn.Conv2d): - m.stride = (1, 1) - print('change stride of ', n) - - fea_dim = last_channel - aux_in = secondlast_channel - - if use_ppm: - self.ppm = PPM(fea_dim, int(fea_dim/len(bins)), bins, BatchNorm) - fea_dim *= 2 - - self.cls = nn.Sequential( - nn.Conv2d(fea_dim, 512, kernel_size=3, padding=1, bias=False), - BatchNorm(512), - nn.ReLU(inplace=True), - nn.Dropout2d(p=dropout), - nn.Conv2d(512, classes, kernel_size=1) - ) - if self.training: - self.aux = nn.Sequential( - nn.Conv2d(aux_in, 256, kernel_size=3, padding=1, bias=False), - BatchNorm(256), - nn.ReLU(inplace=True), - nn.Dropout2d(p=dropout), - nn.Conv2d(256, classes, kernel_size=1) - ) - - def forward(self, x, y=None): - x_size = x.size() - assert (x_size[2]-1) % 8 == 0 and (x_size[3]-1) % 8 == 0 - h = int((x_size[2] - 1) / 8 * self.zoom_factor + 1) - w = int((x_size[3] - 1) / 8 * self.zoom_factor + 1) - - x = self.layer0(x) - x = self.layer1(x) - x = self.layer2(x) - x_tmp = self.layer3(x) - x = self.layer4(x_tmp) - - if self.use_ppm: - x = self.ppm(x) - x = self.cls(x) - if self.zoom_factor != 1: - x = F.interpolate(x, size=(h, w), mode='bilinear', align_corners=True) - - if self.training: - aux = self.aux(x_tmp) - if self.zoom_factor != 1: - aux = F.interpolate(aux, size=(h, w), mode='bilinear', align_corners=True) - main_loss = self.criterion(x, y) - aux_loss = self.criterion(aux, y) - return x.max(1)[1], main_loss, aux_loss - else: - return x - - -if __name__ == '__main__': - # 1. Build the PSPNet with RepVGG backbone. Download the ImageNet-pretrained weight file and load it. - model = PSPNet(backbone_name='RepVGG-A0', backbone_file='RepVGG-A0-train.pth', deploy=False, classes=19, pretrained=True) - - # 2. Train it - # seg_train(model) - - # 3. Convert and check the equivalence - input = torch.rand(4, 3, 713, 713) - model.eval() - print(model) - y_train = model(input) - for module in model.modules(): - if hasattr(module, 'switch_to_deploy'): - module.switch_to_deploy() - y_deploy = model(input) - print('output is ', y_deploy.size()) - print('=================== The diff is') - print(((y_deploy - y_train) ** 2).sum()) - - # 4. Save the converted model - torch.save(model.state_dict(), 'PSPNet-RepVGG-A0-deploy.pth') - del model # Or do whatever you want with it - - # 5. For inference, load the saved model. There is no need to load the ImageNet-pretrained weights again. - deploy_model = PSPNet(backbone_name='RepVGG-A0', backbone_file=None, deploy=True, classes=19, pretrained=False) - deploy_model.eval() - deploy_model.load_state_dict(torch.load('PSPNet-RepVGG-A0-deploy.pth')) - - # 6. Check again or do whatever you want - y_deploy = deploy_model(input) - print('=================== The diff is') - print(((y_deploy - y_train) ** 2).sum()) \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/jizhi_submit_train_repvgg.py b/cv/classification/repvgg/pytorch/jizhi_submit_train_repvgg.py deleted file mode 100755 index 8debce4d2..000000000 --- a/cv/classification/repvgg/pytorch/jizhi_submit_train_repvgg.py +++ /dev/null @@ -1,34 +0,0 @@ -import argparse -import datetime -import os -import json - -parser = argparse.ArgumentParser('JIZHI submit', add_help=False) -parser.add_argument('arch', default=None, type=str) -parser.add_argument('tag', default=None, type=str) -parser.add_argument('--config', default='/apdcephfs_cq2/share_1290939/xiaohanding/cnt/default_V100x8_elastic_config.json', type=str, - help='config file') - - -args = parser.parse_args() -run_dir = f'{args.arch}_{args.tag}' - -cmd = f'python3 -m torch.distributed.launch --nproc_per_node 8 --master_port 12349 main.py ' \ - f'--arch {args.arch} --batch-size 32 --tag {args.tag} --output-dir /apdcephfs_cq2/share_1290939/xiaohanding/swin_exps/{args.arch}_{args.tag} --opts TRAIN.EPOCHS 120 TRAIN.BASE_LR 0.1 TRAIN.WEIGHT_DECAY 4e-5 TRAIN.WARMUP_EPOCHS 5 MODEL.LABEL_SMOOTHING 0.1 AUG.PRESET raug15 DATA.DATASET imagenet' - -os.system('cd /apdcephfs_cq2/share_1290939/xiaohanding/RepVGG/') -os.system(f'mkdir runs/{run_dir}') -with open(f'runs/{run_dir}/start.sh', 'w') as f: - f.write(cmd) -with open(args.config, 'r') as f: - json_content = json.load(f) -json_content['model_local_file_path'] = f'/apdcephfs_cq2/share_1290939/xiaohanding/RepVGG/runs/{run_dir}' -config_file_path = f'/apdcephfs_cq2/share_1290939/xiaohanding/RepVGG/runs/{run_dir}/config.json' -with open(config_file_path, 'w') as f: - json.dump(json_content, f) - -os.system(f'cp *.py runs/{run_dir}/') -os.system(f'cp -r data runs/{run_dir}/') -os.system(f'cp -r train runs/{run_dir}/') -os.system(f'cd runs/{run_dir}') -os.system(f'jizhi_client start -scfg {config_file_path}') \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/main.py b/cv/classification/repvgg/pytorch/main.py deleted file mode 100755 index c721c14bd..000000000 --- a/cv/classification/repvgg/pytorch/main.py +++ /dev/null @@ -1,414 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- -import time -import argparse -import datetime -import numpy as np -import torch -import torch.backends.cudnn as cudnn -import torch.distributed as dist -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.utils import accuracy, AverageMeter -from train.config import get_config -from data import build_loader -from train.lr_scheduler import build_scheduler -from train.logger import create_logger -from utils import load_checkpoint, save_checkpoint, get_grad_norm, auto_resume_helper, reduce_tensor, save_latest, update_model_ema, unwrap_model -import copy -from train.optimizer import build_optimizer -from repvggplus import create_RepVGGplus_by_name - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - -def parse_option(): - parser = argparse.ArgumentParser('RepOpt-VGG training script built on the codebase of Swin Transformer', add_help=False) - parser.add_argument( - "--opts", - help="Modify config options by adding 'KEY VALUE' pairs. ", - default=None, - nargs='+', - ) - - # easy config modification - parser.add_argument('--arch', default=None, type=str, help='arch name') - parser.add_argument('--batch-size', default=128, type=int, help="batch size for single GPU") - parser.add_argument('--data-path', default='/your/path/to/dataset', type=str, help='path to dataset') - parser.add_argument('--scales-path', default=None, type=str, help='path to the trained Hyper-Search model') - parser.add_argument('--zip', action='store_true', help='use zipped dataset instead of folder dataset') - parser.add_argument('--cache-mode', type=str, default='part', choices=['no', 'full', 'part'], - help='no: no cache, ' - 'full: cache all data, ' - 'part: sharding the dataset into nonoverlapping pieces and only cache one piece') - parser.add_argument('--resume', help='resume from checkpoint') - parser.add_argument('--accumulation-steps', type=int, help="gradient accumulation steps") - parser.add_argument('--use-checkpoint', action='store_true', - help="whether to use gradient checkpointing to save memory") - parser.add_argument('--amp-opt-level', type=str, default='O0', choices=['O0', 'O1', 'O2'], #TODO Note: use amp if you have it - help='mixed precision opt level, if O0, no amp is used') - parser.add_argument('--output', default='/your/path/to/save/dir', type=str, metavar='PATH', - help='root of output folder, the full path is // (default: output)') - parser.add_argument('--tag', help='tag of experiment') - parser.add_argument('--eval', action='store_true', help='Perform evaluation only') - parser.add_argument('--throughput', action='store_true', help='Test throughput only') - - # distributed training - parser.add_argument("--local_rank", type=int, default=0, help='local rank for DistributedDataParallel') - - args, unparsed = parser.parse_known_args() - - config = get_config(args) - - return args, config - - - - - -def main(config): - dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn = build_loader(config) - - logger.info(f"Creating model:{config.MODEL.ARCH}") - - model = create_RepVGGplus_by_name(config.MODEL.ARCH, deploy=False, use_checkpoint=args.use_checkpoint) - optimizer = build_optimizer(config, model) - - logger.info(str(model)) - model.cuda() - - if torch.cuda.device_count() > 1: - if config.AMP_OPT_LEVEL != "O0": - model, optimizer = amp.initialize(model, optimizer, opt_level=config.AMP_OPT_LEVEL) - model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.LOCAL_RANK], - broadcast_buffers=False) - model_without_ddp = model.module - else: - if config.AMP_OPT_LEVEL != "O0": - model, optimizer = amp.initialize(model, optimizer, opt_level=config.AMP_OPT_LEVEL) - model_without_ddp = model - - n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params: {n_parameters}") - if hasattr(model_without_ddp, 'flops'): - flops = model_without_ddp.flops() - logger.info(f"number of GFLOPs: {flops / 1e9}") - - if config.THROUGHPUT_MODE: - throughput(data_loader_val, model, logger) - return - - if config.EVAL_MODE: - load_weights(model, config.MODEL.RESUME) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Only eval. top-1 acc, top-5 acc, loss: {acc1:.3f}, {acc5:.3f}, {loss:.5f}") - return - - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train)) - - if config.AUG.MIXUP > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif config.MODEL.LABEL_SMOOTHING > 0.: - criterion = LabelSmoothingCrossEntropy(smoothing=config.MODEL.LABEL_SMOOTHING) - else: - criterion = torch.nn.CrossEntropyLoss() - - max_accuracy = 0.0 - max_ema_accuracy = 0.0 - - if config.TRAIN.EMA_ALPHA > 0 and (not config.EVAL_MODE) and (not config.THROUGHPUT_MODE): - model_ema = copy.deepcopy(model) - else: - model_ema = None - - if config.TRAIN.AUTO_RESUME: - resume_file = auto_resume_helper(config.OUTPUT) - if resume_file: - if config.MODEL.RESUME: - logger.warning(f"auto-resume changing resume file from {config.MODEL.RESUME} to {resume_file}") - config.defrost() - config.MODEL.RESUME = resume_file - config.freeze() - logger.info(f'auto resuming from {resume_file}') - else: - logger.info(f'no checkpoint found in {config.OUTPUT}, ignoring auto resume') - - if (not config.THROUGHPUT_MODE) and config.MODEL.RESUME: - max_accuracy = load_checkpoint(config, model_without_ddp, optimizer, lr_scheduler, logger, model_ema=model_ema) - - - logger.info("Start training") - start_time = time.time() - for epoch in range(config.TRAIN.START_EPOCH, config.TRAIN.EPOCHS): - data_loader_train.sampler.set_epoch(epoch) - - train_one_epoch(config, model, criterion, data_loader_train, optimizer, epoch, mixup_fn, lr_scheduler, model_ema=model_ema) - if dist.get_rank() == 0: - save_latest(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, model_ema=model_ema) - if epoch % config.SAVE_FREQ == 0: - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, model_ema=model_ema) - - if epoch % config.SAVE_FREQ == 0 or epoch >= (config.TRAIN.EPOCHS - 10): - - if data_loader_val is not None: - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network at epoch {epoch}: {acc1:.3f}%") - max_accuracy = max(max_accuracy, acc1) - logger.info(f'Max accuracy: {max_accuracy:.2f}%') - if max_accuracy == acc1 and dist.get_rank() == 0: - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, logger, - is_best=True, model_ema=model_ema) - - if model_ema is not None: - if data_loader_val is not None: - acc1, acc5, loss = validate(config, data_loader_val, model_ema) - logger.info(f"EMAAccuracy of the network at epoch {epoch} test images: {acc1:.3f}%") - max_ema_accuracy = max(max_ema_accuracy, acc1) - logger.info(f'EMAMax accuracy: {max_ema_accuracy:.2f}%') - if max_ema_accuracy == acc1 and dist.get_rank() == 0: - best_ema_path = os.path.join(config.OUTPUT, 'best_ema.pth') - logger.info(f"{best_ema_path} best EMA saving......") - torch.save(unwrap_model(model_ema).state_dict(), best_ema_path) - else: - latest_ema_path = os.path.join(config.OUTPUT, 'latest_ema.pth') - logger.info(f"{latest_ema_path} latest EMA saving......") - torch.save(unwrap_model(model_ema).state_dict(), latest_ema_path) - - total_time = time.time() - start_time - total_time_str = str(datetime.timedelta(seconds=int(total_time))) - logger.info('Training time {}'.format(total_time_str)) - - -def train_one_epoch(config, model, criterion, data_loader, optimizer, epoch, mixup_fn, lr_scheduler, model_ema=None): - model.train() - optimizer.zero_grad() - - num_steps = len(data_loader) - batch_time = AverageMeter() - loss_meter = AverageMeter() - norm_meter = AverageMeter() - - start = time.time() - end = time.time() - for idx, (samples, targets) in enumerate(data_loader): - samples = samples.cuda(non_blocking=True) - targets = targets.cuda(non_blocking=True) - - if mixup_fn is not None: - samples, targets = mixup_fn(samples, targets) - - outputs = model(samples) - - if type(outputs) is dict: - loss = 0.0 - for name, pred in outputs.items(): - if 'aux' in name: - loss += 0.1 * criterion(pred, targets) - else: - loss += criterion(pred, targets) - else: - loss = criterion(outputs, targets) - - if config.TRAIN.ACCUMULATION_STEPS > 1: - - loss = loss / config.TRAIN.ACCUMULATION_STEPS - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - if (idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0: - optimizer.step() - optimizer.zero_grad() - lr_scheduler.step_update(epoch * num_steps + idx) - - else: - - optimizer.zero_grad() - if config.AMP_OPT_LEVEL != "O0": - with amp.scale_loss(loss, optimizer) as scaled_loss: - scaled_loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(amp.master_params(optimizer), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(amp.master_params(optimizer)) - else: - loss.backward() - if config.TRAIN.CLIP_GRAD: - grad_norm = torch.nn.utils.clip_grad_norm_(model.parameters(), config.TRAIN.CLIP_GRAD) - else: - grad_norm = get_grad_norm(model.parameters()) - optimizer.step() - lr_scheduler.step_update(epoch * num_steps + idx) - - torch.cuda.synchronize() - - loss_meter.update(loss.item(), targets.size(0)) - norm_meter.update(grad_norm) - batch_time.update(time.time() - end) - - if model_ema is not None: - update_model_ema(config, dist.get_world_size(), model=model, model_ema=model_ema, cur_epoch=epoch, cur_iter=idx) - - end = time.time() - - if idx % config.PRINT_FREQ == 0: - lr = optimizer.param_groups[0]['lr'] - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - etas = batch_time.avg * (num_steps - idx) - logger.info( - f'Train: [{epoch}/{config.TRAIN.EPOCHS}][{idx}/{num_steps}]\t' - f'eta {datetime.timedelta(seconds=int(etas))} lr {lr:.6f}\t' - f'time {batch_time.val:.4f} ({batch_time.avg:.4f})\t' - f'loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'grad_norm {norm_meter.val:.4f} ({norm_meter.avg:.4f})\t' - f'mem {memory_used:.0f}MB') - epoch_time = time.time() - start - logger.info(f"EPOCH {epoch} training takes {datetime.timedelta(seconds=int(epoch_time))}") - - -@torch.no_grad() -def validate(config, data_loader, model): - criterion = torch.nn.CrossEntropyLoss() - model.eval() - - batch_time = AverageMeter() - loss_meter = AverageMeter() - acc1_meter = AverageMeter() - acc5_meter = AverageMeter() - - end = time.time() - for idx, (images, target) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - output = model(images) - - # =============================== deepsup part - if type(output) is dict: - output = output['main'] - - # measure accuracy and record loss - loss = criterion(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - acc1 = reduce_tensor(acc1) - acc5 = reduce_tensor(acc5) - loss = reduce_tensor(loss) - - loss_meter.update(loss.item(), target.size(0)) - acc1_meter.update(acc1.item(), target.size(0)) - acc5_meter.update(acc5.item(), target.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - logger.info( - f'Test: [{idx}/{len(data_loader)}]\t' - f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' - f'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' - f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' - f'Mem {memory_used:.0f}MB') - logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') - return acc1_meter.avg, acc5_meter.avg, loss_meter.avg - - -@torch.no_grad() -def throughput(data_loader, model, logger): - model.eval() - - for idx, (images, _) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - - batch_size = images.shape[0] - for i in range(50): - model(images) - torch.cuda.synchronize() - logger.info(f"throughput averaged with 30 times") - tic1 = time.time() - for i in range(30): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - throughput = 30 * batch_size / (tic2 - tic1) - logger.info(f"batch_size {batch_size} throughput {throughput}") - return - - -import os - -if __name__ == '__main__': - args, config = parse_option() - - if config.AMP_OPT_LEVEL != "O0": - assert amp is not None, "amp not installed!" - - if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ: - rank = int(os.environ["RANK"]) - world_size = int(os.environ['WORLD_SIZE']) - else: - rank = -1 - world_size = -1 - torch.cuda.set_device(config.LOCAL_RANK) - torch.distributed.init_process_group(backend='nccl', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.barrier() - seed = config.SEED + dist.get_rank() - - torch.manual_seed(seed) - np.random.seed(seed) - cudnn.benchmark = True - - if not config.EVAL_MODE: - # linear scale the learning rate according to total batch size, may not be optimal - linear_scaled_lr = config.TRAIN.BASE_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - linear_scaled_warmup_lr = config.TRAIN.WARMUP_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - linear_scaled_min_lr = config.TRAIN.MIN_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 256.0 - # gradient accumulation also need to scale the learning rate - if config.TRAIN.ACCUMULATION_STEPS > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_warmup_lr = linear_scaled_warmup_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_min_lr = linear_scaled_min_lr * config.TRAIN.ACCUMULATION_STEPS - config.defrost() - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_LR = linear_scaled_warmup_lr - config.TRAIN.MIN_LR = linear_scaled_min_lr - config.freeze() - - print('==========================================') - print('real base lr: ', config.TRAIN.BASE_LR) - print('==========================================') - - os.makedirs(config.OUTPUT, exist_ok=True) - - logger = create_logger(output_dir=config.OUTPUT, dist_rank=0 if torch.cuda.device_count() == 1 else dist.get_rank(), name=f"{config.MODEL.ARCH}") - - if torch.cuda.device_count() == 1 or dist.get_rank() == 0: - path = os.path.join(config.OUTPUT, "config.json") - with open(path, "w") as f: - f.write(config.dump()) - logger.info(f"Full config saved to {path}") - - # print config - logger.info(config.dump()) - - main(config) diff --git a/cv/classification/repvgg/pytorch/quantization/quant_qat_train.py b/cv/classification/repvgg/pytorch/quantization/quant_qat_train.py deleted file mode 100755 index 80e1dcd06..000000000 --- a/cv/classification/repvgg/pytorch/quantization/quant_qat_train.py +++ /dev/null @@ -1,426 +0,0 @@ -import argparse -import random -import shutil -import time -import warnings -import torch.nn as nn -import torch.nn.parallel -import torch.backends.cudnn as cudnn -import torch.distributed as dist -import torch.optim -import torch.multiprocessing as mp -import torch.utils.data -import torch.utils.data.distributed -from utils import * -import torchvision.transforms as transforms -import PIL - -best_acc1 = 0 - -IMAGENET_TRAINSET_SIZE = 1281167 - -parser = argparse.ArgumentParser(description='PyTorch Whole Model Quant') -parser.add_argument('data', metavar='DIR', - help='path to dataset') -parser.add_argument('-a', '--arch', metavar='ARCH', default='RepVGG-A0') -parser.add_argument('-j', '--workers', default=8, type=int, metavar='N', - help='number of data loading workers (default: 4)') -parser.add_argument('--epochs', default=8, type=int, metavar='N', - help='number of epochs for each run') -parser.add_argument('--start-epoch', default=0, type=int, metavar='N', - help='manual epoch number (useful on restarts)') -parser.add_argument('-b', '--batch-size', default=256, type=int, - metavar='N', - help='mini-batch size (default: 256), this is the total ' - 'batch size of all GPUs on the current node when ' - 'using Data Parallel or Distributed Data Parallel') -parser.add_argument('--val-batch-size', default=100, type=int, metavar='V', - help='validation batch size') -parser.add_argument('--lr', '--learning-rate', default=1e-4, type=float, - metavar='LR', help='learning rate for finetuning', dest='lr') -parser.add_argument('--momentum', default=0.9, type=float, metavar='M', - help='momentum') -parser.add_argument('--wd', '--weight-decay', default=1e-4, type=float, - metavar='W', help='weight decay (default: 1e-4)', - dest='weight_decay') -parser.add_argument('-p', '--print-freq', default=10, type=int, - metavar='N', help='print frequency (default: 10)') -parser.add_argument('--resume', default='', type=str, metavar='PATH', - help='path to latest checkpoint (default: none)') -parser.add_argument('-e', '--evaluate', dest='evaluate', action='store_true', - help='evaluate model on validation set') -parser.add_argument('--world-size', default=-1, type=int, - help='number of nodes for distributed training') -parser.add_argument('--rank', default=-1, type=int, - help='node rank for distributed training') -parser.add_argument('--dist-url', default='tcp://127.0.0.1:23333', type=str, - help='url used to set up distributed training') -parser.add_argument('--dist-backend', default='nccl', type=str, - help='distributed backend') -parser.add_argument('--seed', default=None, type=int, - help='seed for initializing training. ') -parser.add_argument('--gpu', default=None, type=int, - help='GPU id to use.') -parser.add_argument('--multiprocessing-distributed', action='store_true', - help='Use multi-processing distributed training to launch ' - 'N processes per node, which has N GPUs. This is the ' - 'fastest way to use PyTorch for either single node or ' - 'multi node data parallel training') -parser.add_argument('--base-weights', default=None, type=str, - help='weights of the base model.') -parser.add_argument('--tag', default='testtest', type=str, - help='the tag for identifying the log and model files. Just a string.') -parser.add_argument('--fpfinetune', dest='fpfinetune', action='store_true', - help='full precision finetune') -parser.add_argument('--fixobserver', dest='fixobserver', action='store_true', - help='fix observer?') -parser.add_argument('--fixbn', dest='fixbn', action='store_true', - help='fix bn?') -parser.add_argument('--quantlayers', default='all', type=str, choices=['all', 'exclud_first_and_linear', 'exclud_first_and_last'], - help='the tag for identifying the log and model files. Just a string.') - - - -def sgd_optimizer(model, lr, momentum, weight_decay): - params = [] - for key, value in model.named_parameters(): - if not value.requires_grad: - continue - apply_weight_decay = weight_decay - apply_lr = lr - if value.ndimension() < 2: #TODO note this - apply_weight_decay = 0 - print('set weight decay=0 for {}'.format(key)) - if 'bias' in key: - apply_lr = 2 * lr # Just a Caffe-style common practice. Made no difference. - params += [{'params': [value], 'lr': apply_lr, 'weight_decay': apply_weight_decay}] - optimizer = torch.optim.SGD(params, lr, momentum=momentum) - return optimizer - -def main(): - args = parser.parse_args() - - if args.seed is not None: - random.seed(args.seed) - torch.manual_seed(args.seed) - cudnn.deterministic = True - warnings.warn('You have chosen to seed training. ' - 'This will turn on the CUDNN deterministic setting, ' - 'which can slow down your training considerably! ' - 'You may see unexpected behavior when restarting ' - 'from checkpoints.') - - if args.gpu is not None: - warnings.warn('You have chosen a specific GPU. This will completely ' - 'disable data parallelism.') - - if args.dist_url == "env://" and args.world_size == -1: - args.world_size = int(os.environ["WORLD_SIZE"]) - - args.distributed = args.world_size > 1 or args.multiprocessing_distributed - - ngpus_per_node = torch.cuda.device_count() - if args.multiprocessing_distributed: - # Since we have ngpus_per_node processes per node, the total world_size - # needs to be adjusted accordingly - args.world_size = ngpus_per_node * args.world_size - # Use torch.multiprocessing.spawn to launch distributed processes: the - # main_worker process function - mp.spawn(main_worker, nprocs=ngpus_per_node, args=(ngpus_per_node, args)) - else: - # Simply call main_worker function - main_worker(args.gpu, ngpus_per_node, args) - - - - -def get_default_train_trans(args): - normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], - std=[0.229, 0.224, 0.225]) - if (not hasattr(args, 'resolution')) or args.resolution == 224: - trans = transforms.Compose([ - transforms.RandomResizedCrop(224), - transforms.RandomHorizontalFlip(), - transforms.ToTensor(), - normalize]) - else: - raise ValueError('Not yet implemented.') - return trans - - -def get_default_val_trans(args): - normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], - std=[0.229, 0.224, 0.225]) - if (not hasattr(args, 'resolution')) or args.resolution == 224: - trans = transforms.Compose([ - transforms.Resize(256), - transforms.CenterCrop(224), - transforms.ToTensor(), - normalize]) - else: - trans = transforms.Compose([ - transforms.Resize(args.resolution, interpolation=PIL.Image.BILINEAR), - transforms.CenterCrop(args.resolution), - transforms.ToTensor(), - normalize, - ]) - return trans - -def main_worker(gpu, ngpus_per_node, args): - global best_acc1 - args.gpu = gpu - log_file = 'quant_{}_exp.txt'.format(args.tag) - - if args.gpu is not None: - print("Use GPU: {} for training".format(args.gpu)) - - if args.distributed: - if args.dist_url == "env://" and args.rank == -1: - args.rank = int(os.environ["RANK"]) - if args.multiprocessing_distributed: - # For multiprocessing distributed training, rank needs to be the - # global rank among all the processes - args.rank = args.rank * ngpus_per_node + gpu - dist.init_process_group(backend=args.dist_backend, init_method=args.dist_url, - world_size=args.world_size, rank=args.rank) - - # 1. Build and load base model - from repvgg import get_RepVGG_func_by_name - repvgg_build_func = get_RepVGG_func_by_name(args.arch) - base_model = repvgg_build_func(deploy=True) - from tools.insert_bn import directly_insert_bn_without_init - directly_insert_bn_without_init(base_model) - if args.base_weights is not None: - load_checkpoint(base_model, args.base_weights) - - # 2. - if not args.fpfinetune: - from quantization.repvgg_quantized import RepVGGWholeQuant - qat_model = RepVGGWholeQuant(repvgg_model=base_model, quantlayers=args.quantlayers) - qat_model.prepare_quant() - else: - qat_model = base_model - log_msg('===================== not QAT, just full-precision finetune ===========', log_file) - - #=================================================== - # From now on, the code will be very similar to ordinary training - # =================================================== - - is_main = not args.multiprocessing_distributed or (args.multiprocessing_distributed and args.rank % ngpus_per_node == 0) - - if is_main: - for n, p in qat_model.named_parameters(): - print(n, p.size()) - for n, p in qat_model.named_buffers(): - print(n, p.size()) - log_msg('epochs {}, lr {}, weight_decay {}'.format(args.epochs, args.lr, args.weight_decay), log_file) - # You will see it now has quantization-related parameters (zero-points and scales) - - if not torch.cuda.is_available(): - print('using CPU, this will be slow') - elif args.distributed: - if args.gpu is not None: - torch.cuda.set_device(args.gpu) - qat_model.cuda(args.gpu) - args.batch_size = int(args.batch_size / ngpus_per_node) - args.workers = int((args.workers + ngpus_per_node - 1) / ngpus_per_node) - qat_model = torch.nn.parallel.DistributedDataParallel(qat_model, device_ids=[args.gpu]) - else: - qat_model.cuda() - qat_model = torch.nn.parallel.DistributedDataParallel(qat_model) - elif args.gpu is not None: - torch.cuda.set_device(args.gpu) - qat_model = qat_model.cuda(args.gpu) - else: - # DataParallel will divide and allocate batch_size to all available GPUs - qat_model = torch.nn.DataParallel(qat_model).cuda() - - - criterion = nn.CrossEntropyLoss().cuda(args.gpu) - optimizer = sgd_optimizer(qat_model, args.lr, args.momentum, args.weight_decay) - - warmup_epochs = 1 - lr_scheduler = WarmupCosineAnnealingLR(optimizer=optimizer, T_cosine_max=args.epochs * IMAGENET_TRAINSET_SIZE // args.batch_size // ngpus_per_node, - eta_min=0, warmup=warmup_epochs * IMAGENET_TRAINSET_SIZE // args.batch_size // ngpus_per_node) - - - # optionally resume from a checkpoint - if args.resume: - if os.path.isfile(args.resume): - print("=> loading checkpoint '{}'".format(args.resume)) - if args.gpu is None: - checkpoint = torch.load(args.resume) - else: - # Map model to be loaded to specified single gpu. - loc = 'cuda:{}'.format(args.gpu) - checkpoint = torch.load(args.resume, map_location=loc) - args.start_epoch = checkpoint['epoch'] - best_acc1 = checkpoint['best_acc1'] - if args.gpu is not None: - # best_acc1 may be from a checkpoint from a different GPU - best_acc1 = best_acc1.to(args.gpu) - qat_model.load_state_dict(checkpoint['state_dict']) - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['scheduler']) - print("=> loaded checkpoint '{}' (epoch {})" - .format(args.resume, checkpoint['epoch'])) - else: - print("=> no checkpoint found at '{}'".format(args.resume)) - - cudnn.benchmark = True - - # todo - train_sampler, train_loader = get_default_ImageNet_train_sampler_loader(args) - val_loader = get_default_ImageNet_val_loader(args) - - if args.evaluate: - validate(val_loader, qat_model, criterion, args) - return - - for epoch in range(args.start_epoch, args.epochs): - if args.distributed: - train_sampler.set_epoch(epoch) - - # train for one epoch - train(train_loader, qat_model, criterion, optimizer, epoch, args, lr_scheduler, is_main=is_main) - - if args.fixobserver and epoch > (3 * args.epochs // 8): - # Freeze quantizer parameters - qat_model.apply(torch.quantization.disable_observer) #TODO testing. May not be useful - log_msg('fix observer after epoch {}'.format(epoch), log_file) - - if args.fixbn and epoch > (2 * args.epochs // 8): #TODO testing. May not be useful - # Freeze batch norm mean and variance estimates - qat_model.apply(torch.nn.intrinsic.qat.freeze_bn_stats) - log_msg('fix bn after epoch {}'.format(epoch), log_file) - - # evaluate on validation set - if is_main: - acc1 = validate(val_loader, qat_model, criterion, args) - msg = '{}, base{}, quant, epoch {}, QAT acc {}'.format(args.arch, args.base_weights, epoch, acc1) - log_msg(msg, log_file) - - is_best = acc1 > best_acc1 - best_acc1 = max(acc1, best_acc1) - - save_checkpoint({ - 'epoch': epoch + 1, - 'arch': args.arch, - 'state_dict': qat_model.state_dict(), - 'best_acc1': best_acc1, - 'optimizer' : optimizer.state_dict(), - 'scheduler': lr_scheduler.state_dict(), - }, is_best, - filename = '{}_{}.pth.tar'.format(args.arch, args.tag), - best_filename='{}_{}_best.pth.tar'.format(args.arch, args.tag)) - - -def train(train_loader, model, criterion, optimizer, epoch, args, lr_scheduler, is_main): - batch_time = AverageMeter('Time', ':6.3f') - data_time = AverageMeter('Data', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - progress = ProgressMeter( - len(train_loader), - [batch_time, data_time, losses, top1, top5, ], - prefix="Epoch: [{}]".format(epoch)) - - # switch to train mode - model.train() - - end = time.time() - for i, (images, target) in enumerate(train_loader): - # measure data loading time - data_time.update(time.time() - end) - - if args.gpu is not None: - images = images.cuda(args.gpu, non_blocking=True) - if torch.cuda.is_available(): - target = target.cuda(args.gpu, non_blocking=True) - - # compute output - - output = model(images) - loss = criterion(output, target) - - # measure accuracy and record loss - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - losses.update(loss.item(), images.size(0)) - top1.update(acc1[0], images.size(0)) - top5.update(acc5[0], images.size(0)) - - # compute gradient and do SGD step - optimizer.zero_grad() - loss.backward() - optimizer.step() - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if lr_scheduler is not None: - lr_scheduler.step() - - if is_main and i % args.print_freq == 0: - progress.display(i) - if is_main and i % 1000 == 0 and lr_scheduler is not None: - print('cur lr: ', lr_scheduler.get_lr()[0]) - - - - -def validate(val_loader, model, criterion, args): - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - progress = ProgressMeter( - len(val_loader), - [batch_time, losses, top1, top5], - prefix='Test: ') - - # switch to evaluate mode - model.eval() - - with torch.no_grad(): - end = time.time() - for i, (images, target) in enumerate(val_loader): - images = images.cuda(args.gpu, non_blocking=True) - target = target.cuda(args.gpu, non_blocking=True) - - # compute output - output = model(images) - loss = criterion(output, target) - - # measure accuracy and record loss - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - losses.update(loss.item(), images.size(0)) - top1.update(acc1[0], images.size(0)) - top5.update(acc5[0], images.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if i % args.print_freq == 0: - progress.display(i) - - # TODO: this should also be done with the ProgressMeter - print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}' - .format(top1=top1, top5=top5)) - - return top1.avg - - -def save_checkpoint(state, is_best, filename, best_filename): - torch.save(state, filename) - if is_best: - shutil.copyfile(filename, best_filename) - - - - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/quantization/repvgg_quantized.py b/cv/classification/repvgg/pytorch/quantization/repvgg_quantized.py deleted file mode 100755 index 9a06a89c7..000000000 --- a/cv/classification/repvgg/pytorch/quantization/repvgg_quantized.py +++ /dev/null @@ -1,63 +0,0 @@ -import torch -import torch.nn as nn -from torch.quantization import QuantStub, DeQuantStub - -class RepVGGWholeQuant(nn.Module): - - def __init__(self, repvgg_model, quantlayers): - super(RepVGGWholeQuant, self).__init__() - assert quantlayers in ['all', 'exclud_first_and_linear', 'exclud_first_and_last'] - self.quantlayers = quantlayers - self.quant = QuantStub() - self.stage0, self.stage1, self.stage2, self.stage3, self.stage4 = repvgg_model.stage0, repvgg_model.stage1, repvgg_model.stage2, repvgg_model.stage3, repvgg_model.stage4 - self.gap, self.linear = repvgg_model.gap, repvgg_model.linear - self.dequant = DeQuantStub() - - - def forward(self, x): - if self.quantlayers == 'all': - x = self.quant(x) - out = self.stage0(x) - else: - out = self.stage0(x) - out = self.quant(out) - out = self.stage1(out) - out = self.stage2(out) - out = self.stage3(out) - if self.quantlayers == 'all': - out = self.stage4(out) - out = self.gap(out).view(out.size(0), -1) - out = self.linear(out) - out = self.dequant(out) - elif self.quantlayers == 'exclud_first_and_linear': - out = self.stage4(out) - out = self.dequant(out) - out = self.gap(out).view(out.size(0), -1) - out = self.linear(out) - else: - out = self.dequant(out) - out = self.stage4(out) - out = self.gap(out).view(out.size(0), -1) - out = self.linear(out) - return out - - # From https://pytorch.org/tutorials/advanced/static_quantization_tutorial.html - def fuse_model(self): - for m in self.modules(): - if type(m) == nn.Sequential and hasattr(m, 'conv'): - # Note that we moved ReLU from "block.nonlinearity" into "rbr_reparam" (nn.Sequential). - # This makes it more convenient to fuse operators using off-the-shelf APIs. - torch.quantization.fuse_modules(m, ['conv', 'bn', 'relu'], inplace=True) - - def _get_qconfig(self): - return torch.quantization.get_default_qat_qconfig('fbgemm') - - def prepare_quant(self): - # From https://pytorch.org/tutorials/advanced/static_quantization_tutorial.html - self.fuse_model() - qconfig = self._get_qconfig() - self.qconfig = qconfig - torch.quantization.prepare_qat(self, inplace=True) - - def freeze_quant_bn(self): - self.apply(torch.nn.intrinsic.qat.freeze_bn_stats) \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/repvgg.py b/cv/classification/repvgg/pytorch/repvgg.py deleted file mode 100755 index 92bd07f46..000000000 --- a/cv/classification/repvgg/pytorch/repvgg.py +++ /dev/null @@ -1,303 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- -import torch.nn as nn -import numpy as np -import torch -import copy -from se_block import SEBlock -import torch.utils.checkpoint as checkpoint - -def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - return result - -class RepVGGBlock(nn.Module): - - def __init__(self, in_channels, out_channels, kernel_size, - stride=1, padding=0, dilation=1, groups=1, padding_mode='zeros', deploy=False, use_se=False): - super(RepVGGBlock, self).__init__() - self.deploy = deploy - self.groups = groups - self.in_channels = in_channels - - assert kernel_size == 3 - assert padding == 1 - - padding_11 = padding - kernel_size // 2 - - self.nonlinearity = nn.ReLU() - - if use_se: - # Note that RepVGG-D2se uses SE before nonlinearity. But RepVGGplus models uses SE after nonlinearity. - self.se = SEBlock(out_channels, internal_neurons=out_channels // 16) - else: - self.se = nn.Identity() - - if deploy: - self.rbr_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, - padding=padding, dilation=dilation, groups=groups, bias=True, padding_mode=padding_mode) - - else: - self.rbr_identity = nn.BatchNorm2d(num_features=in_channels) if out_channels == in_channels and stride == 1 else None - self.rbr_dense = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups) - self.rbr_1x1 = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride, padding=padding_11, groups=groups) - print('RepVGG Block, identity = ', self.rbr_identity) - - - def forward(self, inputs): - if hasattr(self, 'rbr_reparam'): - return self.nonlinearity(self.se(self.rbr_reparam(inputs))) - - if self.rbr_identity is None: - id_out = 0 - else: - id_out = self.rbr_identity(inputs) - - return self.nonlinearity(self.se(self.rbr_dense(inputs) + self.rbr_1x1(inputs) + id_out)) - - - # Optional. This may improve the accuracy and facilitates quantization in some cases. - # 1. Cancel the original weight decay on rbr_dense.conv.weight and rbr_1x1.conv.weight. - # 2. Use like this. - # loss = criterion(....) - # for every RepVGGBlock blk: - # loss += weight_decay_coefficient * 0.5 * blk.get_cust_L2() - # optimizer.zero_grad() - # loss.backward() - def get_custom_L2(self): - K3 = self.rbr_dense.conv.weight - K1 = self.rbr_1x1.conv.weight - t3 = (self.rbr_dense.bn.weight / ((self.rbr_dense.bn.running_var + self.rbr_dense.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() - t1 = (self.rbr_1x1.bn.weight / ((self.rbr_1x1.bn.running_var + self.rbr_1x1.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() - - l2_loss_circle = (K3 ** 2).sum() - (K3[:, :, 1:2, 1:2] ** 2).sum() # The L2 loss of the "circle" of weights in 3x3 kernel. Use regular L2 on them. - eq_kernel = K3[:, :, 1:2, 1:2] * t3 + K1 * t1 # The equivalent resultant central point of 3x3 kernel. - l2_loss_eq_kernel = (eq_kernel ** 2 / (t3 ** 2 + t1 ** 2)).sum() # Normalize for an L2 coefficient comparable to regular L2. - return l2_loss_eq_kernel + l2_loss_circle - - - -# This func derives the equivalent kernel and bias in a DIFFERENTIABLE way. -# You can get the equivalent kernel and bias at any time and do whatever you want, - # for example, apply some penalties or constraints during training, just like you do to the other models. -# May be useful for quantization or pruning. - def get_equivalent_kernel_bias(self): - kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense) - kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1) - kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity) - return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid - - def _pad_1x1_to_3x3_tensor(self, kernel1x1): - if kernel1x1 is None: - return 0 - else: - return torch.nn.functional.pad(kernel1x1, [1,1,1,1]) - - def _fuse_bn_tensor(self, branch): - if branch is None: - return 0, 0 - if isinstance(branch, nn.Sequential): - kernel = branch.conv.weight - running_mean = branch.bn.running_mean - running_var = branch.bn.running_var - gamma = branch.bn.weight - beta = branch.bn.bias - eps = branch.bn.eps - else: - assert isinstance(branch, nn.BatchNorm2d) - if not hasattr(self, 'id_tensor'): - input_dim = self.in_channels // self.groups - kernel_value = np.zeros((self.in_channels, input_dim, 3, 3), dtype=np.float32) - for i in range(self.in_channels): - kernel_value[i, i % input_dim, 1, 1] = 1 - self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device) - kernel = self.id_tensor - running_mean = branch.running_mean - running_var = branch.running_var - gamma = branch.weight - beta = branch.bias - eps = branch.eps - std = (running_var + eps).sqrt() - t = (gamma / std).reshape(-1, 1, 1, 1) - return kernel * t, beta - running_mean * gamma / std - - def switch_to_deploy(self): - if hasattr(self, 'rbr_reparam'): - return - kernel, bias = self.get_equivalent_kernel_bias() - self.rbr_reparam = nn.Conv2d(in_channels=self.rbr_dense.conv.in_channels, out_channels=self.rbr_dense.conv.out_channels, - kernel_size=self.rbr_dense.conv.kernel_size, stride=self.rbr_dense.conv.stride, - padding=self.rbr_dense.conv.padding, dilation=self.rbr_dense.conv.dilation, groups=self.rbr_dense.conv.groups, bias=True) - self.rbr_reparam.weight.data = kernel - self.rbr_reparam.bias.data = bias - self.__delattr__('rbr_dense') - self.__delattr__('rbr_1x1') - if hasattr(self, 'rbr_identity'): - self.__delattr__('rbr_identity') - if hasattr(self, 'id_tensor'): - self.__delattr__('id_tensor') - self.deploy = True - - - -class RepVGG(nn.Module): - - def __init__(self, num_blocks, num_classes=1000, width_multiplier=None, override_groups_map=None, deploy=False, use_se=False, use_checkpoint=False): - super(RepVGG, self).__init__() - assert len(width_multiplier) == 4 - self.deploy = deploy - self.override_groups_map = override_groups_map or dict() - assert 0 not in self.override_groups_map - self.use_se = use_se - self.use_checkpoint = use_checkpoint - - self.in_planes = min(64, int(64 * width_multiplier[0])) - self.stage0 = RepVGGBlock(in_channels=3, out_channels=self.in_planes, kernel_size=3, stride=2, padding=1, deploy=self.deploy, use_se=self.use_se) - self.cur_layer_idx = 1 - self.stage1 = self._make_stage(int(64 * width_multiplier[0]), num_blocks[0], stride=2) - self.stage2 = self._make_stage(int(128 * width_multiplier[1]), num_blocks[1], stride=2) - self.stage3 = self._make_stage(int(256 * width_multiplier[2]), num_blocks[2], stride=2) - self.stage4 = self._make_stage(int(512 * width_multiplier[3]), num_blocks[3], stride=2) - self.gap = nn.AdaptiveAvgPool2d(output_size=1) - self.linear = nn.Linear(int(512 * width_multiplier[3]), num_classes) - - def _make_stage(self, planes, num_blocks, stride): - strides = [stride] + [1]*(num_blocks-1) - blocks = [] - for stride in strides: - cur_groups = self.override_groups_map.get(self.cur_layer_idx, 1) - blocks.append(RepVGGBlock(in_channels=self.in_planes, out_channels=planes, kernel_size=3, - stride=stride, padding=1, groups=cur_groups, deploy=self.deploy, use_se=self.use_se)) - self.in_planes = planes - self.cur_layer_idx += 1 - return nn.ModuleList(blocks) - - def forward(self, x): - out = self.stage0(x) - for stage in (self.stage1, self.stage2, self.stage3, self.stage4): - for block in stage: - if self.use_checkpoint: - out = checkpoint.checkpoint(block, out) - else: - out = block(out) - out = self.gap(out) - out = out.view(out.size(0), -1) - out = self.linear(out) - return out - - -optional_groupwise_layers = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26] -g2_map = {l: 2 for l in optional_groupwise_layers} -g4_map = {l: 4 for l in optional_groupwise_layers} - -def create_RepVGG_A0(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[2, 4, 14, 1], num_classes=1000, - width_multiplier=[0.75, 0.75, 0.75, 2.5], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_A1(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[2, 4, 14, 1], num_classes=1000, - width_multiplier=[1, 1, 1, 2.5], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_A2(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[2, 4, 14, 1], num_classes=1000, - width_multiplier=[1.5, 1.5, 1.5, 2.75], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B0(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[1, 1, 1, 2.5], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B1(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2, 2, 2, 4], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B1g2(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2, 2, 2, 4], override_groups_map=g2_map, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B1g4(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2, 2, 2, 4], override_groups_map=g4_map, deploy=deploy, use_checkpoint=use_checkpoint) - - -def create_RepVGG_B2(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B2g2(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], override_groups_map=g2_map, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B2g4(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], override_groups_map=g4_map, deploy=deploy, use_checkpoint=use_checkpoint) - - -def create_RepVGG_B3(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[3, 3, 3, 5], override_groups_map=None, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B3g2(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[3, 3, 3, 5], override_groups_map=g2_map, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_B3g4(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[4, 6, 16, 1], num_classes=1000, - width_multiplier=[3, 3, 3, 5], override_groups_map=g4_map, deploy=deploy, use_checkpoint=use_checkpoint) - -def create_RepVGG_D2se(deploy=False, use_checkpoint=False): - return RepVGG(num_blocks=[8, 14, 24, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], override_groups_map=None, deploy=deploy, use_se=True, use_checkpoint=use_checkpoint) - - -func_dict = { -'RepVGG-A0': create_RepVGG_A0, -'RepVGG-A1': create_RepVGG_A1, -'RepVGG-A2': create_RepVGG_A2, -'RepVGG-B0': create_RepVGG_B0, -'RepVGG-B1': create_RepVGG_B1, -'RepVGG-B1g2': create_RepVGG_B1g2, -'RepVGG-B1g4': create_RepVGG_B1g4, -'RepVGG-B2': create_RepVGG_B2, -'RepVGG-B2g2': create_RepVGG_B2g2, -'RepVGG-B2g4': create_RepVGG_B2g4, -'RepVGG-B3': create_RepVGG_B3, -'RepVGG-B3g2': create_RepVGG_B3g2, -'RepVGG-B3g4': create_RepVGG_B3g4, -'RepVGG-D2se': create_RepVGG_D2se, # Updated at April 25, 2021. This is not reported in the CVPR paper. -} -def get_RepVGG_func_by_name(name): - return func_dict[name] - - - -# Use this for converting a RepVGG model or a bigger model with RepVGG as its component -# Use like this -# model = create_RepVGG_A0(deploy=False) -# train model or load weights -# repvgg_model_convert(model, save_path='repvgg_deploy.pth') -# If you want to preserve the original model, call with do_copy=True - -# ====================== for using RepVGG as the backbone of a bigger model, e.g., PSPNet, the pseudo code will be like -# train_backbone = create_RepVGG_B2(deploy=False) -# train_backbone.load_state_dict(torch.load('RepVGG-B2-train.pth')) -# train_pspnet = build_pspnet(backbone=train_backbone) -# segmentation_train(train_pspnet) -# deploy_pspnet = repvgg_model_convert(train_pspnet) -# segmentation_test(deploy_pspnet) -# ===================== example_pspnet.py shows an example - -def repvgg_model_convert(model:torch.nn.Module, save_path=None, do_copy=True): - if do_copy: - model = copy.deepcopy(model) - for module in model.modules(): - if hasattr(module, 'switch_to_deploy'): - module.switch_to_deploy() - if save_path is not None: - torch.save(model.state_dict(), save_path) - return model diff --git a/cv/classification/repvgg/pytorch/repvggplus.py b/cv/classification/repvgg/pytorch/repvggplus.py deleted file mode 100755 index 9f365871b..000000000 --- a/cv/classification/repvgg/pytorch/repvggplus.py +++ /dev/null @@ -1,293 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- - -import torch.nn as nn -import torch.utils.checkpoint as checkpoint -from se_block import SEBlock -import torch -import numpy as np - -def conv_bn_relu(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - result.add_module('relu', nn.ReLU()) - return result - -def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - return result - -class RepVGGplusBlock(nn.Module): - - def __init__(self, in_channels, out_channels, kernel_size, - stride=1, padding=0, dilation=1, groups=1, padding_mode='zeros', - deploy=False, - use_post_se=False): - super(RepVGGplusBlock, self).__init__() - self.deploy = deploy - self.groups = groups - self.in_channels = in_channels - - assert kernel_size == 3 - assert padding == 1 - - self.nonlinearity = nn.ReLU() - - if use_post_se: - self.post_se = SEBlock(out_channels, internal_neurons=out_channels // 4) - else: - self.post_se = nn.Identity() - - if deploy: - self.rbr_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, - padding=padding, dilation=dilation, groups=groups, bias=True, padding_mode=padding_mode) - else: - if out_channels == in_channels and stride == 1: - self.rbr_identity = nn.BatchNorm2d(num_features=out_channels) - else: - self.rbr_identity = None - self.rbr_dense = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups) - padding_11 = padding - kernel_size // 2 - self.rbr_1x1 = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride, padding=padding_11, groups=groups) - - def forward(self, x): - if self.deploy: - return self.post_se(self.nonlinearity(self.rbr_reparam(x))) - - if self.rbr_identity is None: - id_out = 0 - else: - id_out = self.rbr_identity(x) - out = self.rbr_dense(x) + self.rbr_1x1(x) + id_out - out = self.post_se(self.nonlinearity(out)) - return out - - - # This func derives the equivalent kernel and bias in a DIFFERENTIABLE way. - # You can get the equivalent kernel and bias at any time and do whatever you want, - # for example, apply some penalties or constraints during training, just like you do to the other models. - # May be useful for quantization or pruning. - def get_equivalent_kernel_bias(self): - kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense) - kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1) - kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity) - return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid - - def _pad_1x1_to_3x3_tensor(self, kernel1x1): - if kernel1x1 is None: - return 0 - else: - return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1]) - - def _fuse_bn_tensor(self, branch): - if branch is None: - return 0, 0 - if isinstance(branch, nn.Sequential): - # For the 1x1 or 3x3 branch - kernel, running_mean, running_var, gamma, beta, eps = branch.conv.weight, branch.bn.running_mean, branch.bn.running_var, branch.bn.weight, branch.bn.bias, branch.bn.eps - else: - # For the identity branch - assert isinstance(branch, nn.BatchNorm2d) - if not hasattr(self, 'id_tensor'): - # Construct and store the identity kernel in case it is used multiple times - input_dim = self.in_channels // self.groups - kernel_value = np.zeros((self.in_channels, input_dim, 3, 3), dtype=np.float32) - for i in range(self.in_channels): - kernel_value[i, i % input_dim, 1, 1] = 1 - self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device) - kernel, running_mean, running_var, gamma, beta, eps = self.id_tensor, branch.running_mean, branch.running_var, branch.weight, branch.bias, branch.eps - std = (running_var + eps).sqrt() - t = (gamma / std).reshape(-1, 1, 1, 1) - return kernel * t, beta - running_mean * gamma / std - - def switch_to_deploy(self): - if hasattr(self, 'rbr_reparam'): - return - kernel, bias = self.get_equivalent_kernel_bias() - self.rbr_reparam = nn.Conv2d(in_channels=self.rbr_dense.conv.in_channels, - out_channels=self.rbr_dense.conv.out_channels, - kernel_size=self.rbr_dense.conv.kernel_size, stride=self.rbr_dense.conv.stride, - padding=self.rbr_dense.conv.padding, dilation=self.rbr_dense.conv.dilation, - groups=self.rbr_dense.conv.groups, bias=True) - self.rbr_reparam.weight.data = kernel - self.rbr_reparam.bias.data = bias - self.__delattr__('rbr_dense') - self.__delattr__('rbr_1x1') - if hasattr(self, 'rbr_identity'): - self.__delattr__('rbr_identity') - if hasattr(self, 'id_tensor'): - self.__delattr__('id_tensor') - self.deploy = True - - - -class RepVGGplusStage(nn.Module): - - def __init__(self, in_planes, planes, num_blocks, stride, use_checkpoint, use_post_se=False, deploy=False): - super().__init__() - strides = [stride] + [1] * (num_blocks - 1) - blocks = [] - self.in_planes = in_planes - for stride in strides: - cur_groups = 1 - blocks.append(RepVGGplusBlock(in_channels=self.in_planes, out_channels=planes, kernel_size=3, - stride=stride, padding=1, groups=cur_groups, deploy=deploy, use_post_se=use_post_se)) - self.in_planes = planes - self.blocks = nn.ModuleList(blocks) - self.use_checkpoint = use_checkpoint - - def forward(self, x): - for block in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(block, x) - else: - x = block(x) - return x - - -class RepVGGplus(nn.Module): - """RepVGGplus - An official improved version of RepVGG (RepVGG: Making VGG-style ConvNets Great Again) `_. - - Args: - num_blocks (tuple[int]): Depths of each stage. - num_classes (tuple[int]): Num of classes. - width_multiplier (tuple[float]): The width of the four stages - will be (64 * width_multiplier[0], 128 * width_multiplier[1], 256 * width_multiplier[2], 512 * width_multiplier[3]). - deploy (bool, optional): If True, the model will have the inference-time structure. - Default: False. - use_post_se (bool, optional): If True, the model will have Squeeze-and-Excitation blocks following the conv-ReLU units. - Default: False. - use_checkpoint (bool, optional): If True, the model will use torch.utils.checkpoint to save the GPU memory during training with acceptable slowdown. - Do not use it if you have sufficient GPU memory. - Default: False. - """ - def __init__(self, - num_blocks, - num_classes, - width_multiplier, - deploy=False, - use_post_se=False, - use_checkpoint=False): - super().__init__() - - self.deploy = deploy - self.num_classes = num_classes - - in_channels = min(64, int(64 * width_multiplier[0])) - stage_channels = [int(64 * width_multiplier[0]), int(128 * width_multiplier[1]), int(256 * width_multiplier[2]), int(512 * width_multiplier[3])] - self.stage0 = RepVGGplusBlock(in_channels=3, out_channels=in_channels, kernel_size=3, stride=2, padding=1, deploy=self.deploy, use_post_se=use_post_se) - self.stage1 = RepVGGplusStage(in_channels, stage_channels[0], num_blocks[0], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage2 = RepVGGplusStage(stage_channels[0], stage_channels[1], num_blocks[1], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - # split stage3 so that we can insert an auxiliary classifier - self.stage3_first = RepVGGplusStage(stage_channels[1], stage_channels[2], num_blocks[2] // 2, stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage3_second = RepVGGplusStage(stage_channels[2], stage_channels[2], num_blocks[2] - num_blocks[2] // 2, stride=1, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage4 = RepVGGplusStage(stage_channels[2], stage_channels[3], num_blocks[3], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.gap = nn.AdaptiveAvgPool2d(output_size=1) - self.flatten = nn.Flatten() - self.linear = nn.Linear(int(512 * width_multiplier[3]), num_classes) - # aux classifiers - if not self.deploy: - self.stage1_aux = self._build_aux_for_stage(self.stage1) - self.stage2_aux = self._build_aux_for_stage(self.stage2) - self.stage3_first_aux = self._build_aux_for_stage(self.stage3_first) - - def _build_aux_for_stage(self, stage): - stage_out_channels = list(stage.blocks.children())[-1].rbr_dense.conv.out_channels - downsample = conv_bn_relu(in_channels=stage_out_channels, out_channels=stage_out_channels, kernel_size=3, stride=2, padding=1) - fc = nn.Linear(stage_out_channels, self.num_classes, bias=True) - return nn.Sequential(downsample, nn.AdaptiveAvgPool2d(1), nn.Flatten(), fc) - - def forward(self, x): - out = self.stage0(x) - out = self.stage1(out) - stage1_aux = self.stage1_aux(out) - out = self.stage2(out) - stage2_aux = self.stage2_aux(out) - out = self.stage3_first(out) - stage3_first_aux = self.stage3_first_aux(out) - out = self.stage3_second(out) - out = self.stage4(out) - y = self.gap(out) - y = self.flatten(y) - y = self.linear(y) - return { - 'main': y, - 'stage1_aux': stage1_aux, - 'stage2_aux': stage2_aux, - 'stage3_first_aux': stage3_first_aux, - } - - def switch_repvggplus_to_deploy(self): - for m in self.modules(): - if hasattr(m, 'switch_to_deploy'): - m.switch_to_deploy() - if hasattr(self, 'stage1_aux'): - self.__delattr__('stage1_aux') - if hasattr(self, 'stage2_aux'): - self.__delattr__('stage2_aux') - if hasattr(self, 'stage3_first_aux'): - self.__delattr__('stage3_first_aux') - self.deploy = True - - -# torch.utils.checkpoint can reduce the memory consumption during training with a minor slowdown. Don't use it if you have sufficient GPU memory. -# Not sure whether it slows down inference -# pse for "post SE", which means using SE block after ReLU -def create_RepVGGplus_L2pse(deploy=False, use_checkpoint=False): - return RepVGGplus(num_blocks=[8, 14, 24, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], deploy=deploy, use_post_se=True, - use_checkpoint=use_checkpoint) - -# Will release more -repvggplus_func_dict = { - 'RepVGGplus-L2pse': create_RepVGGplus_L2pse, -} - -def create_RepVGGplus_by_name(name, deploy=False, use_checkpoint=False): - if 'plus' in name: - return repvggplus_func_dict[name](deploy=deploy, use_checkpoint=use_checkpoint) - else: - print('=================== Building the vanila RepVGG ===================') - from repvgg import get_RepVGG_func_by_name - return get_RepVGG_func_by_name(name)(deploy=deploy, use_checkpoint=use_checkpoint) - - - - - - -# Use this for converting a RepVGG model or a bigger model with RepVGG as its component -# Use like this -# model = create_RepVGG_A0(deploy=False) -# train model or load weights -# repvgg_model_convert(model, save_path='repvgg_deploy.pth') -# If you want to preserve the original model, call with do_copy=True - -# ====================== for using RepVGG as the backbone of a bigger model, e.g., PSPNet, the pseudo code will be like -# train_backbone = create_RepVGG_B2(deploy=False) -# train_backbone.load_state_dict(torch.load('RepVGG-B2-train.pth')) -# train_pspnet = build_pspnet(backbone=train_backbone) -# segmentation_train(train_pspnet) -# deploy_pspnet = repvgg_model_convert(train_pspnet) -# segmentation_test(deploy_pspnet) -# ===================== example_pspnet.py shows an example - -def repvgg_model_convert(model:torch.nn.Module, save_path=None, do_copy=True): - import copy - if do_copy: - model = copy.deepcopy(model) - for module in model.modules(): - if hasattr(module, 'switch_to_deploy'): - module.switch_to_deploy() - if save_path is not None: - torch.save(model.state_dict(), save_path) - return model diff --git a/cv/classification/repvgg/pytorch/repvggplus_custom_L2.py b/cv/classification/repvgg/pytorch/repvggplus_custom_L2.py deleted file mode 100755 index dd8a15bec..000000000 --- a/cv/classification/repvgg/pytorch/repvggplus_custom_L2.py +++ /dev/null @@ -1,268 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- -import torch.nn as nn -import torch.utils.checkpoint as checkpoint -from se_block import SEBlock -import torch -import numpy as np - - -def conv_bn_relu(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - result.add_module('relu', nn.ReLU()) - return result - -def conv_bn(in_channels, out_channels, kernel_size, stride, padding, groups=1): - result = nn.Sequential() - result.add_module('conv', nn.Conv2d(in_channels=in_channels, out_channels=out_channels, - kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)) - result.add_module('bn', nn.BatchNorm2d(num_features=out_channels)) - return result - -class RepVGGplusBlock(nn.Module): - - def __init__(self, in_channels, out_channels, kernel_size, - stride=1, padding=0, dilation=1, groups=1, padding_mode='zeros', - deploy=False, - use_post_se=False): - super(RepVGGplusBlock, self).__init__() - self.deploy = deploy - self.groups = groups - self.in_channels = in_channels - - assert kernel_size == 3 - assert padding == 1 - - self.nonlinearity = nn.ReLU() - - if use_post_se: - self.post_se = SEBlock(out_channels, internal_neurons=out_channels // 4) - else: - self.post_se = nn.Identity() - - if deploy: - self.rbr_reparam = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, - padding=padding, dilation=dilation, groups=groups, bias=True, padding_mode=padding_mode) - else: - if out_channels == in_channels and stride == 1: - self.rbr_identity = nn.BatchNorm2d(num_features=out_channels) - else: - self.rbr_identity = None - self.rbr_dense = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups) - padding_11 = padding - kernel_size // 2 - self.rbr_1x1 = conv_bn(in_channels=in_channels, out_channels=out_channels, kernel_size=1, stride=stride, padding=padding_11, groups=groups) - - def forward(self, x, L2): - - if self.deploy: - return self.post_se(self.nonlinearity(self.rbr_reparam(x))), None - - if self.rbr_identity is None: - id_out = 0 - else: - id_out = self.rbr_identity(x) - out = self.rbr_dense(x) + self.rbr_1x1(x) + id_out - out = self.post_se(self.nonlinearity(out)) - - # Custom L2 - t3 = (self.rbr_dense.bn.weight / ((self.rbr_dense.bn.running_var + self.rbr_dense.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() - t1 = (self.rbr_1x1.bn.weight / ((self.rbr_1x1.bn.running_var + self.rbr_1x1.bn.eps).sqrt())).reshape(-1, 1, 1, 1).detach() - K3 = self.rbr_dense.conv.weight - K1 = self.rbr_1x1.conv.weight - - l2_loss_circle = (K3 ** 2).sum() - (K3[:, :, 1:2, 1:2] ** 2).sum() - eq_kernel = K3[:,:,1:2,1:2] * t3 + K1 * t1 - l2_loss_eq_kernel = (eq_kernel ** 2 / (t3 ** 2 + t1 ** 2)).sum() - - return out, L2 + l2_loss_circle + l2_loss_eq_kernel - - - # This func derives the equivalent kernel and bias in a DIFFERENTIABLE way. - # You can get the equivalent kernel and bias at any time and do whatever you want, - # for example, apply some penalties or constraints during training, just like you do to the other models. - # May be useful for quantization or pruning. - def get_equivalent_kernel_bias(self): - kernel3x3, bias3x3 = self._fuse_bn_tensor(self.rbr_dense) - kernel1x1, bias1x1 = self._fuse_bn_tensor(self.rbr_1x1) - kernelid, biasid = self._fuse_bn_tensor(self.rbr_identity) - return kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid, bias3x3 + bias1x1 + biasid - - def _pad_1x1_to_3x3_tensor(self, kernel1x1): - if kernel1x1 is None: - return 0 - else: - return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1]) - - def _fuse_bn_tensor(self, branch): - if branch is None: - return 0, 0 - if isinstance(branch, nn.Sequential): - # For the 1x1 or 3x3 branch - kernel, running_mean, running_var, gamma, beta, eps = branch.conv.weight, branch.bn.running_mean, branch.bn.running_var, branch.bn.weight, branch.bn.bias, branch.bn.eps - else: - # For the identity branch - assert isinstance(branch, nn.BatchNorm2d) - if not hasattr(self, 'id_tensor'): - # Construct and store the identity kernel in case it is used multiple times - input_dim = self.in_channels // self.groups - kernel_value = np.zeros((self.in_channels, input_dim, 3, 3), dtype=np.float32) - for i in range(self.in_channels): - kernel_value[i, i % input_dim, 1, 1] = 1 - self.id_tensor = torch.from_numpy(kernel_value).to(branch.weight.device) - kernel, running_mean, running_var, gamma, beta, eps = self.id_tensor, branch.running_mean, branch.running_var, branch.weight, branch.bias, branch.eps - std = (running_var + eps).sqrt() - t = (gamma / std).reshape(-1, 1, 1, 1) - return kernel * t, beta - running_mean * gamma / std - - def switch_to_deploy(self): - if hasattr(self, 'rbr_reparam'): - return - kernel, bias = self.get_equivalent_kernel_bias() - self.rbr_reparam = nn.Conv2d(in_channels=self.rbr_dense.conv.in_channels, - out_channels=self.rbr_dense.conv.out_channels, - kernel_size=self.rbr_dense.conv.kernel_size, stride=self.rbr_dense.conv.stride, - padding=self.rbr_dense.conv.padding, dilation=self.rbr_dense.conv.dilation, - groups=self.rbr_dense.conv.groups, bias=True) - self.rbr_reparam.weight.data = kernel - self.rbr_reparam.bias.data = bias - self.__delattr__('rbr_dense') - self.__delattr__('rbr_1x1') - if hasattr(self, 'rbr_identity'): - self.__delattr__('rbr_identity') - if hasattr(self, 'id_tensor'): - self.__delattr__('id_tensor') - self.deploy = True - - - -class RepVGGplusStage(nn.Module): - - def __init__(self, in_planes, planes, num_blocks, stride, use_checkpoint, use_post_se=False, deploy=False): - super().__init__() - strides = [stride] + [1] * (num_blocks - 1) - blocks = [] - self.in_planes = in_planes - for stride in strides: - cur_groups = 1 - blocks.append(RepVGGplusBlock(in_channels=self.in_planes, out_channels=planes, kernel_size=3, - stride=stride, padding=1, groups=cur_groups, deploy=deploy, use_post_se=use_post_se)) - self.in_planes = planes - self.blocks = nn.ModuleList(blocks) - self.use_checkpoint = use_checkpoint - - def forward(self, x, L2): - for block in self.blocks: - if self.use_checkpoint: - x, L2 = checkpoint.checkpoint(block, x, L2) - else: - x, L2 = block(x, L2) - return x, L2 - - -class RepVGGplus(nn.Module): - - def __init__(self, num_blocks, num_classes, - width_multiplier, override_groups_map=None, - deploy=False, - use_post_se=False, - use_checkpoint=False): - super().__init__() - - self.deploy = deploy - self.override_groups_map = override_groups_map or dict() - self.use_post_se = use_post_se - self.use_checkpoint = use_checkpoint - self.num_classes = num_classes - self.nonlinear = 'relu' - - self.in_planes = min(64, int(64 * width_multiplier[0])) - self.stage0 = RepVGGplusBlock(in_channels=3, out_channels=self.in_planes, kernel_size=3, stride=2, padding=1, deploy=self.deploy, use_post_se=use_post_se) - self.cur_layer_idx = 1 - self.stage1 = RepVGGplusStage(self.in_planes, int(64 * width_multiplier[0]), num_blocks[0], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage2 = RepVGGplusStage(int(64 * width_multiplier[0]), int(128 * width_multiplier[1]), num_blocks[1], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - # split stage3 so that we can insert an auxiliary classifier - self.stage3_first = RepVGGplusStage(int(128 * width_multiplier[1]), int(256 * width_multiplier[2]), num_blocks[2] // 2, stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage3_second = RepVGGplusStage(int(256 * width_multiplier[2]), int(256 * width_multiplier[2]), num_blocks[2] // 2, stride=1, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.stage4 = RepVGGplusStage(int(256 * width_multiplier[2]), int(512 * width_multiplier[3]), num_blocks[3], stride=2, use_checkpoint=use_checkpoint, use_post_se=use_post_se, deploy=deploy) - self.gap = nn.AdaptiveAvgPool2d(output_size=1) - self.linear = nn.Linear(int(512 * width_multiplier[3]), num_classes) - # aux classifiers - if not self.deploy: - self.stage1_aux = self._build_aux_for_stage(self.stage1) - self.stage2_aux = self._build_aux_for_stage(self.stage2) - self.stage3_first_aux = self._build_aux_for_stage(self.stage3_first) - - def _build_aux_for_stage(self, stage): - stage_out_channels = list(stage.blocks.children())[-1].rbr_dense.conv.out_channels - downsample = conv_bn_relu(in_channels=stage_out_channels, out_channels=stage_out_channels, kernel_size=3, stride=2, padding=1) - fc = nn.Linear(stage_out_channels, self.num_classes, bias=True) - return nn.Sequential(downsample, nn.AdaptiveAvgPool2d(1), nn.Flatten(), fc) - - def forward(self, x): - if self.deploy: - out, _ = self.stage0(x, L2=None) - out, _ = self.stage1(out, L2=None) - out, _ = self.stage2(out, L2=None) - out, _ = self.stage3_first(out, L2=None) - out, _ = self.stage3_second(out, L2=None) - out, _ = self.stage4(out, L2=None) - y = self.gap(out) - y = y.view(y.size(0), -1) - y = self.linear(y) - return y - - else: - out, L2 = self.stage0(x, L2=0.0) - out, L2 = self.stage1(out, L2=L2) - stage1_aux = self.stage1_aux(out) - out, L2 = self.stage2(out, L2=L2) - stage2_aux = self.stage2_aux(out) - out, L2 = self.stage3_first(out, L2=L2) - stage3_first_aux = self.stage3_first_aux(out) - out, L2 = self.stage3_second(out, L2=L2) - out, L2 = self.stage4(out, L2=L2) - y = self.gap(out) - y = y.view(y.size(0), -1) - y = self.linear(y) - return { - 'main': y, - 'stage1_aux': stage1_aux, - 'stage2_aux': stage2_aux, - 'stage3_first_aux': stage3_first_aux, - 'L2': L2 - } - - def switch_repvggplus_to_deploy(self): - for m in self.modules(): - if hasattr(m, 'switch_to_deploy'): - m.switch_to_deploy() - if hasattr(m, 'use_checkpoint'): - m.use_checkpoint = False # Disable checkpoint. I am not sure whether using checkpoint slows down inference. - if hasattr(self, 'stage1_aux'): - self.__delattr__('stage1_aux') - if hasattr(self, 'stage2_aux'): - self.__delattr__('stage2_aux') - if hasattr(self, 'stage3_first_aux'): - self.__delattr__('stage3_first_aux') - self.deploy = True - - -# torch.utils.checkpoint can reduce the memory consumption during training with a minor slowdown. Don't use it if you have sufficient GPU memory. -# Not sure whether it slows down inference -# pse for "post SE", which means using SE block after ReLU -def create_RepVGGplus_L2pse(deploy=False, use_checkpoint=False): - return RepVGGplus(num_blocks=[8, 14, 24, 1], num_classes=1000, - width_multiplier=[2.5, 2.5, 2.5, 5], override_groups_map=None, deploy=deploy, use_post_se=True, - use_checkpoint=use_checkpoint) - -repvggplus_func_dict = { -'RepVGGplus-L2pse': create_RepVGGplus_L2pse, -} -def get_RepVGGplus_func_by_name(name): - return repvggplus_func_dict[name] \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/se_block.py b/cv/classification/repvgg/pytorch/se_block.py deleted file mode 100755 index e23911e0c..000000000 --- a/cv/classification/repvgg/pytorch/se_block.py +++ /dev/null @@ -1,22 +0,0 @@ -import torch -import torch.nn as nn -import torch.nn.functional as F - -# https://openaccess.thecvf.com/content_cvpr_2018/html/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper.html - -class SEBlock(nn.Module): - - def __init__(self, input_channels, internal_neurons): - super(SEBlock, self).__init__() - self.down = nn.Conv2d(in_channels=input_channels, out_channels=internal_neurons, kernel_size=1, stride=1, bias=True) - self.up = nn.Conv2d(in_channels=internal_neurons, out_channels=input_channels, kernel_size=1, stride=1, bias=True) - self.input_channels = input_channels - - def forward(self, inputs): - x = F.avg_pool2d(inputs, kernel_size=inputs.size(3)) - x = self.down(x) - x = F.relu(x) - x = self.up(x) - x = torch.sigmoid(x) - x = x.view(-1, self.input_channels, 1, 1) - return inputs * x \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/tools/convert.py b/cv/classification/repvgg/pytorch/tools/convert.py deleted file mode 100755 index b239ad0fd..000000000 --- a/cv/classification/repvgg/pytorch/tools/convert.py +++ /dev/null @@ -1,46 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- -import argparse -import os -import torch -import torch.nn.parallel -import torch.optim -import torch.utils.data -import torch.utils.data.distributed -from repvggplus import create_RepVGGplus_by_name, repvgg_model_convert - -parser = argparse.ArgumentParser(description='RepVGG(plus) Conversion') -parser.add_argument('load', metavar='LOAD', help='path to the weights file') -parser.add_argument('save', metavar='SAVE', help='path to the weights file') -parser.add_argument('-a', '--arch', metavar='ARCH', default='RepVGG-A0') - -def convert(): - args = parser.parse_args() - - train_model = create_RepVGGplus_by_name(args.arch, deploy=False) - - if os.path.isfile(args.load): - print("=> loading checkpoint '{}'".format(args.load)) - checkpoint = torch.load(args.load) - if 'state_dict' in checkpoint: - checkpoint = checkpoint['state_dict'] - elif 'model' in checkpoint: - checkpoint = checkpoint['model'] - ckpt = {k.replace('module.', ''): v for k, v in checkpoint.items()} # strip the names - print(ckpt.keys()) - train_model.load_state_dict(ckpt) - else: - print("=> no checkpoint found at '{}'".format(args.load)) - - if 'plus' in args.arch: - train_model.switch_repvggplus_to_deploy() - torch.save(train_model.state_dict(), args.save) - else: - repvgg_model_convert(train_model, save_path=args.save) - - -if __name__ == '__main__': - convert() \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/tools/insert_bn.py b/cv/classification/repvgg/pytorch/tools/insert_bn.py deleted file mode 100755 index 5a66f6b4b..000000000 --- a/cv/classification/repvgg/pytorch/tools/insert_bn.py +++ /dev/null @@ -1,217 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- -import argparse -import os -import time -import torch -import torch.nn as nn -import torch.nn.parallel -import torch.backends.cudnn as cudnn -import torch.optim -import torch.utils.data -import torch.utils.data.distributed -from utils import accuracy, ProgressMeter, AverageMeter -from repvgg import get_RepVGG_func_by_name, RepVGGBlock -from utils import load_checkpoint, get_ImageNet_train_dataset, get_default_train_trans - -# Insert BN into an inference-time RepVGG (e.g., for quantization-aware training). -# Get the mean and std on every conv3x3 (before the bias-adding) on the train set. Then use such data to initialize BN layers and insert them after conv3x3. -# May, 07, 2021 - -parser = argparse.ArgumentParser(description='Get the mean and std on every conv3x3 (before the bias-adding) on the train set. Then use such data to initialize BN layers and insert them after conv3x3.') -parser.add_argument('data', metavar='DIR', help='path to dataset') -parser.add_argument('weights', metavar='WEIGHTS', help='path to the weights file') -parser.add_argument('save', metavar='SAVE', help='path to save the model with BN') -parser.add_argument('-a', '--arch', metavar='ARCH', default='RepVGG-A0') -parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', - help='number of data loading workers (default: 4)') -parser.add_argument('-b', '--batch-size', default=100, type=int, - metavar='N', - help='mini-batch size (default: 100) for test') -parser.add_argument('-n', '--num-batches', default=500, type=int, - metavar='N', - help='number of batches (default: 500) to record the mean and std on the train set') -parser.add_argument('-r', '--resolution', default=224, type=int, - metavar='R', - help='resolution (default: 224) for test') - - -def update_running_mean_var(x, running_mean, running_var, momentum=0.9, is_first_batch=False): - mean = x.mean(dim=(0, 2, 3), keepdim=True) - var = ((x - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True) - if is_first_batch: - running_mean = mean - running_var = var - else: - running_mean = momentum * running_mean + (1.0 - momentum) * mean - running_var = momentum * running_var + (1.0 - momentum) * var - return running_mean, running_var - -# Record the mean and std like a BN layer but do no normalization -class BNStatistics(nn.Module): - def __init__(self, num_features): - super(BNStatistics, self).__init__() - shape = (1, num_features, 1, 1) - self.register_buffer('running_mean', torch.zeros(shape)) - self.register_buffer('running_var', torch.zeros(shape)) - self.is_first_batch = True - - def forward(self, x): - if self.running_mean.device != x.device: - self.running_mean = self.running_mean.to(x.device) - self.running_var = self.running_var.to(x.device) - self.running_mean, self.running_var = update_running_mean_var(x, self.running_mean, self.running_var, momentum=0.9, is_first_batch=self.is_first_batch) - self.is_first_batch = False - return x - -# This is designed to insert BNStat layer between Conv2d(without bias) and its bias -class BiasAdd(nn.Module): - def __init__(self, num_features): - super(BiasAdd, self).__init__() - self.bias = torch.nn.Parameter(torch.Tensor(num_features)) - def forward(self, x): - return x + self.bias.view(1, -1, 1, 1) - -def switch_repvggblock_to_bnstat(model): - for n, block in model.named_modules(): - if isinstance(block, RepVGGBlock): - print('switch to BN Statistics: ', n) - assert hasattr(block, 'rbr_reparam') - stat = nn.Sequential() - stat.add_module('conv', nn.Conv2d(block.rbr_reparam.in_channels, block.rbr_reparam.out_channels, - block.rbr_reparam.kernel_size, - block.rbr_reparam.stride, block.rbr_reparam.padding, - block.rbr_reparam.dilation, - block.rbr_reparam.groups, bias=False)) # Note bias=False - stat.add_module('bnstat', BNStatistics(block.rbr_reparam.out_channels)) - stat.add_module('biasadd', BiasAdd(block.rbr_reparam.out_channels)) # Bias is here - stat.conv.weight.data = block.rbr_reparam.weight.data - stat.biasadd.bias.data = block.rbr_reparam.bias.data - block.__delattr__('rbr_reparam') - block.rbr_reparam = stat - -def switch_bnstat_to_convbn(model): - for n, block in model.named_modules(): - if isinstance(block, RepVGGBlock): - assert hasattr(block, 'rbr_reparam') - assert hasattr(block.rbr_reparam, 'bnstat') - print('switch to ConvBN: ', n) - conv = nn.Conv2d(block.rbr_reparam.conv.in_channels, block.rbr_reparam.conv.out_channels, - block.rbr_reparam.conv.kernel_size, - block.rbr_reparam.conv.stride, block.rbr_reparam.conv.padding, - block.rbr_reparam.conv.dilation, - block.rbr_reparam.conv.groups, bias=False) - bn = nn.BatchNorm2d(block.rbr_reparam.conv.out_channels) - bn.running_mean = block.rbr_reparam.bnstat.running_mean.squeeze() # Initialize the mean and var of BN with the statistics - bn.running_var = block.rbr_reparam.bnstat.running_var.squeeze() - std = (bn.running_var + bn.eps).sqrt() - conv.weight.data = block.rbr_reparam.conv.weight.data - bn.weight.data = std - bn.bias.data = block.rbr_reparam.biasadd.bias.data + bn.running_mean # Initialize gamma = std and beta = bias + mean - - convbn = nn.Sequential() - convbn.add_module('conv', conv) - convbn.add_module('bn', bn) - block.__delattr__('rbr_reparam') - block.rbr_reparam = convbn - - -# Insert a BN after conv3x3 (rbr_reparam). With no reasonable initialization of BN, the model may break down. -# So you have to load the weights obtained through the BN statistics (please see the function "insert_bn" in this file). -def directly_insert_bn_without_init(model): - for n, block in model.named_modules(): - if isinstance(block, RepVGGBlock): - print('directly insert a BN with no initialization: ', n) - assert hasattr(block, 'rbr_reparam') - convbn = nn.Sequential() - convbn.add_module('conv', nn.Conv2d(block.rbr_reparam.in_channels, block.rbr_reparam.out_channels, - block.rbr_reparam.kernel_size, - block.rbr_reparam.stride, block.rbr_reparam.padding, - block.rbr_reparam.dilation, - block.rbr_reparam.groups, bias=False)) # Note bias=False - convbn.add_module('bn', nn.BatchNorm2d(block.rbr_reparam.out_channels)) - # ==================== - convbn.add_module('relu', nn.ReLU()) - # TODO we moved ReLU from "block.nonlinearity" into "rbr_reparam" (nn.Sequential). This makes it more convenient to fuse operators (see RepVGGWholeQuant.fuse_model) using off-the-shelf APIs. - block.nonlinearity = nn.Identity() - #========================== - block.__delattr__('rbr_reparam') - block.rbr_reparam = convbn - - -def insert_bn(): - args = parser.parse_args() - - repvgg_build_func = get_RepVGG_func_by_name(args.arch) - - model = repvgg_build_func(deploy=True).cuda() - - load_checkpoint(model, args.weights) - - switch_repvggblock_to_bnstat(model) - - cudnn.benchmark = True - - trans = get_default_train_trans(args) - print('data aug: ', trans) - - train_dataset = get_ImageNet_train_dataset(args, trans) - - train_loader = torch.utils.data.DataLoader( - train_dataset, - batch_size=args.batch_size, shuffle=False, - num_workers=args.workers, pin_memory=True) - - batch_time = AverageMeter('Time', ':6.3f') - losses = AverageMeter('Loss', ':.4e') - top1 = AverageMeter('Acc@1', ':6.2f') - top5 = AverageMeter('Acc@5', ':6.2f') - - progress = ProgressMeter( - min(len(train_loader), args.num_batches), - [batch_time, losses, top1, top5], - prefix='BN stat: ') - - criterion = nn.CrossEntropyLoss().cuda() - - with torch.no_grad(): - end = time.time() - for i, (images, target) in enumerate(train_loader): - if i >= args.num_batches: - break - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - output = model(images) - loss = criterion(output, target) - - # measure accuracy and record loss - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - losses.update(loss.item(), images.size(0)) - top1.update(acc1[0], images.size(0)) - top5.update(acc5[0], images.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if i % 10 == 0: - progress.display(i) - - - print(' * Acc@1 {top1.avg:.3f} Acc@5 {top5.avg:.3f}' - .format(top1=top1, top5=top5)) - - switch_bnstat_to_convbn(model) - - torch.save(model.state_dict(), args.save) - - - - -if __name__ == '__main__': - insert_bn() \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/tools/verify.py b/cv/classification/repvgg/pytorch/tools/verify.py deleted file mode 100755 index d9f77fda2..000000000 --- a/cv/classification/repvgg/pytorch/tools/verify.py +++ /dev/null @@ -1,30 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- -import torch -import torch.nn as nn -from repvgg import create_RepVGG_B1 - -if __name__ == '__main__': - x = torch.randn(1, 3, 224, 224) - model = create_RepVGG_B1(deploy=False) - model.eval() - - for module in model.modules(): - if isinstance(module, torch.nn.BatchNorm2d): - nn.init.uniform_(module.running_mean, 0, 0.1) - nn.init.uniform_(module.running_var, 0, 0.1) - nn.init.uniform_(module.weight, 0, 0.1) - nn.init.uniform_(module.bias, 0, 0.1) - - train_y = model(x) - for module in model.modules(): - if hasattr(module, 'switch_to_deploy'): - module.switch_to_deploy() - - print(model) - deploy_y = model(x) - print('========================== The diff is') - print(((train_y - deploy_y) ** 2).sum()) diff --git a/cv/classification/repvgg/pytorch/train/config.py b/cv/classification/repvgg/pytorch/train/config.py deleted file mode 100755 index e5fd77728..000000000 --- a/cv/classification/repvgg/pytorch/train/config.py +++ /dev/null @@ -1,217 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import yaml -from yacs.config import CfgNode as CN - -_C = CN() - -# Base config files -_C.BASE = [''] - -# ----------------------------------------------------------------------------- -# Data settings -# ----------------------------------------------------------------------------- -_C.DATA = CN() -# Batch size for a single GPU, could be overwritten by command line argument -_C.DATA.BATCH_SIZE = 128 -# Path to dataset, could be overwritten by command line argument -_C.DATA.DATA_PATH = '/your/path/to/dataset' - -# Dataset name -_C.DATA.DATASET = 'imagenet' -# Input image size -_C.DATA.IMG_SIZE = 224 -_C.DATA.TEST_SIZE = None -_C.DATA.TEST_BATCH_SIZE = None -# Interpolation to resize image (random, bilinear, bicubic) -_C.DATA.INTERPOLATION = 'bilinear' -# Use zipped dataset instead of folder dataset -# could be overwritten by command line argument -_C.DATA.ZIP_MODE = False -# Cache Data in Memory, could be overwritten by command line argument -_C.DATA.CACHE_MODE = 'part' -# Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU. -_C.DATA.PIN_MEMORY = True -# Number of data loading threads -_C.DATA.NUM_WORKERS = 8 - -# ----------------------------------------------------------------------------- -# Model settings -# ----------------------------------------------------------------------------- -_C.MODEL = CN() -# Model type -_C.MODEL.ARCH = 'RepVGG-L2pse' -# Checkpoint to resume, could be overwritten by command line argument -_C.MODEL.RESUME = '' -# Number of classes, overwritten in data preparation -_C.MODEL.NUM_CLASSES = 1000 -# Label Smoothing -_C.MODEL.LABEL_SMOOTHING = 0.1 - -# ----------------------------------------------------------------------------- -# Training settings -# ----------------------------------------------------------------------------- -_C.TRAIN = CN() -_C.TRAIN.START_EPOCH = 0 -_C.TRAIN.EPOCHS = 300 -_C.TRAIN.WARMUP_EPOCHS = 20 -_C.TRAIN.WEIGHT_DECAY = 0.05 -_C.TRAIN.BASE_LR = 5e-4 -_C.TRAIN.WARMUP_LR = 0.0 -_C.TRAIN.MIN_LR = 0.0 -# Clip gradient norm -_C.TRAIN.CLIP_GRAD = 0.0 -# Auto resume from latest checkpoint -_C.TRAIN.AUTO_RESUME = True -# Gradient accumulation steps -# could be overwritten by command line argument -_C.TRAIN.ACCUMULATION_STEPS = 0 -# Whether to use gradient checkpointing to save memory -# could be overwritten by command line argument -_C.TRAIN.USE_CHECKPOINT = False - -# LR scheduler -_C.TRAIN.LR_SCHEDULER = CN() -_C.TRAIN.LR_SCHEDULER.NAME = 'cosine' -# Epoch interval to decay LR, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_EPOCHS = 30 -# LR decay rate, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_RATE = 0.1 - -# Optimizer -_C.TRAIN.OPTIMIZER = CN() -_C.TRAIN.OPTIMIZER.NAME = 'sgd' -# Optimizer Epsilon -_C.TRAIN.OPTIMIZER.EPS = 1e-8 -# Optimizer Betas -_C.TRAIN.OPTIMIZER.BETAS = (0.9, 0.999) -# SGD momentum -_C.TRAIN.OPTIMIZER.MOMENTUM = 0.9 - -# For EMA model -_C.TRAIN.EMA_ALPHA = 0.0 -_C.TRAIN.EMA_UPDATE_PERIOD = 8 - -# For RepOptimizer only -_C.TRAIN.SCALES_PATH = None - -# ----------------------------------------------------------------------------- -# Augmentation settings -# ----------------------------------------------------------------------------- -_C.AUG = CN() -# Mixup alpha, mixup enabled if > 0 -_C.AUG.MIXUP = 0.2 -# Cutmix alpha, cutmix enabled if > 0 -_C.AUG.CUTMIX = 0.0 -# Cutmix min/max ratio, overrides alpha and enables cutmix if set -_C.AUG.CUTMIX_MINMAX = None -# Probability of performing mixup or cutmix when either/both is enabled -_C.AUG.MIXUP_PROB = 1.0 -# Probability of switching to cutmix when both mixup and cutmix enabled -_C.AUG.MIXUP_SWITCH_PROB = 0.5 -# How to apply mixup/cutmix params. Per "batch", "pair", or "elem" -_C.AUG.MIXUP_MODE = 'batch' - -_C.AUG.PRESET = None # If use AUG.PRESET (e.g., 'raug15'), use the pre-defined preprocessing, ignoring the following settings. -# Color jitter factor -_C.AUG.COLOR_JITTER = 0.4 -# Use AutoAugment policy. "v0" or "original" -_C.AUG.AUTO_AUGMENT = 'rand-m9-mstd0.5-inc1' -# Random erase prob -_C.AUG.REPROB = 0.25 -# Random erase mode -_C.AUG.REMODE = 'pixel' -# Random erase count -_C.AUG.RECOUNT = 1 - - -# ----------------------------------------------------------------------------- -# Testing settings -# ----------------------------------------------------------------------------- -_C.TEST = CN() -# Whether to use center crop when testing -_C.TEST.CROP = False - -# ----------------------------------------------------------------------------- -# Misc -# ----------------------------------------------------------------------------- -# Mixed precision opt level, if O0, no amp is used ('O0', 'O1', 'O2') -# overwritten by command line argument -_C.AMP_OPT_LEVEL = '' -# Path to output folder, overwritten by command line argument -_C.OUTPUT = '' -# Tag of experiment, overwritten by command line argument -_C.TAG = 'default' -# Frequency to save checkpoint -_C.SAVE_FREQ = 20 -# Frequency to logging info -_C.PRINT_FREQ = 10 -# Fixed random seed -_C.SEED = 0 -# Perform evaluation only, overwritten by command line argument -_C.EVAL_MODE = False -# Test throughput only, overwritten by command line argument -_C.THROUGHPUT_MODE = False -# local rank for DistributedDataParallel, given by command line argument -_C.LOCAL_RANK = 0 - - -def update_config(config, args): - config.defrost() - if args.opts: - config.merge_from_list(args.opts) - # merge from specific arguments - if args.scales_path: - config.TRAIN.SCALES_PATH = args.scales_path - if args.arch: - config.MODEL.ARCH = args.arch - if args.batch_size: - config.DATA.BATCH_SIZE = args.batch_size - if args.data_path: - config.DATA.DATA_PATH = args.data_path - if args.zip: - config.DATA.ZIP_MODE = True - if args.cache_mode: - config.DATA.CACHE_MODE = args.cache_mode - if args.resume: - config.MODEL.RESUME = args.resume - if args.accumulation_steps: - config.TRAIN.ACCUMULATION_STEPS = args.accumulation_steps - if args.use_checkpoint: - config.TRAIN.USE_CHECKPOINT = True - if args.amp_opt_level: - config.AMP_OPT_LEVEL = args.amp_opt_level - if args.output: - config.OUTPUT = args.output - if args.tag: - config.TAG = args.tag - if args.eval: - config.EVAL_MODE = True - if args.throughput: - config.THROUGHPUT_MODE = True - - if config.DATA.TEST_SIZE is None: - config.DATA.TEST_SIZE = config.DATA.IMG_SIZE - if config.DATA.TEST_BATCH_SIZE is None: - config.DATA.TEST_BATCH_SIZE = config.DATA.BATCH_SIZE - # set local rank for distributed training - config.LOCAL_RANK = args.local_rank - # output folder - config.OUTPUT = os.path.join(config.OUTPUT, config.MODEL.ARCH, config.TAG) - config.freeze() - - -def get_config(args): - """Get a yacs CfgNode object with default values.""" - # Return a clone so that the defaults will not be altered - # This is for the "local variable" use pattern - config = _C.clone() - update_config(config, args) - - return config diff --git a/cv/classification/repvgg/pytorch/train/cutout.py b/cv/classification/repvgg/pytorch/train/cutout.py deleted file mode 100755 index 8592ffc08..000000000 --- a/cv/classification/repvgg/pytorch/train/cutout.py +++ /dev/null @@ -1,55 +0,0 @@ -import numpy as np - -class Cutout: - - def __init__(self, size=16) -> None: - self.size = size - - def _create_cutout_mask(self, img_height, img_width, num_channels, size): - """Creates a zero mask used for cutout of shape `img_height` x `img_width`. - Args: - img_height: Height of image cutout mask will be applied to. - img_width: Width of image cutout mask will be applied to. - num_channels: Number of channels in the image. - size: Size of the zeros mask. - Returns: - A mask of shape `img_height` x `img_width` with all ones except for a - square of zeros of shape `size` x `size`. This mask is meant to be - elementwise multiplied with the original image. Additionally returns - the `upper_coord` and `lower_coord` which specify where the cutout mask - will be applied. - """ - # assert img_height == img_width - - # Sample center where cutout mask will be applied - height_loc = np.random.randint(low=0, high=img_height) - width_loc = np.random.randint(low=0, high=img_width) - - size = int(size) - # Determine upper right and lower left corners of patch - upper_coord = (max(0, height_loc - size // 2), max(0, width_loc - size // 2)) - lower_coord = ( - min(img_height, height_loc + size // 2), - min(img_width, width_loc + size // 2), - ) - mask_height = lower_coord[0] - upper_coord[0] - mask_width = lower_coord[1] - upper_coord[1] - assert mask_height > 0 - assert mask_width > 0 - - mask = np.ones((img_height, img_width, num_channels)) - zeros = np.zeros((mask_height, mask_width, num_channels)) - mask[upper_coord[0]: lower_coord[0], upper_coord[1]: lower_coord[1], :] = zeros - return mask, upper_coord, lower_coord - - def __call__(self, pil_img): - pil_img = pil_img.copy() - img_height, img_width, num_channels = (*pil_img.size, 3) - _, upper_coord, lower_coord = self._create_cutout_mask( - img_height, img_width, num_channels, self.size - ) - pixels = pil_img.load() # create the pixel map - for i in range(upper_coord[0], lower_coord[0]): # for every col: - for j in range(upper_coord[1], lower_coord[1]): # For every row - pixels[i, j] = (125, 122, 113, 0) # set the colour accordingly - return pil_img \ No newline at end of file diff --git a/cv/classification/repvgg/pytorch/train/logger.py b/cv/classification/repvgg/pytorch/train/logger.py deleted file mode 100755 index a0ae05e48..000000000 --- a/cv/classification/repvgg/pytorch/train/logger.py +++ /dev/null @@ -1,41 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import os -import sys -import logging -import functools -from termcolor import colored - - -@functools.lru_cache() -def create_logger(output_dir, dist_rank=0, name=''): - # create logger - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.propagate = False - - # create formatter - fmt = '[%(asctime)s %(name)s] (%(filename)s %(lineno)d): %(levelname)s %(message)s' - color_fmt = colored('[%(asctime)s %(name)s]', 'green') + \ - colored('(%(filename)s %(lineno)d)', 'yellow') + ': %(levelname)s %(message)s' - - # create console handlers for master process - if dist_rank == 0: - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setLevel(logging.DEBUG) - console_handler.setFormatter( - logging.Formatter(fmt=color_fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(console_handler) - - # create file handlers - file_handler = logging.FileHandler(os.path.join(output_dir, f'log_rank{dist_rank}.txt'), mode='a') - file_handler.setLevel(logging.DEBUG) - file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(file_handler) - - return logger diff --git a/cv/classification/repvgg/pytorch/train/lr_scheduler.py b/cv/classification/repvgg/pytorch/train/lr_scheduler.py deleted file mode 100755 index 029b184c1..000000000 --- a/cv/classification/repvgg/pytorch/train/lr_scheduler.py +++ /dev/null @@ -1,101 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import torch -from timm.scheduler.cosine_lr import CosineLRScheduler -from timm.scheduler.step_lr import StepLRScheduler -from timm.scheduler.scheduler import Scheduler - - -def build_scheduler(config, optimizer, n_iter_per_epoch): - num_steps = int(config.TRAIN.EPOCHS * n_iter_per_epoch) - warmup_steps = int(config.TRAIN.WARMUP_EPOCHS * n_iter_per_epoch) - decay_steps = int(config.TRAIN.LR_SCHEDULER.DECAY_EPOCHS * n_iter_per_epoch) - - lr_scheduler = None - if config.TRAIN.LR_SCHEDULER.NAME == 'cosine': - lr_scheduler = CosineLRScheduler( - optimizer, - t_initial=num_steps, - lr_min=config.TRAIN.MIN_LR, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - cycle_limit=1, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'linear': - lr_scheduler = LinearLRScheduler( - optimizer, - t_initial=num_steps, - lr_min_rate=0.01, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'step': - lr_scheduler = StepLRScheduler( - optimizer, - decay_t=decay_steps, - decay_rate=config.TRAIN.LR_SCHEDULER.DECAY_RATE, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - - return lr_scheduler - - -class LinearLRScheduler(Scheduler): - def __init__(self, - optimizer: torch.optim.Optimizer, - t_initial: int, - lr_min_rate: float, - warmup_t=0, - warmup_lr_init=0., - t_in_epochs=True, - noise_range_t=None, - noise_pct=0.67, - noise_std=1.0, - noise_seed=42, - initialize=True, - ) -> None: - super().__init__( - optimizer, param_group_field="lr", - noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, - initialize=initialize) - - self.t_initial = t_initial - self.lr_min_rate = lr_min_rate - self.warmup_t = warmup_t - self.warmup_lr_init = warmup_lr_init - self.t_in_epochs = t_in_epochs - if self.warmup_t: - self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] - super().update_groups(self.warmup_lr_init) - else: - self.warmup_steps = [1 for _ in self.base_values] - - def _get_lr(self, t): - if t < self.warmup_t: - lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] - else: - t = t - self.warmup_t - total_t = self.t_initial - self.warmup_t - lrs = [v - ((v - v * self.lr_min_rate) * (t / total_t)) for v in self.base_values] - return lrs - - def get_epoch_values(self, epoch: int): - if self.t_in_epochs: - return self._get_lr(epoch) - else: - return None - - def get_update_values(self, num_updates: int): - if not self.t_in_epochs: - return self._get_lr(num_updates) - else: - return None diff --git a/cv/classification/repvgg/pytorch/train/optimizer.py b/cv/classification/repvgg/pytorch/train/optimizer.py deleted file mode 100755 index 68abf6d0e..000000000 --- a/cv/classification/repvgg/pytorch/train/optimizer.py +++ /dev/null @@ -1,71 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -from torch import optim as optim - - -def build_optimizer(config, model): - """ - Build optimizer, set weight decay of normalization to 0 by default. - """ - skip = {} - skip_keywords = {} - if hasattr(model, 'no_weight_decay'): - skip = model.no_weight_decay() - if hasattr(model, 'no_weight_decay_keywords'): - skip_keywords = model.no_weight_decay_keywords() - echo = (config.LOCAL_RANK==0) - parameters = set_weight_decay(model, skip, skip_keywords, echo=echo) - opt_lower = config.TRAIN.OPTIMIZER.NAME.lower() - optimizer = None - if opt_lower == 'sgd': - optimizer = optim.SGD(parameters, momentum=config.TRAIN.OPTIMIZER.MOMENTUM, nesterov=True, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - if echo: - print('================================== SGD nest, momentum = {}, wd = {}'.format(config.TRAIN.OPTIMIZER.MOMENTUM, config.TRAIN.WEIGHT_DECAY)) - elif opt_lower == 'adam': - print('adam') - optimizer = optim.Adam(parameters, eps=config.TRAIN.OPTIMIZER.EPS, betas=config.TRAIN.OPTIMIZER.BETAS, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - elif opt_lower == 'adamw': - optimizer = optim.AdamW(parameters, eps=config.TRAIN.OPTIMIZER.EPS, betas=config.TRAIN.OPTIMIZER.BETAS, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - - return optimizer - - -def set_weight_decay(model, skip_list=(), skip_keywords=(), echo=False): - has_decay = [] - no_decay = [] - - for name, param in model.named_parameters(): - if not param.requires_grad: - continue # frozen weights - if 'identity.weight' in name: - has_decay.append(param) - if echo: - print(f"{name} USE weight decay") - elif len(param.shape) == 1 or name.endswith(".bias") or (name in skip_list) or \ - check_keywords_in_name(name, skip_keywords): - no_decay.append(param) - if echo: - print(f"{name} has no weight decay") - else: - has_decay.append(param) - if echo: - print(f"{name} USE weight decay") - - return [{'params': has_decay}, - {'params': no_decay, 'weight_decay': 0.}] - - -def check_keywords_in_name(name, keywords=()): - isin = False - for keyword in keywords: - if keyword in name: - isin = True - return isin diff --git a/cv/classification/repvgg/pytorch/train/randaug.py b/cv/classification/repvgg/pytorch/train/randaug.py deleted file mode 100755 index 6934fb805..000000000 --- a/cv/classification/repvgg/pytorch/train/randaug.py +++ /dev/null @@ -1,407 +0,0 @@ -import math -import random - -import numpy as np -import PIL -from PIL import Image, ImageEnhance, ImageOps - -from train.cutout import Cutout - - -_PIL_VER = tuple([int(x) for x in PIL.__version__.split('.')[:2]]) - -_FILL = (128, 128, 128) - -# This signifies the max integer that the controller RNN could predict for the -# augmentation scheme. -_MAX_LEVEL = 10. - -_HPARAMS_DEFAULT = dict( - translate_const=250, - img_mean=_FILL, -) - -_RANDOM_INTERPOLATION = (Image.BILINEAR, Image.BICUBIC) - - -def _interpolation(kwargs): - interpolation = kwargs.pop('resample', Image.BILINEAR) - if isinstance(interpolation, (list, tuple)): - return random.choice(interpolation) - else: - return interpolation - - -def _check_args_tf(kwargs): - if 'fillcolor' in kwargs and _PIL_VER < (5, 0): - kwargs.pop('fillcolor') - kwargs['resample'] = _interpolation(kwargs) - - -def cutout(img, factor, **kwargs): - _check_args_tf(kwargs) - return Cutout(size=factor)(img) - - -def shear_x(img, factor, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, factor, 0, 0, 1, 0), **kwargs) - - -def shear_y(img, factor, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, factor, 1, 0), **kwargs) - - -def translate_x_rel(img, pct, **kwargs): - pixels = pct * img.size[0] - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, pixels, 0, 1, 0), **kwargs) - - -def translate_y_rel(img, pct, **kwargs): - pixels = pct * img.size[1] - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, pixels), **kwargs) - - -def translate_x_abs(img, pixels, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, pixels, 0, 1, 0), **kwargs) - - -def translate_y_abs(img, pixels, **kwargs): - _check_args_tf(kwargs) - return img.transform(img.size, Image.AFFINE, (1, 0, 0, 0, 1, pixels), **kwargs) - - -def rotate(img, degrees, **kwargs): - _check_args_tf(kwargs) - if _PIL_VER >= (5, 2): - return img.rotate(degrees, **kwargs) - elif _PIL_VER >= (5, 0): - w, h = img.size - post_trans = (0, 0) - rotn_center = (w / 2.0, h / 2.0) - angle = -math.radians(degrees) - matrix = [ - round(math.cos(angle), 15), - round(math.sin(angle), 15), - 0.0, - round(-math.sin(angle), 15), - round(math.cos(angle), 15), - 0.0, - ] - - def transform(x, y, matrix): - (a, b, c, d, e, f) = matrix - return a * x + b * y + c, d * x + e * y + f - - matrix[2], matrix[5] = transform( - -rotn_center[0] - post_trans[0], - - rotn_center[1] - post_trans[1], matrix - ) - matrix[2] += rotn_center[0] - matrix[5] += rotn_center[1] - return img.transform(img.size, Image.AFFINE, matrix, **kwargs) - else: - return img.rotate(degrees, resample=kwargs['resample']) - - -def auto_contrast(img, **__): - return ImageOps.autocontrast(img) - - -def invert(img, **__): - return ImageOps.invert(img) - - -def identity(img, **__): - return img - - -def equalize(img, **__): - return ImageOps.equalize(img) - - -def solarize(img, thresh, **__): - return ImageOps.solarize(img, thresh) - - -def solarize_add(img, add, thresh=128, **__): - lut = [] - for i in range(256): - if i < thresh: - lut.append(min(255, i + add)) - else: - lut.append(i) - if img.mode in ("L", "RGB"): - if img.mode == "RGB" and len(lut) == 256: - lut = lut + lut + lut - return img.point(lut) - else: - return img - - -def posterize(img, bits_to_keep, **__): - if bits_to_keep >= 8: - return img - return ImageOps.posterize(img, bits_to_keep) - - -def contrast(img, factor, **__): - return ImageEnhance.Contrast(img).enhance(factor) - - -def color(img, factor, **__): - return ImageEnhance.Color(img).enhance(factor) - - -def brightness(img, factor, **__): - return ImageEnhance.Brightness(img).enhance(factor) - - -def sharpness(img, factor, **__): - return ImageEnhance.Sharpness(img).enhance(factor) - - -def _randomly_negate(v): - """With 50% prob, negate the value""" - return -v if random.random() > 0.5 else v - - -def _cutout_level_to_arg(level, _hparams): - # range [0, 40] - level = max(2, (level / _MAX_LEVEL) * 40.) - return level, - - -def _rotate_level_to_arg(level, _hparams): - # range [-30, 30] - level = (level / _MAX_LEVEL) * 30. - level = _randomly_negate(level) - return level, - - -def _enhance_level_to_arg(level, _hparams): - # range [0.1, 1.9] - return (level / _MAX_LEVEL) * 1.8 + 0.1, - - -def _shear_level_to_arg(level, _hparams): - # range [-0.3, 0.3] - level = (level / _MAX_LEVEL) * 0.3 - level = _randomly_negate(level) - return level, - - -def _translate_abs_level_to_arg(level, hparams): - translate_const = hparams['translate_const'] - level = (level / _MAX_LEVEL) * float(translate_const) - level = _randomly_negate(level) - return level, - - -def _translate_rel_level_to_arg(level, _hparams): - # range [-0.45, 0.45] - level = (level / _MAX_LEVEL) * 0.45 - level = _randomly_negate(level) - return level, - - -def _posterize_original_level_to_arg(level, _hparams): - # As per original AutoAugment paper description - # range [4, 8], 'keep 4 up to 8 MSB of image' - return int((level / _MAX_LEVEL) * 4) + 4, - - -def _posterize_research_level_to_arg(level, _hparams): - # As per Tensorflow models research and UDA impl - # range [4, 0], 'keep 4 down to 0 MSB of original image' - return 4 - int((level / _MAX_LEVEL) * 4), - - -def _posterize_tpu_level_to_arg(level, _hparams): - # As per Tensorflow TPU EfficientNet impl - # range [0, 4], 'keep 0 up to 4 MSB of original image' - return int((level / _MAX_LEVEL) * 4), - - -def _solarize_level_to_arg(level, _hparams): - # range [0, 256] - return int((level / _MAX_LEVEL) * 256), - - -def _solarize_add_level_to_arg(level, _hparams): - # range [0, 110] - return int((level / _MAX_LEVEL) * 110), - - -LEVEL_TO_ARG = { - 'AutoContrast': None, - 'Equalize': None, - 'Invert': None, - 'Identity': None, - 'Rotate': _rotate_level_to_arg, - 'PosterizeOriginal': _posterize_original_level_to_arg, - 'PosterizeResearch': _posterize_research_level_to_arg, - 'PosterizeTpu': _posterize_tpu_level_to_arg, - 'Solarize': _solarize_level_to_arg, - 'SolarizeAdd': _solarize_add_level_to_arg, - 'Color': _enhance_level_to_arg, - 'Contrast': _enhance_level_to_arg, - 'Brightness': _enhance_level_to_arg, - 'Sharpness': _enhance_level_to_arg, - 'ShearX': _shear_level_to_arg, - 'ShearY': _shear_level_to_arg, - 'TranslateX': _translate_abs_level_to_arg, - 'TranslateY': _translate_abs_level_to_arg, - 'TranslateXRel': _translate_rel_level_to_arg, - 'TranslateYRel': _translate_rel_level_to_arg, - 'Cutout': _cutout_level_to_arg, -} - - -NAME_TO_OP = { - 'AutoContrast': auto_contrast, - 'Equalize': equalize, - 'Invert': invert, - 'Identity': identity, - 'Rotate': rotate, - 'PosterizeOriginal': posterize, - 'PosterizeResearch': posterize, - 'PosterizeTpu': posterize, - 'Solarize': solarize, - 'SolarizeAdd': solarize_add, - 'Color': color, - 'Contrast': contrast, - 'Brightness': brightness, - 'Sharpness': sharpness, - 'ShearX': shear_x, - 'ShearY': shear_y, - 'TranslateX': translate_x_abs, - 'TranslateY': translate_y_abs, - 'TranslateXRel': translate_x_rel, - 'TranslateYRel': translate_y_rel, - 'Cutout': cutout, -} - - -class AutoAugmentTransform(object): - """ - AutoAugment from Google. - Implementation adapted from: - https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/autoaugment.py - """ - - def __init__(self, name, prob=0.5, magnitude=10, hparams=None): - """ - Args: - name (str): any type of transforms list in _RAND_TRANSFORMS. - prob (float): probability of perform current augmentation. - magnitude (int): intensity / magnitude of each augmentation. - hparams (dict): hyper-parameters required by each augmentation. - """ - hparams = hparams or _HPARAMS_DEFAULT - self.aug_fn = NAME_TO_OP[name] - self.level_fn = LEVEL_TO_ARG[name] - self.prob = prob - self.magnitude = magnitude - self.hparams = hparams.copy() - self.kwargs = dict( - fillcolor=hparams['img_mean'] if 'img_mean' in hparams else _FILL, - resample=hparams['interpolation'] if 'interpolation' in hparams - else _RANDOM_INTERPOLATION, - ) - - # If magnitude_std is > 0, we introduce some randomness - # in the usually fixed policy and sample magnitude from a normal distribution - # with mean `magnitude` and std-dev of `magnitude_std`. - # NOTE This is my own hack, being tested, not in papers or reference impls. - self.magnitude_std = self.hparams.get('magnitude_std', 0) - - def __call__(self, img: PIL.Image) -> PIL.Image: - if random.random() > self.prob: - return img - magnitude = self.magnitude - if self.magnitude_std and self.magnitude_std > 0: - magnitude = random.gauss(magnitude, self.magnitude_std) - # NOTE: magnitude fixed and no boundary - # magnitude = min(_MAX_LEVEL, max(0, magnitude)) # clip to valid range - level_args = self.level_fn( - magnitude, self.hparams) if self.level_fn is not None else tuple() - return self.aug_fn(img, *level_args, **self.kwargs) - # return np.array(self.aug_fn(Image.fromarray(img), *level_args, **self.kwargs)) - - # def apply_coords(self, coords: np.ndarray) -> np.ndarray: - # return coords - - -_RAND_TRANSFORMS = [ - 'AutoContrast', - 'Equalize', - 'Invert', - 'Rotate', - 'PosterizeTpu', - 'Solarize', - 'SolarizeAdd', - 'Color', - 'Contrast', - 'Brightness', - 'Sharpness', - 'ShearX', - 'ShearY', - 'TranslateXRel', - 'TranslateYRel', - 'Cutout' # FIXME I implement this as random erasing separately -] - -_RAND_TRANSFORMS_CMC = [ - 'AutoContrast', - 'Identity', - 'Rotate', - 'Sharpness', - 'ShearX', - 'ShearY', - 'TranslateXRel', - 'TranslateYRel', - # 'Cutout' # FIXME I implement this as random erasing separately -] - - -# These experimental weights are based loosely on the relative improvements mentioned in paper. -# They may not result in increased performance, but could likely be tuned to so. -_RAND_CHOICE_WEIGHTS_0 = { - 'Rotate': 0.3, - 'ShearX': 0.2, - 'ShearY': 0.2, - 'TranslateXRel': 0.1, - 'TranslateYRel': 0.1, - 'Color': .025, - 'Sharpness': 0.025, - 'AutoContrast': 0.025, - 'Solarize': .005, - 'SolarizeAdd': .005, - 'Contrast': .005, - 'Brightness': .005, - 'Equalize': .005, - 'PosterizeTpu': 0, - 'Invert': 0, -} - - -class RandAugPolicy(object): - def __init__(self, layers=2, magnitude=10): - self.layers = layers - self.magnitude = magnitude - - def __call__(self, img): - for _ in range(self.layers): - trans = np.random.choice(_RAND_TRANSFORMS) - # NOTE: prob apply, fixed magnitude - # trans_op = AutoAugmentTransform(trans, prob=np.random.uniform(0.2, 0.8), magnitude=self.magnitude) - # NOTE: always apply, random magnitude - trans_op = AutoAugmentTransform(trans, prob=1.0, magnitude=np.random.choice(self.magnitude)) - img = trans_op(img) - assert img is not None, trans - return img diff --git a/cv/classification/repvgg/pytorch/utils.py b/cv/classification/repvgg/pytorch/utils.py deleted file mode 100755 index 78ceb5230..000000000 --- a/cv/classification/repvgg/pytorch/utils.py +++ /dev/null @@ -1,249 +0,0 @@ -# -------------------------------------------------------- -# RepVGG: Making VGG-style ConvNets Great Again (https://openaccess.thecvf.com/content/CVPR2021/papers/Ding_RepVGG_Making_VGG-Style_ConvNets_Great_Again_CVPR_2021_paper.pdf) -# Github source: https://github.com/DingXiaoH/RepVGG -# Licensed under The MIT License [see LICENSE for details] -# The training script is based on the code of Swin Transformer (https://github.com/microsoft/Swin-Transformer) -# -------------------------------------------------------- - -import torch -import math -import os - -class AverageMeter(object): - """Computes and stores the average and current value""" - def __init__(self, name, fmt=':f'): - self.name = name - self.fmt = fmt - self.reset() - - def reset(self): - self.val = 0 - self.avg = 0 - self.sum = 0 - self.count = 0 - - def update(self, val, n=1): - self.val = val - self.sum += val * n - self.count += n - self.avg = self.sum / self.count - - def __str__(self): - fmtstr = '{name} {val' + self.fmt + '} ({avg' + self.fmt + '})' - return fmtstr.format(**self.__dict__) - - -class ProgressMeter(object): - def __init__(self, num_batches, meters, prefix=""): - self.batch_fmtstr = self._get_batch_fmtstr(num_batches) - self.meters = meters - self.prefix = prefix - - def display(self, batch): - entries = [self.prefix + self.batch_fmtstr.format(batch)] - entries += [str(meter) for meter in self.meters] - print('\t'.join(entries)) - - def _get_batch_fmtstr(self, num_batches): - num_digits = len(str(num_batches // 1)) - fmt = '{:' + str(num_digits) + 'd}' - return '[' + fmt + '/' + fmt.format(num_batches) + ']' - - -def accuracy(output, target, topk=(1,)): - """Computes the accuracy over the k top predictions for the specified values of k""" - with torch.no_grad(): - maxk = max(topk) - batch_size = target.size(0) - - _, pred = output.topk(maxk, 1, True, True) - pred = pred.t() - correct = pred.eq(target.view(1, -1).expand_as(pred)) - - res = [] - for k in topk: - correct_k = correct[:k].reshape(-1).float().sum(0, keepdim=True) - res.append(correct_k.mul_(100.0 / batch_size)) - return res - -def load_checkpoint(model, ckpt_path): - checkpoint = torch.load(ckpt_path) - if 'model' in checkpoint: - checkpoint = checkpoint['model'] - if 'state_dict' in checkpoint: - checkpoint = checkpoint['state_dict'] - ckpt = {} - for k, v in checkpoint.items(): - if k.startswith('module.'): - ckpt[k[7:]] = v - else: - ckpt[k] = v - model.load_state_dict(ckpt) - - -class WarmupCosineAnnealingLR(torch.optim.lr_scheduler._LRScheduler): - - def __init__(self, optimizer, T_cosine_max, eta_min=0, last_epoch=-1, warmup=0): - self.eta_min = eta_min - self.T_cosine_max = T_cosine_max - self.warmup = warmup - super(WarmupCosineAnnealingLR, self).__init__(optimizer, last_epoch) - - def get_lr(self): - if self.last_epoch < self.warmup: - return [self.last_epoch / self.warmup * base_lr for base_lr in self.base_lrs] - else: - return [self.eta_min + (base_lr - self.eta_min) * - (1 + math.cos(math.pi * (self.last_epoch - self.warmup) / (self.T_cosine_max - self.warmup))) / 2 - for base_lr in self.base_lrs] - - -def log_msg(message, log_file): - print(message) - with open(log_file, 'a') as f: - print(message, file=f) - - - - - -try: - # noinspection PyUnresolvedReferences - from apex import amp -except ImportError: - amp = None - -def unwrap_model(model): - """Remove the DistributedDataParallel wrapper if present.""" - wrapped = isinstance(model, torch.nn.parallel.distributed.DistributedDataParallel) - return model.module if wrapped else model - - -def load_checkpoint(config, model, optimizer, lr_scheduler, logger, model_ema=None): - logger.info(f"==============> Resuming form {config.MODEL.RESUME}....................") - if config.MODEL.RESUME.startswith('https'): - checkpoint = torch.hub.load_state_dict_from_url( - config.MODEL.RESUME, map_location='cpu', check_hash=True) - else: - checkpoint = torch.load(config.MODEL.RESUME, map_location='cpu') - msg = model.load_state_dict(checkpoint['model'], strict=False) - logger.info(msg) - max_accuracy = 0.0 - if not config.EVAL_MODE and 'optimizer' in checkpoint and 'lr_scheduler' in checkpoint and 'epoch' in checkpoint: - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['lr_scheduler']) - config.defrost() - config.TRAIN.START_EPOCH = checkpoint['epoch'] + 1 - config.freeze() - if 'amp' in checkpoint and config.AMP_OPT_LEVEL != "O0" and checkpoint['config'].AMP_OPT_LEVEL != "O0": - amp.load_state_dict(checkpoint['amp']) - logger.info(f"=> loaded successfully '{config.MODEL.RESUME}' (epoch {checkpoint['epoch']})") - if 'max_accuracy' in checkpoint: - max_accuracy = checkpoint['max_accuracy'] - if model_ema is not None: - unwrap_model(model_ema).load_state_dict(checkpoint['ema']) - print('=================================================== EMAloaded') - - del checkpoint - torch.cuda.empty_cache() - return max_accuracy - - -def load_weights(model, path): - checkpoint = torch.load(path, map_location='cpu') - if 'model' in checkpoint: - checkpoint = checkpoint['model'] - if 'state_dict' in checkpoint: - checkpoint = checkpoint['state_dict'] - unwrap_model(model).load_state_dict(checkpoint, strict=False) - print('=================== loaded from', path) - -def save_latest(config, epoch, model, max_accuracy, optimizer, lr_scheduler, logger, model_ema=None): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'epoch': epoch, - 'config': config} - if config.AMP_OPT_LEVEL != "O0": - save_state['amp'] = amp.state_dict() - if model_ema is not None: - save_state['ema'] = unwrap_model(model_ema).state_dict() - - save_path = os.path.join(config.OUTPUT, 'latest.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - -def save_checkpoint(config, epoch, model, max_accuracy, optimizer, lr_scheduler, logger, is_best=False, model_ema=None): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'epoch': epoch, - 'config': config} - if config.AMP_OPT_LEVEL != "O0": - save_state['amp'] = amp.state_dict() - if model_ema is not None: - save_state['ema'] = unwrap_model(model_ema).state_dict() - - if is_best: - best_path = os.path.join(config.OUTPUT, 'best_ckpt.pth') - torch.save(save_state, best_path) - - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - - -def get_grad_norm(parameters, norm_type=2): - if isinstance(parameters, torch.Tensor): - parameters = [parameters] - parameters = list(filter(lambda p: p.grad is not None, parameters)) - norm_type = float(norm_type) - total_norm = 0 - for p in parameters: - param_norm = p.grad.data.norm(norm_type) - total_norm += param_norm.item() ** norm_type - total_norm = total_norm ** (1. / norm_type) - return total_norm - - -import torch.distributed as dist - -def auto_resume_helper(output_dir): - checkpoints = os.listdir(output_dir) - checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith('pth') and 'ema' not in ckpt] - print(f"All checkpoints founded in {output_dir}: {checkpoints}") - if len(checkpoints) > 0: - latest_checkpoint = max([os.path.join(output_dir, d) for d in checkpoints], key=os.path.getmtime) - print(f"The latest checkpoint founded: {latest_checkpoint}") - resume_file = latest_checkpoint - else: - resume_file = None - return resume_file - - -def reduce_tensor(tensor): - rt = tensor.clone() - dist.all_reduce(rt, op=dist.ReduceOp.SUM) - rt /= dist.get_world_size() - return rt - -def update_model_ema(cfg, num_gpus, model, model_ema, cur_epoch, cur_iter): - """Update exponential moving average (ema) of model weights.""" - update_period = cfg.TRAIN.EMA_UPDATE_PERIOD - if update_period is None or update_period == 0 or cur_iter % update_period != 0: - return - # Adjust alpha to be fairly independent of other parameters - total_batch_size = num_gpus * cfg.DATA.BATCH_SIZE - adjust = total_batch_size / cfg.TRAIN.EPOCHS * update_period - # print('ema adjust', adjust) - alpha = min(1.0, cfg.TRAIN.EMA_ALPHA * adjust) - # During warmup simply copy over weights instead of using ema - alpha = 1.0 if cur_epoch < cfg.TRAIN.WARMUP_EPOCHS else alpha - # Take ema of all parameters (not just named parameters) - params = unwrap_model(model).state_dict() - for name, param in unwrap_model(model_ema).state_dict().items(): - param.copy_(param * (1.0 - alpha) + params[name] * alpha) \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/.gitignore b/cv/classification/swin_transformer/pytorch/.gitignore deleted file mode 100644 index 24f67f2e0..000000000 --- a/cv/classification/swin_transformer/pytorch/.gitignore +++ /dev/null @@ -1,135 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# launch bash -*.sh -# nsight system report files -*.nsys-rep -*.sqlite - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ diff --git a/cv/classification/swin_transformer/pytorch/CODE_OF_CONDUCT.md b/cv/classification/swin_transformer/pytorch/CODE_OF_CONDUCT.md deleted file mode 100644 index f9ba8cf65..000000000 --- a/cv/classification/swin_transformer/pytorch/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,9 +0,0 @@ -# Microsoft Open Source Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). - -Resources: - -- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) -- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) -- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns diff --git a/cv/classification/swin_transformer/pytorch/LICENSE b/cv/classification/swin_transformer/pytorch/LICENSE deleted file mode 100644 index 9e841e7a2..000000000 --- a/cv/classification/swin_transformer/pytorch/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/cv/classification/swin_transformer/pytorch/MODELHUB.md b/cv/classification/swin_transformer/pytorch/MODELHUB.md deleted file mode 100644 index 72985ad54..000000000 --- a/cv/classification/swin_transformer/pytorch/MODELHUB.md +++ /dev/null @@ -1,71 +0,0 @@ -Access code for `baidu` is `swin`. - -## ImageNet-1K and ImageNet-22K Pretrained Swin-V1 Models - -| name | pretrain | resolution |acc@1 | acc@5 | #params | FLOPs | FPS| 22K model | 1K model | -| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |:---: |:---: | -| Swin-T | ImageNet-1K | 224x224 | 81.2 | 95.5 | 28M | 4.5G | 755 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_tiny_patch4_window7_224.pth)/[baidu](https://pan.baidu.com/s/156nWJy4Q28rDlrX-rRbI3w)/[config](configs/swin/swin_tiny_patch4_window7_224.yaml)/[log](https://github.com/SwinTransformer/storage/files/7745562/log_swin_tiny_patch4_window7_224.txt) | -| Swin-S | ImageNet-1K | 224x224 | 83.2 | 96.2 | 50M | 8.7G | 437 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_small_patch4_window7_224.pth)/[baidu](https://pan.baidu.com/s/1KFjpj3Efey3LmtE1QqPeQg)/[config](configs/swin/swin_small_patch4_window7_224.yaml)/[log](https://github.com/SwinTransformer/storage/files/7745563/log_swin_small_patch4_window7_224.txt) | -| Swin-B | ImageNet-1K | 224x224 | 83.5 | 96.5 | 88M | 15.4G | 278 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window7_224.pth)/[baidu](https://pan.baidu.com/s/16bqCTEc70nC_isSsgBSaqQ)/[config](configs/swin/swin_base_patch4_window7_224.yaml)/[log](https://github.com/SwinTransformer/storage/files/7745564/log_swin_base_patch4_window7_224.txt) | -| Swin-B | ImageNet-1K | 384x384 | 84.5 | 97.0 | 88M | 47.1G | 85 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window12_384.pth)/[baidu](https://pan.baidu.com/s/1xT1cu740-ejW7htUdVLnmw)/[config](configs/swin/swin_base_patch4_window12_384_finetune.yaml) | -| Swin-T | ImageNet-22K | 224x224 | 80.9 | 96.0 | 28M | 4.5G | 755 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.8/swin_tiny_patch4_window7_224_22k.pth)/[baidu](https://pan.baidu.com/s/1vct0VYwwQQ8PYkBjwSSBZQ?pwd=swin)/[config](configs/swin/swin_tiny_patch4_window7_224_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.8/swin_tiny_patch4_window7_224_22kto1k_finetune.pth)/[baidu](https://pan.baidu.com/s/1K0OO-nGZDPkR8fm_r83e8Q?pwd=swin)/[config](configs/swin/swin_tiny_patch4_window7_224_22kto1k_finetune.yaml) | -| Swin-S | ImageNet-22K | 224x224 | 83.2 | 97.0 | 50M | 8.7G | 437 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.8/swin_small_patch4_window7_224_22k.pth)/[baidu](https://pan.baidu.com/s/11NC1xdT5BAGBgazdTme5Sg?pwd=swin)/[config](configs/swin/swin_small_patch4_window7_224_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.8/swin_small_patch4_window7_224_22kto1k_finetune.pth)/[baidu](https://pan.baidu.com/s/10RFVfjQJhwPfeHrmxQUaLw?pwd=swin)/[config](configs/swin/swin_small_patch4_window7_224_22kto1k_finetune.yaml) | -| Swin-B | ImageNet-22K | 224x224 | 85.2 | 97.5 | 88M | 15.4G | 278 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window7_224_22k.pth)/[baidu](https://pan.baidu.com/s/1y1Ec3UlrKSI8IMtEs-oBXA)/[config](configs/swin/swin_base_patch4_window7_224_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window7_224_22kto1k.pth)/[baidu](https://pan.baidu.com/s/1n_wNkcbRxVXit8r_KrfAVg)/[config](configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml) | -| Swin-B | ImageNet-22K | 384x384 | 86.4 | 98.0 | 88M | 47.1G | 85 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window12_384_22k.pth)/[baidu](https://pan.baidu.com/s/1vwJxnJcVqcLZAw9HaqiR6g) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_base_patch4_window12_384_22kto1k.pth)/[baidu](https://pan.baidu.com/s/1caKTSdoLJYoi4WBcnmWuWg)/[config](configs/swin/swin_base_patch4_window12_384_22kto1k_finetune.yaml) | -| Swin-L | ImageNet-22K | 224x224 | 86.3 | 97.9 | 197M | 34.5G | 141 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window7_224_22k.pth)/[baidu](https://pan.baidu.com/s/1pws3rOTFuOebBYP3h6Kx8w)/[config](configs/swin/swin_large_patch4_window7_224_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window7_224_22kto1k.pth)/[baidu](https://pan.baidu.com/s/1NkQApMWUhxBGjk1ne6VqBQ)/[config](configs/swin/swin_large_patch4_window7_224_22kto1k_finetune.yaml) | -| Swin-L | ImageNet-22K | 384x384 | 87.3 | 98.2 | 197M | 103.9G | 42 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window12_384_22k.pth)/[baidu](https://pan.baidu.com/s/1sl7o_bJA143OD7UqSLAMoA) | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.0/swin_large_patch4_window12_384_22kto1k.pth)/[baidu](https://pan.baidu.com/s/1X0FLHQyPOC6Kmv2CmgxJvA)/[config](configs/swin/swin_large_patch4_window12_384_22kto1k_finetune.yaml) | - -## ImageNet-1K and ImageNet-22K Pretrained Swin-V2 Models - -| name | pretrain | resolution | window |acc@1 | acc@5 | #params | FLOPs | FPS |22K model | 1K model | -|:---------------------:| :---: | :---: | :---: | :---: | :---: | :---: | :---: |:---:|:---: |:---: | -| SwinV2-T | ImageNet-1K | 256x256 | 8x8 | 81.8 | 95.9 | 28M | 5.9G | 572 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_tiny_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/1RzLkAH_5OtfRCJe6Vlg6rg?pwd=swin)/[config](configs/swinv2/swinv2_tiny_patch4_window8_256.yaml) | -| SwinV2-S | ImageNet-1K | 256x256 | 8x8 | 83.7 | 96.6 | 50M | 11.5G | 327 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_small_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/195PdA41szEduW3jEtRSa4Q?pwd=swin)/[config](configs/swinv2/swinv2_small_patch4_window8_256.yaml) | -| SwinV2-B | ImageNet-1K | 256x256 | 8x8 | 84.2 | 96.9 | 88M | 20.3G | 217 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/18AfMSz3dPyzIvP1dKuERvQ?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window8_256.yaml) | -| SwinV2-T | ImageNet-1K | 256x256 | 16x16 | 82.8 | 96.2 | 28M | 6.6G | 437 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_tiny_patch4_window16_256.pth)/[baidu](https://pan.baidu.com/s/1dyK3cK9Xipmv6RnTtrPocw?pwd=swin)/[config](configs/swinv2/swinv2_tiny_patch4_window16_256.yaml) | -| SwinV2-S | ImageNet-1K | 256x256 | 16x16 | 84.1 | 96.8 | 50M | 12.6G | 257 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_small_patch4_window16_256.pth)/[baidu](https://pan.baidu.com/s/1ZIPiSfWNKTPp821Ka-Mifw?pwd=swin)/[config](configs/swinv2/swinv2_small_patch4_window16_256.yaml) | -| SwinV2-B | ImageNet-1K | 256x256 | 16x16 | 84.6 | 97.0 | 88M | 21.8G | 174 | - | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window16_256.pth)/[baidu](https://pan.baidu.com/s/1dlDQGn8BXCmnh7wQSM5Nhw?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window16_256.yaml) | -| SwinV2-B\* | ImageNet-22K | 256x256 | 16x16 | 86.2 | 97.9 | 88M | 21.8G | 174 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window12_192_22k.pth)/[baidu](https://pan.baidu.com/s/1Xc2rsSsRQz_sy5mjgfxrMQ?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.pth)/[baidu](https://pan.baidu.com/s/1sgstld4MgGsZxhUAW7MlmQ?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.yaml) | -| SwinV2-B\* | ImageNet-22K | 384x384 | 24x24 | 87.1 | 98.2 | 88M | 54.7G | 57 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window12_192_22k.pth)/[baidu](https://pan.baidu.com/s/1Xc2rsSsRQz_sy5mjgfxrMQ?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.pth)/[baidu](https://pan.baidu.com/s/17u3sEQaUYlvfL195rrORzQ?pwd=swin)/[config](configs/swinv2/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.yaml) | -| SwinV2-L\* | ImageNet-22K | 256x256 | 16x16 | 86.9 | 98.0 | 197M | 47.5G | 95 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_large_patch4_window12_192_22k.pth)/[baidu](https://pan.baidu.com/s/11PhCV7qAGXtZ8dXNgyiGOw?pwd=swin)/[config](configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.pth)/[baidu](https://pan.baidu.com/s/1pqp31N80qIWjFPbudzB6Bw?pwd=swin)/[config](configs/swinv2/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.yaml) | -| SwinV2-L\* | ImageNet-22K | 384x384 | 24x24 | 87.6 | 98.3 | 197M | 115.4G | 33 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_large_patch4_window12_192_22k.pth)/[baidu](https://pan.baidu.com/s/11PhCV7qAGXtZ8dXNgyiGOw?pwd=swin)/[config](configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml) | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.0/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.pth)/[baidu](https://pan.baidu.com/s/13URdNkygr3Xn0N3e6IwjgA?pwd=swin)/[config](configs/swinv2/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.yaml) | - -Note: - -- SwinV2-B\* (SwinV2-L\*) with input resolution of 256x256 and 384x384 both fine-tuned from the - same pre-training model using a smaller input resolution of 192x192. -- SwinV2-B\* (384x384) achieves 78.08 acc@1 on ImageNet-1K-V2 while SwinV2-L\* (384x384) achieves - 78.31. - -## ImageNet-1K Pretrained Swin MLP Models - -| name | pretrain | resolution |acc@1 | acc@5 | #params | FLOPs | FPS | 1K model | -| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| [Mixer-B/16](https://arxiv.org/pdf/2105.01601.pdf) | ImageNet-1K | 224x224 | 76.4 | - | 59M | 12.7G | - | [official repo](https://github.com/google-research/vision_transformer) | -| [ResMLP-S24](https://arxiv.org/abs/2105.03404) | ImageNet-1K | 224x224 | 79.4 | - | 30M | 6.0G | 715 | [timm](https://github.com/rwightman/pytorch-image-models) | -| [ResMLP-B24](https://arxiv.org/abs/2105.03404) | ImageNet-1K | 224x224 | 81.0 | - | 116M | 23.0G | 231 | [timm](https://github.com/rwightman/pytorch-image-models) | -| Swin-T/C24 | ImageNet-1K | 256x256 | 81.6 | 95.7 | 28M | 5.9G | 563 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.5/swin_tiny_c24_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/17k-7l6Sxt7uZ7IV0f26GNQ)/[config](configs/swin/swin_tiny_c24_patch4_window8_256.yaml) | -| SwinMLP-T/C24 | ImageNet-1K | 256x256 | 79.4 | 94.6 | 20M | 4.0G | 807 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.5/swin_mlp_tiny_c24_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/1Sa4vP5R0M2RjfIe9HIga-Q)/[config](configs/swin/swin_mlp_tiny_c24_patch4_window8_256.yaml) | -| SwinMLP-T/C12 | ImageNet-1K | 256x256 | 79.6 | 94.7 | 21M | 4.0G | 792 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.5/swin_mlp_tiny_c12_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/1mM9J2_DEVZHUB5ASIpFl0w)/[config](configs/swin/swin_mlp_tiny_c12_patch4_window8_256.yaml) | -| SwinMLP-T/C6 | ImageNet-1K | 256x256 | 79.7 | 94.9 | 23M | 4.0G | 766 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.5/swin_mlp_tiny_c6_patch4_window8_256.pth)/[baidu](https://pan.baidu.com/s/1hUTYVT2W1CsjICw-3W-Vjg)/[config](configs/swin/swin_mlp_tiny_c6_patch4_window8_256.yaml) | -| SwinMLP-B | ImageNet-1K | 224x224 | 81.3 | 95.3 | 61M | 10.4G | 409 | [github](https://github.com/SwinTransformer/storage/releases/download/v1.0.5/swin_mlp_base_patch4_window7_224.pth)/[baidu](https://pan.baidu.com/s/1zww3dnbX3GxNiGfb-GwyUg)/[config](configs/swin/swin_mlp_base_patch4_window7_224.yaml) | - -Note: C24 means each head has 24 channels. - -## ImageNet-22K Pretrained Swin-MoE Models - -| name | #experts | k | router | resolution | window | IN-22K acc@1 | IN-1K/ft acc@1 | IN-1K/5-shot acc@1 | 22K model | -| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| Swin-MoE-S | 1 (dense) | - | - | 192x192 | 8x8 | 35.5| 83.5 | 70.3 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_densebaseline_22k.zip)/[baidu](https://pan.baidu.com/s/1O1m9jT2pGoago_RiRX914w?pwd=swin)/[config](configs/swinmoe/swin_moe_small_patch4_window12_192_densebaseline_22k.yaml) | -| Swin-MoE-S | 8 | 1 | Linear | 192x192 | 8x8 | 36.8 | 84.5 | 75.2 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.zip)/[baidu](https://pan.baidu.com/s/198IlYUrWOxEUp7wNdoJT5Q?pwd=swin)/[config](configs/swinmoe/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.yaml) | -| Swin-MoE-S | 16 | 1 | Linear |192x192 | 8x8 | 37.6 | 84.9 | 76.5 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.zip)/[baidu](https://pan.baidu.com/s/1vRQweedtT42VwMTqe9-r2A?pwd=swin)/[config](configs/swinmoe/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.yaml) | -| Swin-MoE-S | 32 | 1 | Linear | 192x192 | 8x8 | 37.4 | 84.7 | 75.9 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.zip)/[baidu](https://pan.baidu.com/s/1i7rImt5pwO8gJC-PRRuZwQ?pwd=swin)/[config](configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml) | -| Swin-MoE-S | 32 | 1 | Cosine | 192x192 | 8x8 | 37.2 | 84.3 | 75.2 | [github](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.zip)/[baidu](https://pan.baidu.com/s/1Yghr_12ntSrv01I9yatPDQ?pwd=swin)/[config](configs/swinmoe/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml) | -| Swin-MoE-S | 64 | 1 | Linear | 192x192 | 8x8 | 37.8 | 84.7 | 75.7 | - | -| Swin-MoE-S | 128 | 1 | Linear | 192x192 | 8x8 | 37.4 | 84.5 | 75.4 | - | -| Swin-MoE-B | 1 (dense) | - | - | 192x192 | 8x8 | 37.3 | 85.1 | 75.9 | [config](configs/swinmoe/swin_moe_base_patch4_window12_192_densebaseline_22k.yaml) | -| Swin-MoE-B | 8 | 1 | Linear | 192x192 | 8x8 | 38.1 | 85.3 | 77.2 | [config](configs/swinmoe/swin_moe_base_patch4_window12_192_8expert_32gpu_22k.yaml) | -| Swin-MoE-B | 16 | 1 | Linear | 192x192 | 8x8 | 38.7 | 85.5 | 78.2 | [config](configs/swinmoe/swin_moe_base_patch4_window12_192_16expert_32gpu_22k.yaml) | -| Swin-MoE-B | 32 | 1 | Linear | 192x192 | 8x8 | 38.6 | 85.5 | 77.9 | [config](configs/swinmoe/swin_moe_base_patch4_window12_192_32expert_32gpu_22k.yaml) | -| Swin-MoE-B | 32 | 1 | Cosine | 192x192 | 8x8 | 38.5 | 85.3 | 77.3 | [config](configs/swinmoe/swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml) | -| Swin-MoE-B | 32 | 2 | Linear | 192x192 | 8x8 | 38.6 | 85.5 | 78.7 | - | \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/README.md b/cv/classification/swin_transformer/pytorch/README.md index e91396d8f..3b2d0b280 100644 --- a/cv/classification/swin_transformer/pytorch/README.md +++ b/cv/classification/swin_transformer/pytorch/README.md @@ -5,8 +5,10 @@ The Swin Transformer is a type of Vision Transformer. It builds hierarchical fea ## Step 1: Installing ```bash -pip install timm==0.4.12 -pip install yacs +git clone https://github.com/microsoft/Swin-Transformer.git +git checkout f82860bfb5225915aca09c3227159ee9e1df874d +cd Swin-Transformer +pip install timm==0.4.12 yacs ``` Sign up and login in [ImageNet official website](https://www.image-net.org/index.php), then choose 'Download' to download the whole ImageNet dataset. Specify `/path/to/imagenet` to your ImageNet path in later training process. @@ -30,9 +32,12 @@ imagenet ## Step 2: Training ### Multiple GPUs on one machine ```bash +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' main.py + python3 -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ --cfg configs/swin/swin_tiny_patch4_window7_224.yaml --data-path /path/to/imagenet --batch-size 128 ``` ## Reference -https://github.com/microsoft/Swin-Transformer +[Swin-Transformer](https://github.com/microsoft/Swin-Transformer) diff --git a/cv/classification/swin_transformer/pytorch/README_IX.md b/cv/classification/swin_transformer/pytorch/README_IX.md deleted file mode 100644 index 171ab578f..000000000 --- a/cv/classification/swin_transformer/pytorch/README_IX.md +++ /dev/null @@ -1,18 +0,0 @@ -# Swin Transformer - -## Setup -1.Download and extract the imagenet - - Download the datasets in the data site: [imagenet](https://image-net.org/download.php); -2.Install python requirments; - - pip install timm==0.4.12 - - pip install yacs - -## Training -`python3 -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ - --cfg configs/swin/swin_tiny_patch4_window7_224.yaml --data-path --batch-size 128 ` - -## Performace -| card type | FPS(1卡) | FPS(8卡) | -| -------- | -----: | :----: | -| V100S | 310.802 | 1992.264 | -| BI | 145.503 | 1073.904 | diff --git a/cv/classification/swin_transformer/pytorch/SECURITY.md b/cv/classification/swin_transformer/pytorch/SECURITY.md deleted file mode 100644 index f7b89984f..000000000 --- a/cv/classification/swin_transformer/pytorch/SECURITY.md +++ /dev/null @@ -1,41 +0,0 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). - - \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/SUPPORT.md b/cv/classification/swin_transformer/pytorch/SUPPORT.md deleted file mode 100644 index dc72f0e5a..000000000 --- a/cv/classification/swin_transformer/pytorch/SUPPORT.md +++ /dev/null @@ -1,25 +0,0 @@ -# TODO: The maintainer of this repo has not yet edited this file - -**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project? - -- **No CSS support:** Fill out this template with information about how to file issues and get help. -- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). -- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide. - -*Then remove this first heading from this SUPPORT.MD file before publishing your repo.* - -# Support - -## How to file issues and get help - -This project uses GitHub Issues to track bugs and feature requests. Please search the existing -issues before filing new issues to avoid duplicates. For new issues, file your bug or -feature request as a new Issue. - -For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE -FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER -CHANNEL. WHERE WILL YOU HELP PEOPLE?**. - -## Microsoft Support Policy - -Support for this **PROJECT or PRODUCT** is limited to the resources listed above. diff --git a/cv/classification/swin_transformer/pytorch/config.py b/cv/classification/swin_transformer/pytorch/config.py deleted file mode 100644 index c9390df32..000000000 --- a/cv/classification/swin_transformer/pytorch/config.py +++ /dev/null @@ -1,318 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# --------------------------------------------------------' - -import os -import yaml -from yacs.config import CfgNode as CN - -_C = CN() - -# Base config files -_C.BASE = [''] - -# ----------------------------------------------------------------------------- -# Data settings -# ----------------------------------------------------------------------------- -_C.DATA = CN() -# Batch size for a single GPU, could be overwritten by command line argument -_C.DATA.BATCH_SIZE = 128 -# Path to dataset, could be overwritten by command line argument -_C.DATA.DATA_PATH = '' -# Dataset name -_C.DATA.DATASET = 'imagenet' -# Input image size -_C.DATA.IMG_SIZE = 224 -# Interpolation to resize image (random, bilinear, bicubic) -_C.DATA.INTERPOLATION = 'bicubic' -# Use zipped dataset instead of folder dataset -# could be overwritten by command line argument -_C.DATA.ZIP_MODE = False -# Cache Data in Memory, could be overwritten by command line argument -_C.DATA.CACHE_MODE = 'part' -# Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU. -_C.DATA.PIN_MEMORY = True -# Number of data loading threads -_C.DATA.NUM_WORKERS = 8 - -# ----------------------------------------------------------------------------- -# Model settings -# ----------------------------------------------------------------------------- -_C.MODEL = CN() -# Model type -_C.MODEL.TYPE = 'swin' -# Model name -_C.MODEL.NAME = 'swin_tiny_patch4_window7_224' -# Pretrained weight from checkpoint, could be imagenet22k pretrained weight -# could be overwritten by command line argument -_C.MODEL.PRETRAINED = '' -# Checkpoint to resume, could be overwritten by command line argument -_C.MODEL.RESUME = '' -# Number of classes, overwritten in data preparation -_C.MODEL.NUM_CLASSES = 1000 -# Dropout rate -_C.MODEL.DROP_RATE = 0.0 -# Drop path rate -_C.MODEL.DROP_PATH_RATE = 0.1 -# Label Smoothing -_C.MODEL.LABEL_SMOOTHING = 0.1 - -# Swin Transformer parameters -_C.MODEL.SWIN = CN() -_C.MODEL.SWIN.PATCH_SIZE = 4 -_C.MODEL.SWIN.IN_CHANS = 3 -_C.MODEL.SWIN.EMBED_DIM = 96 -_C.MODEL.SWIN.DEPTHS = [2, 2, 6, 2] -_C.MODEL.SWIN.NUM_HEADS = [3, 6, 12, 24] -_C.MODEL.SWIN.WINDOW_SIZE = 7 -_C.MODEL.SWIN.MLP_RATIO = 4. -_C.MODEL.SWIN.QKV_BIAS = True -_C.MODEL.SWIN.QK_SCALE = None -_C.MODEL.SWIN.APE = False -_C.MODEL.SWIN.PATCH_NORM = True - -# Swin Transformer V2 parameters -_C.MODEL.SWINV2 = CN() -_C.MODEL.SWINV2.PATCH_SIZE = 4 -_C.MODEL.SWINV2.IN_CHANS = 3 -_C.MODEL.SWINV2.EMBED_DIM = 96 -_C.MODEL.SWINV2.DEPTHS = [2, 2, 6, 2] -_C.MODEL.SWINV2.NUM_HEADS = [3, 6, 12, 24] -_C.MODEL.SWINV2.WINDOW_SIZE = 7 -_C.MODEL.SWINV2.MLP_RATIO = 4. -_C.MODEL.SWINV2.QKV_BIAS = True -_C.MODEL.SWINV2.APE = False -_C.MODEL.SWINV2.PATCH_NORM = True -_C.MODEL.SWINV2.PRETRAINED_WINDOW_SIZES = [0, 0, 0, 0] - -# Swin Transformer MoE parameters -_C.MODEL.SWIN_MOE = CN() -_C.MODEL.SWIN_MOE.PATCH_SIZE = 4 -_C.MODEL.SWIN_MOE.IN_CHANS = 3 -_C.MODEL.SWIN_MOE.EMBED_DIM = 96 -_C.MODEL.SWIN_MOE.DEPTHS = [2, 2, 6, 2] -_C.MODEL.SWIN_MOE.NUM_HEADS = [3, 6, 12, 24] -_C.MODEL.SWIN_MOE.WINDOW_SIZE = 7 -_C.MODEL.SWIN_MOE.MLP_RATIO = 4. -_C.MODEL.SWIN_MOE.QKV_BIAS = True -_C.MODEL.SWIN_MOE.QK_SCALE = None -_C.MODEL.SWIN_MOE.APE = False -_C.MODEL.SWIN_MOE.PATCH_NORM = True -_C.MODEL.SWIN_MOE.MLP_FC2_BIAS = True -_C.MODEL.SWIN_MOE.INIT_STD = 0.02 -_C.MODEL.SWIN_MOE.PRETRAINED_WINDOW_SIZES = [0, 0, 0, 0] -_C.MODEL.SWIN_MOE.MOE_BLOCKS = [[-1], [-1], [-1], [-1]] -_C.MODEL.SWIN_MOE.NUM_LOCAL_EXPERTS = 1 -_C.MODEL.SWIN_MOE.TOP_VALUE = 1 -_C.MODEL.SWIN_MOE.CAPACITY_FACTOR = 1.25 -_C.MODEL.SWIN_MOE.COSINE_ROUTER = False -_C.MODEL.SWIN_MOE.NORMALIZE_GATE = False -_C.MODEL.SWIN_MOE.USE_BPR = True -_C.MODEL.SWIN_MOE.IS_GSHARD_LOSS = False -_C.MODEL.SWIN_MOE.GATE_NOISE = 1.0 -_C.MODEL.SWIN_MOE.COSINE_ROUTER_DIM = 256 -_C.MODEL.SWIN_MOE.COSINE_ROUTER_INIT_T = 0.5 -_C.MODEL.SWIN_MOE.MOE_DROP = 0.0 -_C.MODEL.SWIN_MOE.AUX_LOSS_WEIGHT = 0.01 - -# Swin MLP parameters -_C.MODEL.SWIN_MLP = CN() -_C.MODEL.SWIN_MLP.PATCH_SIZE = 4 -_C.MODEL.SWIN_MLP.IN_CHANS = 3 -_C.MODEL.SWIN_MLP.EMBED_DIM = 96 -_C.MODEL.SWIN_MLP.DEPTHS = [2, 2, 6, 2] -_C.MODEL.SWIN_MLP.NUM_HEADS = [3, 6, 12, 24] -_C.MODEL.SWIN_MLP.WINDOW_SIZE = 7 -_C.MODEL.SWIN_MLP.MLP_RATIO = 4. -_C.MODEL.SWIN_MLP.APE = False -_C.MODEL.SWIN_MLP.PATCH_NORM = True - -# ----------------------------------------------------------------------------- -# Training settings -# ----------------------------------------------------------------------------- -_C.TRAIN = CN() -_C.TRAIN.START_EPOCH = 0 -_C.TRAIN.EPOCHS = 300 -_C.TRAIN.WARMUP_EPOCHS = 20 -_C.TRAIN.WEIGHT_DECAY = 0.05 -_C.TRAIN.BASE_LR = 5e-4 -_C.TRAIN.WARMUP_LR = 5e-7 -_C.TRAIN.MIN_LR = 5e-6 -# Clip gradient norm -_C.TRAIN.CLIP_GRAD = 5.0 -# Auto resume from latest checkpoint -_C.TRAIN.AUTO_RESUME = True -# Gradient accumulation steps -# could be overwritten by command line argument -_C.TRAIN.ACCUMULATION_STEPS = 1 -# Whether to use gradient checkpointing to save memory -# could be overwritten by command line argument -_C.TRAIN.USE_CHECKPOINT = False - -# LR scheduler -_C.TRAIN.LR_SCHEDULER = CN() -_C.TRAIN.LR_SCHEDULER.NAME = 'cosine' -# Epoch interval to decay LR, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_EPOCHS = 30 -# LR decay rate, used in StepLRScheduler -_C.TRAIN.LR_SCHEDULER.DECAY_RATE = 0.1 - -# Optimizer -_C.TRAIN.OPTIMIZER = CN() -_C.TRAIN.OPTIMIZER.NAME = 'adamw' -# Optimizer Epsilon -_C.TRAIN.OPTIMIZER.EPS = 1e-8 -# Optimizer Betas -_C.TRAIN.OPTIMIZER.BETAS = (0.9, 0.999) -# SGD momentum -_C.TRAIN.OPTIMIZER.MOMENTUM = 0.9 - -# MoE -_C.TRAIN.MOE = CN() -# Only save model on master device -_C.TRAIN.MOE.SAVE_MASTER = False -# ----------------------------------------------------------------------------- -# Augmentation settings -# ----------------------------------------------------------------------------- -_C.AUG = CN() -# Color jitter factor -_C.AUG.COLOR_JITTER = 0.4 -# Use AutoAugment policy. "v0" or "original" -_C.AUG.AUTO_AUGMENT = 'rand-m9-mstd0.5-inc1' -# Random erase prob -_C.AUG.REPROB = 0.25 -# Random erase mode -_C.AUG.REMODE = 'pixel' -# Random erase count -_C.AUG.RECOUNT = 1 -# Mixup alpha, mixup enabled if > 0 -_C.AUG.MIXUP = 0.8 -# Cutmix alpha, cutmix enabled if > 0 -_C.AUG.CUTMIX = 1.0 -# Cutmix min/max ratio, overrides alpha and enables cutmix if set -_C.AUG.CUTMIX_MINMAX = None -# Probability of performing mixup or cutmix when either/both is enabled -_C.AUG.MIXUP_PROB = 1.0 -# Probability of switching to cutmix when both mixup and cutmix enabled -_C.AUG.MIXUP_SWITCH_PROB = 0.5 -# How to apply mixup/cutmix params. Per "batch", "pair", or "elem" -_C.AUG.MIXUP_MODE = 'batch' - -# ----------------------------------------------------------------------------- -# Testing settings -# ----------------------------------------------------------------------------- -_C.TEST = CN() -# Whether to use center crop when testing -_C.TEST.CROP = True -# Whether to use SequentialSampler as validation sampler -_C.TEST.SEQUENTIAL = False -_C.TEST.SHUFFLE = False - -# ----------------------------------------------------------------------------- -# Misc -# ----------------------------------------------------------------------------- -# Enable Pytorch automatic mixed precision (amp). -# _C.AMP_ENABLE = True -_C.AMP_ENABLE = False -# [Deprecated] Mixed precision opt level of apex, if O0, no apex amp is used ('O0', 'O1', 'O2') -_C.AMP_OPT_LEVEL = '' -# Path to output folder, overwritten by command line argument -_C.OUTPUT = '' -# Tag of experiment, overwritten by command line argument -_C.TAG = 'default' -# Frequency to save checkpoint -_C.SAVE_FREQ = 1 -# Frequency to logging info -_C.PRINT_FREQ = 10 -# Fixed random seed -_C.SEED = 0 -# Perform evaluation only, overwritten by command line argument -_C.EVAL_MODE = False -# Test throughput only, overwritten by command line argument -_C.THROUGHPUT_MODE = False -# local rank for DistributedDataParallel, given by command line argument -_C.LOCAL_RANK = 0 -# for acceleration -_C.FUSED_WINDOW_PROCESS = False - - -def _update_config_from_file(config, cfg_file): - config.defrost() - with open(cfg_file, 'r') as f: - yaml_cfg = yaml.load(f, Loader=yaml.FullLoader) - - for cfg in yaml_cfg.setdefault('BASE', ['']): - if cfg: - _update_config_from_file( - config, os.path.join(os.path.dirname(cfg_file), cfg) - ) - print('=> merge config from {}'.format(cfg_file)) - config.merge_from_file(cfg_file) - config.freeze() - - -def update_config(config, args): - _update_config_from_file(config, args.cfg) - - config.defrost() - if args.opts: - config.merge_from_list(args.opts) - - # merge from specific arguments - if args.batch_size: - config.DATA.BATCH_SIZE = args.batch_size - if args.data_path: - config.DATA.DATA_PATH = args.data_path - if args.zip: - config.DATA.ZIP_MODE = True - if args.cache_mode: - config.DATA.CACHE_MODE = args.cache_mode - if args.pretrained: - config.MODEL.PRETRAINED = args.pretrained - if args.resume: - config.MODEL.RESUME = args.resume - if args.accumulation_steps: - config.TRAIN.ACCUMULATION_STEPS = args.accumulation_steps - if args.use_checkpoint: - config.TRAIN.USE_CHECKPOINT = True - if args.amp_opt_level: - print("[warning] Apex amp has been deprecated, please use pytorch amp instead!") - if args.amp_opt_level == 'O0': - config.AMP_ENABLE = False - if args.disable_amp: - config.AMP_ENABLE = False - if args.output: - config.OUTPUT = args.output - if args.tag: - config.TAG = args.tag - if args.eval: - config.EVAL_MODE = True - if args.throughput: - config.THROUGHPUT_MODE = True - - # for acceleration - if args.fused_window_process: - config.FUSED_WINDOW_PROCESS = True - - # set local rank for distributed training - config.LOCAL_RANK = args.local_rank - - # output folder - config.OUTPUT = os.path.join(config.OUTPUT, config.MODEL.NAME, config.TAG) - - config.freeze() - - -def get_config(args): - """Get a yacs CfgNode object with default values.""" - # Return a clone so that the defaults will not be altered - # This is for the "local variable" use pattern - config = _C.clone() - update_config(config, args) - - return config diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_22kto1k_finetune.yaml deleted file mode 100644 index 1c7be5a23..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_22kto1k_finetune.yaml +++ /dev/null @@ -1,20 +0,0 @@ -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swin - NAME: swin_base_patch4_window12_384_22kto1k_finetune - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_finetune.yaml deleted file mode 100644 index 107293b35..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window12_384_finetune.yaml +++ /dev/null @@ -1,20 +0,0 @@ -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swin - NAME: swin_base_patch4_window12_384_finetune - DROP_PATH_RATE: 0.5 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224.yaml deleted file mode 100644 index b29612858..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_base_patch4_window7_224 - DROP_PATH_RATE: 0.5 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22k.yaml deleted file mode 100644 index 143fdfc4b..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22k.yaml +++ /dev/null @@ -1,18 +0,0 @@ -DATA: - DATASET: imagenet22K -MODEL: - TYPE: swin - NAME: swin_base_patch4_window7_224_22k - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.05 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml deleted file mode 100644 index 1f8c1008c..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml +++ /dev/null @@ -1,16 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_base_patch4_window7_224_22kto1k_finetune - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window12_384_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window12_384_22kto1k_finetune.yaml deleted file mode 100644 index 6ee52f622..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window12_384_22kto1k_finetune.yaml +++ /dev/null @@ -1,20 +0,0 @@ -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swin - NAME: swin_large_patch4_window12_384_22kto1k_finetune - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 12 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22k.yaml deleted file mode 100644 index c3e233f21..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22k.yaml +++ /dev/null @@ -1,18 +0,0 @@ -DATA: - DATASET: imagenet22K -MODEL: - TYPE: swin - NAME: swin_large_patch4_window7_224_22k - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.05 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22kto1k_finetune.yaml deleted file mode 100644 index 0183826eb..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_large_patch4_window7_224_22kto1k_finetune.yaml +++ /dev/null @@ -1,16 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_large_patch4_window7_224_22kto1k_finetune - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224.yaml deleted file mode 100644 index 8f5c40fda..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_small_patch4_window7_224 - DROP_PATH_RATE: 0.3 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22k.yaml deleted file mode 100644 index 505fd7bbf..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22k.yaml +++ /dev/null @@ -1,18 +0,0 @@ -DATA: - DATASET: imagenet22K -MODEL: - TYPE: swin - NAME: swin_small_patch4_window7_224_22k - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.05 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22kto1k_finetune.yaml deleted file mode 100644 index 17bdedb06..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_small_patch4_window7_224_22kto1k_finetune.yaml +++ /dev/null @@ -1,16 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_small_patch4_window7_224_22kto1k_finetune - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_c24_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_c24_patch4_window8_256.yaml deleted file mode 100644 index 2c2e9f9dd..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_c24_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swin - NAME: swin_tiny_c24_patch4_window8_256 - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224.yaml deleted file mode 100644 index 851c7451f..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_tiny_patch4_window7_224 - DROP_PATH_RATE: 0.2 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22k.yaml deleted file mode 100644 index 8cabab5a9..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22k.yaml +++ /dev/null @@ -1,18 +0,0 @@ -DATA: - DATASET: imagenet22K -MODEL: - TYPE: swin - NAME: swin_tiny_patch4_window7_224_22k - DROP_PATH_RATE: 0.1 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.05 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22kto1k_finetune.yaml b/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22kto1k_finetune.yaml deleted file mode 100644 index 8082d4dd8..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swin/swin_tiny_patch4_window7_224_22kto1k_finetune.yaml +++ /dev/null @@ -1,16 +0,0 @@ -MODEL: - TYPE: swin - NAME: swin_tiny_patch4_window7_224_22kto1k_finetune - DROP_PATH_RATE: 0.1 - SWIN: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 7 -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_base_patch4_window7_224.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_base_patch4_window7_224.yaml deleted file mode 100644 index 01c48c953..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_base_patch4_window7_224.yaml +++ /dev/null @@ -1,9 +0,0 @@ -MODEL: - TYPE: swin_mlp - NAME: swin_mlp_base_patch4_window7_224 - DROP_PATH_RATE: 0.5 - SWIN_MLP: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 7 diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c12_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c12_patch4_window8_256.yaml deleted file mode 100644 index d6c4576d4..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c12_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swin_mlp - NAME: swin_mlp_tiny_c12_patch4_window8_256 - DROP_PATH_RATE: 0.2 - SWIN_MLP: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 8, 16, 32, 64 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c24_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c24_patch4_window8_256.yaml deleted file mode 100644 index 15552a0d2..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c24_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swin_mlp - NAME: swin_mlp_tiny_c24_patch4_window8_256 - DROP_PATH_RATE: 0.2 - SWIN_MLP: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c6_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c6_patch4_window8_256.yaml deleted file mode 100644 index 533bd8f6a..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmlp/swin_mlp_tiny_c6_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swin_mlp - NAME: swin_mlp_tiny_c6_patch4_window8_256 - DROP_PATH_RATE: 0.2 - SWIN_MLP: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 16, 32, 64, 128 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_16expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_16expert_32gpu_22k.yaml deleted file mode 100644 index 29c40a6cd..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_16expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_base_patch4_window12_192_16expert_32gpu_22k - DROP_PATH_RATE: 0.3 - SWIN_MOE: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: -2 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_32expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_32expert_32gpu_22k.yaml deleted file mode 100644 index 79db3fbf5..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_32expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_base_patch4_window12_192_32expert_32gpu_22k - DROP_PATH_RATE: 0.3 - SWIN_MOE: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: 1 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_8expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_8expert_32gpu_22k.yaml deleted file mode 100644 index 4de518090..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_8expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_base_patch4_window12_192_8expert_32gpu_22k - DROP_PATH_RATE: 0.3 - SWIN_MOE: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: -4 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml deleted file mode 100644 index 8aa7fbb1b..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml +++ /dev/null @@ -1,32 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_base_patch4_window12_192_cosine_router_32expert_32gpu_22k - DROP_PATH_RATE: 0.3 - SWIN_MOE: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: 1 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - COSINE_ROUTER: True - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_densebaseline_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_densebaseline_22k.yaml deleted file mode 100644 index 83a419cfa..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_base_patch4_window12_192_densebaseline_22k.yaml +++ /dev/null @@ -1,26 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_base_patch4_window12_192_densebaseline_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ -1 ], [ -1 ] ] -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 - MOE: - SAVE_MASTER: True -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.yaml deleted file mode 100644 index 4e3a3ece2..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_16expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_16expert_32gpu_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: -2 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml deleted file mode 100644 index a987d9ed3..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_32expert_32gpu_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: 1 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_64expert_64gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_64expert_64gpu_22k.yaml deleted file mode 100644 index 7d941479b..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_64expert_64gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_64expert_64gpu_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: 1 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.yaml deleted file mode 100644 index bfc034d2c..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_8expert_32gpu_22k.yaml +++ /dev/null @@ -1,31 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_8expert_32gpu_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: -4 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml deleted file mode 100644 index 3b6b0022a..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k.yaml +++ /dev/null @@ -1,32 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_cosine_router_32expert_32gpu_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - INIT_STD: 0.005 - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ 1, 3, 5, 7, 9, 11, 13, 15, 17 ], [ 1 ] ] - NUM_LOCAL_EXPERTS: 1 - TOP_VALUE: 1 - CAPACITY_FACTOR: 1.25 - COSINE_ROUTER: True - IS_GSHARD_LOSS: False - MOE_DROP: 0.1 - AUX_LOSS_WEIGHT: 0.01 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_densebaseline_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_densebaseline_22k.yaml deleted file mode 100644 index 3d9ec3097..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinmoe/swin_moe_small_patch4_window12_192_densebaseline_22k.yaml +++ /dev/null @@ -1,26 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swin_moe - NAME: swin_moe_small_patch4_window12_192_densebaseline_22k - DROP_PATH_RATE: 0.2 - SWIN_MOE: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 12 - MLP_FC2_BIAS: False - MOE_BLOCKS: [ [ -1 ], [ -1 ], [ -1 ], [ -1 ] ] -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 10 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 - CLIP_GRAD: 3.0 - MOE: - SAVE_MASTER: True -TEST: - SHUFFLE: True \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml deleted file mode 100644 index d53c1e1fc..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12_192_22k.yaml +++ /dev/null @@ -1,19 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window12_192_22k - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 12 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.yaml deleted file mode 100644 index a47259dbc..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to16_192to256_22kto1k_ft.yaml +++ /dev/null @@ -1,19 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window12to16_192to256_22kto1k_ft - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 16 - PRETRAINED_WINDOW_SIZES: [ 12, 12, 12, 6 ] -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.yaml deleted file mode 100644 index 53faba081..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window12to24_192to384_22kto1k_ft.yaml +++ /dev/null @@ -1,21 +0,0 @@ -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window12to24_192to384_22kto1k_ft - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 24 - PRETRAINED_WINDOW_SIZES: [ 12, 12, 12, 6 ] -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window16_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window16_256.yaml deleted file mode 100644 index 4dee37632..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window16_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window16_256 - DROP_PATH_RATE: 0.5 - SWINV2: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 16 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window8_256.yaml deleted file mode 100644 index 0399484ea..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_base_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window8_256 - DROP_PATH_RATE: 0.5 - SWINV2: - EMBED_DIM: 128 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 4, 8, 16, 32 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml deleted file mode 100644 index 19ea0f119..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12_192_22k.yaml +++ /dev/null @@ -1,19 +0,0 @@ -DATA: - DATASET: imagenet22K - IMG_SIZE: 192 -MODEL: - TYPE: swinv2 - NAME: swinv2_large_patch4_window12_192_22k - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 12 -TRAIN: - EPOCHS: 90 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 0.1 - BASE_LR: 1.25e-4 # 4096 batch-size - WARMUP_LR: 1.25e-7 - MIN_LR: 1.25e-6 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.yaml deleted file mode 100644 index dbdfdcdfc..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to16_192to256_22kto1k_ft.yaml +++ /dev/null @@ -1,19 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_base_patch4_window12to16_192to256_22kto1k_ft - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 16 - PRETRAINED_WINDOW_SIZES: [ 12, 12, 12, 6 ] -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.yaml deleted file mode 100644 index 7bd17d574..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_large_patch4_window12to24_192to384_22kto1k_ft.yaml +++ /dev/null @@ -1,21 +0,0 @@ -DATA: - IMG_SIZE: 384 -MODEL: - TYPE: swinv2 - NAME: swinv2_large_patch4_window12to24_192to384_22kto1k_ft - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 192 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 6, 12, 24, 48 ] - WINDOW_SIZE: 24 - PRETRAINED_WINDOW_SIZES: [ 12, 12, 12, 6 ] -TRAIN: - EPOCHS: 30 - WARMUP_EPOCHS: 5 - WEIGHT_DECAY: 1e-8 - BASE_LR: 2e-05 - WARMUP_LR: 2e-08 - MIN_LR: 2e-07 -TEST: - CROP: False \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window16_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window16_256.yaml deleted file mode 100644 index 8d99caf3a..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window16_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_small_patch4_window16_256 - DROP_PATH_RATE: 0.3 - SWINV2: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 16 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window8_256.yaml deleted file mode 100644 index efa92a6aa..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_small_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_small_patch4_window8_256 - DROP_PATH_RATE: 0.3 - SWINV2: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 18, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window16_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window16_256.yaml deleted file mode 100644 index 0de06c7cb..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window16_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_tiny_patch4_window16_256 - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 16 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window8_256.yaml b/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window8_256.yaml deleted file mode 100644 index be622daa3..000000000 --- a/cv/classification/swin_transformer/pytorch/configs/swinv2/swinv2_tiny_patch4_window8_256.yaml +++ /dev/null @@ -1,11 +0,0 @@ -DATA: - IMG_SIZE: 256 -MODEL: - TYPE: swinv2 - NAME: swinv2_tiny_patch4_window8_256 - DROP_PATH_RATE: 0.2 - SWINV2: - EMBED_DIM: 96 - DEPTHS: [ 2, 2, 6, 2 ] - NUM_HEADS: [ 3, 6, 12, 24 ] - WINDOW_SIZE: 8 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/data/__init__.py b/cv/classification/swin_transformer/pytorch/data/__init__.py deleted file mode 100644 index 90b75c27b..000000000 --- a/cv/classification/swin_transformer/pytorch/data/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -from .build import build_loader diff --git a/cv/classification/swin_transformer/pytorch/data/build.py b/cv/classification/swin_transformer/pytorch/data/build.py deleted file mode 100644 index 5799f2537..000000000 --- a/cv/classification/swin_transformer/pytorch/data/build.py +++ /dev/null @@ -1,162 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import torch -import numpy as np -import torch.distributed as dist -from torchvision import datasets, transforms -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data import Mixup -from timm.data import create_transform - -from .cached_image_folder import CachedImageFolder -from .imagenet22k_dataset import IN22KDATASET -from .samplers import SubsetRandomSampler - -try: - from torchvision.transforms import InterpolationMode - - - def _pil_interp(method): - if method == 'bicubic': - return InterpolationMode.BICUBIC - elif method == 'lanczos': - return InterpolationMode.LANCZOS - elif method == 'hamming': - return InterpolationMode.HAMMING - else: - # default bilinear, do we want to allow nearest? - return InterpolationMode.BILINEAR - - - import timm.data.transforms as timm_transforms - - timm_transforms._pil_interp = _pil_interp -except: - from timm.data.transforms import _pil_interp - - -def build_loader(config): - config.defrost() - dataset_train, config.MODEL.NUM_CLASSES = build_dataset(is_train=True, config=config) - config.freeze() - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build train dataset") - dataset_val, _ = build_dataset(is_train=False, config=config) - print(f"local rank {config.LOCAL_RANK} / global rank {dist.get_rank()} successfully build val dataset") - - num_tasks = dist.get_world_size() - global_rank = dist.get_rank() - if config.DATA.ZIP_MODE and config.DATA.CACHE_MODE == 'part': - indices = np.arange(dist.get_rank(), len(dataset_train), dist.get_world_size()) - sampler_train = SubsetRandomSampler(indices) - else: - sampler_train = torch.utils.data.DistributedSampler( - dataset_train, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - - if config.TEST.SEQUENTIAL: - sampler_val = torch.utils.data.SequentialSampler(dataset_val) - else: - sampler_val = torch.utils.data.distributed.DistributedSampler( - dataset_val, shuffle=config.TEST.SHUFFLE - ) - - data_loader_train = torch.utils.data.DataLoader( - dataset_train, sampler=sampler_train, - batch_size=config.DATA.BATCH_SIZE, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=True, - ) - - data_loader_val = torch.utils.data.DataLoader( - dataset_val, sampler=sampler_val, - batch_size=config.DATA.BATCH_SIZE, - shuffle=False, - num_workers=config.DATA.NUM_WORKERS, - pin_memory=config.DATA.PIN_MEMORY, - drop_last=False - ) - - # setup mixup / cutmix - mixup_fn = None - mixup_active = config.AUG.MIXUP > 0 or config.AUG.CUTMIX > 0. or config.AUG.CUTMIX_MINMAX is not None - if mixup_active: - mixup_fn = Mixup( - mixup_alpha=config.AUG.MIXUP, cutmix_alpha=config.AUG.CUTMIX, cutmix_minmax=config.AUG.CUTMIX_MINMAX, - prob=config.AUG.MIXUP_PROB, switch_prob=config.AUG.MIXUP_SWITCH_PROB, mode=config.AUG.MIXUP_MODE, - label_smoothing=config.MODEL.LABEL_SMOOTHING, num_classes=config.MODEL.NUM_CLASSES) - - return dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn - - -def build_dataset(is_train, config): - transform = build_transform(is_train, config) - if config.DATA.DATASET == 'imagenet': - prefix = 'train' if is_train else 'val' - if config.DATA.ZIP_MODE: - ann_file = prefix + "_map.txt" - prefix = prefix + ".zip@/" - dataset = CachedImageFolder(config.DATA.DATA_PATH, ann_file, prefix, transform, - cache_mode=config.DATA.CACHE_MODE if is_train else 'part') - else: - root = os.path.join(config.DATA.DATA_PATH, prefix) - dataset = datasets.ImageFolder(root, transform=transform) - nb_classes = 1000 - elif config.DATA.DATASET == 'imagenet22K': - prefix = 'ILSVRC2011fall_whole' - if is_train: - ann_file = prefix + "_map_train.txt" - else: - ann_file = prefix + "_map_val.txt" - dataset = IN22KDATASET(config.DATA.DATA_PATH, ann_file, transform) - nb_classes = 21841 - else: - raise NotImplementedError("We only support ImageNet Now.") - - return dataset, nb_classes - - -def build_transform(is_train, config): - resize_im = config.DATA.IMG_SIZE > 32 - if is_train: - # this should always dispatch to transforms_imagenet_train - transform = create_transform( - input_size=config.DATA.IMG_SIZE, - is_training=True, - color_jitter=config.AUG.COLOR_JITTER if config.AUG.COLOR_JITTER > 0 else None, - auto_augment=config.AUG.AUTO_AUGMENT if config.AUG.AUTO_AUGMENT != 'none' else None, - re_prob=config.AUG.REPROB, - re_mode=config.AUG.REMODE, - re_count=config.AUG.RECOUNT, - interpolation=config.DATA.INTERPOLATION, - ) - if not resize_im: - # replace RandomResizedCropAndInterpolation with - # RandomCrop - transform.transforms[0] = transforms.RandomCrop(config.DATA.IMG_SIZE, padding=4) - return transform - - t = [] - if resize_im: - if config.TEST.CROP: - size = int((256 / 224) * config.DATA.IMG_SIZE) - t.append( - transforms.Resize(size, interpolation=_pil_interp(config.DATA.INTERPOLATION)), - # to maintain same ratio w.r.t. 224 images - ) - t.append(transforms.CenterCrop(config.DATA.IMG_SIZE)) - else: - t.append( - transforms.Resize((config.DATA.IMG_SIZE, config.DATA.IMG_SIZE), - interpolation=_pil_interp(config.DATA.INTERPOLATION)) - ) - - t.append(transforms.ToTensor()) - t.append(transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD)) - return transforms.Compose(t) diff --git a/cv/classification/swin_transformer/pytorch/data/cached_image_folder.py b/cv/classification/swin_transformer/pytorch/data/cached_image_folder.py deleted file mode 100644 index 7e1883b17..000000000 --- a/cv/classification/swin_transformer/pytorch/data/cached_image_folder.py +++ /dev/null @@ -1,252 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import io -import os -import time -import torch.distributed as dist -import torch.utils.data as data -from PIL import Image - -from .zipreader import is_zip_path, ZipReader - - -def has_file_allowed_extension(filename, extensions): - """Checks if a file is an allowed extension. - Args: - filename (string): path to a file - Returns: - bool: True if the filename ends with a known image extension - """ - filename_lower = filename.lower() - return any(filename_lower.endswith(ext) for ext in extensions) - - -def find_classes(dir): - classes = [d for d in os.listdir(dir) if os.path.isdir(os.path.join(dir, d))] - classes.sort() - class_to_idx = {classes[i]: i for i in range(len(classes))} - return classes, class_to_idx - - -def make_dataset(dir, class_to_idx, extensions): - images = [] - dir = os.path.expanduser(dir) - for target in sorted(os.listdir(dir)): - d = os.path.join(dir, target) - if not os.path.isdir(d): - continue - - for root, _, fnames in sorted(os.walk(d)): - for fname in sorted(fnames): - if has_file_allowed_extension(fname, extensions): - path = os.path.join(root, fname) - item = (path, class_to_idx[target]) - images.append(item) - - return images - - -def make_dataset_with_ann(ann_file, img_prefix, extensions): - images = [] - with open(ann_file, "r") as f: - contents = f.readlines() - for line_str in contents: - path_contents = [c for c in line_str.split('\t')] - im_file_name = path_contents[0] - class_index = int(path_contents[1]) - - assert str.lower(os.path.splitext(im_file_name)[-1]) in extensions - item = (os.path.join(img_prefix, im_file_name), class_index) - - images.append(item) - - return images - - -class DatasetFolder(data.Dataset): - """A generic data loader where the samples are arranged in this way: :: - root/class_x/xxx.ext - root/class_x/xxy.ext - root/class_x/xxz.ext - root/class_y/123.ext - root/class_y/nsdf3.ext - root/class_y/asd932_.ext - Args: - root (string): Root directory path. - loader (callable): A function to load a sample given its path. - extensions (list[string]): A list of allowed extensions. - transform (callable, optional): A function/transform that takes in - a sample and returns a transformed version. - E.g, ``transforms.RandomCrop`` for images. - target_transform (callable, optional): A function/transform that takes - in the target and transforms it. - Attributes: - samples (list): List of (sample path, class_index) tuples - """ - - def __init__(self, root, loader, extensions, ann_file='', img_prefix='', transform=None, target_transform=None, - cache_mode="no"): - # image folder mode - if ann_file == '': - _, class_to_idx = find_classes(root) - samples = make_dataset(root, class_to_idx, extensions) - # zip mode - else: - samples = make_dataset_with_ann(os.path.join(root, ann_file), - os.path.join(root, img_prefix), - extensions) - - if len(samples) == 0: - raise (RuntimeError("Found 0 files in subfolders of: " + root + "\n" + - "Supported extensions are: " + ",".join(extensions))) - - self.root = root - self.loader = loader - self.extensions = extensions - - self.samples = samples - self.labels = [y_1k for _, y_1k in samples] - self.classes = list(set(self.labels)) - - self.transform = transform - self.target_transform = target_transform - - self.cache_mode = cache_mode - if self.cache_mode != "no": - self.init_cache() - - def init_cache(self): - assert self.cache_mode in ["part", "full"] - n_sample = len(self.samples) - global_rank = dist.get_rank() - world_size = dist.get_world_size() - - samples_bytes = [None for _ in range(n_sample)] - start_time = time.time() - for index in range(n_sample): - if index % (n_sample // 10) == 0: - t = time.time() - start_time - print(f'global_rank {dist.get_rank()} cached {index}/{n_sample} takes {t:.2f}s per block') - start_time = time.time() - path, target = self.samples[index] - if self.cache_mode == "full": - samples_bytes[index] = (ZipReader.read(path), target) - elif self.cache_mode == "part" and index % world_size == global_rank: - samples_bytes[index] = (ZipReader.read(path), target) - else: - samples_bytes[index] = (path, target) - self.samples = samples_bytes - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (sample, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - sample = self.loader(path) - if self.transform is not None: - sample = self.transform(sample) - if self.target_transform is not None: - target = self.target_transform(target) - - return sample, target - - def __len__(self): - return len(self.samples) - - def __repr__(self): - fmt_str = 'Dataset ' + self.__class__.__name__ + '\n' - fmt_str += ' Number of datapoints: {}\n'.format(self.__len__()) - fmt_str += ' Root Location: {}\n'.format(self.root) - tmp = ' Transforms (if any): ' - fmt_str += '{0}{1}\n'.format(tmp, self.transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - tmp = ' Target Transforms (if any): ' - fmt_str += '{0}{1}'.format(tmp, self.target_transform.__repr__().replace('\n', '\n' + ' ' * len(tmp))) - return fmt_str - - -IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif'] - - -def pil_loader(path): - # open path as file to avoid ResourceWarning (https://github.com/python-pillow/Pillow/issues/835) - if isinstance(path, bytes): - img = Image.open(io.BytesIO(path)) - elif is_zip_path(path): - data = ZipReader.read(path) - img = Image.open(io.BytesIO(data)) - else: - with open(path, 'rb') as f: - img = Image.open(f) - return img.convert('RGB') - return img.convert('RGB') - - -def accimage_loader(path): - import accimage - try: - return accimage.Image(path) - except IOError: - # Potentially a decoding problem, fall back to PIL.Image - return pil_loader(path) - - -def default_img_loader(path): - from torchvision import get_image_backend - if get_image_backend() == 'accimage': - return accimage_loader(path) - else: - return pil_loader(path) - - -class CachedImageFolder(DatasetFolder): - """A generic data loader where the images are arranged in this way: :: - root/dog/xxx.png - root/dog/xxy.png - root/dog/xxz.png - root/cat/123.png - root/cat/nsdf3.png - root/cat/asd932_.png - Args: - root (string): Root directory path. - transform (callable, optional): A function/transform that takes in an PIL image - and returns a transformed version. E.g, ``transforms.RandomCrop`` - target_transform (callable, optional): A function/transform that takes in the - target and transforms it. - loader (callable, optional): A function to load an image given its path. - Attributes: - imgs (list): List of (image path, class_index) tuples - """ - - def __init__(self, root, ann_file='', img_prefix='', transform=None, target_transform=None, - loader=default_img_loader, cache_mode="no"): - super(CachedImageFolder, self).__init__(root, loader, IMG_EXTENSIONS, - ann_file=ann_file, img_prefix=img_prefix, - transform=transform, target_transform=target_transform, - cache_mode=cache_mode) - self.imgs = self.samples - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (image, target) where target is class_index of the target class. - """ - path, target = self.samples[index] - image = self.loader(path) - if self.transform is not None: - img = self.transform(image) - else: - img = image - if self.target_transform is not None: - target = self.target_transform(target) - - return img, target diff --git a/cv/classification/swin_transformer/pytorch/data/imagenet22k_dataset.py b/cv/classification/swin_transformer/pytorch/data/imagenet22k_dataset.py deleted file mode 100644 index 5758060b4..000000000 --- a/cv/classification/swin_transformer/pytorch/data/imagenet22k_dataset.py +++ /dev/null @@ -1,55 +0,0 @@ -import os -import json -import torch.utils.data as data -import numpy as np -from PIL import Image - -import warnings - -warnings.filterwarnings("ignore", "(Possibly )?corrupt EXIF data", UserWarning) - - -class IN22KDATASET(data.Dataset): - def __init__(self, root, ann_file='', transform=None, target_transform=None): - super(IN22KDATASET, self).__init__() - - self.data_path = root - self.ann_path = os.path.join(self.data_path, ann_file) - self.transform = transform - self.target_transform = target_transform - # id & label: https://github.com/google-research/big_transfer/issues/7 - # total: 21843; only 21841 class have images: map 21841->9205; 21842->15027 - self.database = json.load(open(self.ann_path)) - - def _load_image(self, path): - try: - im = Image.open(path) - except: - print("ERROR IMG LOADED: ", path) - random_img = np.random.rand(224, 224, 3) * 255 - im = Image.fromarray(np.uint8(random_img)) - return im - - def __getitem__(self, index): - """ - Args: - index (int): Index - Returns: - tuple: (image, target) where target is class_index of the target class. - """ - idb = self.database[index] - - # images - images = self._load_image(self.data_path + '/' + idb[0]).convert('RGB') - if self.transform is not None: - images = self.transform(images) - - # target - target = int(idb[1]) - if self.target_transform is not None: - target = self.target_transform(target) - - return images, target - - def __len__(self): - return len(self.database) diff --git a/cv/classification/swin_transformer/pytorch/data/map22kto1k.txt b/cv/classification/swin_transformer/pytorch/data/map22kto1k.txt deleted file mode 100644 index e3a998fbc..000000000 --- a/cv/classification/swin_transformer/pytorch/data/map22kto1k.txt +++ /dev/null @@ -1,1000 +0,0 @@ -359 -368 -460 -475 -486 -492 -496 -514 -516 -525 -547 -548 -556 -563 -575 -641 -648 -723 -733 -765 -801 -826 -852 -858 -878 -896 -900 -905 -908 -910 -935 -946 -947 -994 -999 -1003 -1005 -1010 -1027 -1029 -1048 -1055 -1064 -1065 -1069 -1075 -1079 -1081 -1085 -1088 -1093 -1106 -1143 -1144 -1145 -1147 -1168 -1171 -1178 -1187 -1190 -1197 -1205 -1216 -1223 -1230 -1236 -1241 -1245 -1257 -1259 -1260 -1267 -1268 -1269 -1271 -1272 -1273 -1277 -1303 -1344 -1349 -1355 -1357 -1384 -1388 -1391 -1427 -1429 -1432 -1437 -1450 -1461 -1462 -1474 -1502 -1503 -1512 -1552 -1555 -1577 -1584 -1587 -1589 -1599 -1615 -1616 -1681 -1692 -1701 -1716 -1729 -1757 -1759 -1764 -1777 -1786 -1822 -1841 -1842 -1848 -1850 -1856 -1860 -1861 -1864 -1876 -1897 -1898 -1910 -1913 -1918 -1922 -1928 -1932 -1935 -1947 -1951 -1953 -1970 -1977 -1979 -2001 -2017 -2067 -2081 -2087 -2112 -2128 -2135 -2147 -2174 -2175 -2176 -2177 -2178 -2181 -2183 -2184 -2187 -2189 -2190 -2191 -2192 -2193 -2197 -2202 -2203 -2206 -2208 -2209 -2211 -2212 -2213 -2214 -2215 -2216 -2217 -2219 -2222 -2223 -2224 -2225 -2226 -2227 -2228 -2229 -2230 -2236 -2238 -2240 -2241 -2242 -2243 -2244 -2245 -2247 -2248 -2249 -2250 -2251 -2252 -2255 -2256 -2257 -2262 -2263 -2264 -2265 -2266 -2268 -2270 -2271 -2272 -2273 -2275 -2276 -2279 -2280 -2281 -2282 -2285 -2289 -2292 -2295 -2296 -2297 -2298 -2299 -2300 -2301 -2302 -2303 -2304 -2305 -2306 -2309 -2310 -2312 -2313 -2314 -2315 -2316 -2318 -2319 -2321 -2322 -2326 -2329 -2330 -2331 -2332 -2334 -2335 -2336 -2337 -2338 -2339 -2341 -2342 -2343 -2344 -2346 -2348 -2349 -2351 -2352 -2353 -2355 -2357 -2358 -2359 -2360 -2364 -2365 -2368 -2369 -2377 -2382 -2383 -2385 -2397 -2398 -2400 -2402 -2405 -2412 -2421 -2428 -2431 -2432 -2433 -2436 -2441 -2445 -2450 -2453 -2454 -2465 -2469 -2532 -2533 -2538 -2544 -2547 -2557 -2565 -2578 -2612 -2658 -2702 -2722 -2731 -2738 -2741 -2747 -2810 -2818 -2833 -2844 -2845 -2867 -2874 -2882 -2884 -2888 -2889 -3008 -3012 -3019 -3029 -3033 -3042 -3091 -3106 -3138 -3159 -3164 -3169 -3280 -3296 -3311 -3318 -3320 -3324 -3330 -3366 -3375 -3381 -3406 -3419 -3432 -3434 -3435 -3493 -3495 -3503 -3509 -3511 -3513 -3517 -3521 -3526 -3546 -3554 -3600 -3601 -3606 -3612 -3613 -3616 -3622 -3623 -3627 -3632 -3634 -3636 -3638 -3644 -3646 -3649 -3650 -3651 -3656 -3663 -3673 -3674 -3689 -3690 -3702 -3733 -3769 -3971 -3974 -4065 -4068 -4073 -4102 -4136 -4140 -4151 -4159 -4165 -4207 -4219 -4226 -4249 -4256 -4263 -4270 -4313 -4321 -4378 -4386 -4478 -4508 -4512 -4536 -4542 -4550 -4560 -4562 -4570 -4571 -4572 -4583 -4588 -4594 -4604 -4608 -4623 -4634 -4636 -4646 -4651 -4652 -4686 -4688 -4691 -4699 -4724 -4727 -4737 -4770 -4774 -4789 -4802 -4807 -4819 -4880 -4886 -4908 -4927 -4931 -4936 -4964 -4976 -4993 -5028 -5033 -5043 -5046 -5096 -5111 -5114 -5131 -5132 -5183 -5199 -5235 -5275 -5291 -5293 -5294 -5343 -5360 -5362 -5364 -5390 -5402 -5418 -5428 -5430 -5437 -5443 -5473 -5484 -5486 -5505 -5507 -5508 -5510 -5567 -5578 -5580 -5584 -5606 -5613 -5629 -5672 -5676 -5692 -5701 -5760 -5769 -5770 -5779 -5814 -5850 -5871 -5893 -5911 -5949 -5954 -6005 -6006 -6012 -6017 -6023 -6024 -6040 -6050 -6054 -6087 -6105 -6157 -6235 -6237 -6256 -6259 -6286 -6291 -6306 -6339 -6341 -6343 -6379 -6383 -6393 -6405 -6479 -6511 -6517 -6541 -6561 -6608 -6611 -6615 -6678 -6682 -6707 -6752 -6798 -6850 -6880 -6885 -6890 -6920 -6981 -7000 -7009 -7038 -7049 -7050 -7052 -7073 -7078 -7098 -7111 -7165 -7198 -7204 -7280 -7283 -7286 -7287 -7293 -7294 -7305 -7318 -7341 -7346 -7354 -7382 -7427 -7428 -7435 -7445 -7450 -7455 -7467 -7469 -7497 -7502 -7506 -7514 -7523 -7651 -7661 -7664 -7672 -7679 -7685 -7696 -7730 -7871 -7873 -7895 -7914 -7915 -7920 -7934 -7935 -7949 -8009 -8036 -8051 -8065 -8074 -8090 -8112 -8140 -8164 -8168 -8178 -8182 -8198 -8212 -8216 -8230 -8242 -8288 -8289 -8295 -8318 -8352 -8368 -8371 -8375 -8376 -8401 -8416 -8419 -8436 -8460 -8477 -8478 -8482 -8498 -8500 -8539 -8543 -8552 -8555 -8580 -8584 -8586 -8594 -8598 -8601 -8606 -8610 -8611 -8622 -8627 -8639 -8649 -8650 -8653 -8654 -8667 -8672 -8673 -8674 -8676 -8684 -8720 -8723 -8750 -8753 -8801 -8815 -8831 -8835 -8842 -8845 -8858 -8897 -8916 -8951 -8954 -8959 -8970 -8976 -8981 -8983 -8989 -8991 -8993 -9019 -9039 -9042 -9043 -9056 -9057 -9070 -9087 -9098 -9106 -9130 -9131 -9155 -9171 -9183 -9198 -9199 -9201 -9204 -9212 -9221 -9225 -9229 -9250 -9260 -9271 -9279 -9295 -9300 -9310 -9322 -9345 -9352 -9376 -9377 -9382 -9392 -9401 -9405 -9441 -9449 -9464 -9475 -9502 -9505 -9514 -9515 -9545 -9567 -9576 -9608 -9609 -9624 -9633 -9639 -9643 -9656 -9674 -9740 -9752 -9760 -9767 -9778 -9802 -9820 -9839 -9879 -9924 -9956 -9961 -9963 -9970 -9997 -10010 -10031 -10040 -10052 -10073 -10075 -10078 -10094 -10097 -10109 -10118 -10121 -10124 -10158 -10226 -10276 -10304 -10307 -10314 -10315 -10332 -10337 -10338 -10413 -10423 -10451 -10463 -10465 -10487 -10519 -10522 -10523 -10532 -10534 -10535 -10551 -10559 -10574 -10583 -10586 -10589 -10612 -10626 -10635 -10638 -10677 -10683 -10726 -10776 -10782 -10783 -10807 -10837 -10840 -10848 -10859 -10871 -10881 -10884 -10908 -10914 -10921 -10936 -10947 -10951 -10952 -10957 -10999 -11003 -11018 -11023 -11025 -11027 -11045 -11055 -11095 -11110 -11137 -5564 -11168 -11186 -11221 -11223 -11242 -11255 -11259 -11279 -11306 -11311 -11331 -11367 -11377 -11389 -11392 -11401 -11407 -11437 -11449 -11466 -11469 -11473 -11478 -11483 -11484 -11507 -11536 -11558 -11566 -11575 -11584 -11594 -11611 -11612 -11619 -11621 -11640 -11643 -11664 -11674 -11689 -11709 -11710 -11716 -11721 -11726 -11729 -11743 -11760 -11771 -11837 -11839 -11856 -11876 -11878 -11884 -11889 -11896 -11917 -11923 -11930 -11944 -11952 -11980 -11984 -12214 -12229 -12239 -12241 -12242 -12247 -12283 -12349 -12369 -12373 -12422 -12560 -12566 -12575 -12688 -12755 -12768 -12778 -12780 -12812 -12832 -12835 -12836 -12843 -12847 -12849 -12850 -12856 -12858 -12873 -12938 -12971 -13017 -13038 -13046 -13059 -13085 -13086 -13088 -13094 -13134 -13182 -13230 -13406 -13444 -13614 -13690 -13698 -13709 -13749 -13804 -13982 -14051 -14059 -14219 -14246 -14256 -14264 -14294 -14324 -14367 -14389 -14394 -14438 -14442 -14965 -15732 -16744 -18037 -18205 -18535 -18792 -19102 -20019 -20462 -21026 -21045 -21163 -21171 -21181 -21196 -21200 -21369 -21817 \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/data/samplers.py b/cv/classification/swin_transformer/pytorch/data/samplers.py deleted file mode 100644 index 596e22099..000000000 --- a/cv/classification/swin_transformer/pytorch/data/samplers.py +++ /dev/null @@ -1,29 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch - - -class SubsetRandomSampler(torch.utils.data.Sampler): - r"""Samples elements randomly from a given list of indices, without replacement. - - Arguments: - indices (sequence): a sequence of indices - """ - - def __init__(self, indices): - self.epoch = 0 - self.indices = indices - - def __iter__(self): - return (self.indices[i] for i in torch.randperm(len(self.indices))) - - def __len__(self): - return len(self.indices) - - def set_epoch(self, epoch): - self.epoch = epoch diff --git a/cv/classification/swin_transformer/pytorch/data/zipreader.py b/cv/classification/swin_transformer/pytorch/data/zipreader.py deleted file mode 100644 index 060bc46a7..000000000 --- a/cv/classification/swin_transformer/pytorch/data/zipreader.py +++ /dev/null @@ -1,103 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import zipfile -import io -import numpy as np -from PIL import Image -from PIL import ImageFile - -ImageFile.LOAD_TRUNCATED_IMAGES = True - - -def is_zip_path(img_or_path): - """judge if this is a zip path""" - return '.zip@' in img_or_path - - -class ZipReader(object): - """A class to read zipped files""" - zip_bank = dict() - - def __init__(self): - super(ZipReader, self).__init__() - - @staticmethod - def get_zipfile(path): - zip_bank = ZipReader.zip_bank - if path not in zip_bank: - zfile = zipfile.ZipFile(path, 'r') - zip_bank[path] = zfile - return zip_bank[path] - - @staticmethod - def split_zip_style_path(path): - pos_at = path.index('@') - assert pos_at != -1, "character '@' is not found from the given path '%s'" % path - - zip_path = path[0: pos_at] - folder_path = path[pos_at + 1:] - folder_path = str.strip(folder_path, '/') - return zip_path, folder_path - - @staticmethod - def list_folder(path): - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - folder_list = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - len(os.path.splitext(file_foler_name)[-1]) == 0 and \ - file_foler_name != folder_path: - if len(folder_path) == 0: - folder_list.append(file_foler_name) - else: - folder_list.append(file_foler_name[len(folder_path) + 1:]) - - return folder_list - - @staticmethod - def list_files(path, extension=None): - if extension is None: - extension = ['.*'] - zip_path, folder_path = ZipReader.split_zip_style_path(path) - - zfile = ZipReader.get_zipfile(zip_path) - file_lists = [] - for file_foler_name in zfile.namelist(): - file_foler_name = str.strip(file_foler_name, '/') - if file_foler_name.startswith(folder_path) and \ - str.lower(os.path.splitext(file_foler_name)[-1]) in extension: - if len(folder_path) == 0: - file_lists.append(file_foler_name) - else: - file_lists.append(file_foler_name[len(folder_path) + 1:]) - - return file_lists - - @staticmethod - def read(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - return data - - @staticmethod - def imread(path): - zip_path, path_img = ZipReader.split_zip_style_path(path) - zfile = ZipReader.get_zipfile(zip_path) - data = zfile.read(path_img) - try: - im = Image.open(io.BytesIO(data)) - except: - print("ERROR IMG LOADED: ", path_img) - random_img = np.random.rand(224, 224, 3) * 255 - im = Image.fromarray(np.uint8(random_img)) - return im diff --git a/cv/classification/swin_transformer/pytorch/figures/teaser.png b/cv/classification/swin_transformer/pytorch/figures/teaser.png deleted file mode 100644 index bcd2f74ba2ab964f1c0752b330519a60bad8e2bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 930622 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 vPh^MBxQ?mi+!>68MAsR)Ot1r+8PQ( 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

    eZ_yG{pDuNS$X2#N6CcssBsF6lmyEhi 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 z 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

    pu(eQz8pd4n+&`KYkYC$-?Hs$-*G_Z`b{wzuka> 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

    AELxxK`&w0JB&08_yZBs@z)f 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

    ;oT#}JKV}p^Yx@itp+>F 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�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 z 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

    NnPnz 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 z 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

    SA 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.05` by -nvidia: https://catalog.ngc.nvidia.com/orgs/nvidia/containers/pytorch. - -- Clone this repo: - -```bash -git clone https://github.com/microsoft/Swin-Transformer.git -cd Swin-Transformer -``` - -- Create a conda virtual environment and activate it: - -```bash -conda create -n swin python=3.7 -y -conda activate swin -``` - -- Install `CUDA>=10.2` with `cudnn>=7` following - the [official installation instructions](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html) -- Install `PyTorch>=1.8.0` and `torchvision>=0.9.0` with `CUDA>=10.2`: - -```bash -conda install pytorch==1.8.0 torchvision==0.9.0 cudatoolkit=10.2 -c pytorch -``` - -- Install `timm==0.4.12`: - -```bash -pip install timm==0.4.12 -``` - -- Install other requirements: - -```bash -pip install opencv-python==4.4.0.46 termcolor==1.1.0 yacs==0.1.8 -``` - -- Install fused window process for acceleration, activated by passing `--fused_window_process` in the running script -```bash -cd kernels/window_process -python setup.py install #--user -``` - -### Data preparation - -We use standard ImageNet dataset, you can download it from http://image-net.org/. We provide the following two ways to -load data: - -- For standard folder dataset, move validation images to labeled sub-folders. The file structure should look like: - ```bash - $ tree data - imagenet - ├── train - │ ├── class1 - │ │ ├── img1.jpeg - │ │ ├── img2.jpeg - │ │ └── ... - │ ├── class2 - │ │ ├── img3.jpeg - │ │ └── ... - │ └── ... - └── val - ├── class1 - │ ├── img4.jpeg - │ ├── img5.jpeg - │ └── ... - ├── class2 - │ ├── img6.jpeg - │ └── ... - └── ... - - ``` -- To boost the slow speed when reading images from massive small files, we also support zipped ImageNet, which includes - four files: - - `train.zip`, `val.zip`: which store the zipped folder for train and validate splits. - - `train_map.txt`, `val_map.txt`: which store the relative path in the corresponding zip file and ground truth - label. Make sure the data folder looks like this: - - ```bash - $ tree data - data - └── ImageNet-Zip - ├── train_map.txt - ├── train.zip - ├── val_map.txt - └── val.zip - - $ head -n 5 data/ImageNet-Zip/val_map.txt - ILSVRC2012_val_00000001.JPEG 65 - ILSVRC2012_val_00000002.JPEG 970 - ILSVRC2012_val_00000003.JPEG 230 - ILSVRC2012_val_00000004.JPEG 809 - ILSVRC2012_val_00000005.JPEG 516 - - $ head -n 5 data/ImageNet-Zip/train_map.txt - n01440764/n01440764_10026.JPEG 0 - n01440764/n01440764_10027.JPEG 0 - n01440764/n01440764_10029.JPEG 0 - n01440764/n01440764_10040.JPEG 0 - n01440764/n01440764_10042.JPEG 0 - ``` -- For ImageNet-22K dataset, make a folder named `fall11_whole` and move all images to labeled sub-folders in this - folder. Then download the train-val split - file ([ILSVRC2011fall_whole_map_train.txt](https://github.com/SwinTransformer/storage/releases/download/v2.0.1/ILSVRC2011fall_whole_map_train.txt) - & [ILSVRC2011fall_whole_map_val.txt](https://github.com/SwinTransformer/storage/releases/download/v2.0.1/ILSVRC2011fall_whole_map_val.txt)) - , and put them in the parent directory of `fall11_whole`. The file structure should look like: - - ```bash - $ tree imagenet22k/ - imagenet22k/ - ├── ILSVRC2011fall_whole_map_train.txt - ├── ILSVRC2011fall_whole_map_val.txt - └── fall11_whole - ├── n00004475 - ├── n00005787 - ├── n00006024 - ├── n00006484 - └── ... - ``` - -### Evaluation - -To evaluate a pre-trained `Swin Transformer` on ImageNet val, run: - -```bash -python -m torch.distributed.launch --nproc_per_node --master_port 12345 main.py --eval \ ---cfg --resume --data-path -``` - -For example, to evaluate the `Swin-B` with a single GPU: - -```bash -python -m torch.distributed.launch --nproc_per_node 1 --master_port 12345 main.py --eval \ ---cfg configs/swin/swin_base_patch4_window7_224.yaml --resume swin_base_patch4_window7_224.pth --data-path -``` - -### Training from scratch on ImageNet-1K - -To train a `Swin Transformer` on ImageNet from scratch, run: - -```bash -python -m torch.distributed.launch --nproc_per_node --master_port 12345 main.py \ ---cfg --data-path [--batch-size --output --tag ] -``` - -**Notes**: - -- To use zipped ImageNet instead of folder dataset, add `--zip` to the parameters. - - To cache the dataset in the memory instead of reading from files every time, add `--cache-mode part`, which will - shard the dataset into non-overlapping pieces for different GPUs and only load the corresponding one for each GPU. -- When GPU memory is not enough, you can try the following suggestions: - - Use gradient accumulation by adding `--accumulation-steps `, set appropriate `` according to your need. - - Use gradient checkpointing by adding `--use-checkpoint`, e.g., it saves about 60% memory when training `Swin-B`. - Please refer to [this page](https://pytorch.org/docs/stable/checkpoint.html) for more details. - - We recommend using multi-node with more GPUs for training very large models, a tutorial can be found - in [this page](https://pytorch.org/tutorials/intermediate/dist_tuto.html). -- To change config options in general, you can use `--opts KEY1 VALUE1 KEY2 VALUE2`, e.g., - `--opts TRAIN.EPOCHS 100 TRAIN.WARMUP_EPOCHS 5` will change total epochs to 100 and warm-up epochs to 5. -- For additional options, see [config](config.py) and run `python main.py --help` to get detailed message. - -For example, to train `Swin Transformer` with 8 GPU on a single node for 300 epochs, run: - -`Swin-T`: - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_tiny_patch4_window7_224.yaml --data-path --batch-size 128 -``` - -`Swin-S`: - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_small_patch4_window7_224.yaml --data-path --batch-size 128 -``` - -`Swin-B`: - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_base_patch4_window7_224.yaml --data-path --batch-size 64 \ ---accumulation-steps 2 [--use-checkpoint] -``` - -### Pre-training on ImageNet-22K - -For example, to pre-train a `Swin-B` model on ImageNet-22K: - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_base_patch4_window7_224_22k.yaml --data-path --batch-size 64 \ ---accumulation-steps 8 [--use-checkpoint] -``` - -### Fine-tuning on higher resolution - -For example, to fine-tune a `Swin-B` model pre-trained on 224x224 resolution to 384x384 resolution: - -```bashs -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_base_patch4_window12_384_finetune.yaml --pretrained swin_base_patch4_window7_224.pth \ ---data-path --batch-size 64 --accumulation-steps 2 [--use-checkpoint] -``` - -### Fine-tuning from a ImageNet-22K(21K) pre-trained model - -For example, to fine-tune a `Swin-B` model pre-trained on ImageNet-22K(21K): - -```bashs -python -m torch.distributed.launch --nproc_per_node 8 --master_port 12345 main.py \ ---cfg configs/swin/swin_base_patch4_window7_224_22kto1k_finetune.yaml --pretrained swin_base_patch4_window7_224_22k.pth \ ---data-path --batch-size 64 --accumulation-steps 2 [--use-checkpoint] -``` - -### Throughput - -To measure the throughput, run: - -```bash -python -m torch.distributed.launch --nproc_per_node 1 --master_port 12345 main.py \ ---cfg --data-path --batch-size 64 --throughput --disable_amp -``` - - -## Mixture-of-Experts Support - -### Install [Tutel](https://github.com/microsoft/tutel) -```bash -python3 -m pip uninstall tutel -y -python3 -m pip install --user --upgrade git+https://github.com/microsoft/tutel@main -``` - -### Training Swin-MoE -For example, to train a `Swin-MoE-S` model with 32 experts on ImageNet-22K with 32 GPUs (4 nodes): - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --nnode=4 \ ---node_rank= --master_addr= --master_port 12345 main_moe.py \ ---cfg configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml --data-path --batch-size 128 -``` - -### Evaluating Swin-MoE - -To evaluate a `Swin-MoE-S` with 32 experts on ImageNet-22K with 32 GPUs (4 nodes): - -1. Download the zip file [swin_moe_small_patch4_window12_192_32expert_32gpu_22k.zip](https://github.com/SwinTransformer/storage/releases/download/v2.0.2/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.zip) which contains the pre-trained models for each rank, and unzip them to the folder "swin_moe_small_patch4_window12_192_32expert_32gpu_22k". -2. Run the following evaluation command, note the checkpoint path should not contain the ".rank\" suffix. - -```bash -python -m torch.distributed.launch --nproc_per_node 8 --nnode=4 \ ---node_rank= --master_addr= --master_port 12345 main_moe.py \ ---cfg configs/swinmoe/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.yaml --data-path --batch-size 128 \ ---resume swin_moe_small_patch4_window12_192_32expert_32gpu_22k/swin_moe_small_patch4_window12_192_32expert_32gpu_22k.pth -``` - -More Swin-MoE models can be found in [MODEL HUB](MODELHUB.md#imagenet-22k-pretrained-swin-moe-models) \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/kernels/window_process/setup.py b/cv/classification/swin_transformer/pytorch/kernels/window_process/setup.py deleted file mode 100644 index c78526d0a..000000000 --- a/cv/classification/swin_transformer/pytorch/kernels/window_process/setup.py +++ /dev/null @@ -1,12 +0,0 @@ -from setuptools import setup -from torch.utils.cpp_extension import BuildExtension, CUDAExtension - - -setup(name='swin_window_process', - ext_modules=[ - CUDAExtension('swin_window_process', [ - 'swin_window_process.cpp', - 'swin_window_process_kernel.cu', - ]) - ], - cmdclass={'build_ext': BuildExtension}) \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process.cpp b/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process.cpp deleted file mode 100644 index a7f15b048..000000000 --- a/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - - -at::Tensor roll_and_window_partition_forward_cuda( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size); - - -at::Tensor roll_and_window_partition_backward_cuda( - at::Tensor & grad_in, - //at::Tensor & grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size); - - -at::Tensor window_merge_and_roll_forward_cuda( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size); - -at::Tensor window_merge_and_roll_backward_cuda( - at::Tensor & grad_in, - //at::Tensor & grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size); - - -#define CHECK_CUDA(x) AT_ASSERTM(x.type().is_cuda(), #x " must be a CUDA tensor") -#define CHECK_CONTIGUOUS(x) AT_ASSERTM(x.is_contiguous(), #x " must be contiguous") -#define CHECK_INPUT(x) CHECK_CUDA(x); CHECK_CONTIGUOUS(x) - - - -at::Tensor roll_and_window_partition_forward( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - CHECK_INPUT(input); - return roll_and_window_partition_forward_cuda(input, B, H, W, C, shift_size, window_size); -} - - -at::Tensor roll_and_window_partition_backward( - at::Tensor & grad_in, - //at::Tensor & grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - CHECK_INPUT(grad_in); - return roll_and_window_partition_backward_cuda(grad_in, B, H, W, C, shift_size, window_size); -} - - -at::Tensor window_merge_and_roll_forward( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - CHECK_INPUT(input); - return window_merge_and_roll_forward_cuda(input, B, H, W, C, shift_size, window_size); -} - - -at::Tensor window_merge_and_roll_backward( - at::Tensor & grad_in, - //at::Tensor & grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - CHECK_INPUT(grad_in); - return window_merge_and_roll_backward_cuda(grad_in, B, H, W, C, shift_size, window_size); -} - - - -PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { - m.def("roll_and_window_partition_forward", &roll_and_window_partition_forward, "torch.roll and window_partition."); - m.def("roll_and_window_partition_backward", &roll_and_window_partition_backward, "torch.roll and window_partition."); - m.def("window_merge_and_roll_forward", &window_merge_and_roll_forward, "window merge and torch.roll."); - m.def("window_merge_and_roll_backward", &window_merge_and_roll_backward, "window merge and torch.roll."); -} \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process_kernel.cu b/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process_kernel.cu deleted file mode 100644 index 4976949ee..000000000 --- a/cv/classification/swin_transformer/pytorch/kernels/window_process/swin_window_process_kernel.cu +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include - -int best_block_dim(int feat_dim){ - int best_dim; - if (feat_dim < 384){ - best_dim = 64; - } - else{ - if (feat_dim < 1024){ - best_dim = 128; - } - else{ - best_dim = 256; - } - } - return best_dim; -} - - -template -__global__ void roll_and_window_partition_forward_cuda_kernel( - T* input, - T* output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size, - const int nH, - const int nW){ - // start - //bool qual = threadIdx.x < C; - int index = threadIdx.x; - int offset; - for (int i = index; i < C; i += blockDim.x) { - offset = ((blockIdx.z * gridDim.y + blockIdx.y) * gridDim.x + blockIdx.x) * C + i; // C = blocksize - int input_offset = blockIdx.z / (nH * nW) * H * W * C + - (blockIdx.z % (nH * nW) / nW * window_size + blockIdx.y - shift_size + H) % H * W * C + - (blockIdx.z % nW * window_size + blockIdx.x - shift_size + W) % W * C + - i; - output[offset] = (T)(__ldg(input + input_offset)); - } -} - - -template -__global__ void roll_and_window_partition_backward_cuda_kernel( - T* grad_in, - T* grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size, - const int nH, - const int nW){ - // start - int index = threadIdx.x; - int offset; - for (int i = index; i < C; i += blockDim.x) { - offset = ((blockIdx.z * gridDim.y + blockIdx.y) * gridDim.x + blockIdx.x) * C + i; // C = blocksize - int input_offset = - (blockIdx.z * nH * nW + (blockIdx.y + shift_size + H) % H / window_size * nW + (blockIdx.x + shift_size + W) % W / window_size) * window_size * window_size * C + - (blockIdx.y + shift_size + H ) % H % window_size * window_size * C + - (blockIdx.x + shift_size + W ) % W % window_size * C + - i; - grad_out[offset] = (T)(__ldg(grad_in + input_offset)); - } -} - - -template -__global__ void window_merge_and_roll_forward_cuda_kernel( - T* input, - T* output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size, - const int nH, - const int nW){ - // start - int index = threadIdx.x; - int offset; - for (int i = index; i < C; i += blockDim.x) { - offset = ((blockIdx.z * gridDim.y + blockIdx.y) * gridDim.x + blockIdx.x) * C + i; // C = blocksize - int input_offset = - (blockIdx.z * nH * nW + (blockIdx.y - shift_size + H) % H / window_size * nH + (blockIdx.x - shift_size + W) % W / window_size) * window_size * window_size * C + - (blockIdx.y - shift_size + H) % window_size * window_size * C + - (blockIdx.x - shift_size + W) % window_size * C + - i; - output[offset] = (T)(__ldg(input + input_offset)); - } -} - - - -template -__global__ void window_merge_and_roll_backward_cuda_kernel( - T* grad_in, - T* grad_out, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size, - const int nH, - const int nW){ - // start - int index = threadIdx.x; - int offset; - for (int i = index; i < C; i += blockDim.x) { - offset = ((blockIdx.z * gridDim.y + blockIdx.y) * gridDim.x + blockIdx.x) * C + i; // C = blocksize - int input_offset = - (blockIdx.z / (nH * nW)) * H * W * C + - (blockIdx.z % (nH * nW) / nW * window_size + blockIdx.y + shift_size + H) % H * W * C + - (blockIdx.z % nW * window_size + blockIdx.x + shift_size + W) % W * C + - i; - grad_out[offset] = (T)(__ldg(grad_in + input_offset)); - } -} - -// input: [B, H, W, C] -// output: [B*nH*nW, window_size, window_size, C] -at::Tensor roll_and_window_partition_forward_cuda( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - - int nH = H / window_size; - int nW = W / window_size; - - dim3 grid(window_size, window_size, B * nH * nW); - //dim3 block((C + 31) / 32 * 32); - int blocknum = best_block_dim(C); - dim3 block(blocknum); - - at::Tensor output; - if (input.scalar_type() == torch::kFloat16){ - output = torch::empty({B*nH*nW, window_size, window_size, C}, torch::dtype(torch::kFloat16).device(torch::kCUDA).requires_grad(true)); - } - else{ - output = torch::empty({B*nH*nW, window_size, window_size, C}, torch::dtype(torch::kFloat32).device(torch::kCUDA).requires_grad(true)); - } - - AT_DISPATCH_FLOATING_TYPES_AND_HALF(input.type(), "roll_and_window_partition_forward_cuda_kernel", ([&] { - roll_and_window_partition_forward_cuda_kernel<<>>( - input.data(), - output.data(), - B, - H, - W, - C, - shift_size, - window_size, - nH, - nW); - })); - return output; -} - - -// grad_in: [B*nH*nW, window_size, window_size, C] -// grad_out: [B, H, W, C] -at::Tensor roll_and_window_partition_backward_cuda( - at::Tensor & grad_in, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - - int nH = H / window_size; - int nW = W / window_size; - - dim3 grid(W, H, B); - //dim3 block((C + 31) / 32 * 32); - int blocknum = best_block_dim(C); - dim3 block(blocknum); - - at::Tensor grad_out; - if (grad_in.scalar_type() == torch::kFloat16){ - grad_out = torch::empty({B, H, W, C}, torch::dtype(torch::kFloat16).device(torch::kCUDA).requires_grad(false)); - } - else{ - grad_out = torch::empty({B, H, W, C}, torch::dtype(torch::kFloat32).device(torch::kCUDA).requires_grad(false)); - } - - AT_DISPATCH_FLOATING_TYPES_AND_HALF(grad_in.type(), "roll_and_window_partition_backward_cuda_kernel", ([&] { - roll_and_window_partition_backward_cuda_kernel<<>>( - grad_in.data(), - grad_out.data(), - B, - H, - W, - C, - shift_size, - window_size, - nH, - nW); - })); - return grad_out; -} - - -// input: [B*nH*nW, window_size, window_size, C] -// output: [B, H, W, C] -at::Tensor window_merge_and_roll_forward_cuda( - at::Tensor & input, - //at::Tensor & output, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - - int nH = H / window_size; - int nW = W / window_size; - - dim3 grid(W, H, B); - //dim3 block((C + 31) / 32 * 32); - int blocknum = best_block_dim(C); - dim3 block(blocknum); - - //generate output tensor inside - at::Tensor output; - if (input.scalar_type() == torch::kFloat16){ - output = torch::empty({B, H, W, C}, torch::dtype(torch::kFloat16).device(torch::kCUDA).requires_grad(true)); - } - else{ - output = torch::empty({B, H, W, C}, torch::dtype(torch::kFloat32).device(torch::kCUDA).requires_grad(true)); - } - - AT_DISPATCH_FLOATING_TYPES_AND_HALF(input.type(), "window_merge_and_roll_forward_cuda_kernel", ([&] { - window_merge_and_roll_forward_cuda_kernel<<>>( - input.data(), - output.data(), - B, - H, - W, - C, - shift_size, - window_size, - nH, - nW); - })); - return output; -} - - -at::Tensor window_merge_and_roll_backward_cuda( - at::Tensor & grad_in, - const int B, - const int H, - const int W, - const int C, - const int shift_size, - const int window_size){ - - int nH = H / window_size; - int nW = W / window_size; - - dim3 grid(window_size, window_size, B * nH * nW); - //dim3 block((C + 31) / 32 * 32); - int blocknum = best_block_dim(C); - dim3 block(blocknum); - - at::Tensor grad_out; - if (grad_in.scalar_type() == torch::kFloat16){ - grad_out = torch::empty({B*nH*nW, window_size, window_size, C}, torch::dtype(torch::kFloat16).device(torch::kCUDA).requires_grad(false)); - } - else{ - grad_out = torch::empty({B*nH*nW, window_size, window_size, C}, torch::dtype(torch::kFloat32).device(torch::kCUDA).requires_grad(false)); - } - - AT_DISPATCH_FLOATING_TYPES_AND_HALF(grad_in.type(), "window_merge_and_roll_backward_cuda_kernel", ([&] { - window_merge_and_roll_backward_cuda_kernel<<>>( - grad_in.data(), - grad_out.data(), - B, - H, - W, - C, - shift_size, - window_size, - nH, - nW); - })); - return grad_out; -} \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/kernels/window_process/unit_test.py b/cv/classification/swin_transformer/pytorch/kernels/window_process/unit_test.py deleted file mode 100644 index 65dee5661..000000000 --- a/cv/classification/swin_transformer/pytorch/kernels/window_process/unit_test.py +++ /dev/null @@ -1,250 +0,0 @@ -# -------------------------------------------------------- -# Fused kernel for window process for SwinTransformer -# Copyright (c) 2022 Nvidia -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- - -import torch -import swin_window_process -import random -import time -import unittest - - -class WindowProcess(torch.autograd.Function): - @staticmethod - def forward(ctx, input, B, H, W, C, shift_size, window_size): - output = swin_window_process.roll_and_window_partition_forward(input, B, H, W, C, shift_size, window_size) - - ctx.B = B - ctx.H = H - ctx.W = W - ctx.C = C - ctx.shift_size = shift_size - ctx.window_size = window_size - return output - - @staticmethod - def backward(ctx, grad_in): - B = ctx.B - H = ctx.H - W = ctx.W - C = ctx.C - shift_size = ctx.shift_size - window_size = ctx.window_size - - grad_out = swin_window_process.roll_and_window_partition_backward(grad_in, B, H, W, C, shift_size, window_size) - return grad_out, None, None, None, None, None, None, None - - -class WindowProcessReverse(torch.autograd.Function): - @staticmethod - def forward(ctx, input, B, H, W, C, shift_size, window_size): - output = swin_window_process.window_merge_and_roll_forward(input, B, H, W, C, shift_size, window_size) - - ctx.B = B - ctx.H = H - ctx.W = W - ctx.C = C - ctx.shift_size = shift_size - ctx.window_size = window_size - - return output - - @staticmethod - def backward(ctx, grad_in): - B = ctx.B - H = ctx.H - W = ctx.W - C = ctx.C - shift_size = ctx.shift_size - window_size = ctx.window_size - - grad_out = swin_window_process.window_merge_and_roll_backward(grad_in, B, H, W, C, shift_size, window_size) - return grad_out, None, None, None, None, None, None, None - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - Returns: - x: (B, H, W, C) - """ - 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 pyt_forward(x, shift_size, window_size): - # x in shape(B, H, W, C) - # cyclic shift - if shift_size > 0: - shifted_x = torch.roll(x, shifts=(-shift_size, -shift_size), dims=(1, 2)) - else: - shifted_x = x - # partition windows - x_windows = window_partition(shifted_x, window_size) - return x_windows - - -def reverse_pyt_forward(attn_windows, shift_size, window_size, H, W): - # x in shape(B*nH*nW, window_size, window_size, C) - shifted_x = window_reverse(attn_windows, window_size, H, W) - if shift_size > 0: - x = torch.roll(shifted_x, shifts=(shift_size, shift_size), dims=(1, 2)) - else: - x = shifted_x - return x - - -def copy_one_tensor(input, requires_grad=True): - input1 = input.clone().detach().requires_grad_(requires_grad).cuda() - return input1 - -class Test_WindowProcess(unittest.TestCase): - def setUp(self): - self.B = 192 - self.H = 56 - self.W = 56 - self.C = 96 - self.shift_size = 2 - self.window_size = 7 - self.nH = self.H // self.window_size - self.nW = self.W // self.window_size - - def test_roll_and_window_partition_forward(self, dtype=torch.float32): - input = torch.randn((self.B, self.H, self.W, self.C), dtype=dtype, requires_grad=True).cuda() - - input1 = copy_one_tensor(input, True) - input2 = copy_one_tensor(input, True) - - with torch.no_grad(): - # ori - expected = pyt_forward(input1, self.shift_size, self.window_size) - # fused kernel - fused_output = WindowProcess.apply(input2, self.B, self.H, self.W, self.C, -self.shift_size, self.window_size) - - self.assertTrue(torch.equal(expected, fused_output)) - #self.assertTrue(torch.allclose(expected, fused_output, rtol=1e-05, atol=1e-08)) - - def test_roll_and_window_partition_backward(self, dtype=torch.float32): - input = torch.randn((self.B, self.H, self.W, self.C), dtype=dtype, requires_grad=True).cuda() - d_loss_tensor = torch.randn((self.B*self.nW*self.nH, self.window_size, self.window_size, self.C), dtype=dtype).cuda() - - input1 = copy_one_tensor(input, True) - input2 = copy_one_tensor(input, True) - - # ori - expected = pyt_forward(input1, self.shift_size, self.window_size) - expected.backward(d_loss_tensor) - # fused kernel - fused_output = WindowProcess.apply(input2, self.B, self.H, self.W, self.C, -self.shift_size, self.window_size) - fused_output.backward(d_loss_tensor) - - self.assertTrue(torch.equal(expected, fused_output)) - #self.assertTrue(torch.allclose(expected, fused_output, rtol=1e-05, atol=1e-08)) - - def test_window_merge_and_roll_forward(self, dtype=torch.float32): - input = torch.randn((self.B*self.nH*self.nW, self.window_size, self.window_size, self.C), dtype=dtype, requires_grad=True).cuda() - - input1 = copy_one_tensor(input, True) - input2 = copy_one_tensor(input, True) - - with torch.no_grad(): - # ori - expected = reverse_pyt_forward(input1, self.shift_size, self.window_size, self.H, self.W) - # fused kernel - fused_output = WindowProcessReverse.apply(input2, self.B, self.H, self.W, self.C, self.shift_size, self.window_size) - - self.assertTrue(torch.equal(expected, fused_output)) - #self.assertTrue(torch.allclose(expected, fused_output, rtol=1e-05, atol=1e-08)) - - - def test_window_merge_and_roll_backward(self, dtype=torch.float32): - input = torch.randn((self.B*self.nH*self.nW, self.window_size, self.window_size, self.C), dtype=dtype, requires_grad=True).cuda() - d_loss_tensor = torch.randn((self.B, self.H, self.W, self.C), dtype=dtype, requires_grad=True).cuda() - - input1 = copy_one_tensor(input, True) - input2 = copy_one_tensor(input, True) - - # ori - expected = reverse_pyt_forward(input1, self.shift_size, self.window_size, self.H, self.W) - expected.backward(d_loss_tensor) - # fused kernel - fused_output = WindowProcessReverse.apply(input2, self.B, self.H, self.W, self.C, self.shift_size, self.window_size) - fused_output.backward(d_loss_tensor) - - self.assertTrue(torch.equal(expected, fused_output)) - #self.assertTrue(torch.allclose(expected, fused_output, rtol=1e-05, atol=1e-08)) - - def test_forward_backward_speed(self, dtype=torch.float32, times=1000): - input = torch.randn((self.B*self.nH*self.nW, self.window_size, self.window_size, self.C), dtype=dtype, requires_grad=True).cuda() - d_loss_tensor = torch.randn((self.B, self.H, self.W, self.C), dtype=dtype, requires_grad=True).cuda() - - input1 = copy_one_tensor(input, True) - input2 = copy_one_tensor(input, True) - - # SwinTransformer official - def run_pyt(t=1000): - for _ in range(t): - expected = reverse_pyt_forward(input1, self.shift_size, self.window_size, self.H, self.W) - expected.backward(d_loss_tensor) - - # my op - def run_fusedop(t=1000): - for _ in range(t): - fused_output = WindowProcessReverse.apply(input2, self.B, self.H, self.W, self.C, self.shift_size, self.window_size) - fused_output.backward(d_loss_tensor) - - torch.cuda.synchronize() - t1 = time.time() - run_pyt(t=times) - torch.cuda.synchronize() - t2 = time.time() - run_fusedop(t=times) - torch.cuda.synchronize() - t3 = time.time() - self.assertTrue((t3 - t2) < (t2 - t1)) - - print('Run {} times'.format(times)) - print('Original time cost: {}'.format(t2 - t1)) - print('Fused op time cost: {}'.format(t3 - t2)) - - def test_roll_and_window_partition_forward_fp16(self, dtype=torch.float16): - self.test_roll_and_window_partition_forward(dtype=dtype) - - def test_roll_and_window_partition_backward_fp16(self, dtype=torch.float16): - self.test_roll_and_window_partition_backward(dtype=dtype) - - def test_window_merge_and_roll_forward_fp16(self, dtype=torch.float16): - self.test_window_merge_and_roll_forward(dtype=dtype) - - def test_window_merge_and_roll_backward_fp16(self, dtype=torch.float16): - self.test_window_merge_and_roll_backward(dtype=dtype) - - def test_forward_backward_speed_fp16(self, dtype=torch.float16, times=1000): - self.test_forward_backward_speed(dtype=dtype, times=times) - - -if __name__ == '__main__': - print('Pass only two tensors are exactly the same (using torch.equal).\n') - torch.manual_seed(0) - unittest.main(verbosity=2) diff --git a/cv/classification/swin_transformer/pytorch/kernels/window_process/window_process.py b/cv/classification/swin_transformer/pytorch/kernels/window_process/window_process.py deleted file mode 100644 index ee43e9e97..000000000 --- a/cv/classification/swin_transformer/pytorch/kernels/window_process/window_process.py +++ /dev/null @@ -1,63 +0,0 @@ -# -------------------------------------------------------- -# Fused kernel for window process for SwinTransformer -# Copyright (c) 2022 Nvidia -# Licensed under The MIT License [see LICENSE for details] -# -------------------------------------------------------- - -import torch -import swin_window_process - - -class WindowProcess(torch.autograd.Function): - @staticmethod - def forward(ctx, input, B, H, W, C, shift_size, window_size): - output = swin_window_process.roll_and_window_partition_forward(input, B, H, W, C, shift_size, window_size) - - ctx.B = B - ctx.H = H - ctx.W = W - ctx.C = C - ctx.shift_size = shift_size - ctx.window_size = window_size - return output - - @staticmethod - def backward(ctx, grad_in): - B = ctx.B - H = ctx.H - W = ctx.W - C = ctx.C - shift_size = ctx.shift_size - window_size = ctx.window_size - - grad_out = swin_window_process.roll_and_window_partition_backward(grad_in, B, H, W, C, shift_size, window_size) - return grad_out, None, None, None, None, None, None, None - - -class WindowProcessReverse(torch.autograd.Function): - @staticmethod - def forward(ctx, input, B, H, W, C, shift_size, window_size): - output = swin_window_process.window_merge_and_roll_forward(input, B, H, W, C, shift_size, window_size) - - ctx.B = B - ctx.H = H - ctx.W = W - ctx.C = C - ctx.shift_size = shift_size - ctx.window_size = window_size - - return output - - @staticmethod - def backward(ctx, grad_in): - B = ctx.B - H = ctx.H - W = ctx.W - C = ctx.C - shift_size = ctx.shift_size - window_size = ctx.window_size - - #grad_out = ctx.saved_tensors[0] - #grad_out = torch.zeros((B, H, W, C), dtype=dtype).cuda() - grad_out = swin_window_process.window_merge_and_roll_backward(grad_in, B, H, W, C, shift_size, window_size) - return grad_out, None, None, None, None, None, None, None diff --git a/cv/classification/swin_transformer/pytorch/logger.py b/cv/classification/swin_transformer/pytorch/logger.py deleted file mode 100644 index a066e55ba..000000000 --- a/cv/classification/swin_transformer/pytorch/logger.py +++ /dev/null @@ -1,41 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import sys -import logging -import functools -from termcolor import colored - - -@functools.lru_cache() -def create_logger(output_dir, dist_rank=0, name=''): - # create logger - logger = logging.getLogger(name) - logger.setLevel(logging.DEBUG) - logger.propagate = False - - # create formatter - fmt = '[%(asctime)s %(name)s] (%(filename)s %(lineno)d): %(levelname)s %(message)s' - color_fmt = colored('[%(asctime)s %(name)s]', 'green') + \ - colored('(%(filename)s %(lineno)d)', 'yellow') + ': %(levelname)s %(message)s' - - # create console handlers for master process - if dist_rank == 0: - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setLevel(logging.DEBUG) - console_handler.setFormatter( - logging.Formatter(fmt=color_fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(console_handler) - - # create file handlers - file_handler = logging.FileHandler(os.path.join(output_dir, f'log_rank{dist_rank}.txt'), mode='a') - file_handler.setLevel(logging.DEBUG) - file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt='%Y-%m-%d %H:%M:%S')) - logger.addHandler(file_handler) - - return logger diff --git a/cv/classification/swin_transformer/pytorch/lr_scheduler.py b/cv/classification/swin_transformer/pytorch/lr_scheduler.py deleted file mode 100644 index 36bb30f8f..000000000 --- a/cv/classification/swin_transformer/pytorch/lr_scheduler.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -from timm.scheduler.cosine_lr import CosineLRScheduler -from timm.scheduler.step_lr import StepLRScheduler -from timm.scheduler.scheduler import Scheduler - - -def build_scheduler(config, optimizer, n_iter_per_epoch): - num_steps = int(config.TRAIN.EPOCHS * n_iter_per_epoch) - warmup_steps = int(config.TRAIN.WARMUP_EPOCHS * n_iter_per_epoch) - decay_steps = int(config.TRAIN.LR_SCHEDULER.DECAY_EPOCHS * n_iter_per_epoch) - - lr_scheduler = None - if config.TRAIN.LR_SCHEDULER.NAME == 'cosine': - lr_scheduler = CosineLRScheduler( - optimizer, - t_initial=num_steps, - t_mul=1., - lr_min=config.TRAIN.MIN_LR, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - cycle_limit=1, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'linear': - lr_scheduler = LinearLRScheduler( - optimizer, - t_initial=num_steps, - lr_min_rate=0.01, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - elif config.TRAIN.LR_SCHEDULER.NAME == 'step': - lr_scheduler = StepLRScheduler( - optimizer, - decay_t=decay_steps, - decay_rate=config.TRAIN.LR_SCHEDULER.DECAY_RATE, - warmup_lr_init=config.TRAIN.WARMUP_LR, - warmup_t=warmup_steps, - t_in_epochs=False, - ) - - return lr_scheduler - - -class LinearLRScheduler(Scheduler): - def __init__(self, - optimizer: torch.optim.Optimizer, - t_initial: int, - lr_min_rate: float, - warmup_t=0, - warmup_lr_init=0., - t_in_epochs=True, - noise_range_t=None, - noise_pct=0.67, - noise_std=1.0, - noise_seed=42, - initialize=True, - ) -> None: - super().__init__( - optimizer, param_group_field="lr", - noise_range_t=noise_range_t, noise_pct=noise_pct, noise_std=noise_std, noise_seed=noise_seed, - initialize=initialize) - - self.t_initial = t_initial - self.lr_min_rate = lr_min_rate - self.warmup_t = warmup_t - self.warmup_lr_init = warmup_lr_init - self.t_in_epochs = t_in_epochs - if self.warmup_t: - self.warmup_steps = [(v - warmup_lr_init) / self.warmup_t for v in self.base_values] - super().update_groups(self.warmup_lr_init) - else: - self.warmup_steps = [1 for _ in self.base_values] - - def _get_lr(self, t): - if t < self.warmup_t: - lrs = [self.warmup_lr_init + t * s for s in self.warmup_steps] - else: - t = t - self.warmup_t - total_t = self.t_initial - self.warmup_t - lrs = [v - ((v - v * self.lr_min_rate) * (t / total_t)) for v in self.base_values] - return lrs - - def get_epoch_values(self, epoch: int): - if self.t_in_epochs: - return self._get_lr(epoch) - else: - return None - - def get_update_values(self, num_updates: int): - if not self.t_in_epochs: - return self._get_lr(num_updates) - else: - return None diff --git a/cv/classification/swin_transformer/pytorch/main.py b/cv/classification/swin_transformer/pytorch/main.py deleted file mode 100644 index 88d51443d..000000000 --- a/cv/classification/swin_transformer/pytorch/main.py +++ /dev/null @@ -1,345 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import time -import json -import random -import argparse -import datetime -import numpy as np - -import torch -import torch.backends.cudnn as cudnn -import torch.distributed as dist - -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.utils import accuracy, AverageMeter - -from config import get_config -from models import build_model -from data import build_loader -from lr_scheduler import build_scheduler -from optimizer import build_optimizer -from logger import create_logger -from utils import load_checkpoint, load_pretrained, save_checkpoint, NativeScalerWithGradNormCount, auto_resume_helper, \ - reduce_tensor - - -def parse_option(): - parser = argparse.ArgumentParser('Swin Transformer training and evaluation script', add_help=False) - parser.add_argument('--cfg', type=str, required=True, metavar="FILE", help='path to config file', ) - parser.add_argument( - "--opts", - help="Modify config options by adding 'KEY VALUE' pairs. ", - default=None, - nargs='+', - ) - - # easy config modification - parser.add_argument('--batch-size', type=int, help="batch size for single GPU") - parser.add_argument('--data-path', type=str, help='path to dataset') - parser.add_argument('--zip', action='store_true', help='use zipped dataset instead of folder dataset') - parser.add_argument('--cache-mode', type=str, default='part', choices=['no', 'full', 'part'], - help='no: no cache, ' - 'full: cache all data, ' - 'part: sharding the dataset into nonoverlapping pieces and only cache one piece') - parser.add_argument('--pretrained', - help='pretrained weight from checkpoint, could be imagenet22k pretrained weight') - parser.add_argument('--resume', help='resume from checkpoint') - parser.add_argument('--accumulation-steps', type=int, help="gradient accumulation steps") - parser.add_argument('--use-checkpoint', action='store_true', - help="whether to use gradient checkpointing to save memory") - parser.add_argument('--disable_amp', action='store_true', help='Disable pytorch amp') - parser.add_argument('--amp-opt-level', type=str, choices=['O0', 'O1', 'O2'], - help='mixed precision opt level, if O0, no amp is used (deprecated!)') - parser.add_argument('--output', default='output', type=str, metavar='PATH', - help='root of output folder, the full path is // (default: output)') - parser.add_argument('--tag', help='tag of experiment') - parser.add_argument('--eval', action='store_true', help='Perform evaluation only') - parser.add_argument('--throughput', action='store_true', help='Test throughput only') - - # distributed training - parser.add_argument("--local_rank", type=int, required=True, help='local rank for DistributedDataParallel') - - # for acceleration - parser.add_argument('--fused_window_process', action='store_true', help='Fused window shift & window partition, similar for reversed part.') - - args, unparsed = parser.parse_known_args() - - config = get_config(args) - - return args, config - - -def main(config): - dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn = build_loader(config) - - logger.info(f"Creating model:{config.MODEL.TYPE}/{config.MODEL.NAME}") - model = build_model(config) - logger.info(str(model)) - - n_parameters = sum(p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params: {n_parameters}") - if hasattr(model, 'flops'): - flops = model.flops() - logger.info(f"number of GFLOPs: {flops / 1e9}") - - model.cuda() - model_without_ddp = model - - optimizer = build_optimizer(config, model) - model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.LOCAL_RANK], broadcast_buffers=False) - loss_scaler = NativeScalerWithGradNormCount() - - if config.TRAIN.ACCUMULATION_STEPS > 1: - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train) // config.TRAIN.ACCUMULATION_STEPS) - else: - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train)) - - if config.AUG.MIXUP > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif config.MODEL.LABEL_SMOOTHING > 0.: - criterion = LabelSmoothingCrossEntropy(smoothing=config.MODEL.LABEL_SMOOTHING) - else: - criterion = torch.nn.CrossEntropyLoss() - - max_accuracy = 0.0 - - if config.TRAIN.AUTO_RESUME: - resume_file = auto_resume_helper(config.OUTPUT) - if resume_file: - if config.MODEL.RESUME: - logger.warning(f"auto-resume changing resume file from {config.MODEL.RESUME} to {resume_file}") - config.defrost() - config.MODEL.RESUME = resume_file - config.freeze() - logger.info(f'auto resuming from {resume_file}') - else: - logger.info(f'no checkpoint found in {config.OUTPUT}, ignoring auto resume') - - if config.MODEL.RESUME: - max_accuracy = load_checkpoint(config, model_without_ddp, optimizer, lr_scheduler, loss_scaler, logger) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - if config.EVAL_MODE: - return - - if config.MODEL.PRETRAINED and (not config.MODEL.RESUME): - load_pretrained(config, model_without_ddp, logger) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - - if config.THROUGHPUT_MODE: - throughput(data_loader_val, model, logger) - return - - logger.info("Start training") - start_time = time.time() - for epoch in range(config.TRAIN.START_EPOCH, config.TRAIN.EPOCHS): - data_loader_train.sampler.set_epoch(epoch) - train_one_epoch(config, model, criterion, data_loader_train, optimizer, epoch, mixup_fn, lr_scheduler, - loss_scaler) - if dist.get_rank() == 0 and (epoch % config.SAVE_FREQ == 0 or epoch == (config.TRAIN.EPOCHS - 1)): - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, loss_scaler, - logger) - - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - max_accuracy = max(max_accuracy, acc1) - logger.info(f'Max accuracy: {max_accuracy:.2f}%') - - total_time = time.time() - start_time - total_time_str = str(datetime.timedelta(seconds=int(total_time))) - logger.info('Training time {}'.format(total_time_str)) - - -def train_one_epoch(config, model, criterion, data_loader, optimizer, epoch, mixup_fn, lr_scheduler, loss_scaler): - model.train() - optimizer.zero_grad() - - num_steps = len(data_loader) - batch_time = AverageMeter() - loss_meter = AverageMeter() - norm_meter = AverageMeter() - scaler_meter = AverageMeter() - - start = time.time() - end = time.time() - for idx, (samples, targets) in enumerate(data_loader): - samples = samples.cuda(non_blocking=True) - targets = targets.cuda(non_blocking=True) - - if mixup_fn is not None: - samples, targets = mixup_fn(samples, targets) - - with torch.cuda.amp.autocast(enabled=config.AMP_ENABLE): - outputs = model(samples) - loss = criterion(outputs, targets) - loss = loss / config.TRAIN.ACCUMULATION_STEPS - - # this attribute is added by timm on one optimizer (adahessian) - is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order - grad_norm = loss_scaler(loss, optimizer, clip_grad=config.TRAIN.CLIP_GRAD, - parameters=model.parameters(), create_graph=is_second_order, - update_grad=(idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0) - if (idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0: - optimizer.zero_grad() - lr_scheduler.step_update((epoch * num_steps + idx) // config.TRAIN.ACCUMULATION_STEPS) - loss_scale_value = loss_scaler.state_dict()["scale"] - - torch.cuda.synchronize() - - loss_meter.update(loss.item(), targets.size(0)) - if grad_norm is not None: # loss_scaler return None if not update - norm_meter.update(grad_norm) - scaler_meter.update(loss_scale_value) - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - lr = optimizer.param_groups[0]['lr'] - wd = optimizer.param_groups[0]['weight_decay'] - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - etas = batch_time.avg * (num_steps - idx) - logger.info( - f'Train: [{epoch}/{config.TRAIN.EPOCHS}][{idx}/{num_steps}]\t' - f'eta {datetime.timedelta(seconds=int(etas))} lr {lr:.6f}\t wd {wd:.4f}\t' - f'time {batch_time.val:.4f} ({batch_time.avg:.4f})\t' - f'loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'grad_norm {norm_meter.val:.4f} ({norm_meter.avg:.4f})\t' - f'loss_scale {scaler_meter.val:.4f} ({scaler_meter.avg:.4f})\t' - f'mem {memory_used:.0f}MB') - epoch_time = time.time() - start - logger.info(f"EPOCH {epoch} training takes {datetime.timedelta(seconds=int(epoch_time))}") - - -@torch.no_grad() -def validate(config, data_loader, model): - criterion = torch.nn.CrossEntropyLoss() - model.eval() - - batch_time = AverageMeter() - loss_meter = AverageMeter() - acc1_meter = AverageMeter() - acc5_meter = AverageMeter() - - end = time.time() - for idx, (images, target) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - with torch.cuda.amp.autocast(enabled=config.AMP_ENABLE): - output = model(images) - - # measure accuracy and record loss - loss = criterion(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - acc1 = reduce_tensor(acc1) - acc5 = reduce_tensor(acc5) - loss = reduce_tensor(loss) - - loss_meter.update(loss.item(), target.size(0)) - acc1_meter.update(acc1.item(), target.size(0)) - acc5_meter.update(acc5.item(), target.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - logger.info( - f'Test: [{idx}/{len(data_loader)}]\t' - f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' - f'Loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' - f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' - f'Mem {memory_used:.0f}MB') - logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') - return acc1_meter.avg, acc5_meter.avg, loss_meter.avg - - -@torch.no_grad() -def throughput(data_loader, model, logger): - model.eval() - - for idx, (images, _) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - batch_size = images.shape[0] - for i in range(50): - model(images) - torch.cuda.synchronize() - logger.info(f"throughput averaged with 30 times") - tic1 = time.time() - for i in range(30): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - logger.info(f"batch_size {batch_size} throughput {30 * batch_size / (tic2 - tic1)}") - return - - -if __name__ == '__main__': - args, config = parse_option() - - if config.AMP_OPT_LEVEL: - print("[warning] Apex amp has been deprecated, please use pytorch amp instead!") - - if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ: - rank = int(os.environ["RANK"]) - world_size = int(os.environ['WORLD_SIZE']) - print(f"RANK and WORLD_SIZE in environ: {rank}/{world_size}") - else: - rank = -1 - world_size = -1 - torch.cuda.set_device(config.LOCAL_RANK) - # torch.distributed.init_process_group(backend='nccl', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.init_process_group(backend='gloo', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.barrier() - - seed = config.SEED + dist.get_rank() - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - np.random.seed(seed) - random.seed(seed) - cudnn.benchmark = True - - # linear scale the learning rate according to total batch size, may not be optimal - linear_scaled_lr = config.TRAIN.BASE_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_warmup_lr = config.TRAIN.WARMUP_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_min_lr = config.TRAIN.MIN_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - # gradient accumulation also need to scale the learning rate - if config.TRAIN.ACCUMULATION_STEPS > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_warmup_lr = linear_scaled_warmup_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_min_lr = linear_scaled_min_lr * config.TRAIN.ACCUMULATION_STEPS - config.defrost() - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_LR = linear_scaled_warmup_lr - config.TRAIN.MIN_LR = linear_scaled_min_lr - config.freeze() - - os.makedirs(config.OUTPUT, exist_ok=True) - logger = create_logger(output_dir=config.OUTPUT, dist_rank=dist.get_rank(), name=f"{config.MODEL.NAME}") - - if dist.get_rank() == 0: - path = os.path.join(config.OUTPUT, "config.json") - with open(path, "w") as f: - f.write(config.dump()) - logger.info(f"Full config saved to {path}") - - # print config - logger.info(config.dump()) - logger.info(json.dumps(vars(args))) - - main(config) diff --git a/cv/classification/swin_transformer/pytorch/main_moe.py b/cv/classification/swin_transformer/pytorch/main_moe.py deleted file mode 100644 index 6cd4e7f97..000000000 --- a/cv/classification/swin_transformer/pytorch/main_moe.py +++ /dev/null @@ -1,369 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from tutel import system - -import os -import time -import json -import random -import argparse -import datetime -import numpy as np -from functools import partial -import torch -import torch.backends.cudnn as cudnn -import torch.distributed as dist - -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy -from timm.utils import accuracy, AverageMeter - -from config import get_config -from models import build_model -from data import build_loader -from lr_scheduler import build_scheduler -from optimizer import build_optimizer -from logger import create_logger -from utils import NativeScalerWithGradNormCount, reduce_tensor -from utils_moe import load_checkpoint, load_pretrained, save_checkpoint, auto_resume_helper, hook_scale_grad - -assert torch.__version__ >= '1.8.0', "DDP-based MoE requires Pytorch >= 1.8.0" - - -def parse_option(): - parser = argparse.ArgumentParser('Swin Transformer training and evaluation script', add_help=False) - parser.add_argument('--cfg', type=str, required=True, metavar="FILE", help='path to config file', ) - parser.add_argument( - "--opts", - help="Modify config options by adding 'KEY VALUE' pairs. ", - default=None, - nargs='+', - ) - - # easy config modification - parser.add_argument('--batch-size', type=int, help="batch size for single GPU") - parser.add_argument('--data-path', type=str, help='path to dataset') - parser.add_argument('--zip', action='store_true', help='use zipped dataset instead of folder dataset') - parser.add_argument('--cache-mode', type=str, default='part', choices=['no', 'full', 'part'], - help='no: no cache, ' - 'full: cache all data, ' - 'part: sharding the dataset into nonoverlapping pieces and only cache one piece') - parser.add_argument('--pretrained', - help='pretrained weight from checkpoint, could be imagenet22k pretrained weight') - parser.add_argument('--resume', help='resume from checkpoint') - parser.add_argument('--accumulation-steps', type=int, help="gradient accumulation steps") - parser.add_argument('--use-checkpoint', action='store_true', - help="whether to use gradient checkpointing to save memory") - parser.add_argument('--disable_amp', action='store_true', help='Disable pytorch amp') - parser.add_argument('--amp-opt-level', type=str, choices=['O0', 'O1', 'O2'], - help='mixed precision opt level, if O0, no amp is used (deprecated!)') - parser.add_argument('--output', default='output', type=str, metavar='PATH', - help='root of output folder, the full path is // (default: output)') - parser.add_argument('--tag', help='tag of experiment') - parser.add_argument('--eval', action='store_true', help='Perform evaluation only') - parser.add_argument('--throughput', action='store_true', help='Test throughput only') - - # distributed training - parser.add_argument("--local_rank", type=int, required=True, help='local rank for DistributedDataParallel') - - args, unparsed = parser.parse_known_args() - - config = get_config(args) - - return args, config - - -def main(config): - dataset_train, dataset_val, data_loader_train, data_loader_val, mixup_fn = build_loader(config) - - logger.info(f"Creating model:{config.MODEL.TYPE}/{config.MODEL.NAME}") - model = build_model(config) - logger.info(str(model)) - - # For Tutel MoE - for name, param in model.named_parameters(): - if param.requires_grad == True and hasattr(param, 'skip_allreduce') and param.skip_allreduce is True: - model.add_param_to_skip_allreduce(name) - param.register_hook(partial(hook_scale_grad, dist.get_world_size())) - logger.info(f"[rank{dist.get_rank()}] [{name}] skip all_reduce and div {dist.get_world_size()} for grad") - - n_parameters_single = sum(p.numel() * model.sharded_count if hasattr(p, 'skip_allreduce') - else p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params single: {n_parameters_single}") - n_parameters_whole = sum(p.numel() * model.sharded_count * model.global_experts if hasattr(p, 'skip_allreduce') - else p.numel() for p in model.parameters() if p.requires_grad) - logger.info(f"number of params whole: {n_parameters_whole}") - if hasattr(model, 'flops'): - flops = model.flops() - logger.info(f"number of GFLOPs: {flops / 1e9}") - - model.cuda(config.LOCAL_RANK) - model_without_ddp = model - - optimizer = build_optimizer(config, model) - model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[config.LOCAL_RANK], broadcast_buffers=False) - loss_scaler = NativeScalerWithGradNormCount() - - if config.TRAIN.ACCUMULATION_STEPS > 1: - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train) // config.TRAIN.ACCUMULATION_STEPS) - else: - lr_scheduler = build_scheduler(config, optimizer, len(data_loader_train)) - - if config.AUG.MIXUP > 0.: - # smoothing is handled with mixup label transform - criterion = SoftTargetCrossEntropy() - elif config.MODEL.LABEL_SMOOTHING > 0.: - criterion = LabelSmoothingCrossEntropy(smoothing=config.MODEL.LABEL_SMOOTHING) - else: - criterion = torch.nn.CrossEntropyLoss() - - max_accuracy = 0.0 - - if config.TRAIN.AUTO_RESUME: - resume_file = auto_resume_helper(config.OUTPUT, config.TRAIN.MOE.SAVE_MASTER) - if resume_file: - if config.MODEL.RESUME: - logger.warning(f"auto-resume changing resume file from {config.MODEL.RESUME} to {resume_file}") - config.defrost() - config.MODEL.RESUME = resume_file - config.freeze() - logger.info(f'auto resuming from {resume_file}') - else: - logger.info(f'no checkpoint found in {config.OUTPUT}, ignoring auto resume') - - if config.MODEL.RESUME: - max_accuracy = load_checkpoint(config, model_without_ddp, optimizer, lr_scheduler, loss_scaler, logger) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - if config.EVAL_MODE: - return - - if config.MODEL.PRETRAINED and (not config.MODEL.RESUME): - load_pretrained(config, model_without_ddp, logger) - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - if config.EVAL_MODE: - return - - if config.THROUGHPUT_MODE: - throughput(data_loader_val, model, logger) - return - - logger.info("Start training") - start_time = time.time() - for epoch in range(config.TRAIN.START_EPOCH, config.TRAIN.EPOCHS): - data_loader_train.sampler.set_epoch(epoch) - - train_one_epoch(config, model, criterion, data_loader_train, optimizer, epoch, mixup_fn, lr_scheduler, - loss_scaler) - if (epoch % config.SAVE_FREQ == 0 or epoch == (config.TRAIN.EPOCHS - 1)): - save_checkpoint(config, epoch, model_without_ddp, max_accuracy, optimizer, lr_scheduler, loss_scaler, - logger) - - acc1, acc5, loss = validate(config, data_loader_val, model) - logger.info(f"Accuracy of the network on the {len(dataset_val)} test images: {acc1:.1f}%") - max_accuracy = max(max_accuracy, acc1) - logger.info(f'Max accuracy: {max_accuracy:.2f}%') - save_checkpoint(config, 'final', model_without_ddp, max_accuracy, optimizer, lr_scheduler, loss_scaler, - logger, zero_redundancy=True) - total_time = time.time() - start_time - total_time_str = str(datetime.timedelta(seconds=int(total_time))) - logger.info('Training time {}'.format(total_time_str)) - - -def train_one_epoch(config, model, criterion, data_loader, optimizer, epoch, mixup_fn, lr_scheduler, loss_scaler): - model.train() - optimizer.zero_grad() - - num_steps = len(data_loader) - batch_time = AverageMeter() - loss_meter = AverageMeter() - loss_aux_meter = AverageMeter() - loss_cls_meter = AverageMeter() - norm_meter = AverageMeter() - scaler_meter = AverageMeter() - - start = time.time() - end = time.time() - for idx, (samples, targets) in enumerate(data_loader): - samples = samples.cuda(non_blocking=True) - targets = targets.cuda(non_blocking=True) - - if mixup_fn is not None: - samples, targets = mixup_fn(samples, targets) - - with torch.cuda.amp.autocast(enabled=config.AMP_ENABLE): - outputs, l_aux = model(samples) - l_cls = criterion(outputs, targets) - loss = l_cls + l_aux - loss = loss / config.TRAIN.ACCUMULATION_STEPS - - # this attribute is added by timm on one optimizer (adahessian) - is_second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order - grad_norm = loss_scaler(loss, optimizer, clip_grad=config.TRAIN.CLIP_GRAD, - parameters=model.parameters(), create_graph=is_second_order, - update_grad=(idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0) - if (idx + 1) % config.TRAIN.ACCUMULATION_STEPS == 0: - optimizer.zero_grad() - lr_scheduler.step_update((epoch * num_steps + idx) // config.TRAIN.ACCUMULATION_STEPS) - loss_scale_value = loss_scaler.state_dict()["scale"] - - torch.cuda.synchronize() - - loss_meter.update(loss.item(), targets.size(0)) - loss_cls_meter.update(l_cls.item(), targets.size(0)) - loss_aux_meter.update(l_aux if isinstance(l_aux, float) else l_aux.item(), targets.size(0)) - if grad_norm is not None: # loss_scaler return None if not update - norm_meter.update(grad_norm) - scaler_meter.update(loss_scale_value) - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - lr = optimizer.param_groups[0]['lr'] - wd = optimizer.param_groups[0]['weight_decay'] - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - etas = batch_time.avg * (num_steps - idx) - logger.info( - f'Train: [{epoch}/{config.TRAIN.EPOCHS}][{idx}/{num_steps}]\t' - f'eta {datetime.timedelta(seconds=int(etas))} lr {lr:.6f}\t wd {wd:.4f}\t' - f'time {batch_time.val:.4f} ({batch_time.avg:.4f})\t' - f'loss {loss_meter.val:.4f} ({loss_meter.avg:.4f})\t' - f'loss-cls {loss_cls_meter.val:.4f} ({loss_cls_meter.avg:.4f})\t' - f'loss-aux {loss_aux_meter.val:.4f} ({loss_aux_meter.avg:.4f})\t' - f'grad_norm {norm_meter.val:.4f} ({norm_meter.avg:.4f})\t' - f'loss_scale {scaler_meter.val:.4f} ({scaler_meter.avg:.4f})\t' - f'mem {memory_used:.0f}MB') - epoch_time = time.time() - start - logger.info(f"EPOCH {epoch} training takes {datetime.timedelta(seconds=int(epoch_time))}") - - -@torch.no_grad() -def validate(config, data_loader, model): - criterion = torch.nn.CrossEntropyLoss() - model.eval() - - batch_time = AverageMeter() - loss_cls_meter = AverageMeter() - loss_aux_meter = AverageMeter() - acc1_meter = AverageMeter() - acc5_meter = AverageMeter() - - end = time.time() - for idx, (images, target) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - target = target.cuda(non_blocking=True) - - # compute output - with torch.cuda.amp.autocast(enabled=config.AMP_ENABLE): - output, l_aux = model(images) - - # measure accuracy and record loss - l_cls = criterion(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - acc1 = reduce_tensor(acc1) - acc5 = reduce_tensor(acc5) - - loss_cls_meter.update(l_cls.item(), target.size(0)) - loss_aux_meter.update(l_aux if isinstance(l_aux, float) else l_aux.item(), target.size(0)) - acc1_meter.update(acc1.item(), target.size(0)) - acc5_meter.update(acc5.item(), target.size(0)) - - # measure elapsed time - batch_time.update(time.time() - end) - end = time.time() - - if idx % config.PRINT_FREQ == 0: - memory_used = torch.cuda.max_memory_allocated() / (1024.0 * 1024.0) - logger.info( - f'Test: [{idx}/{len(data_loader)}]\t' - f'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' - f'Loss-Cls {loss_cls_meter.val:.4f} ({loss_cls_meter.avg:.4f})\t' - f'Loss-Aux {loss_aux_meter.val:.4f} ({loss_aux_meter.avg:.4f})\t' - f'Acc@1 {acc1_meter.val:.3f} ({acc1_meter.avg:.3f})\t' - f'Acc@5 {acc5_meter.val:.3f} ({acc5_meter.avg:.3f})\t' - f'Mem {memory_used:.0f}MB') - logger.info(f' * Acc@1 {acc1_meter.avg:.3f} Acc@5 {acc5_meter.avg:.3f}') - return acc1_meter.avg, acc5_meter.avg, loss_cls_meter.avg - - -@torch.no_grad() -def throughput(data_loader, model, logger): - model.eval() - - for idx, (images, _) in enumerate(data_loader): - images = images.cuda(non_blocking=True) - batch_size = images.shape[0] - for i in range(50): - model(images) - torch.cuda.synchronize() - logger.info(f"throughput averaged with 30 times") - tic1 = time.time() - for i in range(30): - model(images) - torch.cuda.synchronize() - tic2 = time.time() - logger.info(f"batch_size {batch_size} throughput {30 * batch_size / (tic2 - tic1)}") - return - - -if __name__ == '__main__': - args, config = parse_option() - - if config.AMP_OPT_LEVEL: - print("[warning] Apex amp has been deprecated, please use pytorch amp instead!") - - if 'RANK' in os.environ and 'WORLD_SIZE' in os.environ: - rank = int(os.environ["RANK"]) - world_size = int(os.environ['WORLD_SIZE']) - print(f"RANK and WORLD_SIZE in environ: {rank}/{world_size}") - else: - rank = -1 - world_size = -1 - torch.cuda.set_device(config.LOCAL_RANK) - torch.distributed.init_process_group(backend='nccl', init_method='env://', world_size=world_size, rank=rank) - torch.distributed.barrier() - - seed = config.SEED + dist.get_rank() - torch.manual_seed(seed) - torch.cuda.manual_seed(seed) - np.random.seed(seed) - random.seed(seed) - cudnn.benchmark = True - - # linear scale the learning rate according to total batch size, may not be optimal - linear_scaled_lr = config.TRAIN.BASE_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_warmup_lr = config.TRAIN.WARMUP_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - linear_scaled_min_lr = config.TRAIN.MIN_LR * config.DATA.BATCH_SIZE * dist.get_world_size() / 512.0 - # gradient accumulation also need to scale the learning rate - if config.TRAIN.ACCUMULATION_STEPS > 1: - linear_scaled_lr = linear_scaled_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_warmup_lr = linear_scaled_warmup_lr * config.TRAIN.ACCUMULATION_STEPS - linear_scaled_min_lr = linear_scaled_min_lr * config.TRAIN.ACCUMULATION_STEPS - config.defrost() - config.TRAIN.BASE_LR = linear_scaled_lr - config.TRAIN.WARMUP_LR = linear_scaled_warmup_lr - config.TRAIN.MIN_LR = linear_scaled_min_lr - config.freeze() - - os.makedirs(config.OUTPUT, exist_ok=True) - logger = create_logger(output_dir=config.OUTPUT, dist_rank=dist.get_rank(), name=f"{config.MODEL.NAME}") - - if dist.get_rank() == 0: - path = os.path.join(config.OUTPUT, "config.json") - with open(path, "w") as f: - f.write(config.dump()) - logger.info(f"Full config saved to {path}") - - # print config - logger.info(config.dump()) - logger.info(json.dumps(vars(args))) - - main(config) diff --git a/cv/classification/swin_transformer/pytorch/models/__init__.py b/cv/classification/swin_transformer/pytorch/models/__init__.py deleted file mode 100644 index 2d9c65e39..000000000 --- a/cv/classification/swin_transformer/pytorch/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .build import build_model \ No newline at end of file diff --git a/cv/classification/swin_transformer/pytorch/models/build.py b/cv/classification/swin_transformer/pytorch/models/build.py deleted file mode 100644 index aac054e4e..000000000 --- a/cv/classification/swin_transformer/pytorch/models/build.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from .swin_transformer import SwinTransformer -from .swin_transformer_v2 import SwinTransformerV2 -from .swin_transformer_moe import SwinTransformerMoE -from .swin_mlp import SwinMLP - - -def build_model(config): - model_type = config.MODEL.TYPE - if model_type == 'swin': - model = SwinTransformer(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN.PATCH_SIZE, - in_chans=config.MODEL.SWIN.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN.EMBED_DIM, - depths=config.MODEL.SWIN.DEPTHS, - num_heads=config.MODEL.SWIN.NUM_HEADS, - window_size=config.MODEL.SWIN.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN.MLP_RATIO, - qkv_bias=config.MODEL.SWIN.QKV_BIAS, - qk_scale=config.MODEL.SWIN.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN.APE, - patch_norm=config.MODEL.SWIN.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT, - fused_window_process=config.FUSED_WINDOW_PROCESS) - elif model_type == 'swinv2': - model = SwinTransformerV2(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWINV2.PATCH_SIZE, - in_chans=config.MODEL.SWINV2.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWINV2.EMBED_DIM, - depths=config.MODEL.SWINV2.DEPTHS, - num_heads=config.MODEL.SWINV2.NUM_HEADS, - window_size=config.MODEL.SWINV2.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWINV2.MLP_RATIO, - qkv_bias=config.MODEL.SWINV2.QKV_BIAS, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWINV2.APE, - patch_norm=config.MODEL.SWINV2.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT, - pretrained_window_sizes=config.MODEL.SWINV2.PRETRAINED_WINDOW_SIZES) - elif model_type == 'swin_moe': - model = SwinTransformerMoE(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN_MOE.PATCH_SIZE, - in_chans=config.MODEL.SWIN_MOE.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN_MOE.EMBED_DIM, - depths=config.MODEL.SWIN_MOE.DEPTHS, - num_heads=config.MODEL.SWIN_MOE.NUM_HEADS, - window_size=config.MODEL.SWIN_MOE.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN_MOE.MLP_RATIO, - qkv_bias=config.MODEL.SWIN_MOE.QKV_BIAS, - qk_scale=config.MODEL.SWIN_MOE.QK_SCALE, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN_MOE.APE, - patch_norm=config.MODEL.SWIN_MOE.PATCH_NORM, - mlp_fc2_bias=config.MODEL.SWIN_MOE.MLP_FC2_BIAS, - init_std=config.MODEL.SWIN_MOE.INIT_STD, - use_checkpoint=config.TRAIN.USE_CHECKPOINT, - pretrained_window_sizes=config.MODEL.SWIN_MOE.PRETRAINED_WINDOW_SIZES, - moe_blocks=config.MODEL.SWIN_MOE.MOE_BLOCKS, - num_local_experts=config.MODEL.SWIN_MOE.NUM_LOCAL_EXPERTS, - top_value=config.MODEL.SWIN_MOE.TOP_VALUE, - capacity_factor=config.MODEL.SWIN_MOE.CAPACITY_FACTOR, - cosine_router=config.MODEL.SWIN_MOE.COSINE_ROUTER, - normalize_gate=config.MODEL.SWIN_MOE.NORMALIZE_GATE, - use_bpr=config.MODEL.SWIN_MOE.USE_BPR, - is_gshard_loss=config.MODEL.SWIN_MOE.IS_GSHARD_LOSS, - gate_noise=config.MODEL.SWIN_MOE.GATE_NOISE, - cosine_router_dim=config.MODEL.SWIN_MOE.COSINE_ROUTER_DIM, - cosine_router_init_t=config.MODEL.SWIN_MOE.COSINE_ROUTER_INIT_T, - moe_drop=config.MODEL.SWIN_MOE.MOE_DROP, - aux_loss_weight=config.MODEL.SWIN_MOE.AUX_LOSS_WEIGHT) - elif model_type == 'swin_mlp': - model = SwinMLP(img_size=config.DATA.IMG_SIZE, - patch_size=config.MODEL.SWIN_MLP.PATCH_SIZE, - in_chans=config.MODEL.SWIN_MLP.IN_CHANS, - num_classes=config.MODEL.NUM_CLASSES, - embed_dim=config.MODEL.SWIN_MLP.EMBED_DIM, - depths=config.MODEL.SWIN_MLP.DEPTHS, - num_heads=config.MODEL.SWIN_MLP.NUM_HEADS, - window_size=config.MODEL.SWIN_MLP.WINDOW_SIZE, - mlp_ratio=config.MODEL.SWIN_MLP.MLP_RATIO, - drop_rate=config.MODEL.DROP_RATE, - drop_path_rate=config.MODEL.DROP_PATH_RATE, - ape=config.MODEL.SWIN_MLP.APE, - patch_norm=config.MODEL.SWIN_MLP.PATCH_NORM, - use_checkpoint=config.TRAIN.USE_CHECKPOINT) - else: - raise NotImplementedError(f"Unkown model: {model_type}") - - return model diff --git a/cv/classification/swin_transformer/pytorch/models/swin_mlp.py b/cv/classification/swin_transformer/pytorch/models/swin_mlp.py deleted file mode 100644 index 115c43cd1..000000000 --- a/cv/classification/swin_transformer/pytorch/models/swin_mlp.py +++ /dev/null @@ -1,468 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ - - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 - - -class SwinMLPBlock(nn.Module): - r""" Swin MLP Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - drop (float, optional): Dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: nn.GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., drop=0., drop_path=0., - act_layer=nn.GELU, norm_layer=nn.LayerNorm): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.padding = [self.window_size - self.shift_size, self.shift_size, - self.window_size - self.shift_size, self.shift_size] # P_l,P_r,P_t,P_b - - self.norm1 = norm_layer(dim) - # use group convolution to implement multi-head MLP - self.spatial_mlp = nn.Conv1d(self.num_heads * self.window_size ** 2, - self.num_heads * self.window_size ** 2, - kernel_size=1, - groups=self.num_heads) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = self.norm1(x) - x = x.view(B, H, W, C) - - # shift - if self.shift_size > 0: - P_l, P_r, P_t, P_b = self.padding - shifted_x = F.pad(x, [0, 0, P_l, P_r, P_t, P_b], "constant", 0) - else: - shifted_x = x - _, _H, _W, _ = shifted_x.shape - - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C - - # Window/Shifted-Window Spatial MLP - x_windows_heads = x_windows.view(-1, self.window_size * self.window_size, self.num_heads, C // self.num_heads) - x_windows_heads = x_windows_heads.transpose(1, 2) # nW*B, nH, window_size*window_size, C//nH - x_windows_heads = x_windows_heads.reshape(-1, self.num_heads * self.window_size * self.window_size, - C // self.num_heads) - spatial_mlp_windows = self.spatial_mlp(x_windows_heads) # nW*B, nH*window_size*window_size, C//nH - spatial_mlp_windows = spatial_mlp_windows.view(-1, self.num_heads, self.window_size * self.window_size, - C // self.num_heads).transpose(1, 2) - spatial_mlp_windows = spatial_mlp_windows.reshape(-1, self.window_size * self.window_size, C) - - # merge windows - spatial_mlp_windows = spatial_mlp_windows.reshape(-1, self.window_size, self.window_size, C) - shifted_x = window_reverse(spatial_mlp_windows, self.window_size, _H, _W) # B H' W' C - - # reverse shift - if self.shift_size > 0: - P_l, P_r, P_t, P_b = self.padding - x = shifted_x[:, P_t:-P_b, P_l:-P_r, :].contiguous() - else: - x = shifted_x - x = x.view(B, H * W, C) - - # FFN - x = shortcut + self.drop_path(x) - x = x + self.drop_path(self.mlp(self.norm2(x))) - - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - - # Window/Shifted-Window Spatial MLP - if self.shift_size > 0: - nW = (H / self.window_size + 1) * (W / self.window_size + 1) - else: - nW = H * W / self.window_size / self.window_size - flops += nW * self.dim * (self.window_size * self.window_size) * (self.window_size * self.window_size) - # mlp - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(4 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.norm(x) - x = self.reduction(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = H * W * self.dim - flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin MLP layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - drop (float, optional): Dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., drop=0., drop_path=0., - norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinMLPBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - drop=drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - for blk in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(blk, x) - else: - x = blk(x) - if self.downsample is not None: - x = self.downsample(x) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinMLP(nn.Module): - r""" Swin MLP - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin MLP layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - drop_rate (float): Dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - use_checkpoint=False, **kwargs): - super().__init__() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=.02) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - drop=drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - use_checkpoint=use_checkpoint) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, (nn.Linear, nn.Conv1d)): - trunc_normal_(m.weight, std=.02) - if m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {'relative_position_bias_table'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - - for layer in self.layers: - x = layer(x) - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x - - def forward(self, x): - x = self.forward_features(x) - x = self.head(x) - return x - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops diff --git a/cv/classification/swin_transformer/pytorch/models/swin_transformer.py b/cv/classification/swin_transformer/pytorch/models/swin_transformer.py deleted file mode 100644 index dde06bc5b..000000000 --- a/cv/classification/swin_transformer/pytorch/models/swin_transformer.py +++ /dev/null @@ -1,614 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ - -try: - import os, sys - - kernel_path = os.path.abspath(os.path.join('..')) - sys.path.append(kernel_path) - from kernels.window_process.window_process import WindowProcess, WindowProcessReverse - -except: - WindowProcess = None - WindowProcessReverse = None - print("[Warning] Fused window process have not been installed. Please refer to get_started.md for installation.") - - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 - - -class WindowAttention(nn.Module): - r""" Window based multi-head self attention (W-MSA) module with relative position bias. - It supports both of shifted and non-shifted window. - - Args: - dim (int): Number of input channels. - window_size (tuple[int]): The height and width of the window. - num_heads (int): Number of attention heads. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set - attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 - proj_drop (float, optional): Dropout ratio of output. Default: 0.0 - """ - - def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0.): - - super().__init__() - self.dim = dim - self.window_size = window_size # Wh, Ww - self.num_heads = num_heads - head_dim = dim // num_heads - self.scale = qk_scale or head_dim ** -0.5 - - # define a parameter table of relative position bias - self.relative_position_bias_table = nn.Parameter( - torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1), num_heads)) # 2*Wh-1 * 2*Ww-1, nH - - # get pair-wise relative position index for each token inside the window - coords_h = torch.arange(self.window_size[0]) - coords_w = torch.arange(self.window_size[1]) - coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww - coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += self.window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 - relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - self.register_buffer("relative_position_index", relative_position_index) - - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) - self.attn_drop = nn.Dropout(attn_drop) - self.proj = nn.Linear(dim, dim) - self.proj_drop = nn.Dropout(proj_drop) - - trunc_normal_(self.relative_position_bias_table, std=.02) - self.softmax = nn.Softmax(dim=-1) - - def forward(self, x, mask=None): - """ - Args: - x: input features with shape of (num_windows*B, N, C) - mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None - """ - B_, N, C = x.shape - qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) - q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) - - q = q * self.scale - attn = (q @ k.transpose(-2, -1)) - - relative_position_bias = self.relative_position_bias_table[self.relative_position_index.view(-1)].view( - self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH - relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww - attn = attn + relative_position_bias.unsqueeze(0) - - 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) - else: - attn = self.softmax(attn) - - attn = self.attn_drop(attn) - - x = (attn @ v).transpose(1, 2).reshape(B_, N, C) - x = self.proj(x) - x = self.proj_drop(x) - return x - - def extra_repr(self) -> str: - return f'dim={self.dim}, window_size={self.window_size}, num_heads={self.num_heads}' - - def flops(self, N): - # calculate flops for 1 window with token length of N - flops = 0 - # qkv = self.qkv(x) - flops += N * self.dim * 3 * self.dim - # attn = (q @ k.transpose(-2, -1)) - flops += self.num_heads * N * (self.dim // self.num_heads) * N - # x = (attn @ v) - flops += self.num_heads * N * N * (self.dim // self.num_heads) - # x = self.proj(x) - flops += N * self.dim * self.dim - return flops - - -class SwinTransformerBlock(nn.Module): - r""" Swin Transformer Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: nn.GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - fused_window_process (bool, optional): If True, use one kernel to fused window shift & window partition for acceleration, similar for the reversed part. Default: False - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0., - act_layer=nn.GELU, norm_layer=nn.LayerNorm, - fused_window_process=False): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.norm1 = norm_layer(dim) - self.attn = WindowAttention( - dim, window_size=to_2tuple(self.window_size), num_heads=num_heads, - qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) - - if self.shift_size > 0: - # calculate attention mask for SW-MSA - H, W = self.input_resolution - img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1 - 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 - - mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1 - 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: - attn_mask = None - - self.register_buffer("attn_mask", attn_mask) - self.fused_window_process = fused_window_process - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = self.norm1(x) - x = x.view(B, H, W, C) - - # cyclic shift - if self.shift_size > 0: - if not self.fused_window_process: - shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - else: - x_windows = WindowProcess.apply(x, B, H, W, C, -self.shift_size, self.window_size) - else: - shifted_x = x - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - - x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C - - # W-MSA/SW-MSA - attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C - - # merge windows - attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) - - # reverse cyclic shift - if self.shift_size > 0: - if not self.fused_window_process: - shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C - x = torch.roll(shifted_x, shifts=(self.shift_size, self.shift_size), dims=(1, 2)) - else: - x = WindowProcessReverse.apply(attn_windows, B, H, W, C, self.shift_size, self.window_size) - else: - shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C - x = shifted_x - x = x.view(B, H * W, C) - x = shortcut + self.drop_path(x) - - # FFN - x = x + self.drop_path(self.mlp(self.norm2(x))) - - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - # W-MSA/SW-MSA - nW = H * W / self.window_size / self.window_size - flops += nW * self.attn.flops(self.window_size * self.window_size) - # mlp - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(4 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.norm(x) - x = self.reduction(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = H * W * self.dim - flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin Transformer layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - fused_window_process (bool, optional): If True, use one kernel to fused window shift & window partition for acceleration, similar for the reversed part. Default: False - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., - drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False, - fused_window_process=False): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinTransformerBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop, attn_drop=attn_drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer, - fused_window_process=fused_window_process) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - for blk in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(blk, x) - else: - x = blk(x) - if self.downsample is not None: - x = self.downsample(x) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinTransformer(nn.Module): - r""" Swin Transformer - A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - - https://arxiv.org/pdf/2103.14030 - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin Transformer layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None - drop_rate (float): Dropout rate. Default: 0 - attn_drop_rate (float): Attention dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - fused_window_process (bool, optional): If True, use one kernel to fused window shift & window partition for acceleration, similar for the reversed part. Default: False - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None, - drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - use_checkpoint=False, fused_window_process=False, **kwargs): - super().__init__() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=.02) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop_rate, attn_drop=attn_drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - use_checkpoint=use_checkpoint, - fused_window_process=fused_window_process) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {'relative_position_bias_table'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - - for layer in self.layers: - x = layer(x) - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x - - def forward(self, x): - x = self.forward_features(x) - x = self.head(x) - return x - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops diff --git a/cv/classification/swin_transformer/pytorch/models/swin_transformer_moe.py b/cv/classification/swin_transformer/pytorch/models/swin_transformer_moe.py deleted file mode 100644 index e9f26d435..000000000 --- a/cv/classification/swin_transformer/pytorch/models/swin_transformer_moe.py +++ /dev/null @@ -1,824 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer MoE -# Copyright (c) 2022 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.distributed as dist -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ -import numpy as np - -try: - from tutel import moe as tutel_moe -except: - tutel_moe = None - print("Tutel has not been installed. To use Swin-MoE, please install Tutel; otherwise, just ignore this.") - - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0., - mlp_fc2_bias=True): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features, bias=mlp_fc2_bias) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -class MoEMlp(nn.Module): - def __init__(self, in_features, hidden_features, num_local_experts, top_value, capacity_factor=1.25, - cosine_router=False, normalize_gate=False, use_bpr=True, is_gshard_loss=True, - gate_noise=1.0, cosine_router_dim=256, cosine_router_init_t=0.5, moe_drop=0.0, init_std=0.02, - mlp_fc2_bias=True): - super().__init__() - - self.in_features = in_features - self.hidden_features = hidden_features - self.num_local_experts = num_local_experts - self.top_value = top_value - self.capacity_factor = capacity_factor - self.cosine_router = cosine_router - self.normalize_gate = normalize_gate - self.use_bpr = use_bpr - self.init_std = init_std - self.mlp_fc2_bias = mlp_fc2_bias - - self.dist_rank = dist.get_rank() - - self._dropout = nn.Dropout(p=moe_drop) - - _gate_type = {'type': 'cosine_top' if cosine_router else 'top', - 'k': top_value, 'capacity_factor': capacity_factor, - 'gate_noise': gate_noise, 'fp32_gate': True} - if cosine_router: - _gate_type['proj_dim'] = cosine_router_dim - _gate_type['init_t'] = cosine_router_init_t - self._moe_layer = tutel_moe.moe_layer( - gate_type=_gate_type, - model_dim=in_features, - experts={'type': 'ffn', 'count_per_node': num_local_experts, 'hidden_size_per_expert': hidden_features, - 'activation_fn': lambda x: self._dropout(F.gelu(x))}, - scan_expert_func=lambda name, param: setattr(param, 'skip_allreduce', True), - seeds=(1, self.dist_rank + 1, self.dist_rank + 1), - batch_prioritized_routing=use_bpr, - normalize_gate=normalize_gate, - is_gshard_loss=is_gshard_loss, - - ) - if not self.mlp_fc2_bias: - self._moe_layer.experts.batched_fc2_bias.requires_grad = False - - def forward(self, x): - x = self._moe_layer(x) - return x, x.l_aux - - def extra_repr(self) -> str: - return f'[Statistics-{self.dist_rank}] param count for MoE, ' \ - f'in_features = {self.in_features}, hidden_features = {self.hidden_features}, ' \ - f'num_local_experts = {self.num_local_experts}, top_value = {self.top_value}, ' \ - f'cosine_router={self.cosine_router} normalize_gate={self.normalize_gate}, use_bpr = {self.use_bpr}' - - def _init_weights(self): - if hasattr(self._moe_layer, "experts"): - trunc_normal_(self._moe_layer.experts.batched_fc1_w, std=self.init_std) - trunc_normal_(self._moe_layer.experts.batched_fc2_w, std=self.init_std) - nn.init.constant_(self._moe_layer.experts.batched_fc1_bias, 0) - nn.init.constant_(self._moe_layer.experts.batched_fc2_bias, 0) - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 - - -class WindowAttention(nn.Module): - r""" Window based multi-head self attention (W-MSA) module with relative position bias. - It supports both of shifted and non-shifted window. - - Args: - dim (int): Number of input channels. - window_size (tuple[int]): The height and width of the window. - num_heads (int): Number of attention heads. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set - attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 - proj_drop (float, optional): Dropout ratio of output. Default: 0.0 - pretrained_window_size (tuple[int]): The height and width of the window in pre-training. - """ - - def __init__(self, dim, window_size, num_heads, qkv_bias=True, qk_scale=None, attn_drop=0., proj_drop=0., - pretrained_window_size=[0, 0]): - - super().__init__() - self.dim = dim - self.window_size = window_size # Wh, Ww - self.pretrained_window_size = pretrained_window_size - self.num_heads = num_heads - - head_dim = dim // num_heads - self.scale = qk_scale or head_dim ** -0.5 - - # mlp to generate continuous relative position bias - self.cpb_mlp = nn.Sequential(nn.Linear(2, 512, bias=True), - nn.ReLU(inplace=True), - nn.Linear(512, num_heads, bias=False)) - - # get relative_coords_table - relative_coords_h = torch.arange(-(self.window_size[0] - 1), self.window_size[0], dtype=torch.float32) - relative_coords_w = torch.arange(-(self.window_size[1] - 1), self.window_size[1], dtype=torch.float32) - relative_coords_table = torch.stack( - torch.meshgrid([relative_coords_h, - relative_coords_w])).permute(1, 2, 0).contiguous().unsqueeze(0) # 1, 2*Wh-1, 2*Ww-1, 2 - if pretrained_window_size[0] > 0: - relative_coords_table[:, :, :, 0] /= (pretrained_window_size[0] - 1) - relative_coords_table[:, :, :, 1] /= (pretrained_window_size[1] - 1) - else: - relative_coords_table[:, :, :, 0] /= (self.window_size[0] - 1) - relative_coords_table[:, :, :, 1] /= (self.window_size[1] - 1) - relative_coords_table *= 8 # normalize to -8, 8 - relative_coords_table = torch.sign(relative_coords_table) * torch.log2( - torch.abs(relative_coords_table) + 1.0) / np.log2(8) - - self.register_buffer("relative_coords_table", relative_coords_table) - - # get pair-wise relative position index for each token inside the window - coords_h = torch.arange(self.window_size[0]) - coords_w = torch.arange(self.window_size[1]) - coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww - coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += self.window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 - relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - self.register_buffer("relative_position_index", relative_position_index) - - self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias) - self.attn_drop = nn.Dropout(attn_drop) - self.proj = nn.Linear(dim, dim) - self.proj_drop = nn.Dropout(proj_drop) - self.softmax = nn.Softmax(dim=-1) - - def forward(self, x, mask=None): - """ - Args: - x: input features with shape of (num_windows*B, N, C) - mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None - """ - B_, N, C = x.shape - qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4) - q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) - - q = q * self.scale - attn = (q @ k.transpose(-2, -1)) - - relative_position_bias_table = self.cpb_mlp(self.relative_coords_table).view(-1, self.num_heads) - relative_position_bias = relative_position_bias_table[self.relative_position_index.view(-1)].view( - self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH - relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww - attn = attn + relative_position_bias.unsqueeze(0) - - 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) - else: - attn = self.softmax(attn) - - attn = self.attn_drop(attn) - - x = (attn @ v).transpose(1, 2).reshape(B_, N, C) - x = self.proj(x) - x = self.proj_drop(x) - return x - - def extra_repr(self) -> str: - return f'dim={self.dim}, window_size={self.window_size}, ' \ - f'pretrained_window_size={self.pretrained_window_size}, num_heads={self.num_heads}' - - def flops(self, N): - # calculate flops for 1 window with token length of N - flops = 0 - # qkv = self.qkv(x) - flops += N * self.dim * 3 * self.dim - # attn = (q @ k.transpose(-2, -1)) - flops += self.num_heads * N * (self.dim // self.num_heads) * N - # x = (attn @ v) - flops += self.num_heads * N * N * (self.dim // self.num_heads) - # x = self.proj(x) - flops += N * self.dim * self.dim - return flops - - -class SwinTransformerBlock(nn.Module): - r""" Swin Transformer Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: nn.GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True - init_std: Initialization std. Default: 0.02 - pretrained_window_size (int): Window size in pre-training. - is_moe (bool): If True, this block is a MoE block. - num_local_experts (int): number of local experts in each device (GPU). Default: 1 - top_value (int): the value of k in top-k gating. Default: 1 - capacity_factor (float): the capacity factor in MoE. Default: 1.25 - cosine_router (bool): Whether to use cosine router. Default: False - normalize_gate (bool): Whether to normalize the gating score in top-k gating. Default: False - use_bpr (bool): Whether to use batch-prioritized-routing. Default: True - is_gshard_loss (bool): If True, use Gshard balance loss. - If False, use the load loss and importance loss in "arXiv:1701.06538". Default: False - gate_noise (float): the noise ratio in top-k gating. Default: 1.0 - cosine_router_dim (int): Projection dimension in cosine router. - cosine_router_init_t (float): Initialization temperature in cosine router. - moe_drop (float): Dropout rate in MoE. Default: 0.0 - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., drop_path=0., - act_layer=nn.GELU, norm_layer=nn.LayerNorm, mlp_fc2_bias=True, init_std=0.02, pretrained_window_size=0, - is_moe=False, num_local_experts=1, top_value=1, capacity_factor=1.25, cosine_router=False, - normalize_gate=False, use_bpr=True, is_gshard_loss=True, gate_noise=1.0, - cosine_router_dim=256, cosine_router_init_t=0.5, moe_drop=0.0): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - self.is_moe = is_moe - self.capacity_factor = capacity_factor - self.top_value = top_value - - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.norm1 = norm_layer(dim) - self.attn = WindowAttention( - dim, window_size=to_2tuple(self.window_size), num_heads=num_heads, - qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop, - pretrained_window_size=to_2tuple(pretrained_window_size)) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - if self.is_moe: - self.mlp = MoEMlp(in_features=dim, - hidden_features=mlp_hidden_dim, - num_local_experts=num_local_experts, - top_value=top_value, - capacity_factor=capacity_factor, - cosine_router=cosine_router, - normalize_gate=normalize_gate, - use_bpr=use_bpr, - is_gshard_loss=is_gshard_loss, - gate_noise=gate_noise, - cosine_router_dim=cosine_router_dim, - cosine_router_init_t=cosine_router_init_t, - moe_drop=moe_drop, - mlp_fc2_bias=mlp_fc2_bias, - init_std=init_std) - else: - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop, - mlp_fc2_bias=mlp_fc2_bias) - - if self.shift_size > 0: - # calculate attention mask for SW-MSA - H, W = self.input_resolution - img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1 - 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 - - mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1 - 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: - attn_mask = None - - self.register_buffer("attn_mask", attn_mask) - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = self.norm1(x) - x = x.view(B, H, W, C) - - # cyclic shift - if self.shift_size > 0: - shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) - else: - shifted_x = x - - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C - - # W-MSA/SW-MSA - attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C - - # merge windows - attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) - shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C - - # 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 - x = x.view(B, H * W, C) - x = shortcut + self.drop_path(x) - - # FFN - shortcut = x - x = self.norm2(x) - if self.is_moe: - x, l_aux = self.mlp(x) - x = shortcut + self.drop_path(x) - return x, l_aux - else: - x = shortcut + self.drop_path(self.mlp(x)) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - # W-MSA/SW-MSA - nW = H * W / self.window_size / self.window_size - flops += nW * self.attn.flops(self.window_size * self.window_size) - # mlp - if self.is_moe: - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio * self.capacity_factor * self.top_value - else: - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(4 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.norm(x) - x = self.reduction(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = H * W * self.dim - flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin Transformer layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 if set. - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True - init_std: Initialization std. Default: 0.02 - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - pretrained_window_size (int): Local window size in pre-training. - moe_blocks (tuple(int)): The index of each MoE block. - num_local_experts (int): number of local experts in each device (GPU). Default: 1 - top_value (int): the value of k in top-k gating. Default: 1 - capacity_factor (float): the capacity factor in MoE. Default: 1.25 - cosine_router (bool): Whether to use cosine router Default: False - normalize_gate (bool): Whether to normalize the gating score in top-k gating. Default: False - use_bpr (bool): Whether to use batch-prioritized-routing. Default: True - is_gshard_loss (bool): If True, use Gshard balance loss. - If False, use the load loss and importance loss in "arXiv:1701.06538". Default: False - gate_noise (float): the noise ratio in top-k gating. Default: 1.0 - cosine_router_dim (int): Projection dimension in cosine router. - cosine_router_init_t (float): Initialization temperature in cosine router. - moe_drop (float): Dropout rate in MoE. Default: 0.0 - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., qkv_bias=True, qk_scale=None, drop=0., attn_drop=0., - drop_path=0., norm_layer=nn.LayerNorm, downsample=None, - mlp_fc2_bias=True, init_std=0.02, use_checkpoint=False, pretrained_window_size=0, - moe_block=[-1], num_local_experts=1, top_value=1, capacity_factor=1.25, cosine_router=False, - normalize_gate=False, use_bpr=True, is_gshard_loss=True, - cosine_router_dim=256, cosine_router_init_t=0.5, gate_noise=1.0, moe_drop=0.0): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinTransformerBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop, attn_drop=attn_drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer, - mlp_fc2_bias=mlp_fc2_bias, - init_std=init_std, - pretrained_window_size=pretrained_window_size, - - is_moe=True if i in moe_block else False, - num_local_experts=num_local_experts, - top_value=top_value, - capacity_factor=capacity_factor, - cosine_router=cosine_router, - normalize_gate=normalize_gate, - use_bpr=use_bpr, - is_gshard_loss=is_gshard_loss, - gate_noise=gate_noise, - cosine_router_dim=cosine_router_dim, - cosine_router_init_t=cosine_router_init_t, - moe_drop=moe_drop) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - l_aux = 0.0 - for blk in self.blocks: - if self.use_checkpoint: - out = checkpoint.checkpoint(blk, x) - else: - out = blk(x) - if isinstance(out, tuple): - x = out[0] - cur_l_aux = out[1] - l_aux = cur_l_aux + l_aux - else: - x = out - - if self.downsample is not None: - x = self.downsample(x) - return x, l_aux - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinTransformerMoE(nn.Module): - r""" Swin Transformer - A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - - https://arxiv.org/pdf/2103.14030 - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin Transformer layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True - qk_scale (float): Override default qk scale of head_dim ** -0.5 if set. Default: None - drop_rate (float): Dropout rate. Default: 0 - attn_drop_rate (float): Attention dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True - init_std: Initialization std. Default: 0.02 - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - pretrained_window_sizes (tuple(int)): Pretrained window sizes of each layer. - moe_blocks (tuple(tuple(int))): The index of each MoE block in each layer. - num_local_experts (int): number of local experts in each device (GPU). Default: 1 - top_value (int): the value of k in top-k gating. Default: 1 - capacity_factor (float): the capacity factor in MoE. Default: 1.25 - cosine_router (bool): Whether to use cosine router Default: False - normalize_gate (bool): Whether to normalize the gating score in top-k gating. Default: False - use_bpr (bool): Whether to use batch-prioritized-routing. Default: True - is_gshard_loss (bool): If True, use Gshard balance loss. - If False, use the load loss and importance loss in "arXiv:1701.06538". Default: False - gate_noise (float): the noise ratio in top-k gating. Default: 1.0 - cosine_router_dim (int): Projection dimension in cosine router. - cosine_router_init_t (float): Initialization temperature in cosine router. - moe_drop (float): Dropout rate in MoE. Default: 0.0 - aux_loss_weight (float): auxiliary loss weight. Default: 0.1 - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., qkv_bias=True, qk_scale=None, - drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - mlp_fc2_bias=True, init_std=0.02, use_checkpoint=False, pretrained_window_sizes=[0, 0, 0, 0], - moe_blocks=[[-1], [-1], [-1], [-1]], num_local_experts=1, top_value=1, capacity_factor=1.25, - cosine_router=False, normalize_gate=False, use_bpr=True, is_gshard_loss=True, gate_noise=1.0, - cosine_router_dim=256, cosine_router_init_t=0.5, moe_drop=0.0, aux_loss_weight=0.01, **kwargs): - super().__init__() - self._ddp_params_and_buffers_to_ignore = list() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - self.init_std = init_std - self.aux_loss_weight = aux_loss_weight - self.num_local_experts = num_local_experts - self.global_experts = num_local_experts * dist.get_world_size() if num_local_experts > 0 \ - else dist.get_world_size() // (-num_local_experts) - self.sharded_count = (1.0 / num_local_experts) if num_local_experts > 0 else (-num_local_experts) - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=self.init_std) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - qkv_bias=qkv_bias, qk_scale=qk_scale, - drop=drop_rate, attn_drop=attn_drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - mlp_fc2_bias=mlp_fc2_bias, - init_std=init_std, - use_checkpoint=use_checkpoint, - pretrained_window_size=pretrained_window_sizes[i_layer], - - moe_block=moe_blocks[i_layer], - num_local_experts=num_local_experts, - top_value=top_value, - capacity_factor=capacity_factor, - cosine_router=cosine_router, - normalize_gate=normalize_gate, - use_bpr=use_bpr, - is_gshard_loss=is_gshard_loss, - gate_noise=gate_noise, - cosine_router_dim=cosine_router_dim, - cosine_router_init_t=cosine_router_init_t, - moe_drop=moe_drop) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=self.init_std) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - elif isinstance(m, MoEMlp): - m._init_weights() - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {"cpb_mlp", 'relative_position_bias_table', 'fc1_bias', 'fc2_bias', - 'temperature', 'cosine_projector', 'sim_matrix'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - l_aux = 0.0 - for layer in self.layers: - x, cur_l_aux = layer(x) - l_aux = cur_l_aux + l_aux - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x, l_aux - - def forward(self, x): - x, l_aux = self.forward_features(x) - x = self.head(x) - return x, l_aux * self.aux_loss_weight - - def add_param_to_skip_allreduce(self, param_name): - self._ddp_params_and_buffers_to_ignore.append(param_name) - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops diff --git a/cv/classification/swin_transformer/pytorch/models/swin_transformer_v2.py b/cv/classification/swin_transformer/pytorch/models/swin_transformer_v2.py deleted file mode 100644 index a429d0a2c..000000000 --- a/cv/classification/swin_transformer/pytorch/models/swin_transformer_v2.py +++ /dev/null @@ -1,633 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer V2 -# Copyright (c) 2022 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import torch -import torch.nn as nn -import torch.nn.functional as F -import torch.utils.checkpoint as checkpoint -from timm.models.layers import DropPath, to_2tuple, trunc_normal_ -import numpy as np - - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): - super().__init__() - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.fc1 = nn.Linear(in_features, hidden_features) - self.act = act_layer() - self.fc2 = nn.Linear(hidden_features, out_features) - self.drop = nn.Dropout(drop) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -def window_partition(x, window_size): - """ - Args: - x: (B, H, W, C) - window_size (int): window size - - Returns: - windows: (num_windows*B, window_size, window_size, C) - """ - B, H, W, C = x.shape - 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().view(-1, window_size, window_size, C) - return windows - - -def window_reverse(windows, window_size, H, W): - """ - Args: - windows: (num_windows*B, window_size, window_size, C) - window_size (int): Window size - H (int): Height of image - W (int): Width of image - - Returns: - x: (B, H, W, C) - """ - 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 - - -class WindowAttention(nn.Module): - r""" Window based multi-head self attention (W-MSA) module with relative position bias. - It supports both of shifted and non-shifted window. - - Args: - dim (int): Number of input channels. - window_size (tuple[int]): The height and width of the window. - num_heads (int): Number of attention heads. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - attn_drop (float, optional): Dropout ratio of attention weight. Default: 0.0 - proj_drop (float, optional): Dropout ratio of output. Default: 0.0 - pretrained_window_size (tuple[int]): The height and width of the window in pre-training. - """ - - def __init__(self, dim, window_size, num_heads, qkv_bias=True, attn_drop=0., proj_drop=0., - pretrained_window_size=[0, 0]): - - super().__init__() - self.dim = dim - self.window_size = window_size # Wh, Ww - self.pretrained_window_size = pretrained_window_size - self.num_heads = num_heads - - self.logit_scale = nn.Parameter(torch.log(10 * torch.ones((num_heads, 1, 1))), requires_grad=True) - - # mlp to generate continuous relative position bias - self.cpb_mlp = nn.Sequential(nn.Linear(2, 512, bias=True), - nn.ReLU(inplace=True), - nn.Linear(512, num_heads, bias=False)) - - # get relative_coords_table - relative_coords_h = torch.arange(-(self.window_size[0] - 1), self.window_size[0], dtype=torch.float32) - relative_coords_w = torch.arange(-(self.window_size[1] - 1), self.window_size[1], dtype=torch.float32) - relative_coords_table = torch.stack( - torch.meshgrid([relative_coords_h, - relative_coords_w])).permute(1, 2, 0).contiguous().unsqueeze(0) # 1, 2*Wh-1, 2*Ww-1, 2 - if pretrained_window_size[0] > 0: - relative_coords_table[:, :, :, 0] /= (pretrained_window_size[0] - 1) - relative_coords_table[:, :, :, 1] /= (pretrained_window_size[1] - 1) - else: - relative_coords_table[:, :, :, 0] /= (self.window_size[0] - 1) - relative_coords_table[:, :, :, 1] /= (self.window_size[1] - 1) - relative_coords_table *= 8 # normalize to -8, 8 - relative_coords_table = torch.sign(relative_coords_table) * torch.log2( - torch.abs(relative_coords_table) + 1.0) / np.log2(8) - - self.register_buffer("relative_coords_table", relative_coords_table) - - # get pair-wise relative position index for each token inside the window - coords_h = torch.arange(self.window_size[0]) - coords_w = torch.arange(self.window_size[1]) - coords = torch.stack(torch.meshgrid([coords_h, coords_w])) # 2, Wh, Ww - coords_flatten = torch.flatten(coords, 1) # 2, Wh*Ww - relative_coords = coords_flatten[:, :, None] - coords_flatten[:, None, :] # 2, Wh*Ww, Wh*Ww - relative_coords = relative_coords.permute(1, 2, 0).contiguous() # Wh*Ww, Wh*Ww, 2 - relative_coords[:, :, 0] += self.window_size[0] - 1 # shift to start from 0 - relative_coords[:, :, 1] += self.window_size[1] - 1 - relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1 - relative_position_index = relative_coords.sum(-1) # Wh*Ww, Wh*Ww - self.register_buffer("relative_position_index", relative_position_index) - - self.qkv = nn.Linear(dim, dim * 3, bias=False) - if qkv_bias: - self.q_bias = nn.Parameter(torch.zeros(dim)) - self.v_bias = nn.Parameter(torch.zeros(dim)) - else: - self.q_bias = None - self.v_bias = None - self.attn_drop = nn.Dropout(attn_drop) - self.proj = nn.Linear(dim, dim) - self.proj_drop = nn.Dropout(proj_drop) - self.softmax = nn.Softmax(dim=-1) - - def forward(self, x, mask=None): - """ - Args: - x: input features with shape of (num_windows*B, N, C) - mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None - """ - B_, N, C = x.shape - qkv_bias = None - if self.q_bias is not None: - qkv_bias = torch.cat((self.q_bias, torch.zeros_like(self.v_bias, requires_grad=False), self.v_bias)) - qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias) - qkv = qkv.reshape(B_, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4) - q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple) - - # cosine attention - attn = (F.normalize(q, dim=-1) @ F.normalize(k, dim=-1).transpose(-2, -1)) - logit_scale = torch.clamp(self.logit_scale, max=torch.log(torch.tensor(1. / 0.01))).exp() - attn = attn * logit_scale - - relative_position_bias_table = self.cpb_mlp(self.relative_coords_table).view(-1, self.num_heads) - relative_position_bias = relative_position_bias_table[self.relative_position_index.view(-1)].view( - self.window_size[0] * self.window_size[1], self.window_size[0] * self.window_size[1], -1) # Wh*Ww,Wh*Ww,nH - relative_position_bias = relative_position_bias.permute(2, 0, 1).contiguous() # nH, Wh*Ww, Wh*Ww - relative_position_bias = 16 * torch.sigmoid(relative_position_bias) - attn = attn + relative_position_bias.unsqueeze(0) - - 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) - else: - attn = self.softmax(attn) - - attn = self.attn_drop(attn) - - x = (attn @ v).transpose(1, 2).reshape(B_, N, C) - x = self.proj(x) - x = self.proj_drop(x) - return x - - def extra_repr(self) -> str: - return f'dim={self.dim}, window_size={self.window_size}, ' \ - f'pretrained_window_size={self.pretrained_window_size}, num_heads={self.num_heads}' - - def flops(self, N): - # calculate flops for 1 window with token length of N - flops = 0 - # qkv = self.qkv(x) - flops += N * self.dim * 3 * self.dim - # attn = (q @ k.transpose(-2, -1)) - flops += self.num_heads * N * (self.dim // self.num_heads) * N - # x = (attn @ v) - flops += self.num_heads * N * N * (self.dim // self.num_heads) - # x = self.proj(x) - flops += N * self.dim * self.dim - return flops - - -class SwinTransformerBlock(nn.Module): - r""" Swin Transformer Block. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resulotion. - num_heads (int): Number of attention heads. - window_size (int): Window size. - shift_size (int): Shift size for SW-MSA. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float, optional): Stochastic depth rate. Default: 0.0 - act_layer (nn.Module, optional): Activation layer. Default: nn.GELU - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - pretrained_window_size (int): Window size in pre-training. - """ - - def __init__(self, dim, input_resolution, num_heads, window_size=7, shift_size=0, - mlp_ratio=4., qkv_bias=True, drop=0., attn_drop=0., drop_path=0., - act_layer=nn.GELU, norm_layer=nn.LayerNorm, pretrained_window_size=0): - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.num_heads = num_heads - self.window_size = window_size - self.shift_size = shift_size - self.mlp_ratio = mlp_ratio - if min(self.input_resolution) <= self.window_size: - # if window size is larger than input resolution, we don't partition windows - self.shift_size = 0 - self.window_size = min(self.input_resolution) - assert 0 <= self.shift_size < self.window_size, "shift_size must in 0-window_size" - - self.norm1 = norm_layer(dim) - self.attn = WindowAttention( - dim, window_size=to_2tuple(self.window_size), num_heads=num_heads, - qkv_bias=qkv_bias, attn_drop=attn_drop, proj_drop=drop, - pretrained_window_size=to_2tuple(pretrained_window_size)) - - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop) - - if self.shift_size > 0: - # calculate attention mask for SW-MSA - H, W = self.input_resolution - img_mask = torch.zeros((1, H, W, 1)) # 1 H W 1 - 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 - - mask_windows = window_partition(img_mask, self.window_size) # nW, window_size, window_size, 1 - 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: - attn_mask = None - - self.register_buffer("attn_mask", attn_mask) - - def forward(self, x): - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - - shortcut = x - x = x.view(B, H, W, C) - - # cyclic shift - if self.shift_size > 0: - shifted_x = torch.roll(x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2)) - else: - shifted_x = x - - # partition windows - x_windows = window_partition(shifted_x, self.window_size) # nW*B, window_size, window_size, C - x_windows = x_windows.view(-1, self.window_size * self.window_size, C) # nW*B, window_size*window_size, C - - # W-MSA/SW-MSA - attn_windows = self.attn(x_windows, mask=self.attn_mask) # nW*B, window_size*window_size, C - - # merge windows - attn_windows = attn_windows.view(-1, self.window_size, self.window_size, C) - shifted_x = window_reverse(attn_windows, self.window_size, H, W) # B H' W' C - - # 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 - x = x.view(B, H * W, C) - x = shortcut + self.drop_path(self.norm1(x)) - - # FFN - x = x + self.drop_path(self.norm2(self.mlp(x))) - - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, num_heads={self.num_heads}, " \ - f"window_size={self.window_size}, shift_size={self.shift_size}, mlp_ratio={self.mlp_ratio}" - - def flops(self): - flops = 0 - H, W = self.input_resolution - # norm1 - flops += self.dim * H * W - # W-MSA/SW-MSA - nW = H * W / self.window_size / self.window_size - flops += nW * self.attn.flops(self.window_size * self.window_size) - # mlp - flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio - # norm2 - flops += self.dim * H * W - return flops - - -class PatchMerging(nn.Module): - r""" Patch Merging Layer. - - Args: - input_resolution (tuple[int]): Resolution of input feature. - dim (int): Number of input channels. - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - """ - - def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm): - super().__init__() - self.input_resolution = input_resolution - self.dim = dim - self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False) - self.norm = norm_layer(2 * dim) - - def forward(self, x): - """ - x: B, H*W, C - """ - H, W = self.input_resolution - B, L, C = x.shape - assert L == H * W, "input feature has wrong size" - assert H % 2 == 0 and W % 2 == 0, f"x size ({H}*{W}) are not even." - - x = x.view(B, H, W, C) - - x0 = x[:, 0::2, 0::2, :] # B H/2 W/2 C - x1 = x[:, 1::2, 0::2, :] # B H/2 W/2 C - x2 = x[:, 0::2, 1::2, :] # B H/2 W/2 C - x3 = x[:, 1::2, 1::2, :] # B H/2 W/2 C - x = torch.cat([x0, x1, x2, x3], -1) # B H/2 W/2 4*C - x = x.view(B, -1, 4 * C) # B H/2*W/2 4*C - - x = self.reduction(x) - x = self.norm(x) - - return x - - def extra_repr(self) -> str: - return f"input_resolution={self.input_resolution}, dim={self.dim}" - - def flops(self): - H, W = self.input_resolution - flops = (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim - flops += H * W * self.dim // 2 - return flops - - -class BasicLayer(nn.Module): - """ A basic Swin Transformer layer for one stage. - - Args: - dim (int): Number of input channels. - input_resolution (tuple[int]): Input resolution. - depth (int): Number of blocks. - num_heads (int): Number of attention heads. - window_size (int): Local window size. - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. - qkv_bias (bool, optional): If True, add a learnable bias to query, key, value. Default: True - drop (float, optional): Dropout rate. Default: 0.0 - attn_drop (float, optional): Attention dropout rate. Default: 0.0 - drop_path (float | tuple[float], optional): Stochastic depth rate. Default: 0.0 - norm_layer (nn.Module, optional): Normalization layer. Default: nn.LayerNorm - downsample (nn.Module | None, optional): Downsample layer at the end of the layer. Default: None - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False. - pretrained_window_size (int): Local window size in pre-training. - """ - - def __init__(self, dim, input_resolution, depth, num_heads, window_size, - mlp_ratio=4., qkv_bias=True, drop=0., attn_drop=0., - drop_path=0., norm_layer=nn.LayerNorm, downsample=None, use_checkpoint=False, - pretrained_window_size=0): - - super().__init__() - self.dim = dim - self.input_resolution = input_resolution - self.depth = depth - self.use_checkpoint = use_checkpoint - - # build blocks - self.blocks = nn.ModuleList([ - SwinTransformerBlock(dim=dim, input_resolution=input_resolution, - num_heads=num_heads, window_size=window_size, - shift_size=0 if (i % 2 == 0) else window_size // 2, - mlp_ratio=mlp_ratio, - qkv_bias=qkv_bias, - drop=drop, attn_drop=attn_drop, - drop_path=drop_path[i] if isinstance(drop_path, list) else drop_path, - norm_layer=norm_layer, - pretrained_window_size=pretrained_window_size) - for i in range(depth)]) - - # patch merging layer - if downsample is not None: - self.downsample = downsample(input_resolution, dim=dim, norm_layer=norm_layer) - else: - self.downsample = None - - def forward(self, x): - for blk in self.blocks: - if self.use_checkpoint: - x = checkpoint.checkpoint(blk, x) - else: - x = blk(x) - if self.downsample is not None: - x = self.downsample(x) - return x - - def extra_repr(self) -> str: - return f"dim={self.dim}, input_resolution={self.input_resolution}, depth={self.depth}" - - def flops(self): - flops = 0 - for blk in self.blocks: - flops += blk.flops() - if self.downsample is not None: - flops += self.downsample.flops() - return flops - - def _init_respostnorm(self): - for blk in self.blocks: - nn.init.constant_(blk.norm1.bias, 0) - nn.init.constant_(blk.norm1.weight, 0) - nn.init.constant_(blk.norm2.bias, 0) - nn.init.constant_(blk.norm2.weight, 0) - - -class PatchEmbed(nn.Module): - r""" Image to Patch Embedding - - Args: - img_size (int): Image size. Default: 224. - patch_size (int): Patch token size. Default: 4. - in_chans (int): Number of input image channels. Default: 3. - embed_dim (int): Number of linear projection output channels. Default: 96. - norm_layer (nn.Module, optional): Normalization layer. Default: None - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, embed_dim=96, norm_layer=None): - super().__init__() - img_size = to_2tuple(img_size) - patch_size = to_2tuple(patch_size) - patches_resolution = [img_size[0] // patch_size[0], img_size[1] // patch_size[1]] - self.img_size = img_size - self.patch_size = patch_size - self.patches_resolution = patches_resolution - self.num_patches = patches_resolution[0] * patches_resolution[1] - - self.in_chans = in_chans - self.embed_dim = embed_dim - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size) - if norm_layer is not None: - self.norm = norm_layer(embed_dim) - else: - self.norm = None - - def forward(self, x): - B, C, H, W = x.shape - # FIXME look at relaxing size constraints - assert H == self.img_size[0] and W == self.img_size[1], \ - f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})." - x = self.proj(x).flatten(2).transpose(1, 2) # B Ph*Pw C - if self.norm is not None: - x = self.norm(x) - return x - - def flops(self): - Ho, Wo = self.patches_resolution - flops = Ho * Wo * self.embed_dim * self.in_chans * (self.patch_size[0] * self.patch_size[1]) - if self.norm is not None: - flops += Ho * Wo * self.embed_dim - return flops - - -class SwinTransformerV2(nn.Module): - r""" Swin Transformer - A PyTorch impl of : `Swin Transformer: Hierarchical Vision Transformer using Shifted Windows` - - https://arxiv.org/pdf/2103.14030 - - Args: - img_size (int | tuple(int)): Input image size. Default 224 - patch_size (int | tuple(int)): Patch size. Default: 4 - in_chans (int): Number of input image channels. Default: 3 - num_classes (int): Number of classes for classification head. Default: 1000 - embed_dim (int): Patch embedding dimension. Default: 96 - depths (tuple(int)): Depth of each Swin Transformer layer. - num_heads (tuple(int)): Number of attention heads in different layers. - window_size (int): Window size. Default: 7 - mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4 - qkv_bias (bool): If True, add a learnable bias to query, key, value. Default: True - drop_rate (float): Dropout rate. Default: 0 - attn_drop_rate (float): Attention dropout rate. Default: 0 - drop_path_rate (float): Stochastic depth rate. Default: 0.1 - norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm. - ape (bool): If True, add absolute position embedding to the patch embedding. Default: False - patch_norm (bool): If True, add normalization after patch embedding. Default: True - use_checkpoint (bool): Whether to use checkpointing to save memory. Default: False - pretrained_window_sizes (tuple(int)): Pretrained window sizes of each layer. - """ - - def __init__(self, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dim=96, depths=[2, 2, 6, 2], num_heads=[3, 6, 12, 24], - window_size=7, mlp_ratio=4., qkv_bias=True, - drop_rate=0., attn_drop_rate=0., drop_path_rate=0.1, - norm_layer=nn.LayerNorm, ape=False, patch_norm=True, - use_checkpoint=False, pretrained_window_sizes=[0, 0, 0, 0], **kwargs): - super().__init__() - - self.num_classes = num_classes - self.num_layers = len(depths) - self.embed_dim = embed_dim - self.ape = ape - self.patch_norm = patch_norm - self.num_features = int(embed_dim * 2 ** (self.num_layers - 1)) - self.mlp_ratio = mlp_ratio - - # split image into non-overlapping patches - self.patch_embed = PatchEmbed( - img_size=img_size, patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dim, - norm_layer=norm_layer if self.patch_norm else None) - num_patches = self.patch_embed.num_patches - patches_resolution = self.patch_embed.patches_resolution - self.patches_resolution = patches_resolution - - # absolute position embedding - if self.ape: - self.absolute_pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim)) - trunc_normal_(self.absolute_pos_embed, std=.02) - - self.pos_drop = nn.Dropout(p=drop_rate) - - # stochastic depth - dpr = [x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))] # stochastic depth decay rule - - # build layers - self.layers = nn.ModuleList() - for i_layer in range(self.num_layers): - layer = BasicLayer(dim=int(embed_dim * 2 ** i_layer), - input_resolution=(patches_resolution[0] // (2 ** i_layer), - patches_resolution[1] // (2 ** i_layer)), - depth=depths[i_layer], - num_heads=num_heads[i_layer], - window_size=window_size, - mlp_ratio=self.mlp_ratio, - qkv_bias=qkv_bias, - drop=drop_rate, attn_drop=attn_drop_rate, - drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])], - norm_layer=norm_layer, - downsample=PatchMerging if (i_layer < self.num_layers - 1) else None, - use_checkpoint=use_checkpoint, - pretrained_window_size=pretrained_window_sizes[i_layer]) - self.layers.append(layer) - - self.norm = norm_layer(self.num_features) - self.avgpool = nn.AdaptiveAvgPool1d(1) - self.head = nn.Linear(self.num_features, num_classes) if num_classes > 0 else nn.Identity() - - self.apply(self._init_weights) - for bly in self.layers: - bly._init_respostnorm() - - def _init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - @torch.jit.ignore - def no_weight_decay(self): - return {'absolute_pos_embed'} - - @torch.jit.ignore - def no_weight_decay_keywords(self): - return {"cpb_mlp", "logit_scale", 'relative_position_bias_table'} - - def forward_features(self, x): - x = self.patch_embed(x) - if self.ape: - x = x + self.absolute_pos_embed - x = self.pos_drop(x) - - for layer in self.layers: - x = layer(x) - - x = self.norm(x) # B L C - x = self.avgpool(x.transpose(1, 2)) # B C 1 - x = torch.flatten(x, 1) - return x - - def forward(self, x): - x = self.forward_features(x) - x = self.head(x) - return x - - def flops(self): - flops = 0 - flops += self.patch_embed.flops() - for i, layer in enumerate(self.layers): - flops += layer.flops() - flops += self.num_features * self.patches_resolution[0] * self.patches_resolution[1] // (2 ** self.num_layers) - flops += self.num_features * self.num_classes - return flops diff --git a/cv/classification/swin_transformer/pytorch/optimizer.py b/cv/classification/swin_transformer/pytorch/optimizer.py deleted file mode 100644 index 3c50669a1..000000000 --- a/cv/classification/swin_transformer/pytorch/optimizer.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -from torch import optim as optim - - -def build_optimizer(config, model): - """ - Build optimizer, set weight decay of normalization to 0 by default. - """ - skip = {} - skip_keywords = {} - if hasattr(model, 'no_weight_decay'): - skip = model.no_weight_decay() - if hasattr(model, 'no_weight_decay_keywords'): - skip_keywords = model.no_weight_decay_keywords() - parameters = set_weight_decay(model, skip, skip_keywords) - - opt_lower = config.TRAIN.OPTIMIZER.NAME.lower() - optimizer = None - if opt_lower == 'sgd': - optimizer = optim.SGD(parameters, momentum=config.TRAIN.OPTIMIZER.MOMENTUM, nesterov=True, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - elif opt_lower == 'adamw': - optimizer = optim.AdamW(parameters, eps=config.TRAIN.OPTIMIZER.EPS, betas=config.TRAIN.OPTIMIZER.BETAS, - lr=config.TRAIN.BASE_LR, weight_decay=config.TRAIN.WEIGHT_DECAY) - - return optimizer - - -def set_weight_decay(model, skip_list=(), skip_keywords=()): - has_decay = [] - no_decay = [] - - for name, param in model.named_parameters(): - if not param.requires_grad: - continue # frozen weights - if len(param.shape) == 1 or name.endswith(".bias") or (name in skip_list) or \ - check_keywords_in_name(name, skip_keywords): - no_decay.append(param) - # print(f"{name} has no weight decay") - else: - has_decay.append(param) - return [{'params': has_decay}, - {'params': no_decay, 'weight_decay': 0.}] - - -def check_keywords_in_name(name, keywords=()): - isin = False - for keyword in keywords: - if keyword in name: - isin = True - return isin diff --git a/cv/classification/swin_transformer/pytorch/utils.py b/cv/classification/swin_transformer/pytorch/utils.py deleted file mode 100644 index f71397a33..000000000 --- a/cv/classification/swin_transformer/pytorch/utils.py +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import torch -import torch.distributed as dist -from torch._six import inf - - -def load_checkpoint(config, model, optimizer, lr_scheduler, loss_scaler, logger): - logger.info(f"==============> Resuming form {config.MODEL.RESUME}....................") - if config.MODEL.RESUME.startswith('https'): - checkpoint = torch.hub.load_state_dict_from_url( - config.MODEL.RESUME, map_location='cpu', check_hash=True) - else: - checkpoint = torch.load(config.MODEL.RESUME, map_location='cpu') - msg = model.load_state_dict(checkpoint['model'], strict=False) - logger.info(msg) - max_accuracy = 0.0 - if not config.EVAL_MODE and 'optimizer' in checkpoint and 'lr_scheduler' in checkpoint and 'epoch' in checkpoint: - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['lr_scheduler']) - config.defrost() - config.TRAIN.START_EPOCH = checkpoint['epoch'] + 1 - config.freeze() - if 'scaler' in checkpoint: - loss_scaler.load_state_dict(checkpoint['scaler']) - logger.info(f"=> loaded successfully '{config.MODEL.RESUME}' (epoch {checkpoint['epoch']})") - if 'max_accuracy' in checkpoint: - max_accuracy = checkpoint['max_accuracy'] - - del checkpoint - torch.cuda.empty_cache() - return max_accuracy - - -def load_pretrained(config, model, logger): - logger.info(f"==============> Loading weight {config.MODEL.PRETRAINED} for fine-tuning......") - checkpoint = torch.load(config.MODEL.PRETRAINED, map_location='cpu') - state_dict = checkpoint['model'] - - # delete relative_position_index since we always re-init it - relative_position_index_keys = [k for k in state_dict.keys() if "relative_position_index" in k] - for k in relative_position_index_keys: - del state_dict[k] - - # delete relative_coords_table since we always re-init it - relative_position_index_keys = [k for k in state_dict.keys() if "relative_coords_table" in k] - for k in relative_position_index_keys: - del state_dict[k] - - # delete attn_mask since we always re-init it - attn_mask_keys = [k for k in state_dict.keys() if "attn_mask" in k] - for k in attn_mask_keys: - del state_dict[k] - - # bicubic interpolate relative_position_bias_table if not match - relative_position_bias_table_keys = [k for k in state_dict.keys() if "relative_position_bias_table" in k] - for k in relative_position_bias_table_keys: - relative_position_bias_table_pretrained = state_dict[k] - relative_position_bias_table_current = model.state_dict()[k] - L1, nH1 = relative_position_bias_table_pretrained.size() - L2, nH2 = relative_position_bias_table_current.size() - if nH1 != nH2: - logger.warning(f"Error in loading {k}, passing......") - else: - if L1 != L2: - # bicubic interpolate relative_position_bias_table if not match - S1 = int(L1 ** 0.5) - S2 = int(L2 ** 0.5) - relative_position_bias_table_pretrained_resized = torch.nn.functional.interpolate( - relative_position_bias_table_pretrained.permute(1, 0).view(1, nH1, S1, S1), size=(S2, S2), - mode='bicubic') - state_dict[k] = relative_position_bias_table_pretrained_resized.view(nH2, L2).permute(1, 0) - - # bicubic interpolate absolute_pos_embed if not match - absolute_pos_embed_keys = [k for k in state_dict.keys() if "absolute_pos_embed" in k] - for k in absolute_pos_embed_keys: - # dpe - absolute_pos_embed_pretrained = state_dict[k] - absolute_pos_embed_current = model.state_dict()[k] - _, L1, C1 = absolute_pos_embed_pretrained.size() - _, L2, C2 = absolute_pos_embed_current.size() - if C1 != C1: - logger.warning(f"Error in loading {k}, passing......") - else: - if L1 != L2: - S1 = int(L1 ** 0.5) - S2 = int(L2 ** 0.5) - absolute_pos_embed_pretrained = absolute_pos_embed_pretrained.reshape(-1, S1, S1, C1) - absolute_pos_embed_pretrained = absolute_pos_embed_pretrained.permute(0, 3, 1, 2) - absolute_pos_embed_pretrained_resized = torch.nn.functional.interpolate( - absolute_pos_embed_pretrained, size=(S2, S2), mode='bicubic') - absolute_pos_embed_pretrained_resized = absolute_pos_embed_pretrained_resized.permute(0, 2, 3, 1) - absolute_pos_embed_pretrained_resized = absolute_pos_embed_pretrained_resized.flatten(1, 2) - state_dict[k] = absolute_pos_embed_pretrained_resized - - # check classifier, if not match, then re-init classifier to zero - head_bias_pretrained = state_dict['head.bias'] - Nc1 = head_bias_pretrained.shape[0] - Nc2 = model.head.bias.shape[0] - if (Nc1 != Nc2): - if Nc1 == 21841 and Nc2 == 1000: - logger.info("loading ImageNet-22K weight to ImageNet-1K ......") - map22kto1k_path = f'data/map22kto1k.txt' - with open(map22kto1k_path) as f: - map22kto1k = f.readlines() - map22kto1k = [int(id22k.strip()) for id22k in map22kto1k] - state_dict['head.weight'] = state_dict['head.weight'][map22kto1k, :] - state_dict['head.bias'] = state_dict['head.bias'][map22kto1k] - else: - torch.nn.init.constant_(model.head.bias, 0.) - torch.nn.init.constant_(model.head.weight, 0.) - del state_dict['head.weight'] - del state_dict['head.bias'] - logger.warning(f"Error in loading classifier head, re-init classifier head to 0") - - msg = model.load_state_dict(state_dict, strict=False) - logger.warning(msg) - - logger.info(f"=> loaded successfully '{config.MODEL.PRETRAINED}'") - - del checkpoint - torch.cuda.empty_cache() - - -def save_checkpoint(config, epoch, model, max_accuracy, optimizer, lr_scheduler, loss_scaler, logger): - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'scaler': loss_scaler.state_dict(), - 'epoch': epoch, - 'config': config} - - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - - -def get_grad_norm(parameters, norm_type=2): - if isinstance(parameters, torch.Tensor): - parameters = [parameters] - parameters = list(filter(lambda p: p.grad is not None, parameters)) - norm_type = float(norm_type) - total_norm = 0 - for p in parameters: - param_norm = p.grad.data.norm(norm_type) - total_norm += param_norm.item() ** norm_type - total_norm = total_norm ** (1. / norm_type) - return total_norm - - -def auto_resume_helper(output_dir): - checkpoints = os.listdir(output_dir) - checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith('pth')] - print(f"All checkpoints founded in {output_dir}: {checkpoints}") - if len(checkpoints) > 0: - latest_checkpoint = max([os.path.join(output_dir, d) for d in checkpoints], key=os.path.getmtime) - print(f"The latest checkpoint founded: {latest_checkpoint}") - resume_file = latest_checkpoint - else: - resume_file = None - return resume_file - - -def reduce_tensor(tensor): - rt = tensor.clone() - dist.all_reduce(rt, op=dist.ReduceOp.SUM) - rt /= dist.get_world_size() - return rt - - -def ampscaler_get_grad_norm(parameters, norm_type: float = 2.0) -> torch.Tensor: - if isinstance(parameters, torch.Tensor): - parameters = [parameters] - parameters = [p for p in parameters if p.grad is not None] - norm_type = float(norm_type) - if len(parameters) == 0: - return torch.tensor(0.) - device = parameters[0].grad.device - if norm_type == inf: - total_norm = max(p.grad.detach().abs().max().to(device) for p in parameters) - else: - total_norm = torch.norm(torch.stack([torch.norm(p.grad.detach(), - norm_type).to(device) for p in parameters]), norm_type) - return total_norm - - -class NativeScalerWithGradNormCount: - state_dict_key = "amp_scaler" - - def __init__(self): - self._scaler = torch.cuda.amp.GradScaler() - - def __call__(self, loss, optimizer, clip_grad=None, parameters=None, create_graph=False, update_grad=True): - self._scaler.scale(loss).backward(create_graph=create_graph) - if update_grad: - if clip_grad is not None: - assert parameters is not None - self._scaler.unscale_(optimizer) # unscale the gradients of optimizer's assigned params in-place - norm = torch.nn.utils.clip_grad_norm_(parameters, clip_grad) - else: - self._scaler.unscale_(optimizer) - norm = ampscaler_get_grad_norm(parameters) - self._scaler.step(optimizer) - self._scaler.update() - else: - norm = None - return norm - - def state_dict(self): - return self._scaler.state_dict() - - def load_state_dict(self, state_dict): - self._scaler.load_state_dict(state_dict) diff --git a/cv/classification/swin_transformer/pytorch/utils_moe.py b/cv/classification/swin_transformer/pytorch/utils_moe.py deleted file mode 100644 index c5368a1a6..000000000 --- a/cv/classification/swin_transformer/pytorch/utils_moe.py +++ /dev/null @@ -1,241 +0,0 @@ -# -------------------------------------------------------- -# Swin Transformer -# Copyright (c) 2021 Microsoft -# Licensed under The MIT License [see LICENSE for details] -# Written by Ze Liu -# -------------------------------------------------------- - -import os -import torch -import torch.distributed as dist - - -def split_moe_model_state_dict(moe_keys, model_state_dict): - moe_model_state_dict = {} - non_moe_model_state_dict = {} - for (k, v) in model_state_dict.items(): - if k in moe_keys: - moe_model_state_dict[k] = v - else: - non_moe_model_state_dict[k] = v - return moe_model_state_dict, non_moe_model_state_dict - - -def merge_moe_model_state_dict(moe_model_state_dict, non_moe_model_state_dict): - model_state_dict = {} - model_state_dict.update(moe_model_state_dict) - model_state_dict.update(non_moe_model_state_dict) - return model_state_dict - - -def load_checkpoint(config, model, optimizer, lr_scheduler, loss_scaler, logger): - global_rank = dist.get_rank() - logger.info(f"==============> Rank[{global_rank}] Resuming form {config.MODEL.RESUME}....................") - if config.MODEL.RESUME.endswith(f'.pth'): - if config.TRAIN.MOE.SAVE_MASTER: - resume_path = config.MODEL.RESUME + f'.global' - else: - resume_path = config.MODEL.RESUME + f'.rank{global_rank}' - logger.info(f"===> Rank[{global_rank}] Re-formatting checkpoint name to {resume_path}......") - else: - resume_path = config.MODEL.RESUME - - checkpoint = torch.load(resume_path, map_location='cpu') - msg = model.load_state_dict(checkpoint['model'], strict=False) - logger.info(msg) - max_accuracy = 0.0 - if not config.EVAL_MODE and 'optimizer' in checkpoint and 'lr_scheduler' in checkpoint and 'epoch' in checkpoint: - optimizer.load_state_dict(checkpoint['optimizer']) - lr_scheduler.load_state_dict(checkpoint['lr_scheduler']) - config.defrost() - config.TRAIN.START_EPOCH = checkpoint['epoch'] + 1 - config.freeze() - if 'scaler' in checkpoint: - loss_scaler.load_state_dict(checkpoint['scaler']) - logger.info(f"=>Rank[{global_rank}] loaded successfully '{config.MODEL.RESUME}' (epoch {checkpoint['epoch']})") - if 'max_accuracy' in checkpoint: - max_accuracy = checkpoint['max_accuracy'] - - del checkpoint - torch.cuda.empty_cache() - return max_accuracy - - -def load_pretrained(config, model, logger): - global_rank = dist.get_rank() - logger.info(f"==============> Rank[{global_rank}] Loading weight {config.MODEL.PRETRAINED} for fine-tuning......") - if config.MODEL.PRETRAINED.endswith(f'.pth'): - if config.TRAIN.MOE.SAVE_MASTER: - pretrained_path = config.MODEL.PRETRAINED + f'.global' - else: - pretrained_path = config.MODEL.PRETRAINED + f'.rank{global_rank}' - logger.info(f"===> Rank[{global_rank}] Re-formatting checkpoint name to {pretrained_path}......") - else: - pretrained_path = config.MODEL.PRETRAINED - - if pretrained_path.endswith(f'.rank{global_rank}'): - checkpoint = torch.load(pretrained_path, map_location='cpu') - if os.path.exists(pretrained_path.replace(f'.rank{global_rank}', f'.master')): - checkpoint_master = torch.load(pretrained_path.replace(f'.rank{global_rank}', f'.master'), - map_location='cpu') - state_dict = merge_moe_model_state_dict(checkpoint['model'], checkpoint_master['model']) - else: - state_dict = checkpoint['model'] - elif pretrained_path.endswith(f'.pth.global'): - checkpoint = torch.load(pretrained_path, map_location='cpu') - state_dict = checkpoint['model'] - else: - raise NotImplementedError(f"{config.MODEL.PRETRAINED} file error...") - - # delete relative_position_index since we always re-init it - relative_position_index_keys = [k for k in state_dict.keys() if "relative_position_index" in k] - for k in relative_position_index_keys: - del state_dict[k] - - # delete relative_coords_table since we always re-init it - relative_position_index_keys = [k for k in state_dict.keys() if "relative_coords_table" in k] - for k in relative_position_index_keys: - del state_dict[k] - - # delete attn_mask since we always re-init it - attn_mask_keys = [k for k in state_dict.keys() if "attn_mask" in k] - for k in attn_mask_keys: - del state_dict[k] - - # bicubic interpolate relative_position_bias_table if not match - relative_position_bias_table_keys = [k for k in state_dict.keys() if "relative_position_bias_table" in k] - for k in relative_position_bias_table_keys: - relative_position_bias_table_pretrained = state_dict[k] - relative_position_bias_table_current = model.state_dict()[k] - L1, nH1 = relative_position_bias_table_pretrained.size() - L2, nH2 = relative_position_bias_table_current.size() - if nH1 != nH2: - logger.warning(f"Error in loading {k}, passing......") - else: - if L1 != L2: - # bicubic interpolate relative_position_bias_table if not match - S1 = int(L1 ** 0.5) - S2 = int(L2 ** 0.5) - relative_position_bias_table_pretrained_resized = torch.nn.functional.interpolate( - relative_position_bias_table_pretrained.permute(1, 0).view(1, nH1, S1, S1), size=(S2, S2), - mode='bicubic') - state_dict[k] = relative_position_bias_table_pretrained_resized.view(nH2, L2).permute(1, 0) - - # bicubic interpolate absolute_pos_embed if not match - absolute_pos_embed_keys = [k for k in state_dict.keys() if "absolute_pos_embed" in k] - for k in absolute_pos_embed_keys: - # dpe - absolute_pos_embed_pretrained = state_dict[k] - absolute_pos_embed_current = model.state_dict()[k] - _, L1, C1 = absolute_pos_embed_pretrained.size() - _, L2, C2 = absolute_pos_embed_current.size() - if C1 != C1: - logger.warning(f"Error in loading {k}, passing......") - else: - if L1 != L2: - S1 = int(L1 ** 0.5) - S2 = int(L2 ** 0.5) - absolute_pos_embed_pretrained = absolute_pos_embed_pretrained.reshape(-1, S1, S1, C1) - absolute_pos_embed_pretrained = absolute_pos_embed_pretrained.permute(0, 3, 1, 2) - absolute_pos_embed_pretrained_resized = torch.nn.functional.interpolate( - absolute_pos_embed_pretrained, size=(S2, S2), mode='bicubic') - absolute_pos_embed_pretrained_resized = absolute_pos_embed_pretrained_resized.permute(0, 2, 3, 1) - absolute_pos_embed_pretrained_resized = absolute_pos_embed_pretrained_resized.flatten(1, 2) - state_dict[k] = absolute_pos_embed_pretrained_resized - - # check classifier, if not match, then re-init classifier to zero - head_bias_pretrained = state_dict['head.bias'] - Nc1 = head_bias_pretrained.shape[0] - Nc2 = model.head.bias.shape[0] - if (Nc1 != Nc2): - if Nc1 == 21841 and Nc2 == 1000: - logger.info("loading ImageNet-22K weight to ImageNet-1K ......") - map22kto1k_path = f'data/map22kto1k.txt' - with open(map22kto1k_path) as f: - map22kto1k = f.readlines() - map22kto1k = [int(id22k.strip()) for id22k in map22kto1k] - state_dict['head.weight'] = state_dict['head.weight'][map22kto1k, :] - state_dict['head.bias'] = state_dict['head.bias'][map22kto1k] - else: - torch.nn.init.constant_(model.head.bias, 0.) - torch.nn.init.constant_(model.head.weight, 0.) - del state_dict['head.weight'] - del state_dict['head.bias'] - logger.warning(f"Error in loading classifier head, re-init classifier head to 0") - - msg = model.load_state_dict(state_dict, strict=False) - logger.warning(msg) - - logger.info(f"=> loaded successfully '{config.MODEL.PRETRAINED}'") - - del checkpoint - torch.cuda.empty_cache() - - -def save_checkpoint(config, epoch, model, max_accuracy, optimizer, lr_scheduler, loss_scaler, logger, - zero_redundancy=False): - global_rank = dist.get_rank() - - if zero_redundancy: - if config.TRAIN.MOE.SAVE_MASTER: - save_state = {'model': model.state_dict()} - if global_rank == 0: - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth.global') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - else: - moe_model_state_dict, non_moe_model_state_dict = \ - split_moe_model_state_dict(model._ddp_params_and_buffers_to_ignore, model.state_dict()) - save_state = {'model': moe_model_state_dict} - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth.rank{global_rank}') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - if global_rank == 0: - save_state_master = {'model': non_moe_model_state_dict} - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth.master') - logger.info(f"{save_path} saving......") - torch.save(save_state_master, save_path) - logger.info(f"{save_path} saved !!!") - else: - save_state = {'model': model.state_dict(), - 'optimizer': optimizer.state_dict(), - 'lr_scheduler': lr_scheduler.state_dict(), - 'max_accuracy': max_accuracy, - 'scaler': loss_scaler.state_dict(), - 'epoch': epoch, - 'config': config} - if config.TRAIN.MOE.SAVE_MASTER: - if global_rank == 0: - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth.global') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - else: - save_path = os.path.join(config.OUTPUT, f'ckpt_epoch_{epoch}.pth.rank{global_rank}') - logger.info(f"{save_path} saving......") - torch.save(save_state, save_path) - logger.info(f"{save_path} saved !!!") - - -def auto_resume_helper(output_dir, save_master=False): - global_rank = dist.get_rank() - checkpoints = os.listdir(output_dir) - if not save_master: - master_checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith(f'pth.rank0')] - else: - master_checkpoints = [ckpt for ckpt in checkpoints if ckpt.endswith(f'pth.global')] - print(f"All master checkpoints founded in {output_dir}: {master_checkpoints}") - if len(master_checkpoints) > 0: - latest_master_checkpoint = max([os.path.join(output_dir, d) for d in master_checkpoints], key=os.path.getmtime) - latest_checkpoint = latest_master_checkpoint.replace('pth.rank0', f'pth.rank{global_rank}') - print(f"The latest checkpoint founded: {latest_checkpoint}") - resume_file = latest_checkpoint - else: - resume_file = None - return resume_file - - -def hook_scale_grad(scale, tensor): - return tensor / scale diff --git a/cv/classification/wavemlp/pytorch/.gitignore b/cv/classification/wavemlp/pytorch/.gitignore deleted file mode 100644 index 61f2dc9f8..000000000 --- a/cv/classification/wavemlp/pytorch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -**/__pycache__/ diff --git a/cv/classification/wavemlp/pytorch/License.txt b/cv/classification/wavemlp/pytorch/License.txt deleted file mode 100644 index 73bb3ea15..000000000 --- a/cv/classification/wavemlp/pytorch/License.txt +++ /dev/null @@ -1,204 +0,0 @@ -Copyright (c) 2022. Huawei Technologies Co., Ltd. - All rights reserved. - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2022 Huawei Technologies Co., Ltd. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/cv/classification/wavemlp/pytorch/README.md b/cv/classification/wavemlp/pytorch/README.md index 0371a2763..ac8c08c43 100644 --- a/cv/classification/wavemlp/pytorch/README.md +++ b/cv/classification/wavemlp/pytorch/README.md @@ -7,6 +7,9 @@ In the field of computer vision, recent works show that a pure MLP architecture ## Step 1: Installing ```bash pip install thop timm==0.4.5 torchprofile +git clone https://github.com/huawei-noah/Efficient-AI-Backbones.git +cd Efficient-AI-Backbones/wavemlp_pytorch/ +git checkout 25531f7fdcf61e300b47c52ba80973d0af8bb011 ``` Sign up and login in [ImageNet official website](https://www.image-net.org/index.php), then choose 'Download' to download the whole ImageNet dataset. Specify `/path/to/imagenet` to your ImageNet path in later training process. @@ -34,7 +37,15 @@ imagenet ### Multiple GPUs on one machine ```bash -bash run.sh /path/to/imagenet/ +# fix --local-rank for torch 2.x +sed -i 's/--local_rank/--local-rank/g' train.py +# change dataset +sed -i "s@from timm.data import Dataset@from timm.data import ImageDataset@" train.py +sed -i "s@dataset_train = Dataset(train_dir)@dataset_train = ImageDataset(train_dir)@" train.py +sed -i "s@dataset_eval = Dataset(eval_dir)@dataset_eval = ImageDataset(eval_dir)@" train.py +sed -i 's/args.max_history/100/g' train.py + +python3 -m torch.distributed.launch --nproc_per_node 8 --nnodes=1 --node_rank=0 train.py /your_path_to/imagenet/ --output /your_path_to/output/ --model WaveMLP_T_dw --sched cosine --epochs 300 --opt adamw -j 8 --warmup-lr 1e-6 --mixup .8 --cutmix 1.0 --model-ema --model-ema-decay 0.99996 --aa rand-m9-mstd0.5-inc1 --color-jitter 0.4 --warmup-epochs 5 --opt-eps 1e-8 --repeated-aug --remode pixel --reprob 0.25 --amp --lr 1e-3 --weight-decay .05 --drop 0 --drop-path 0.1 -b 128 ``` ## Results on BI-V100 @@ -58,4 +69,4 @@ bash run.sh /path/to/imagenet/ ## Reference -https://github.com/huawei-noah/Efficient-AI-Backbones/blob/master/wavemlp_pytorch/ +[wavemlp_pytorch](https://github.com/huawei-noah/Efficient-AI-Backbones/blob/master/wavemlp_pytorch/) diff --git a/cv/classification/wavemlp/pytorch/THIRD PARTY OPEN SOURCE SOFTWARE NOTICE.txt b/cv/classification/wavemlp/pytorch/THIRD PARTY OPEN SOURCE SOFTWARE NOTICE.txt deleted file mode 100644 index c375b208f..000000000 --- a/cv/classification/wavemlp/pytorch/THIRD PARTY OPEN SOURCE SOFTWARE NOTICE.txt +++ /dev/null @@ -1,853 +0,0 @@ -Please note we provide an open source software notice for the third party open source software along with this software and/or this software component contributed by Huawei (in the following just “this SOFTWARE”). The open source software licenses are granted by the respective right holders. - -Warranty Disclaimer -THE OPEN SOURCE SOFTWARE IN THIS SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. - -Copyright Notice and License Texts -Software: tensorpack (https://github.com/tensorpack/tensorpack) -Copyright notice: -Copyright (c), Yuxin Wu - -License: Apache License Version 2.0 - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright Yuxin Wu - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -Copyright Notice and License Texts -Software: tf-imagenet (https://github.com/balancap/tf-imagenet) -Copyright notice: -Copyright (c), 2018 The TensorFlow Authors - -Copyright 2018 The TensorFlow Authors. All rights reserved. - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017, The TensorFlow Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -Copyright Notice and License Texts -Software: pytorch-image-models (https://github.com/rwightman/pytorch-image-models) -Copyright notice: -Copyright 2019 Ross Wightman - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019 Ross Wightman - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -Copyright Notice and License Texts -Software: deit (https://github.com/facebookresearch/deit) -Copyright notice: -Copyright (c), facebook research - -License: Apache License Version 2.0 - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2019 Ross Wightman - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - - Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/cv/classification/wavemlp/pytorch/data/myloader.py b/cv/classification/wavemlp/pytorch/data/myloader.py deleted file mode 100644 index 388c07606..000000000 --- a/cv/classification/wavemlp/pytorch/data/myloader.py +++ /dev/null @@ -1,160 +0,0 @@ -# 2022.02.14-Changed for main script for wavemlp model -# Huawei Technologies Co., Ltd. - -""" Loader Factory, Fast Collate, CUDA Prefetcher - -Prefetcher and Fast Collate inspired by NVIDIA APEX example at -https://github.com/NVIDIA/apex/commit/d5e2bb4bdeedd27b1dfaf5bb2b24d6c000dee9be#diff-cf86c282ff7fba81fad27a559379d5bf - -Hacked together by / Copyright 2020 Ross Wightman -""" - -import torch.utils.data -import torch.distributed as dist -import numpy as np - -from timm.data.transforms_factory import create_transform -from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.data.distributed_sampler import OrderedDistributedSampler -from timm.data.random_erasing import RandomErasing -from timm.data.mixup import FastCollateMixup -from timm.data.loader import fast_collate, PrefetchLoader, MultiEpochsDataLoader - -from .rasampler import RASampler - - -def is_dist_avail_and_initialized(): - if not dist.is_available(): - return False - if not dist.is_initialized(): - return False - return True - - -def get_world_size(): - if not is_dist_avail_and_initialized(): - return 1 - return dist.get_world_size() - - -def get_rank(): - if not is_dist_avail_and_initialized(): - return 0 - return dist.get_rank() - - -def create_loader( - dataset, - input_size, - batch_size, - is_training=False, - use_prefetcher=True, - no_aug=False, - re_prob=0., - re_mode='const', - re_count=1, - re_split=False, - scale=None, - ratio=None, - hflip=0.5, - vflip=0., - color_jitter=0.4, - auto_augment=None, - num_aug_splits=0, - interpolation='bilinear', - mean=IMAGENET_DEFAULT_MEAN, - std=IMAGENET_DEFAULT_STD, - num_workers=1, - distributed=False, - crop_pct=None, - collate_fn=None, - pin_memory=False, - fp16=False, - tf_preprocessing=False, - use_multi_epochs_loader=False, - repeated_aug=False -): - re_num_splits = 0 - if re_split: - # apply RE to second half of batch if no aug split otherwise line up with aug split - re_num_splits = num_aug_splits or 2 - dataset.transform = create_transform( - input_size, - is_training=is_training, - use_prefetcher=use_prefetcher, - no_aug=no_aug, - scale=scale, - ratio=ratio, - hflip=hflip, - vflip=vflip, - color_jitter=color_jitter, - auto_augment=auto_augment, - interpolation=interpolation, - mean=mean, - std=std, - crop_pct=crop_pct, - tf_preprocessing=tf_preprocessing, - re_prob=re_prob, - re_mode=re_mode, - re_count=re_count, - re_num_splits=re_num_splits, - separate=num_aug_splits > 0, - ) - - sampler = None - if distributed: - if is_training: - if repeated_aug: - print('using repeated_aug') - num_tasks = get_world_size() - global_rank = get_rank() - sampler = RASampler( - dataset, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - else: - sampler = torch.utils.data.distributed.DistributedSampler(dataset) - else: - # This will add extra duplicate entries to result in equal num - # of samples per-process, will slightly alter validation results - sampler = OrderedDistributedSampler(dataset) - else: - if is_training and repeated_aug: - print('using repeated_aug') - num_tasks = get_world_size() - global_rank = get_rank() - sampler = RASampler( - dataset, num_replicas=num_tasks, rank=global_rank, shuffle=True - ) - - if collate_fn is None: - collate_fn = fast_collate if use_prefetcher else torch.utils.data.dataloader.default_collate - - loader_class = torch.utils.data.DataLoader - - if use_multi_epochs_loader: - loader_class = MultiEpochsDataLoader - - loader = loader_class( - dataset, - batch_size=batch_size, - shuffle=sampler is None and is_training, - num_workers=num_workers, - sampler=sampler, - collate_fn=collate_fn, - pin_memory=pin_memory, - drop_last=is_training, - ) - if use_prefetcher: - prefetch_re_prob = re_prob if is_training and not no_aug else 0. - loader = PrefetchLoader( - loader, - mean=mean, - std=std, - fp16=fp16, - re_prob=prefetch_re_prob, - re_mode=re_mode, - re_count=re_count, - re_num_splits=re_num_splits - ) - - return loader diff --git a/cv/classification/wavemlp/pytorch/data/rasampler.py b/cv/classification/wavemlp/pytorch/data/rasampler.py deleted file mode 100644 index 5aad9bf0a..000000000 --- a/cv/classification/wavemlp/pytorch/data/rasampler.py +++ /dev/null @@ -1,67 +0,0 @@ -# 2022.02.14-Changed for main script for wavemlp model -# Huawei Technologies Co., Ltd. - -# from https://github.com/facebookresearch/deit/blob/main/samplers.py -# Copyright (c) 2015-present, Facebook, Inc. -# All rights reserved. -# -# This source code is licensed under the CC-by-NC license found in the -# LICENSE file in the root directory of this source tree. -# -import torch -import torch.distributed as dist -import math - - -class RASampler(torch.utils.data.Sampler): - """Sampler that restricts data loading to a subset of the dataset for distributed, - with repeated augmentation. - It ensures that different each augmented version of a sample will be visible to a - different process (GPU) - Heavily based on torch.utils.data.DistributedSampler - """ - - def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True): - if num_replicas is None: - if not dist.is_available(): - raise RuntimeError("Requires distributed package to be available") - num_replicas = dist.get_world_size() - if rank is None: - if not dist.is_available(): - raise RuntimeError("Requires distributed package to be available") - rank = dist.get_rank() - self.dataset = dataset - self.num_replicas = num_replicas - self.rank = rank - self.epoch = 0 - self.num_samples = int(math.ceil(len(self.dataset) * 3.0 / self.num_replicas)) - self.total_size = self.num_samples * self.num_replicas - # self.num_selected_samples = int(math.ceil(len(self.dataset) / self.num_replicas)) - self.num_selected_samples = int(math.floor(len(self.dataset) // 256 * 256 / self.num_replicas)) - self.shuffle = shuffle - - def __iter__(self): - # deterministically shuffle based on epoch - g = torch.Generator() - g.manual_seed(self.epoch) - if self.shuffle: - indices = torch.randperm(len(self.dataset), generator=g).tolist() - else: - indices = list(range(len(self.dataset))) - - # add extra samples to make it evenly divisible - indices = [ele for ele in indices for i in range(3)] - indices += indices[:(self.total_size - len(indices))] - assert len(indices) == self.total_size - - # subsample - indices = indices[self.rank:self.total_size:self.num_replicas] - assert len(indices) == self.num_samples - - return iter(indices[:self.num_selected_samples]) - - def __len__(self): - return self.num_selected_samples - - def set_epoch(self, epoch): - self.epoch = epoch diff --git a/cv/classification/wavemlp/pytorch/figures/patm.PNG b/cv/classification/wavemlp/pytorch/figures/patm.PNG deleted file mode 100644 index b7526e104ca99e6999a6acd3eb5df40d27002c50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84733 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�H 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 KQa>aNA^#r|wt+JM diff --git a/cv/classification/wavemlp/pytorch/models/wavemlp.py b/cv/classification/wavemlp/pytorch/models/wavemlp.py deleted file mode 100644 index 6b11d19ad..000000000 --- a/cv/classification/wavemlp/pytorch/models/wavemlp.py +++ /dev/null @@ -1,330 +0,0 @@ -# 2022.02.14-Changed for main script for wavemlp model -# Huawei Technologies Co., Ltd. -""" Vision Transformer (ViT) in PyTorch - -A PyTorch implement of Vision Transformers as described in -'An Image Is Worth 16 x 16 Words: Transformers for Image Recognition at Scale' - https://arxiv.org/abs/2010.11929 - -The official jax code is released and available at https://github.com/google-research/vision_transformer - -Status/TODO: -* Models updated to be compatible with official impl. Args added to support backward compat for old PyTorch weights. -* Weights ported from official jax impl for 384x384 base and small models, 16x16 and 32x32 patches. -* Trained (supervised on ImageNet-1k) my custom 'small' patch model to 77.9, 'base' to 79.4 top-1 with this code. -* Hopefully find time and GPUs for SSL or unsupervised pretraining on OpenImages w/ ImageNet fine-tune in future. - -Acknowledgments: -* The paper authors for releasing code and weights, thanks! -* I fixed my class token impl based on Phil Wang's https://github.com/lucidrains/vit-pytorch ... check it out -for some einops/einsum fun -* Simple transformer style inspired by Andrej Karpathy's https://github.com/karpathy/minGPT -* Bert reference code checks against Huggingface Transformers and Tensorflow Bert - -Hacked together by / Copyright 2020 Ross Wightman -""" - -import os -import torch -import torch.nn as nn - -from timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD -from timm.models.layers import DropPath, trunc_normal_ -from timm.models.registry import register_model -from timm.models.layers.helpers import to_2tuple - -import math -from torch import Tensor -from torch.nn import init -from torch.nn.modules.utils import _pair -import torch.nn.functional as F - - -def _cfg(url='', **kwargs): - return { - 'url': url, - 'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None, - 'crop_pct': .96, 'interpolation': 'bicubic', - 'mean': IMAGENET_DEFAULT_MEAN, 'std': IMAGENET_DEFAULT_STD, 'classifier': 'head', - **kwargs - } - -default_cfgs = { - 'wave_T': _cfg(crop_pct=0.9), - 'wave_S': _cfg(crop_pct=0.9), - 'wave_M': _cfg(crop_pct=0.9), - 'wave_B': _cfg(crop_pct=0.875), -} - -class Mlp(nn.Module): - def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.): - super().__init__() - - out_features = out_features or in_features - hidden_features = hidden_features or in_features - self.act = act_layer() - self.drop = nn.Dropout(drop) - self.fc1 = nn.Conv2d(in_features, hidden_features, 1, 1) - self.fc2 = nn.Conv2d(hidden_features, out_features, 1, 1) - - def forward(self, x): - x = self.fc1(x) - x = self.act(x) - x = self.drop(x) - x = self.fc2(x) - x = self.drop(x) - return x - - -class PATM(nn.Module): - def __init__(self, dim, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.,mode='fc'): - super().__init__() - - - self.fc_h = nn.Conv2d(dim, dim, 1, 1,bias=qkv_bias) - self.fc_w = nn.Conv2d(dim, dim, 1, 1,bias=qkv_bias) - self.fc_c = nn.Conv2d(dim, dim, 1, 1,bias=qkv_bias) - - self.tfc_h = nn.Conv2d(2*dim, dim, (1,7), stride=1, padding=(0,7//2), groups=dim, bias=False) - self.tfc_w = nn.Conv2d(2*dim, dim, (7,1), stride=1, padding=(7//2,0), groups=dim, bias=False) - self.reweight = Mlp(dim, dim // 4, dim * 3) - self.proj = nn.Conv2d(dim, dim, 1, 1,bias=True) - self.proj_drop = nn.Dropout(proj_drop) - self.mode=mode - - if mode=='fc': - self.theta_h_conv=nn.Sequential(nn.Conv2d(dim, dim, 1, 1,bias=True),nn.BatchNorm2d(dim),nn.ReLU()) - self.theta_w_conv=nn.Sequential(nn.Conv2d(dim, dim, 1, 1,bias=True),nn.BatchNorm2d(dim),nn.ReLU()) - else: - self.theta_h_conv=nn.Sequential(nn.Conv2d(dim, dim, 3, stride=1, padding=1, groups=dim, bias=False),nn.BatchNorm2d(dim),nn.ReLU()) - self.theta_w_conv=nn.Sequential(nn.Conv2d(dim, dim, 3, stride=1, padding=1, groups=dim, bias=False),nn.BatchNorm2d(dim),nn.ReLU()) - - def forward(self, x): - - B, C, H, W = x.shape - theta_h=self.theta_h_conv(x) - theta_w=self.theta_w_conv(x) - - x_h=self.fc_h(x) - x_w=self.fc_w(x) - x_h=torch.cat([x_h*torch.cos(theta_h),x_h*torch.sin(theta_h)],dim=1) - x_w=torch.cat([x_w*torch.cos(theta_w),x_w*torch.sin(theta_w)],dim=1) - -# x_1=self.fc_h(x) -# x_2=self.fc_w(x) -# x_h=torch.cat([x_1*torch.cos(theta_h),x_2*torch.sin(theta_h)],dim=1) -# x_w=torch.cat([x_1*torch.cos(theta_w),x_2*torch.sin(theta_w)],dim=1) - - h = self.tfc_h(x_h) - w = self.tfc_w(x_w) - c = self.fc_c(x) - a = F.adaptive_avg_pool2d(h + w + c,output_size=1) - a = self.reweight(a).reshape(B, C, 3).permute(2, 0, 1).softmax(dim=0).unsqueeze(-1).unsqueeze(-1) - x = h * a[0] + w * a[1] + c * a[2] - x = self.proj(x) - x = self.proj_drop(x) - return x - -class WaveBlock(nn.Module): - - def __init__(self, dim, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0., - drop_path=0., act_layer=nn.GELU, norm_layer=nn.BatchNorm2d, mode='fc'): - super().__init__() - self.norm1 = norm_layer(dim) - self.attn = PATM(dim, qkv_bias=qkv_bias, qk_scale=None, attn_drop=attn_drop,mode=mode) - self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity() - self.norm2 = norm_layer(dim) - mlp_hidden_dim = int(dim * mlp_ratio) - self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer) - - def forward(self, x): - x = x + self.drop_path(self.attn(self.norm1(x))) - x = x + self.drop_path(self.mlp(self.norm2(x))) - return x - - -class PatchEmbedOverlapping(nn.Module): - def __init__(self, patch_size=16, stride=16, padding=0, in_chans=3, embed_dim=768, norm_layer=nn.BatchNorm2d, groups=1,use_norm=True): - super().__init__() - patch_size = to_2tuple(patch_size) - stride = to_2tuple(stride) - padding = to_2tuple(padding) - self.patch_size = patch_size - - self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=stride, padding=padding, groups=groups) - self.norm = norm_layer(embed_dim) if use_norm==True else nn.Identity() - - def forward(self, x): - x = self.proj(x) - x = self.norm(x) - return x - - -class Downsample(nn.Module): - def __init__(self, in_embed_dim, out_embed_dim, patch_size,norm_layer=nn.BatchNorm2d,use_norm=True): - super().__init__() - assert patch_size == 2, patch_size - self.proj = nn.Conv2d(in_embed_dim, out_embed_dim, kernel_size=(3, 3), stride=(2, 2), padding=1) - self.norm = norm_layer(out_embed_dim) if use_norm==True else nn.Identity() - def forward(self, x): - x = self.proj(x) - x = self.norm(x) - return x - - -def basic_blocks(dim, index, layers, mlp_ratio=3., qkv_bias=False, qk_scale=None, attn_drop=0., - drop_path_rate=0.,norm_layer=nn.BatchNorm2d,mode='fc', **kwargs): - blocks = [] - for block_idx in range(layers[index]): - block_dpr = drop_path_rate * (block_idx + sum(layers[:index])) / (sum(layers) - 1) - blocks.append(WaveBlock(dim, mlp_ratio=mlp_ratio, qkv_bias=qkv_bias, qk_scale=qk_scale, - attn_drop=attn_drop, drop_path=block_dpr, norm_layer=norm_layer,mode=mode)) - blocks = nn.Sequential(*blocks) - return blocks - -class WaveNet(nn.Module): - def __init__(self, layers, img_size=224, patch_size=4, in_chans=3, num_classes=1000, - embed_dims=None, transitions=None, mlp_ratios=None, - qkv_bias=False, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0., - norm_layer=nn.BatchNorm2d, fork_feat=False,mode='fc',ds_use_norm=True,args=None): - - super().__init__() - - if not fork_feat: - self.num_classes = num_classes - self.fork_feat = fork_feat - - self.patch_embed = PatchEmbedOverlapping(patch_size=7, stride=4, padding=2, in_chans=3, embed_dim=embed_dims[0],norm_layer=norm_layer,use_norm=ds_use_norm) - - network = [] - for i in range(len(layers)): - stage = basic_blocks(embed_dims[i], i, layers, mlp_ratio=mlp_ratios[i], qkv_bias=qkv_bias, - qk_scale=qk_scale, attn_drop=attn_drop_rate, drop_path_rate=drop_path_rate, - norm_layer=norm_layer,mode=mode) - network.append(stage) - if i >= len(layers) - 1: - break - if transitions[i] or embed_dims[i] != embed_dims[i+1]: - patch_size = 2 if transitions[i] else 1 - network.append(Downsample(embed_dims[i], embed_dims[i+1], patch_size,norm_layer=norm_layer,use_norm=ds_use_norm)) - - self.network = nn.ModuleList(network) - - if self.fork_feat: - # add a norm layer for each output - self.out_indices = [0, 2, 4, 6] - for i_emb, i_layer in enumerate(self.out_indices): - if i_emb == 0 and os.environ.get('FORK_LAST3', None): - layer = nn.Identity() - else: - layer = norm_layer(embed_dims[i_emb]) - layer_name = f'norm{i_layer}' - self.add_module(layer_name, layer) - else: - self.norm = norm_layer(embed_dims[-1]) - self.head = nn.Linear(embed_dims[-1], num_classes) if num_classes > 0 else nn.Identity() - self.apply(self.cls_init_weights) - - def cls_init_weights(self, m): - if isinstance(m, nn.Linear): - trunc_normal_(m.weight, std=.02) - if isinstance(m, nn.Linear) and m.bias is not None: - nn.init.constant_(m.bias, 0) - elif isinstance(m, nn.LayerNorm) or isinstance(m, nn.BatchNorm2d): - nn.init.constant_(m.bias, 0) - nn.init.constant_(m.weight, 1.0) - - def init_weights(self, pretrained=None): - """ mmseg or mmdet `init_weight` """ - if isinstance(pretrained, str): - logger = get_root_logger() - load_checkpoint(self, pretrained, map_location='cpu', strict=False, logger=logger) - - def get_classifier(self): - return self.head - - def reset_classifier(self, num_classes, global_pool=''): - self.num_classes = num_classes - self.head = nn.Linear(self.embed_dim, num_classes) if num_classes > 0 else nn.Identity() - - def forward_embeddings(self, x): - x = self.patch_embed(x) - return x - - def forward_tokens(self, x): - outs = [] - for idx, block in enumerate(self.network): - x = block(x) - if self.fork_feat and idx in self.out_indices: - norm_layer = getattr(self, f'norm{idx}') - x_out = norm_layer(x) - outs.append(x_out) - if self.fork_feat: - return outs - return x - - def forward(self, x): - x = self.forward_embeddings(x) - x = self.forward_tokens(x) - if self.fork_feat: - return x - x = self.norm(x) - cls_out = self.head(F.adaptive_avg_pool2d(x,output_size=1).flatten(1))#x.mean(1) - return cls_out - -def MyNorm(dim): - return nn.GroupNorm(1, dim) - -@register_model -def WaveMLP_T_dw(pretrained=False, **kwargs): - transitions = [True, True, True, True] - layers = [2, 2, 4, 2] - mlp_ratios = [4, 4, 4, 4] - embed_dims = [64, 128, 320, 512] - model = WaveNet(layers, embed_dims=embed_dims, patch_size=7, transitions=transitions, - mlp_ratios=mlp_ratios,mode='depthwise', **kwargs) - model.default_cfg = default_cfgs['wave_T'] - return model - -@register_model -def WaveMLP_T(pretrained=False, **kwargs): - transitions = [True, True, True, True] - layers = [2, 2, 4, 2] - mlp_ratios = [4, 4, 4, 4] - embed_dims = [64, 128, 320, 512] - model = WaveNet(layers, embed_dims=embed_dims, patch_size=7, transitions=transitions, - mlp_ratios=mlp_ratios, **kwargs) - model.default_cfg = default_cfgs['wave_T'] - return model - -@register_model -def WaveMLP_S(pretrained=False, **kwargs): - transitions = [True, True, True, True] - layers = [2, 3, 10, 3] - mlp_ratios = [4, 4, 4, 4] - embed_dims = [64, 128, 320, 512] - model = WaveNet(layers, embed_dims=embed_dims, patch_size=7, transitions=transitions, - mlp_ratios=mlp_ratios,norm_layer=MyNorm, **kwargs) - model.default_cfg = default_cfgs['wave_S'] - return model - -@register_model -def WaveMLP_M(pretrained=False, **kwargs): - transitions = [True, True, True, True] - layers = [3, 4, 18, 3] - mlp_ratios = [8, 8, 4, 4] - embed_dims = [64, 128, 320, 512] - model = WaveNet(layers, embed_dims=embed_dims, patch_size=7, transitions=transitions, - mlp_ratios=mlp_ratios,norm_layer=MyNorm,ds_use_norm=False, **kwargs) - model.default_cfg = default_cfgs['wave_M'] - return model - -@register_model -def WaveMLP_B(pretrained=False, **kwargs): - transitions = [True, True, True, True] - layers = [2, 2, 18, 2] - mlp_ratios = [4, 4, 4, 4] - embed_dims = [96, 192, 384, 768] - model = WaveNet(layers, embed_dims=embed_dims, patch_size=7, transitions=transitions, - mlp_ratios=mlp_ratios,norm_layer=MyNorm,ds_use_norm=False, **kwargs) - model.default_cfg = default_cfgs['wave_B'] - return model diff --git a/cv/classification/wavemlp/pytorch/run.sh b/cv/classification/wavemlp/pytorch/run.sh deleted file mode 100644 index 6120235e3..000000000 --- a/cv/classification/wavemlp/pytorch/run.sh +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright (c) 2022, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -DATA_PATH=$1 - -python3 -m torch.distributed.launch --nproc_per_node 8 --nnodes=1 --node_rank=0 train.py \ - ${DATA_PATH} \ - --output ./work_dir \ - --model WaveMLP_T_dw \ - --sched cosine \ - --epochs 300 \ - --opt adamw \ - -j 8 \ - --warmup-lr 1e-6 \ - --mixup .8 \ - --cutmix 1.0 \ - --model-ema \ - --model-ema-decay 0.99996 \ - --aa rand-m9-mstd0.5-inc1 \ - --color-jitter 0.4 \ - --warmup-epochs 5 \ - --opt-eps 1e-8 \ - --repeated-aug \ - --remode pixel \ - --reprob 0.25 \ - --amp \ - --lr 1e-3 \ - --weight-decay .05 \ - --drop 0 \ - --drop-path 0.1 \ - -b 128 \ - --log-interval 1 diff --git a/cv/classification/wavemlp/pytorch/train.py b/cv/classification/wavemlp/pytorch/train.py deleted file mode 100644 index 63a47ec8b..000000000 --- a/cv/classification/wavemlp/pytorch/train.py +++ /dev/null @@ -1,858 +0,0 @@ -# Copyright (c) 2024, Shanghai Iluvatar CoreX Semiconductor Co., Ltd. -# All Rights Reserved. -# 2022.02.14-Changed for main script for wavemlp model -# Huawei Technologies Co., Ltd. -#!/usr/bin/env python -""" ImageNet Training Script - -This is intended to be a lean and easily modifiable ImageNet training script that reproduces ImageNet -training results with some of the latest networks and training techniques. It favours canonical PyTorch -and standard Python style over trying to be able to 'do it all.' That said, it offers quite a few speed -and training result improvements over the usual PyTorch example scripts. Repurpose as you see fit. - -This script was started from an early version of the PyTorch ImageNet example -(https://github.com/pytorch/examples/tree/master/imagenet) - -NVIDIA CUDA specific speedups adopted from NVIDIA Apex examples -(https://github.com/NVIDIA/apex/tree/master/examples/imagenet) - -Hacked together by / Copyright 2020 Ross Wightman (https://github.com/rwightman) -""" - - -import warnings -warnings.filterwarnings('ignore') -import argparse -import time -import yaml -import os -import logging -from collections import OrderedDict -from contextlib import suppress -from datetime import datetime - -import math - -import torch -import torch.nn as nn -import torchvision.utils -from torch.nn.parallel import DistributedDataParallel as NativeDDP - -from timm.data import ImageDataset, resolve_data_config, Mixup, FastCollateMixup, AugMixDataset -from timm.models import create_model, resume_checkpoint, convert_splitbn_model -from timm.utils import * -from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy, JsdCrossEntropy -from timm.optim import create_optimizer -from timm.scheduler import create_scheduler -from timm.utils import ApexScaler, NativeScaler - -from data.myloader import create_loader -import models.wavemlp - -try: - from apex import amp - from apex.parallel import DistributedDataParallel as ApexDDP - from apex.parallel import convert_syncbn_model - has_apex = True -except ImportError: - has_apex = False - -has_native_amp = False -try: - if getattr(torch.cuda.amp, 'autocast') is not None: - has_native_amp = True -except AttributeError: - pass - -torch.backends.cudnn.benchmark = True -_logger = logging.getLogger('train') - -# The first arg parser parses out only the --config argument, this argument is used to -# load a yaml file containing key-values that override the defaults for the main parser below -config_parser = parser = argparse.ArgumentParser(description='Training Config', add_help=False) -parser.add_argument('-c', '--config', default='', type=str, metavar='FILE', - help='YAML config file specifying default arguments') - - -parser = argparse.ArgumentParser(description='PyTorch ImageNet Training') - -# Dataset / Model parameters -parser.add_argument('data', metavar='DIR', - help='path to dataset') -parser.add_argument('--model', default='resnet101', type=str, metavar='MODEL', - help='Name of model to train (default: "countception"') -parser.add_argument('--pretrained', action='store_true', default=False, - help='Start with pretrained version of specified network (if avail)') -parser.add_argument('--initial-checkpoint', default='', type=str, metavar='PATH', - help='Initialize model from this checkpoint (default: none)') -parser.add_argument('--resume', default='', type=str, metavar='PATH', - help='Resume full model and optimizer state from checkpoint (default: none)') -parser.add_argument('--no-resume-opt', action='store_true', default=False, - help='prevent resume of optimizer state when resuming model') -parser.add_argument('--num-classes', type=int, default=1000, metavar='N', - help='number of label classes (default: 1000)') -parser.add_argument('--gp', default=None, type=str, metavar='POOL', - help='Global pool type, one of (fast, avg, max, avgmax, avgmaxc). Model default if None.') -parser.add_argument('--img-size', type=int, default=None, metavar='N', - help='Image patch size (default: None => model default)') -parser.add_argument('--crop-pct', default=None, type=float, - metavar='N', help='Input image center crop percent (for validation only)') -parser.add_argument('--mean', type=float, nargs='+', default=None, metavar='MEAN', - help='Override mean pixel value of dataset') -parser.add_argument('--std', type=float, nargs='+', default=None, metavar='STD', - help='Override std deviation of of dataset') -parser.add_argument('--interpolation', default='', type=str, metavar='NAME', - help='Image resize interpolation type (overrides model)') -parser.add_argument('-b', '--batch-size', type=int, default=32, metavar='N', - help='input batch size for training (default: 32)') -parser.add_argument('-vb', '--validation-batch-size-multiplier', type=int, default=1, metavar='N', - help='ratio of validation batch size to training batch size (default: 1)') - -# Optimizer parameters -parser.add_argument('--opt', default='sgd', type=str, metavar='OPTIMIZER', - help='Optimizer (default: "sgd"') -parser.add_argument('--opt-eps', default=None, type=float, metavar='EPSILON', - help='Optimizer Epsilon (default: None, use opt default)') -parser.add_argument('--opt-betas', default=None, type=float, nargs='+', metavar='BETA', - help='Optimizer Betas (default: None, use opt default)') -parser.add_argument('--momentum', type=float, default=0.9, metavar='M', - help='Optimizer momentum (default: 0.9)') -parser.add_argument('--weight-decay', type=float, default=0.0001, - help='weight decay (default: 0.0001)') -parser.add_argument('--clip-grad', type=float, default=None, metavar='NORM', - help='Clip gradient norm (default: None, no clipping)') - - - -# Learning rate schedule parameters -parser.add_argument('--sched', default='step', type=str, metavar='SCHEDULER', - help='LR scheduler (default: "step"') -parser.add_argument('--lr', type=float, default=0.01, metavar='LR', - help='learning rate (default: 0.01)') -parser.add_argument('--lr-noise', type=float, nargs='+', default=None, metavar='pct, pct', - help='learning rate noise on/off epoch percentages') -parser.add_argument('--lr-noise-pct', type=float, default=0.67, metavar='PERCENT', - help='learning rate noise limit percent (default: 0.67)') -parser.add_argument('--lr-noise-std', type=float, default=1.0, metavar='STDDEV', - help='learning rate noise std-dev (default: 1.0)') -parser.add_argument('--lr-cycle-mul', type=float, default=1.0, metavar='MULT', - help='learning rate cycle len multiplier (default: 1.0)') -parser.add_argument('--lr-cycle-limit', type=int, default=1, metavar='N', - help='learning rate cycle limit') -parser.add_argument('--warmup-lr', type=float, default=0.0001, metavar='LR', - help='warmup learning rate (default: 0.0001)') -parser.add_argument('--min-lr', type=float, default=1e-5, metavar='LR', - help='lower lr bound for cyclic schedulers that hit 0 (1e-5)') -parser.add_argument('--epochs', type=int, default=200, metavar='N', - help='number of epochs to train (default: 2)') -parser.add_argument('--start-epoch', default=None, type=int, metavar='N', - help='manual epoch number (useful on restarts)') -parser.add_argument('--decay-epochs', type=float, default=30, metavar='N', - help='epoch interval to decay LR') -parser.add_argument('--warmup-epochs', type=int, default=3, metavar='N', - help='epochs to warmup LR, if scheduler supports') -parser.add_argument('--cooldown-epochs', type=int, default=10, metavar='N', - help='epochs to cooldown LR at min_lr, after cyclic schedule ends') -parser.add_argument('--patience-epochs', type=int, default=10, metavar='N', - help='patience epochs for Plateau LR scheduler (default: 10') -parser.add_argument('--decay-rate', '--dr', type=float, default=0.1, metavar='RATE', - help='LR decay rate (default: 0.1)') - -# Augmentation & regularization parameters -parser.add_argument('--no-aug', action='store_true', default=False, - help='Disable all training augmentation, override other train aug args') -parser.add_argument('--repeated-aug', action='store_true') -parser.add_argument('--scale', type=float, nargs='+', default=[0.08, 1.0], metavar='PCT', - help='Random resize scale (default: 0.08 1.0)') -parser.add_argument('--ratio', type=float, nargs='+', default=[3./4., 4./3.], metavar='RATIO', - help='Random resize aspect ratio (default: 0.75 1.33)') -parser.add_argument('--hflip', type=float, default=0.5, - help='Horizontal flip training aug probability') -parser.add_argument('--vflip', type=float, default=0., - help='Vertical flip training aug probability') -parser.add_argument('--color-jitter', type=float, default=0.4, metavar='PCT', - help='Color jitter factor (default: 0.4)') -parser.add_argument('--aa', type=str, default=None, metavar='NAME', - help='Use AutoAugment policy. "v0" or "original". (default: None)'), -parser.add_argument('--aug-splits', type=int, default=0, - help='Number of augmentation splits (default: 0, valid: 0 or >=2)') -parser.add_argument('--jsd', action='store_true', default=False, - help='Enable Jensen-Shannon Divergence + CE loss. Use with `--aug-splits`.') -parser.add_argument('--reprob', type=float, default=0., metavar='PCT', - help='Random erase prob (default: 0.)') -parser.add_argument('--remode', type=str, default='const', - help='Random erase mode (default: "const")') -parser.add_argument('--recount', type=int, default=1, - help='Random erase count (default: 1)') -parser.add_argument('--resplit', action='store_true', default=False, - help='Do not random erase first (clean) augmentation split') -parser.add_argument('--mixup', type=float, default=0.0, - help='mixup alpha, mixup enabled if > 0. (default: 0.)') -parser.add_argument('--cutmix', type=float, default=0.0, - help='cutmix alpha, cutmix enabled if > 0. (default: 0.)') -parser.add_argument('--cutmix-minmax', type=float, nargs='+', default=None, - help='cutmix min/max ratio, overrides alpha and enables cutmix if set (default: None)') -parser.add_argument('--mixup-prob', type=float, default=1.0, - help='Probability of performing mixup or cutmix when either/both is enabled') -parser.add_argument('--mixup-switch-prob', type=float, default=0.5, - help='Probability of switching to cutmix when both mixup and cutmix enabled') -parser.add_argument('--mixup-mode', type=str, default='batch', - help='How to apply mixup/cutmix params. Per "batch", "pair", or "elem"') -parser.add_argument('--mixup-off-epoch', default=0, type=int, metavar='N', - help='Turn off mixup after this epoch, disabled if 0 (default: 0)') -parser.add_argument('--smoothing', type=float, default=0.1, - help='Label smoothing (default: 0.1)') -parser.add_argument('--train-interpolation', type=str, default='random', - help='Training interpolation (random, bilinear, bicubic default: "random")') -parser.add_argument('--drop', type=float, default=0.0, metavar='PCT', - help='Dropout rate (default: 0.)') -parser.add_argument('--drop-connect', type=float, default=None, metavar='PCT', - help='Drop connect rate, DEPRECATED, use drop-path (default: None)') -parser.add_argument('--drop-path', type=float, default=None, metavar='PCT', - help='Drop path rate (default: None)') -parser.add_argument('--drop-block', type=float, default=None, metavar='PCT', - help='Drop block rate (default: None)') - -# Batch norm parameters (only works with gen_efficientnet based models currently) -parser.add_argument('--bn-tf', action='store_true', default=False, - help='Use Tensorflow BatchNorm defaults for models that support it (default: False)') -parser.add_argument('--bn-momentum', type=float, default=None, - help='BatchNorm momentum override (if not None)') -parser.add_argument('--bn-eps', type=float, default=None, - help='BatchNorm epsilon override (if not None)') -parser.add_argument('--sync-bn', action='store_true', - help='Enable NVIDIA Apex or Torch synchronized BatchNorm.') -parser.add_argument('--dist-bn', type=str, default='', - help='Distribute BatchNorm stats between nodes after each epoch ("broadcast", "reduce", or "")') -parser.add_argument('--split-bn', action='store_true', - help='Enable separate BN layers per augmentation split.') - -# Model Exponential Moving Average -parser.add_argument('--model-ema', action='store_true', default=False, - help='Enable tracking moving average of model weights') -parser.add_argument('--model-ema-force-cpu', action='store_true', default=False, - help='Force ema to be tracked on CPU, rank=0 node only. Disables EMA validation.') -parser.add_argument('--model-ema-decay', type=float, default=0.9998, - help='decay factor for model weights moving average (default: 0.9998)') - -# Misc -parser.add_argument('--seed', type=int, default=42, metavar='S', - help='random seed (default: 42)') -parser.add_argument('--log-interval', type=int, default=10, metavar='N', - help='how many batches to wait before logging training status') -parser.add_argument('--recovery-interval', type=int, default=0, metavar='N', - help='how many batches to wait before writing recovery checkpoint') -parser.add_argument('-j', '--workers', type=int, default=4, metavar='N', - help='how many training processes to use (default: 1)') -parser.add_argument('--num-gpu', type=int, default=1, - help='Number of GPUS to use') -parser.add_argument('--save-images', action='store_true', default=False, - help='save images of input bathes every log interval for debugging') -parser.add_argument('--amp', action='store_true', default=False, - help='use NVIDIA Apex AMP or Native AMP for mixed precision training') -parser.add_argument('--apex-amp', action='store_true', default=False, - help='Use NVIDIA Apex AMP mixed precision') -parser.add_argument('--apex-opt-level', type=int, default=1, - help='Use NVIDIA Apex Opt-level') -parser.add_argument('--native-amp', action='store_true', default=False, - help='Use Native Torch AMP mixed precision') -parser.add_argument('--channels-last', action='store_true', default=False, - help='Use channels_last memory layout') -parser.add_argument('--pin-mem', action='store_true', default=False, - help='Pin CPU memory in DataLoader for more efficient (sometimes) transfer to GPU.') -parser.add_argument('--no-prefetcher', action='store_true', default=False, - help='disable fast prefetcher') -parser.add_argument('--output', default='', type=str, metavar='PATH', - help='path to output folder (default: none, current dir)') -parser.add_argument('--eval-metric', default='top1', type=str, metavar='EVAL_METRIC', - help='Best metric (default: "top1"') -parser.add_argument('--tta', type=int, default=0, metavar='N', - help='Test/inference time augmentation (oversampling) factor. 0=None (default: 0)') -parser.add_argument("--local_rank", default=0, type=int) -parser.add_argument('--use-multi-epochs-loader', action='store_true', default=False, - help='use the multi-epochs-loader to save time at the beginning of every epoch') - - -parser.add_argument("--init_method", default='env://', type=str) -parser.add_argument('--debug', action='store_true', default=False, - help='Debug mode.') - - -def _parse_args(): - # Do we have a config file to parse? - args_config, remaining = config_parser.parse_known_args() - if args_config.config: - with open(args_config.config, 'r') as f: - cfg = yaml.safe_load(f) - parser.set_defaults(**cfg) - - # The main arg parser parses the rest of the args, the usual - # defaults will have been overridden if config file specified. - args = parser.parse_args(remaining) - - # Cache the args as a text string to save them in the output dir later - args_text = yaml.safe_dump(args.__dict__, default_flow_style=False) - return args, args_text - - -def main(): - setup_default_logging() - args, args_text = _parse_args() - - args.prefetcher = not args.no_prefetcher - args.distributed = False - if 'WORLD_SIZE' in os.environ: - args.distributed = int(os.environ['WORLD_SIZE']) > 1 - if args.distributed and args.num_gpu > 1: - _logger.warning( - 'Using more than one GPU per process in distributed mode is not allowed.Setting num_gpu to 1.') - args.num_gpu = 1 - - args.device = 'cuda:0' - args.world_size = 1 - args.rank = 0 # global rank - if args.distributed: - args.num_gpu = 1 - args.device = 'cuda:%d' % args.local_rank - torch.cuda.set_device(args.local_rank) - args.world_size = int(os.environ['WORLD_SIZE']) - args.rank = int(os.environ['RANK']) - torch.distributed.init_process_group(backend='nccl', init_method=args.init_method, rank=args.rank, world_size=args.world_size) - args.world_size = torch.distributed.get_world_size() - args.rank = torch.distributed.get_rank() - assert args.rank >= 0 - - if args.distributed: - _logger.info('Training in distributed mode with multiple processes, 1 GPU per process. Process %d, total %d.' - % (args.rank, args.world_size)) - else: - _logger.info('Training with a single process on %d GPUs.' % args.num_gpu) - - torch.manual_seed(args.seed + args.rank) - - - extra_dict = {} - extra_dict['args'] = args - model = create_model( - args.model, - pretrained=args.pretrained, - num_classes=args.num_classes, - drop_rate=args.drop, - drop_connect_rate=args.drop_connect, - drop_path_rate=args.drop_path, - drop_block_rate=args.drop_block, - global_pool=args.gp, - bn_tf=args.bn_tf, - bn_momentum=args.bn_momentum, - bn_eps=args.bn_eps, - checkpoint_path=args.initial_checkpoint, - **extra_dict) - - ################### flops ################# - if args.local_rank == 0: - print(model) - from thop import profile - from thop.vision.basic_hooks import zero_ops - if hasattr(model, 'default_cfg'): - default_cfg = model.default_cfg - input_size = [1] + list(default_cfg['input_size']) - else: - input_size = [1, 3, 224, 224] - input = torch.randn(input_size)#.cuda() - - - _, params = profile(model, inputs=(input, ), custom_ops={nn.BatchNorm2d: zero_ops}) - print('params:',params) - from torchprofile import profile_macs - macs = profile_macs(model, input) - print('model flops:', macs, 'input_size:', input_size) - - def backward_hook(module, grad_input, grad_output): - #print("==="*20) - print('Inside ' + module.__class__.__name__ + ' backward') - #print("input:") - #print([x.shape if x is not None else 0 for x in grad_input]) - #print("ouput:") - #print([x.shape if x is not None else 0 for x in grad_output]) - - def forward_hook(module, fea_input, fea_output): - #print("==="*20) - print('Inside ' + module.__class__.__name__ + ' forward') - #print("input: ") - #print([x.shape if x is not None else 0 for x in fea_input]) - #print("ouput:") - #print([x.shape if x is not None else 0 for x in fea_output]) - - if args.debug: - for net in model.children(): - net.register_backward_hook(backward_hook) - net.register_forward_hook(forward_hook) - - if args.local_rank == 0: - _logger.info('Model %s created, param count: %d' % - (args.model, sum([m.numel() for m in model.parameters()]))) - - data_config = resolve_data_config(vars(args), model=model, verbose=args.local_rank == 0) - - num_aug_splits = 0 - if args.aug_splits > 0: - assert args.aug_splits > 1, 'A split of 1 makes no sense' - num_aug_splits = args.aug_splits - - if args.split_bn: - assert num_aug_splits > 1 or args.resplit - model = convert_splitbn_model(model, max(num_aug_splits, 2)) - - use_amp = None - if args.amp: - # for backwards compat, `--amp` arg tries apex before native amp - if has_apex: - args.apex_amp = True - elif has_native_amp: - args.native_amp = True - if args.apex_amp and has_apex: - use_amp = 'apex' - elif args.native_amp and has_native_amp: - use_amp = 'native' - elif args.apex_amp or args.native_amp: - _logger.warning("Neither APEX or native Torch AMP is available, using float32. " - "Install NVIDA apex or upgrade to PyTorch 1.6") - - if args.num_gpu > 1: - if use_amp == 'apex': - _logger.warning( - 'Apex AMP does not work well with nn.DataParallel, disabling. Use DDP or Torch AMP.') - use_amp = None - model = nn.DataParallel(model, device_ids=list(range(args.num_gpu))).cuda() - assert not args.channels_last, "Channels last not supported with DP, use DDP." - else: - model.cuda() - if args.channels_last: - model = model.to(memory_format=torch.channels_last) - - optimizer = create_optimizer(args, model) - - amp_autocast = suppress # do nothing - loss_scaler = None - if use_amp == 'apex': - model, optimizer = amp.initialize(model, optimizer, opt_level="O{}".format(args.apex_opt_level)) - loss_scaler = ApexScaler() - if args.local_rank == 0: - _logger.info('Using NVIDIA APEX AMP. Training in mixed precision.') - elif use_amp == 'native': - amp_autocast = torch.cuda.amp.autocast - loss_scaler = NativeScaler() - if args.local_rank == 0: - _logger.info('Using native Torch AMP. Training in mixed precision.') - else: - if args.local_rank == 0: - _logger.info('AMP not enabled. Training in float32.') - - # optionally resume from a checkpoint - resume_epoch = None - if args.resume: - resume_epoch = resume_checkpoint( - model, args.resume, - optimizer=None if args.no_resume_opt else optimizer, - loss_scaler=None if args.no_resume_opt else loss_scaler, - log_info=args.local_rank == 0) - - model_ema = None - if args.model_ema: - # Important to create EMA model after cuda(), DP wrapper, and AMP but before SyncBN and DDP wrapper - model_ema = ModelEma( - model, - decay=args.model_ema_decay, - device='cpu' if args.model_ema_force_cpu else '', - resume=args.resume) - - if args.distributed: - if args.sync_bn: - assert not args.split_bn - try: - if has_apex and use_amp != 'native': - # Apex SyncBN preferred unless native amp is activated - model = convert_syncbn_model(model) - else: - model = torch.nn.SyncBatchNorm.convert_sync_batchnorm(model) - if args.local_rank == 0: - _logger.info( - 'Converted model to use Synchronized BatchNorm. WARNING: You may have issues if using ' - 'zero initialized BN layers (enabled by default for ResNets) while sync-bn enabled.') - except Exception as e: - _logger.error('Failed to enable Synchronized BatchNorm. Install Apex or Torch >= 1.1') - if has_apex and use_amp != 'native': - # Apex DDP preferred unless native amp is activated - if args.local_rank == 0: - _logger.info("Using NVIDIA APEX DistributedDataParallel.") - model = ApexDDP(model, delay_allreduce=True) - else: - if args.local_rank == 0: - _logger.info("Using native Torch DistributedDataParallel.") - #model = NativeDDP(model, device_ids=[args.local_rank]) # can use device str in Torch >= 1.1 - model = NativeDDP(model, device_ids=[args.local_rank],find_unused_parameters=True) - # NOTE: EMA model does not need to be wrapped by DDP - - lr_scheduler, num_epochs = create_scheduler(args, optimizer) - start_epoch = 0 - if args.start_epoch is not None: - # a specified start_epoch will always override the resume epoch - start_epoch = args.start_epoch - elif resume_epoch is not None: - start_epoch = resume_epoch - if lr_scheduler is not None and start_epoch > 0: - lr_scheduler.step(start_epoch) - - if args.local_rank == 0: - _logger.info('Scheduled epochs: {}'.format(num_epochs)) - - if 'cifar100' in args.data: - dataset_train = torchvision.datasets.CIFAR100(root=args.data, train=True, download=False, transform=None) - elif 'cifar10' in args.data: - dataset_train = torchvision.datasets.CIFAR10(root=args.data, train=True, download=False, transform=None) - else: - train_dir = os.path.join(args.data, 'train') - if not os.path.exists(train_dir): - _logger.error('Training folder does not exist at: {}'.format(train_dir)) - exit(1) - dataset_train = ImageDataset(train_dir) - - collate_fn = None - mixup_fn = None - mixup_active = args.mixup > 0 or args.cutmix > 0. or args.cutmix_minmax is not None - if mixup_active: - mixup_args = dict( - mixup_alpha=args.mixup, cutmix_alpha=args.cutmix, cutmix_minmax=args.cutmix_minmax, - prob=args.mixup_prob, switch_prob=args.mixup_switch_prob, mode=args.mixup_mode, - label_smoothing=args.smoothing, num_classes=args.num_classes) - if args.prefetcher: - assert not num_aug_splits # collate conflict (need to support deinterleaving in collate mixup) - collate_fn = FastCollateMixup(**mixup_args) - else: - mixup_fn = Mixup(**mixup_args) - - if num_aug_splits > 1: - dataset_train = AugMixDataset(dataset_train, num_splits=num_aug_splits) - - train_interpolation = args.train_interpolation - if args.no_aug or not train_interpolation: - train_interpolation = data_config['interpolation'] - loader_train = create_loader( - dataset_train, - input_size=data_config['input_size'], - batch_size=args.batch_size, - is_training=True, - use_prefetcher=args.prefetcher, - no_aug=args.no_aug, - re_prob=args.reprob, - re_mode=args.remode, - re_count=args.recount, - re_split=args.resplit, - scale=args.scale, - ratio=args.ratio, - hflip=args.hflip, - vflip=args.vflip, - color_jitter=args.color_jitter, - auto_augment=args.aa, - num_aug_splits=num_aug_splits, - interpolation=train_interpolation, - mean=data_config['mean'], - std=data_config['std'], - num_workers=args.workers, - distributed=args.distributed, - collate_fn=collate_fn, - pin_memory=args.pin_mem, - use_multi_epochs_loader=args.use_multi_epochs_loader, - repeated_aug=args.repeated_aug - ) - if 'cifar100' in args.data: - dataset_eval = torchvision.datasets.CIFAR100(root=args.data, train=False, download=False, transform=None) - elif 'cifar10' in args.data: - dataset_eval = torchvision.datasets.CIFAR10(root=args.data, train=False, download=False, transform=None) - else: - eval_dir = os.path.join(args.data, 'val') - if not os.path.isdir(eval_dir): - eval_dir = os.path.join(args.data, 'validation') - if not os.path.isdir(eval_dir): - _logger.error('Validation folder does not exist at: {}'.format(eval_dir)) - exit(1) - dataset_eval = ImageDataset(eval_dir) - - loader_eval = create_loader( - dataset_eval, - input_size=data_config['input_size'], - batch_size=args.validation_batch_size_multiplier * args.batch_size, - is_training=False, - use_prefetcher=args.prefetcher, - interpolation=data_config['interpolation'], - mean=data_config['mean'], - std=data_config['std'], - num_workers=args.workers, - distributed=args.distributed, - crop_pct=data_config['crop_pct'], - pin_memory=args.pin_mem, - ) - - if args.jsd: - assert num_aug_splits > 1 # JSD only valid with aug splits set - train_loss_fn = JsdCrossEntropy(num_splits=num_aug_splits, smoothing=args.smoothing).cuda() - elif mixup_active: - # smoothing is handled with mixup target transform - train_loss_fn = SoftTargetCrossEntropy().cuda() - elif args.smoothing: - train_loss_fn = LabelSmoothingCrossEntropy(smoothing=args.smoothing).cuda() - else: - train_loss_fn = nn.CrossEntropyLoss().cuda() - validate_loss_fn = nn.CrossEntropyLoss().cuda() - - eval_metric = args.eval_metric - best_metric = None - best_epoch = None - saver = None - output_dir = '' - if args.local_rank == 0: - output_base = args.output if args.output else './output' - exp_name = '-'.join([ - datetime.now().strftime("%Y%m%d-%H%M%S"), - args.model, - str(data_config['input_size'][-1]) - ]) - output_dir = get_outdir(output_base, 'train', exp_name) - decreasing = True if eval_metric == 'loss' else False - saver = CheckpointSaver( - model=model, optimizer=optimizer, args=args, model_ema=model_ema, amp_scaler=loss_scaler, - checkpoint_dir=output_dir, recovery_dir=output_dir, decreasing=decreasing, max_history=100) - - with open(os.path.join(output_dir, 'args.yaml'), 'w') as f: - f.write(args_text) - - try: - for epoch in range(start_epoch, num_epochs): - _logger.info(f"epoch: {epoch}") - if args.distributed: - loader_train.sampler.set_epoch(epoch) - - train_metrics = train_epoch( - epoch, model, loader_train, optimizer, train_loss_fn, args, - lr_scheduler=lr_scheduler, saver=saver, output_dir=output_dir, - amp_autocast=amp_autocast, loss_scaler=loss_scaler, model_ema=model_ema, mixup_fn=mixup_fn) - - if args.distributed and args.dist_bn in ('broadcast', 'reduce'): - if args.local_rank == 0: - _logger.info("Distributing BatchNorm running means and vars") - distribute_bn(model, args.world_size, args.dist_bn == 'reduce') - - eval_metrics = validate(model, loader_eval, validate_loss_fn, args, amp_autocast=amp_autocast) - - if model_ema is not None and not args.model_ema_force_cpu: - if args.distributed and args.dist_bn in ('broadcast', 'reduce'): - distribute_bn(model_ema, args.world_size, args.dist_bn == 'reduce') - ema_eval_metrics = validate( - model_ema.ema, loader_eval, validate_loss_fn, args, amp_autocast=amp_autocast, log_suffix=' (EMA)') - eval_metrics = ema_eval_metrics - - if lr_scheduler is not None: - # step LR for next epoch - lr_scheduler.step(epoch + 1, eval_metrics[eval_metric]) - - update_summary( - epoch, train_metrics, eval_metrics, os.path.join(output_dir, 'summary.csv'), - write_header=best_metric is None) - - if saver is not None: - # save proper checkpoint with eval metric - save_metric = eval_metrics[eval_metric] - best_metric, best_epoch = saver.save_checkpoint(epoch, metric=save_metric) - - except KeyboardInterrupt: - pass - if best_metric is not None: - _logger.info('*** Best metric: {0} (epoch {1})'.format(best_metric, best_epoch)) - - - -def train_epoch( - epoch, model, loader, optimizer, loss_fn, args, - lr_scheduler=None, saver=None, output_dir='', amp_autocast=suppress, - loss_scaler=None, model_ema=None, mixup_fn=None): - - if args.mixup_off_epoch and epoch >= args.mixup_off_epoch: - if args.prefetcher and loader.mixup_enabled: - loader.mixup_enabled = False - elif mixup_fn is not None: - mixup_fn.mixup_enabled = False - - second_order = hasattr(optimizer, 'is_second_order') and optimizer.is_second_order - batch_time_m = AverageMeter() - data_time_m = AverageMeter() - losses_m = AverageMeter() - - top1_m = AverageMeter() - top5_m = AverageMeter() - - - model.train() - - end = time.time() - last_idx = len(loader) - 1 - num_updates = epoch * len(loader) - for batch_idx, (input, target) in enumerate(loader): - last_batch = batch_idx == last_idx - data_time_m.update(time.time() - end) - if not args.prefetcher: - input, target = input.cuda(), target.cuda() - if mixup_fn is not None: - input, target = mixup_fn(input, target) - if args.channels_last: - input = input.contiguous(memory_format=torch.channels_last) - - with amp_autocast(): - output = model(input) - loss = loss_fn(output, target) - - acc1, acc5 = accuracy(output, target.argmax(dim=-1), topk=(1, 5)) - if args.distributed: - acc1 = reduce_tensor(acc1, args.world_size) - acc5 = reduce_tensor(acc5, args.world_size) - - if not args.distributed: - losses_m.update(loss.item(), input.size(0)) - - optimizer.zero_grad() - if loss_scaler is not None: - loss_scaler( - loss, optimizer, clip_grad=args.clip_grad, parameters=model.parameters(), create_graph=second_order) - else: - loss.backward(create_graph=second_order) - if args.clip_grad is not None: - torch.nn.utils.clip_grad_norm_(model.parameters(), args.clip_grad) - optimizer.step() - - torch.cuda.synchronize() - - top1_m.update(acc1.item(), output.size(0)) - top5_m.update(acc5.item(), output.size(0)) - - if model_ema is not None: - model_ema.update(model) - num_updates += 1 - - batch_time_m.update(time.time() - end) - if last_batch or batch_idx % args.log_interval == 0: - lrl = [param_group['lr'] for param_group in optimizer.param_groups] - lr = sum(lrl) / len(lrl) - - if args.distributed: - reduced_loss = reduce_tensor(loss.data, args.world_size) - losses_m.update(reduced_loss.item(), input.size(0)) - - if args.local_rank == 0: - _logger.info( - 'Train: {} [{:>4d}/{} ({:>3.0f}%)] ' - 'Loss: {loss.val:>9.6f} ({loss.avg:>6.4f}) ' - 'Time: {batch_time.val:.3f}s, {rate:>7.2f}/s ' - '({batch_time.avg:.3f}s, {rate_avg:>7.2f}/s) ' - 'LR: {lr:.3e} ' - 'Data: {data_time.val:.3f} ({data_time.avg:.3f})'.format( - epoch, - batch_idx, len(loader), - 100. * batch_idx / last_idx, - loss=losses_m, - batch_time=batch_time_m, - rate=input.size(0) * args.world_size / batch_time_m.val, - rate_avg=input.size(0) * args.world_size / batch_time_m.avg, - lr=lr, - data_time=data_time_m)) - _logger.info( - 'Acc@1: {top1.val:>7.4f} ({top1.avg:>7.4f}) ' - 'Acc@5: {top5.val:>7.4f} ({top5.avg:>7.4f})'.format(top1=top1_m, top5=top5_m)) - - if args.save_images and output_dir: - torchvision.utils.save_image( - input, - os.path.join(output_dir, 'train-batch-%d.jpg' % batch_idx), - padding=0, - normalize=True) - - if saver is not None and args.recovery_interval and ( - last_batch or (batch_idx + 1) % args.recovery_interval == 0): - saver.save_recovery(epoch, batch_idx=batch_idx) - - if lr_scheduler is not None: - lr_scheduler.step_update(num_updates=num_updates, metric=losses_m.avg) - - end = time.time() - # end for - - if hasattr(optimizer, 'sync_lookahead'): - optimizer.sync_lookahead() - - return OrderedDict([('loss', losses_m.avg)]) - - -def validate(model, loader, loss_fn, args, amp_autocast=suppress, log_suffix=''): - batch_time_m = AverageMeter() - losses_m = AverageMeter() - top1_m = AverageMeter() - top5_m = AverageMeter() - - model.eval() - - end = time.time() - last_idx = len(loader) - 1 - with torch.no_grad(): - for batch_idx, (input, target) in enumerate(loader): - last_batch = batch_idx == last_idx - if not args.prefetcher: - input = input.cuda() - target = target.cuda() - if args.channels_last: - input = input.contiguous(memory_format=torch.channels_last) - - with amp_autocast(): - output = model(input) - if isinstance(output, (tuple, list)): - output = output[0] - - # augmentation reduction - reduce_factor = args.tta - if reduce_factor > 1: - output = output.unfold(0, reduce_factor, reduce_factor).mean(dim=2) - target = target[0:target.size(0):reduce_factor] - - loss = loss_fn(output, target) - acc1, acc5 = accuracy(output, target, topk=(1, 5)) - - if args.distributed: - reduced_loss = reduce_tensor(loss.data, args.world_size) - acc1 = reduce_tensor(acc1, args.world_size) - acc5 = reduce_tensor(acc5, args.world_size) - else: - reduced_loss = loss.data - - torch.cuda.synchronize() - - losses_m.update(reduced_loss.item(), input.size(0)) - top1_m.update(acc1.item(), output.size(0)) - top5_m.update(acc5.item(), output.size(0)) - - batch_time_m.update(time.time() - end) - end = time.time() - if args.local_rank == 0 and (last_batch or batch_idx % args.log_interval == 0): - log_name = 'Test' + log_suffix - _logger.info( - '{0}: [{1:>4d}/{2}] ' - 'Time: {batch_time.val:.3f} ({batch_time.avg:.3f}) ' - 'Loss: {loss.val:>7.4f} ({loss.avg:>6.4f}) ' - 'Acc@1: {top1.val:>7.4f} ({top1.avg:>7.4f}) ' - 'Acc@5: {top5.val:>7.4f} ({top5.avg:>7.4f})'.format( - log_name, batch_idx, last_idx, batch_time=batch_time_m, - loss=losses_m, top1=top1_m, top5=top5_m)) - - metrics = OrderedDict([('loss', losses_m.avg), ('top1', top1_m.avg), ('top5', top5_m.avg)]) - - return metrics - - -if __name__ == '__main__': - main() -- Gitee

    N{eY$ghqiG-Spe@1p0x82UaluPo{Oa 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