From c696588a448705d11ae3e6bd5cb3f222083aa1b9 Mon Sep 17 00:00:00 2001 From: "xiaomei.wang" Date: Fri, 14 Apr 2023 13:56:19 +0800 Subject: [PATCH 1/9] Add FasterNet --- cv/classification/fasternet/README.MD | 64 ++++ .../fasternet/cfg/fasternet_l.yaml | 72 ++++ .../fasternet/cfg/fasternet_m.yaml | 72 ++++ .../fasternet/cfg/fasternet_s.yaml | 72 ++++ .../fasternet/cfg/fasternet_t0.yaml | 72 ++++ .../fasternet/cfg/fasternet_t1.yaml | 72 ++++ .../fasternet/cfg/fasternet_t2.yaml | 72 ++++ cv/classification/fasternet/data/__init__.py | 0 .../data/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 136 bytes .../custom_imagenet_data.cpython-39.pyc | Bin 0 -> 6722 bytes .../data/__pycache__/data_api.cpython-39.pyc | Bin 0 -> 1426 bytes .../fasternet/data/custom_imagenet_data.py | 237 ++++++++++++ cv/classification/fasternet/data/data_api.py | 47 +++ .../fasternet/detection/README.MD | 75 ++++ .../fasternet/detection/backbones/__init__.py | 1 + .../detection/backbones/fasternet.py | 59 +++ .../fasternet/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/detection/dist_test.sh | 22 ++ .../fasternet/detection/dist_train.sh | 20 + .../fasternet/detection/get_flops.py | 112 ++++++ cv/classification/fasternet/detection/test.py | 276 ++++++++++++++ .../fasternet/detection/train.py | 243 ++++++++++++ .../fasternet/models/__init__.py | 1 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 163 bytes .../__pycache__/fasternet.cpython-39.pyc | Bin 0 -> 8983 bytes .../__pycache__/model_api.cpython-39.pyc | Bin 0 -> 4800 bytes .../__pycache__/registry.cpython-39.pyc | Bin 0 -> 400 bytes .../fasternet/models/fasternet.py | 360 ++++++++++++++++++ .../fasternet/models/model_api.py | 158 ++++++++ .../fasternet/models/registry.py | 9 + cv/classification/fasternet/requirements.txt | 20 + cv/classification/fasternet/train_test.py | 152 ++++++++ cv/classification/fasternet/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 137 bytes .../__pycache__/fuse_conv_bn.cpython-39.pyc | Bin 0 -> 1675 bytes .../utils/__pycache__/loss.cpython-39.pyc | Bin 0 -> 2060 bytes .../utils/__pycache__/utils.cpython-39.pyc | Bin 0 -> 3675 bytes .../fasternet/utils/fuse_conv_bn.py | 60 +++ cv/classification/fasternet/utils/loss.py | 71 ++++ cv/classification/fasternet/utils/utils.py | 188 +++++++++ 50 files changed, 3148 insertions(+) create mode 100644 cv/classification/fasternet/README.MD create mode 100644 cv/classification/fasternet/cfg/fasternet_l.yaml create mode 100644 cv/classification/fasternet/cfg/fasternet_m.yaml create mode 100644 cv/classification/fasternet/cfg/fasternet_s.yaml create mode 100644 cv/classification/fasternet/cfg/fasternet_t0.yaml create mode 100644 cv/classification/fasternet/cfg/fasternet_t1.yaml create mode 100644 cv/classification/fasternet/cfg/fasternet_t2.yaml create mode 100644 cv/classification/fasternet/data/__init__.py create mode 100644 cv/classification/fasternet/data/__pycache__/__init__.cpython-39.pyc create mode 100644 cv/classification/fasternet/data/__pycache__/custom_imagenet_data.cpython-39.pyc create mode 100644 cv/classification/fasternet/data/__pycache__/data_api.cpython-39.pyc create mode 100644 cv/classification/fasternet/data/custom_imagenet_data.py create mode 100644 cv/classification/fasternet/data/data_api.py create mode 100644 cv/classification/fasternet/detection/README.MD create mode 100644 cv/classification/fasternet/detection/backbones/__init__.py create mode 100644 cv/classification/fasternet/detection/backbones/fasternet.py create mode 100644 cv/classification/fasternet/detection/benchmark.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/datasets/coco_detection.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/datasets/coco_instance.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/default_runtime.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/models/mask_rcnn_r50_fpn.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/schedules/schedule_1x.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/schedules/schedule_20e.py create mode 100644 cv/classification/fasternet/detection/configs/_base_/schedules/schedule_2x.py create mode 100644 cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py create mode 100644 cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py create mode 100644 cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py create mode 100755 cv/classification/fasternet/detection/dist_test.sh create mode 100755 cv/classification/fasternet/detection/dist_train.sh create mode 100644 cv/classification/fasternet/detection/get_flops.py create mode 100644 cv/classification/fasternet/detection/test.py create mode 100644 cv/classification/fasternet/detection/train.py create mode 100644 cv/classification/fasternet/models/__init__.py create mode 100644 cv/classification/fasternet/models/__pycache__/__init__.cpython-39.pyc create mode 100644 cv/classification/fasternet/models/__pycache__/fasternet.cpython-39.pyc create mode 100644 cv/classification/fasternet/models/__pycache__/model_api.cpython-39.pyc create mode 100644 cv/classification/fasternet/models/__pycache__/registry.cpython-39.pyc create mode 100644 cv/classification/fasternet/models/fasternet.py create mode 100644 cv/classification/fasternet/models/model_api.py create mode 100644 cv/classification/fasternet/models/registry.py create mode 100644 cv/classification/fasternet/requirements.txt create mode 100644 cv/classification/fasternet/train_test.py create mode 100644 cv/classification/fasternet/utils/__init__.py create mode 100644 cv/classification/fasternet/utils/__pycache__/__init__.cpython-39.pyc create mode 100644 cv/classification/fasternet/utils/__pycache__/fuse_conv_bn.cpython-39.pyc create mode 100644 cv/classification/fasternet/utils/__pycache__/loss.cpython-39.pyc create mode 100644 cv/classification/fasternet/utils/__pycache__/utils.cpython-39.pyc create mode 100644 cv/classification/fasternet/utils/fuse_conv_bn.py create mode 100644 cv/classification/fasternet/utils/loss.py create mode 100644 cv/classification/fasternet/utils/utils.py diff --git a/cv/classification/fasternet/README.MD b/cv/classification/fasternet/README.MD new file mode 100644 index 000000000..643d79826 --- /dev/null +++ b/cv/classification/fasternet/README.MD @@ -0,0 +1,64 @@ +# FasterNet + +## Model description + +This is the official Pytorch/PytorchLightning implementation of the paper:
+> [**Run, Don't Walk: Chasing Higher FLOPS for Faster Neural Networks**](https://arxiv.org/abs/2303.03667) +> Jierun Chen, Shiu-hong Kao, Hao He, Weipeng Zhuo, Song Wen, Chul-Ho Lee, S.-H. Gary Chan +> *IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR), 2023* +> + +--- +We propose a simple yet fast and effective partial convolution (**PConv**), as well as a latency-efficient family of architectures called **FasterNet**. + +## Step 1: Installing +### 1. Dependency Setup +Clone this repo and install required packages: +``` +pip install -r requirements.txt +``` + +### 2. Dataset Preparation + +Download the [ImageNet-1K](http://image-net.org/) classification dataset and structure the data as follows: +``` +/path/to/imagenet-1k/ + train/ + class1/ + img1.jpeg + class2/ + img2.jpeg + val/ + class1/ + img3.jpeg + class2/ + img4.jpeg +``` + +## Step 2: Training + +FasterNet-T0 training on ImageNet-1K with a 8-GPU node: +``` +python3 train_test.py -g 0,1,2,3,4,5,6,7 --num_nodes 1 -n 4 -b 4096 -e 2000 \ +--data_dir /home/datasets/cv/imagenet --pin_memory --wandb_project_name fasternet \ +--model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml +``` + +FasterNet-T0 training on ImageNet-1K with a 8-GPU node: +``` +python3 train_test.py -g 0 --num_nodes 1 -n 4 -b 4096 -e 2000 \ +--data_dir ../../data/imagenet --pin_memory --wandb_project_name fasternet \ +--model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml +``` + +To train other FasterNet variants, `--cfg` need to be changed. You may also want to change the training batch size `-b`. + + +## Result + +| GPU | FP32 | +| ----------- | ------------------------------------ | +| 8 cards | test_acc1 71.832 val_acc1 71.722 | + +## Reference +This repository is built using the [timm](https://github.com/rwightman/pytorch-image-models) , [poolformer](https://github.com/sail-sg/poolformer), [ConvNeXt](https://github.com/facebookresearch/ConvNeXt) and [mmdetection](https://github.com/open-mmlab/mmdetection) repositories. diff --git a/cv/classification/fasternet/cfg/fasternet_l.yaml b/cv/classification/fasternet/cfg/fasternet_l.yaml new file mode 100644 index 000000000..8932f6cdc --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_l.yaml @@ -0,0 +1,72 @@ +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/cfg/fasternet_m.yaml b/cv/classification/fasternet/cfg/fasternet_m.yaml new file mode 100644 index 000000000..651976879 --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_m.yaml @@ -0,0 +1,72 @@ +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/cfg/fasternet_s.yaml b/cv/classification/fasternet/cfg/fasternet_s.yaml new file mode 100644 index 000000000..80b17d2eb --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_s.yaml @@ -0,0 +1,72 @@ +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/cfg/fasternet_t0.yaml b/cv/classification/fasternet/cfg/fasternet_t0.yaml new file mode 100644 index 000000000..9a2c2915e --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_t0.yaml @@ -0,0 +1,72 @@ +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/cfg/fasternet_t1.yaml b/cv/classification/fasternet/cfg/fasternet_t1.yaml new file mode 100644 index 000000000..d9af3f8b1 --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_t1.yaml @@ -0,0 +1,72 @@ +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/cfg/fasternet_t2.yaml b/cv/classification/fasternet/cfg/fasternet_t2.yaml new file mode 100644 index 000000000..17d3eb5d9 --- /dev/null +++ b/cv/classification/fasternet/cfg/fasternet_t2.yaml @@ -0,0 +1,72 @@ +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/data/__init__.py b/cv/classification/fasternet/data/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cv/classification/fasternet/data/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/data/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c13cc637e2da5b3ffd2f15880d6f37999f9cf669 GIT binary patch literal 136 zcmYe~<>g`kf@vSLQ$X}%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!Hnenx(7s(wXg zB9O||D^JWz*LO=SE=eu&OD)k)Ni0d!kB`sH%PfhH*DI*J#bJ}1pHiBWY6mjrGY~TX E0898DEC2ui literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/data/__pycache__/custom_imagenet_data.cpython-39.pyc b/cv/classification/fasternet/data/__pycache__/custom_imagenet_data.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5de39b5bd0a12595afcc647b63d795af6c09eb93 GIT binary patch literal 6722 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 literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/data/__pycache__/data_api.cpython-39.pyc b/cv/classification/fasternet/data/__pycache__/data_api.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5e3643b50c5bf8ac67d5906fec49b4237898fb61 GIT binary patch literal 1426 zcmZ8hJ8v8}5GJ|Ld+H<$K?ECyqACX`ryx~|Ac^6`fB{>LQn4YZBXy#+ySE^DvSsX5 z3ep4yQl*y4wD~zix>W8Aq)U^`?46^tN$}$g=i}@=h?Rpum%#Y#?F02oM#x{NY>ph1 z?_jx~0TfZRAbhn`PFtOErpfc@I&Lx1>^g;&-H;oKljmz|4su6RV0IPJof}5c4=Z|Q zpZ8liDhB0{4_i3~d5dp>oXjX6sZ=FD5x%YHF&SrXAQo~orXhFUepwjjLEf7#oS&EC zNhxQ#(*Aqt<+Hh36dH^lpDawFgjw5!x3Y4lb6bYNQ?o&xQgpo@SeXH=N3h(dU{PcV zIWL)_%cvpG$ub6{%LI@qvY_@0A9*}uSM-WjC?(4jFkNPVnPTV6a-XZHiFZkp-X%?T zmjIJB@iPCP(X@=@14gp!0HdSgbM`B>JH88A4_4m~6m1A`@mE-+Q{-lL}vkB`OC!)HGn+dIf+ zCyu8l4zuKGB`{o`RjbHu^Z1?EPk{Z;=Z9zWQXjrF5;ik=A*hl-`GRKo3}-vi599NA#nAW42F+s51uV?C*S()0B;O0-Hk( z-K7hesa&n6kX_ILCRzHPS) RkW-xZX`c=udzeug{RfGvit7LX literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/data/custom_imagenet_data.py b/cv/classification/fasternet/data/custom_imagenet_data.py new file mode 100644 index 000000000..5ed8ed9c2 --- /dev/null +++ b/cv/classification/fasternet/data/custom_imagenet_data.py @@ -0,0 +1,237 @@ +# 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/data/data_api.py b/cv/classification/fasternet/data/data_api.py new file mode 100644 index 000000000..082c5a27c --- /dev/null +++ b/cv/classification/fasternet/data/data_api.py @@ -0,0 +1,47 @@ +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/detection/README.MD b/cv/classification/fasternet/detection/README.MD new file mode 100644 index 000000000..fb0355c05 --- /dev/null +++ b/cv/classification/fasternet/detection/README.MD @@ -0,0 +1,75 @@ +# 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/detection/backbones/__init__.py b/cv/classification/fasternet/detection/backbones/__init__.py new file mode 100644 index 000000000..2249d1d23 --- /dev/null +++ b/cv/classification/fasternet/detection/backbones/__init__.py @@ -0,0 +1 @@ +from .fasternet import * \ No newline at end of file diff --git a/cv/classification/fasternet/detection/backbones/fasternet.py b/cv/classification/fasternet/detection/backbones/fasternet.py new file mode 100644 index 000000000..a8ab981c9 --- /dev/null +++ b/cv/classification/fasternet/detection/backbones/fasternet.py @@ -0,0 +1,59 @@ +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/detection/benchmark.py b/cv/classification/fasternet/detection/benchmark.py new file mode 100644 index 000000000..d1629070d --- /dev/null +++ b/cv/classification/fasternet/detection/benchmark.py @@ -0,0 +1,197 @@ +# 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/detection/configs/_base_/datasets/coco_detection.py b/cv/classification/fasternet/detection/configs/_base_/datasets/coco_detection.py new file mode 100644 index 000000000..149f590bb --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/datasets/coco_detection.py @@ -0,0 +1,49 @@ +# 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/detection/configs/_base_/datasets/coco_instance.py b/cv/classification/fasternet/detection/configs/_base_/datasets/coco_instance.py new file mode 100644 index 000000000..9901a8584 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/datasets/coco_instance.py @@ -0,0 +1,49 @@ +# 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/detection/configs/_base_/default_runtime.py b/cv/classification/fasternet/detection/configs/_base_/default_runtime.py new file mode 100644 index 000000000..5b0b1452c --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/default_runtime.py @@ -0,0 +1,27 @@ +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/detection/configs/_base_/models/mask_rcnn_r50_fpn.py b/cv/classification/fasternet/detection/configs/_base_/models/mask_rcnn_r50_fpn.py new file mode 100644 index 000000000..d903e55e2 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/models/mask_rcnn_r50_fpn.py @@ -0,0 +1,120 @@ +# 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/detection/configs/_base_/schedules/schedule_1x.py b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_1x.py new file mode 100644 index 000000000..13b3783cb --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_1x.py @@ -0,0 +1,11 @@ +# 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/detection/configs/_base_/schedules/schedule_20e.py b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_20e.py new file mode 100644 index 000000000..00e859022 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_20e.py @@ -0,0 +1,11 @@ +# 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/detection/configs/_base_/schedules/schedule_2x.py b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_2x.py new file mode 100644 index 000000000..69dc9ee80 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_2x.py @@ -0,0 +1,11 @@ +# 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/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py new file mode 100644 index 000000000..1c2134bc4 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py @@ -0,0 +1,22 @@ +_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/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py new file mode 100644 index 000000000..20a896271 --- /dev/null +++ b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py @@ -0,0 +1,22 @@ +_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/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py new file mode 100644 index 000000000..f5f84c30a --- /dev/null +++ b/cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py @@ -0,0 +1,22 @@ +_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/detection/dist_test.sh b/cv/classification/fasternet/detection/dist_test.sh new file mode 100755 index 000000000..dea131b43 --- /dev/null +++ b/cv/classification/fasternet/detection/dist_test.sh @@ -0,0 +1,22 @@ +#!/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/detection/dist_train.sh b/cv/classification/fasternet/detection/dist_train.sh new file mode 100755 index 000000000..aa71bf4ae --- /dev/null +++ b/cv/classification/fasternet/detection/dist_train.sh @@ -0,0 +1,20 @@ +#!/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/detection/get_flops.py b/cv/classification/fasternet/detection/get_flops.py new file mode 100644 index 000000000..8b99dfd30 --- /dev/null +++ b/cv/classification/fasternet/detection/get_flops.py @@ -0,0 +1,112 @@ +# 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/detection/test.py b/cv/classification/fasternet/detection/test.py new file mode 100644 index 000000000..d9c5c3706 --- /dev/null +++ b/cv/classification/fasternet/detection/test.py @@ -0,0 +1,276 @@ +# 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/detection/train.py b/cv/classification/fasternet/detection/train.py new file mode 100644 index 000000000..db062a9ad --- /dev/null +++ b/cv/classification/fasternet/detection/train.py @@ -0,0 +1,243 @@ +# 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/models/__init__.py b/cv/classification/fasternet/models/__init__.py new file mode 100644 index 000000000..30c636589 --- /dev/null +++ b/cv/classification/fasternet/models/__init__.py @@ -0,0 +1 @@ +from .registry import * \ No newline at end of file diff --git a/cv/classification/fasternet/models/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/models/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6adab8a421d392cddf57a31ca4915154276a9ab5 GIT binary patch literal 163 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 aX&i(V7O-L%r?jnC&Q!iqd8#s1nfgCq?)K3D literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/models/__pycache__/model_api.cpython-39.pyc b/cv/classification/fasternet/models/__pycache__/model_api.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b49b41b9b94ff443ee54b5d4e66254dec79c33d GIT binary patch literal 4800 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 mgZC)Y zFku-YXsJRKy}>J%fx 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/models/model_api.py b/cv/classification/fasternet/models/model_api.py new file mode 100644 index 000000000..b4021b6ab --- /dev/null +++ b/cv/classification/fasternet/models/model_api.py @@ -0,0 +1,158 @@ +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/models/registry.py b/cv/classification/fasternet/models/registry.py new file mode 100644 index 000000000..169a6645a --- /dev/null +++ b/cv/classification/fasternet/models/registry.py @@ -0,0 +1,9 @@ +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/requirements.txt b/cv/classification/fasternet/requirements.txt new file mode 100644 index 000000000..e02c51aab --- /dev/null +++ b/cv/classification/fasternet/requirements.txt @@ -0,0 +1,20 @@ +# 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 diff --git a/cv/classification/fasternet/train_test.py b/cv/classification/fasternet/train_test.py new file mode 100644 index 000000000..127e13b6c --- /dev/null +++ b/cv/classification/fasternet/train_test.py @@ -0,0 +1,152 @@ +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/utils/__init__.py b/cv/classification/fasternet/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cv/classification/fasternet/utils/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/utils/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ab051312a6806e4b6fc6c19b717fee27f009221 GIT binary patch literal 137 zcmYe~<>g`kf@vSLQ$X}%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HXenx(7s(wXg zB9O||D^JWz*LO=SE=eu&OD)kaEy>I&){l?R%*!l^kJl@xyv1RYo1apelWGSt=Q9v9 F004As9>f3u literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/utils/__pycache__/fuse_conv_bn.cpython-39.pyc b/cv/classification/fasternet/utils/__pycache__/fuse_conv_bn.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d820a0ad768fbfb5ce0e021d4915faf53d69701a GIT binary patch literal 1675 zcmbtUy>A;g6eoGq>2$UQqi_-f=|FU<&_D(<1%^@N!wAr!LXm7j3zfQ~taDC0ndDiK zahj5Up&g10_Sn6D4cAWDI(Kp3qin%0x|IihzxR8O@BQA%ot>0G`}MDH@?YA7{E3^p zjl==K7JhMbZWgOTR6rsg58bn4h;)X-CYMOQcz z*tcMgp|>BAEBctMxJxcO4Qu#i3OZXk!|wz%_TauDBNFZd%06lM9sym7x^M>_e2y;u zcwJj1&|x8UF2-6E+Et>`O3bRfE>%BG1+*9D#2$tf?t=W+TKB&XGQC6b3K2kYti%Km z^ZrH_An!@O9Nd=+f^R~c?pWAh9}4s^-*|)O2cId#t+(ytg(^;_&hv30t#7%?WK*AB zC{x){S-ewz+tgYY`eZayQhRRCjPqN!XXn!RNX@NhTKmoq(#V-|%J{ZXb}HwfUDa-s zO{LbVw7r(WG@1woA7cbYi<^1uF>XU=l(gOHE zxr5pjr9HqfjRMSA_vcH$GrD^c1B~5+fuu3rqx_mj`!uFsTqo>HY97IPkNJ3=B7`8HL2iwcg7$gCSG0*%3{JN|mr`=J8`#F=Z{Xw` zmDR=;=c-%=s{D(5LT*wWm~mVi$RDtBqKwj+dLrBuIi@pLR9c#)s3u}8T{acEGBZ)i zr7~6&R$%1;ajMBA0F7%0v<9Q7k8}ux2M!2XBHeHEETmBaDfdJyrUk&N_w&jsz?-T7 zgo2qu5@W(d;l!eF(*Qd+DpNW78!F_+7m&2_9II?Lubo7{EgBDKwwTS!VzLxkxkY8( z3F}Oqf$z%xXX&j|e!ryFRrvqQ3M#6rp$KvyeNpBRZ=V*n(AMFLO&5sd+iM4`?}VUZ z%zZj~i3u3sdgtv@XPa$cs!v9@O38P*(ynkzALAe6Y3{f0vc4CaeK0cYlu#_8IELNL za)hpV9>!L1(5I*j-U3u8y!G%9Ak0@VJce#@LAsoBwo5tfUUQaEMpK%yE)>)@oW(4q wK_1K}AncRyBk60sesa8yZ+J_PyJHK>-Jn6A9IYSuE&e4eR$xN6qx}c}0DpSaiU0rr literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/utils/__pycache__/loss.cpython-39.pyc b/cv/classification/fasternet/utils/__pycache__/loss.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6af4a40087c6eedd26fd2d1019c1f38dc410ca1c GIT binary patch literal 2060 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 literal 0 HcmV?d00001 diff --git a/cv/classification/fasternet/utils/fuse_conv_bn.py b/cv/classification/fasternet/utils/fuse_conv_bn.py new file mode 100644 index 000000000..8f1b7686a --- /dev/null +++ b/cv/classification/fasternet/utils/fuse_conv_bn.py @@ -0,0 +1,60 @@ +# 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/utils/loss.py b/cv/classification/fasternet/utils/loss.py new file mode 100644 index 000000000..ed725e0aa --- /dev/null +++ b/cv/classification/fasternet/utils/loss.py @@ -0,0 +1,71 @@ +# 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/utils/utils.py b/cv/classification/fasternet/utils/utils.py new file mode 100644 index 000000000..a4970342c --- /dev/null +++ b/cv/classification/fasternet/utils/utils.py @@ -0,0 +1,188 @@ +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 -- Gitee From 1362d22524751a028d37593b2c222a1df83d94bb Mon Sep 17 00:00:00 2001 From: "xiaomei.wang" Date: Fri, 14 Apr 2023 14:07:16 +0800 Subject: [PATCH 2/9] Add FasterNet --- cv/classification/fasternet/{ => pytorch}/README.MD | 0 .../fasternet/{ => pytorch}/cfg/fasternet_l.yaml | 0 .../fasternet/{ => pytorch}/cfg/fasternet_m.yaml | 0 .../fasternet/{ => pytorch}/cfg/fasternet_s.yaml | 0 .../fasternet/{ => pytorch}/cfg/fasternet_t0.yaml | 0 .../fasternet/{ => pytorch}/cfg/fasternet_t1.yaml | 0 .../fasternet/{ => pytorch}/cfg/fasternet_t2.yaml | 0 .../fasternet/{ => pytorch}/data/__init__.py | 0 .../data/__pycache__/__init__.cpython-39.pyc | Bin .../__pycache__/custom_imagenet_data.cpython-39.pyc | Bin .../data/__pycache__/data_api.cpython-39.pyc | Bin .../{ => pytorch}/data/custom_imagenet_data.py | 0 .../fasternet/{ => pytorch}/data/data_api.py | 0 .../fasternet/{ => pytorch}/detection/README.MD | 0 .../{ => pytorch}/detection/backbones/__init__.py | 0 .../{ => pytorch}/detection/backbones/fasternet.py | 0 .../fasternet/{ => pytorch}/detection/benchmark.py | 0 .../configs/_base_/datasets/coco_detection.py | 0 .../configs/_base_/datasets/coco_instance.py | 0 .../detection/configs/_base_/default_runtime.py | 0 .../configs/_base_/models/mask_rcnn_r50_fpn.py | 0 .../configs/_base_/schedules/schedule_1x.py | 0 .../configs/_base_/schedules/schedule_20e.py | 0 .../configs/_base_/schedules/schedule_2x.py | 0 .../fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py | 0 .../fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py | 0 .../fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py | 0 .../fasternet/{ => pytorch}/detection/dist_test.sh | 0 .../fasternet/{ => pytorch}/detection/dist_train.sh | 0 .../fasternet/{ => pytorch}/detection/get_flops.py | 0 .../fasternet/{ => pytorch}/detection/test.py | 0 .../fasternet/{ => pytorch}/detection/train.py | 0 .../fasternet/{ => pytorch}/models/__init__.py | 0 .../models/__pycache__/__init__.cpython-39.pyc | Bin .../models/__pycache__/fasternet.cpython-39.pyc | Bin .../models/__pycache__/model_api.cpython-39.pyc | Bin .../models/__pycache__/registry.cpython-39.pyc | Bin .../fasternet/{ => pytorch}/models/fasternet.py | 0 .../fasternet/{ => pytorch}/models/model_api.py | 0 .../fasternet/{ => pytorch}/models/registry.py | 0 .../fasternet/{ => pytorch}/requirements.txt | 0 .../fasternet/{ => pytorch}/train_test.py | 0 .../fasternet/{ => pytorch}/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-39.pyc | Bin .../utils/__pycache__/fuse_conv_bn.cpython-39.pyc | Bin .../utils/__pycache__/loss.cpython-39.pyc | Bin .../utils/__pycache__/utils.cpython-39.pyc | Bin .../fasternet/{ => pytorch}/utils/fuse_conv_bn.py | 0 .../fasternet/{ => pytorch}/utils/loss.py | 0 .../fasternet/{ => pytorch}/utils/utils.py | 0 50 files changed, 0 insertions(+), 0 deletions(-) rename cv/classification/fasternet/{ => pytorch}/README.MD (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_l.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_m.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_s.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_t0.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_t1.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/cfg/fasternet_t2.yaml (100%) rename cv/classification/fasternet/{ => pytorch}/data/__init__.py (100%) rename cv/classification/fasternet/{ => pytorch}/data/__pycache__/__init__.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/data/__pycache__/custom_imagenet_data.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/data/__pycache__/data_api.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/data/custom_imagenet_data.py (100%) rename cv/classification/fasternet/{ => pytorch}/data/data_api.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/README.MD (100%) rename cv/classification/fasternet/{ => pytorch}/detection/backbones/__init__.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/backbones/fasternet.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/benchmark.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/datasets/coco_detection.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/datasets/coco_instance.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/default_runtime.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/models/mask_rcnn_r50_fpn.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/schedules/schedule_1x.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/schedules/schedule_20e.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/_base_/schedules/schedule_2x.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/dist_test.sh (100%) rename cv/classification/fasternet/{ => pytorch}/detection/dist_train.sh (100%) rename cv/classification/fasternet/{ => pytorch}/detection/get_flops.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/test.py (100%) rename cv/classification/fasternet/{ => pytorch}/detection/train.py (100%) rename cv/classification/fasternet/{ => pytorch}/models/__init__.py (100%) rename cv/classification/fasternet/{ => pytorch}/models/__pycache__/__init__.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/models/__pycache__/fasternet.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/models/__pycache__/model_api.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/models/__pycache__/registry.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/models/fasternet.py (100%) rename cv/classification/fasternet/{ => pytorch}/models/model_api.py (100%) rename cv/classification/fasternet/{ => pytorch}/models/registry.py (100%) rename cv/classification/fasternet/{ => pytorch}/requirements.txt (100%) rename cv/classification/fasternet/{ => pytorch}/train_test.py (100%) rename cv/classification/fasternet/{ => pytorch}/utils/__init__.py (100%) rename cv/classification/fasternet/{ => pytorch}/utils/__pycache__/__init__.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/utils/__pycache__/fuse_conv_bn.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/utils/__pycache__/loss.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/utils/__pycache__/utils.cpython-39.pyc (100%) rename cv/classification/fasternet/{ => pytorch}/utils/fuse_conv_bn.py (100%) rename cv/classification/fasternet/{ => pytorch}/utils/loss.py (100%) rename cv/classification/fasternet/{ => pytorch}/utils/utils.py (100%) diff --git a/cv/classification/fasternet/README.MD b/cv/classification/fasternet/pytorch/README.MD similarity index 100% rename from cv/classification/fasternet/README.MD rename to cv/classification/fasternet/pytorch/README.MD diff --git a/cv/classification/fasternet/cfg/fasternet_l.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_l.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_l.yaml diff --git a/cv/classification/fasternet/cfg/fasternet_m.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_m.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_m.yaml diff --git a/cv/classification/fasternet/cfg/fasternet_s.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_s.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_s.yaml diff --git a/cv/classification/fasternet/cfg/fasternet_t0.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_t0.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_t0.yaml diff --git a/cv/classification/fasternet/cfg/fasternet_t1.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_t1.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_t1.yaml diff --git a/cv/classification/fasternet/cfg/fasternet_t2.yaml b/cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml similarity index 100% rename from cv/classification/fasternet/cfg/fasternet_t2.yaml rename to cv/classification/fasternet/pytorch/cfg/fasternet_t2.yaml diff --git a/cv/classification/fasternet/data/__init__.py b/cv/classification/fasternet/pytorch/data/__init__.py similarity index 100% rename from cv/classification/fasternet/data/__init__.py rename to cv/classification/fasternet/pytorch/data/__init__.py diff --git a/cv/classification/fasternet/data/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/__init__.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/data/__pycache__/__init__.cpython-39.pyc rename to cv/classification/fasternet/pytorch/data/__pycache__/__init__.cpython-39.pyc diff --git a/cv/classification/fasternet/data/__pycache__/custom_imagenet_data.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/custom_imagenet_data.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/data/__pycache__/custom_imagenet_data.cpython-39.pyc rename to cv/classification/fasternet/pytorch/data/__pycache__/custom_imagenet_data.cpython-39.pyc diff --git a/cv/classification/fasternet/data/__pycache__/data_api.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/data_api.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/data/__pycache__/data_api.cpython-39.pyc rename to cv/classification/fasternet/pytorch/data/__pycache__/data_api.cpython-39.pyc diff --git a/cv/classification/fasternet/data/custom_imagenet_data.py b/cv/classification/fasternet/pytorch/data/custom_imagenet_data.py similarity index 100% rename from cv/classification/fasternet/data/custom_imagenet_data.py rename to cv/classification/fasternet/pytorch/data/custom_imagenet_data.py diff --git a/cv/classification/fasternet/data/data_api.py b/cv/classification/fasternet/pytorch/data/data_api.py similarity index 100% rename from cv/classification/fasternet/data/data_api.py rename to cv/classification/fasternet/pytorch/data/data_api.py diff --git a/cv/classification/fasternet/detection/README.MD b/cv/classification/fasternet/pytorch/detection/README.MD similarity index 100% rename from cv/classification/fasternet/detection/README.MD rename to cv/classification/fasternet/pytorch/detection/README.MD diff --git a/cv/classification/fasternet/detection/backbones/__init__.py b/cv/classification/fasternet/pytorch/detection/backbones/__init__.py similarity index 100% rename from cv/classification/fasternet/detection/backbones/__init__.py rename to cv/classification/fasternet/pytorch/detection/backbones/__init__.py diff --git a/cv/classification/fasternet/detection/backbones/fasternet.py b/cv/classification/fasternet/pytorch/detection/backbones/fasternet.py similarity index 100% rename from cv/classification/fasternet/detection/backbones/fasternet.py rename to cv/classification/fasternet/pytorch/detection/backbones/fasternet.py diff --git a/cv/classification/fasternet/detection/benchmark.py b/cv/classification/fasternet/pytorch/detection/benchmark.py similarity index 100% rename from cv/classification/fasternet/detection/benchmark.py rename to cv/classification/fasternet/pytorch/detection/benchmark.py diff --git a/cv/classification/fasternet/detection/configs/_base_/datasets/coco_detection.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/datasets/coco_detection.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_detection.py diff --git a/cv/classification/fasternet/detection/configs/_base_/datasets/coco_instance.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/datasets/coco_instance.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/datasets/coco_instance.py diff --git a/cv/classification/fasternet/detection/configs/_base_/default_runtime.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/default_runtime.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/default_runtime.py diff --git a/cv/classification/fasternet/detection/configs/_base_/models/mask_rcnn_r50_fpn.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/models/mask_rcnn_r50_fpn.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/models/mask_rcnn_r50_fpn.py diff --git a/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_1x.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/schedules/schedule_1x.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_1x.py diff --git a/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_20e.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/schedules/schedule_20e.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_20e.py diff --git a/cv/classification/fasternet/detection/configs/_base_/schedules/schedule_2x.py b/cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py similarity index 100% rename from cv/classification/fasternet/detection/configs/_base_/schedules/schedule_2x.py rename to cv/classification/fasternet/pytorch/detection/configs/_base_/schedules/schedule_2x.py diff --git a/cv/classification/fasternet/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 similarity index 100% rename from cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py rename to cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_l_fpn_1x_coco.py diff --git a/cv/classification/fasternet/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 similarity index 100% rename from cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py rename to cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_m_fpn_1x_coco.py diff --git a/cv/classification/fasternet/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 similarity index 100% rename from cv/classification/fasternet/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py rename to cv/classification/fasternet/pytorch/detection/configs/fasternet/mask_rcnn_fasternet_s_fpn_1x_coco.py diff --git a/cv/classification/fasternet/detection/dist_test.sh b/cv/classification/fasternet/pytorch/detection/dist_test.sh similarity index 100% rename from cv/classification/fasternet/detection/dist_test.sh rename to cv/classification/fasternet/pytorch/detection/dist_test.sh diff --git a/cv/classification/fasternet/detection/dist_train.sh b/cv/classification/fasternet/pytorch/detection/dist_train.sh similarity index 100% rename from cv/classification/fasternet/detection/dist_train.sh rename to cv/classification/fasternet/pytorch/detection/dist_train.sh diff --git a/cv/classification/fasternet/detection/get_flops.py b/cv/classification/fasternet/pytorch/detection/get_flops.py similarity index 100% rename from cv/classification/fasternet/detection/get_flops.py rename to cv/classification/fasternet/pytorch/detection/get_flops.py diff --git a/cv/classification/fasternet/detection/test.py b/cv/classification/fasternet/pytorch/detection/test.py similarity index 100% rename from cv/classification/fasternet/detection/test.py rename to cv/classification/fasternet/pytorch/detection/test.py diff --git a/cv/classification/fasternet/detection/train.py b/cv/classification/fasternet/pytorch/detection/train.py similarity index 100% rename from cv/classification/fasternet/detection/train.py rename to cv/classification/fasternet/pytorch/detection/train.py diff --git a/cv/classification/fasternet/models/__init__.py b/cv/classification/fasternet/pytorch/models/__init__.py similarity index 100% rename from cv/classification/fasternet/models/__init__.py rename to cv/classification/fasternet/pytorch/models/__init__.py diff --git a/cv/classification/fasternet/models/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/__init__.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/models/__pycache__/__init__.cpython-39.pyc rename to cv/classification/fasternet/pytorch/models/__pycache__/__init__.cpython-39.pyc diff --git a/cv/classification/fasternet/models/__pycache__/fasternet.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/fasternet.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/models/__pycache__/fasternet.cpython-39.pyc rename to cv/classification/fasternet/pytorch/models/__pycache__/fasternet.cpython-39.pyc diff --git a/cv/classification/fasternet/models/__pycache__/model_api.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/model_api.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/models/__pycache__/model_api.cpython-39.pyc rename to cv/classification/fasternet/pytorch/models/__pycache__/model_api.cpython-39.pyc diff --git a/cv/classification/fasternet/models/__pycache__/registry.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/registry.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/models/__pycache__/registry.cpython-39.pyc rename to cv/classification/fasternet/pytorch/models/__pycache__/registry.cpython-39.pyc diff --git a/cv/classification/fasternet/models/fasternet.py b/cv/classification/fasternet/pytorch/models/fasternet.py similarity index 100% rename from cv/classification/fasternet/models/fasternet.py rename to cv/classification/fasternet/pytorch/models/fasternet.py diff --git a/cv/classification/fasternet/models/model_api.py b/cv/classification/fasternet/pytorch/models/model_api.py similarity index 100% rename from cv/classification/fasternet/models/model_api.py rename to cv/classification/fasternet/pytorch/models/model_api.py diff --git a/cv/classification/fasternet/models/registry.py b/cv/classification/fasternet/pytorch/models/registry.py similarity index 100% rename from cv/classification/fasternet/models/registry.py rename to cv/classification/fasternet/pytorch/models/registry.py diff --git a/cv/classification/fasternet/requirements.txt b/cv/classification/fasternet/pytorch/requirements.txt similarity index 100% rename from cv/classification/fasternet/requirements.txt rename to cv/classification/fasternet/pytorch/requirements.txt diff --git a/cv/classification/fasternet/train_test.py b/cv/classification/fasternet/pytorch/train_test.py similarity index 100% rename from cv/classification/fasternet/train_test.py rename to cv/classification/fasternet/pytorch/train_test.py diff --git a/cv/classification/fasternet/utils/__init__.py b/cv/classification/fasternet/pytorch/utils/__init__.py similarity index 100% rename from cv/classification/fasternet/utils/__init__.py rename to cv/classification/fasternet/pytorch/utils/__init__.py diff --git a/cv/classification/fasternet/utils/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/__init__.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/utils/__pycache__/__init__.cpython-39.pyc rename to cv/classification/fasternet/pytorch/utils/__pycache__/__init__.cpython-39.pyc diff --git a/cv/classification/fasternet/utils/__pycache__/fuse_conv_bn.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/fuse_conv_bn.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/utils/__pycache__/fuse_conv_bn.cpython-39.pyc rename to cv/classification/fasternet/pytorch/utils/__pycache__/fuse_conv_bn.cpython-39.pyc diff --git a/cv/classification/fasternet/utils/__pycache__/loss.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/loss.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/utils/__pycache__/loss.cpython-39.pyc rename to cv/classification/fasternet/pytorch/utils/__pycache__/loss.cpython-39.pyc diff --git a/cv/classification/fasternet/utils/__pycache__/utils.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/utils.cpython-39.pyc similarity index 100% rename from cv/classification/fasternet/utils/__pycache__/utils.cpython-39.pyc rename to cv/classification/fasternet/pytorch/utils/__pycache__/utils.cpython-39.pyc diff --git a/cv/classification/fasternet/utils/fuse_conv_bn.py b/cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py similarity index 100% rename from cv/classification/fasternet/utils/fuse_conv_bn.py rename to cv/classification/fasternet/pytorch/utils/fuse_conv_bn.py diff --git a/cv/classification/fasternet/utils/loss.py b/cv/classification/fasternet/pytorch/utils/loss.py similarity index 100% rename from cv/classification/fasternet/utils/loss.py rename to cv/classification/fasternet/pytorch/utils/loss.py diff --git a/cv/classification/fasternet/utils/utils.py b/cv/classification/fasternet/pytorch/utils/utils.py similarity index 100% rename from cv/classification/fasternet/utils/utils.py rename to cv/classification/fasternet/pytorch/utils/utils.py -- Gitee From bcc91792c4d1135c324aa67cba4f574b7638c432 Mon Sep 17 00:00:00 2001 From: "xiaomei.wang" Date: Mon, 17 Apr 2023 10:18:30 +0800 Subject: [PATCH 3/9] Add FasterNet --- .../data/__pycache__/__init__.cpython-39.pyc | Bin 136 -> 0 bytes .../custom_imagenet_data.cpython-39.pyc | Bin 6722 -> 0 bytes .../data/__pycache__/data_api.cpython-39.pyc | Bin 1426 -> 0 bytes .../models/__pycache__/__init__.cpython-39.pyc | Bin 163 -> 0 bytes .../models/__pycache__/fasternet.cpython-39.pyc | Bin 8983 -> 0 bytes .../models/__pycache__/model_api.cpython-39.pyc | Bin 4800 -> 0 bytes .../models/__pycache__/registry.cpython-39.pyc | Bin 400 -> 0 bytes .../utils/__pycache__/__init__.cpython-39.pyc | Bin 137 -> 0 bytes .../__pycache__/fuse_conv_bn.cpython-39.pyc | Bin 1675 -> 0 bytes .../utils/__pycache__/loss.cpython-39.pyc | Bin 2060 -> 0 bytes .../utils/__pycache__/utils.cpython-39.pyc | Bin 3675 -> 0 bytes 11 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cv/classification/fasternet/pytorch/data/__pycache__/__init__.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/data/__pycache__/custom_imagenet_data.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/data/__pycache__/data_api.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/models/__pycache__/__init__.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/models/__pycache__/fasternet.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/models/__pycache__/model_api.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/models/__pycache__/registry.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/utils/__pycache__/__init__.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/utils/__pycache__/fuse_conv_bn.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/utils/__pycache__/loss.cpython-39.pyc delete mode 100644 cv/classification/fasternet/pytorch/utils/__pycache__/utils.cpython-39.pyc diff --git a/cv/classification/fasternet/pytorch/data/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index c13cc637e2da5b3ffd2f15880d6f37999f9cf669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136 zcmYe~<>g`kf@vSLQ$X}%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!Hnenx(7s(wXg zB9O||D^JWz*LO=SE=eu&OD)k)Ni0d!kB`sH%PfhH*DI*J#bJ}1pHiBWY6mjrGY~TX E0898DEC2ui diff --git a/cv/classification/fasternet/pytorch/data/__pycache__/custom_imagenet_data.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/custom_imagenet_data.cpython-39.pyc deleted file mode 100644 index 5de39b5bd0a12595afcc647b63d795af6c09eb93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6722 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 diff --git a/cv/classification/fasternet/pytorch/data/__pycache__/data_api.cpython-39.pyc b/cv/classification/fasternet/pytorch/data/__pycache__/data_api.cpython-39.pyc deleted file mode 100644 index 5e3643b50c5bf8ac67d5906fec49b4237898fb61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1426 zcmZ8hJ8v8}5GJ|Ld+H<$K?ECyqACX`ryx~|Ac^6`fB{>LQn4YZBXy#+ySE^DvSsX5 z3ep4yQl*y4wD~zix>W8Aq)U^`?46^tN$}$g=i}@=h?Rpum%#Y#?F02oM#x{NY>ph1 z?_jx~0TfZRAbhn`PFtOErpfc@I&Lx1>^g;&-H;oKljmz|4su6RV0IPJof}5c4=Z|Q zpZ8liDhB0{4_i3~d5dp>oXjX6sZ=FD5x%YHF&SrXAQo~orXhFUepwjjLEf7#oS&EC zNhxQ#(*Aqt<+Hh36dH^lpDawFgjw5!x3Y4lb6bYNQ?o&xQgpo@SeXH=N3h(dU{PcV zIWL)_%cvpG$ub6{%LI@qvY_@0A9*}uSM-WjC?(4jFkNPVnPTV6a-XZHiFZkp-X%?T zmjIJB@iPCP(X@=@14gp!0HdSgbM`B>JH88A4_4m~6m1A`@mE-+Q{-lL}vkB`OC!)HGn+dIf+ zCyu8l4zuKGB`{o`RjbHu^Z1?EPk{Z;=Z9zWQXjrF5;ik=A*hl-`GRKo3}-vi599NA#nAW42F+s51uV?C*S()0B;O0-Hk( z-K7hesa&n6kX_ILCRzHPS) RkW-xZX`c=udzeug{RfGvit7LX diff --git a/cv/classification/fasternet/pytorch/models/__pycache__/__init__.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/__init__.cpython-39.pyc deleted file mode 100644 index 6adab8a421d392cddf57a31ca4915154276a9ab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163 zcmYe~<>g`kf@vSLQ^bMvV-N=!FabFZKwQiNBvKes7;_jx7*d#m88n$+G6ID(8E-La z`2k6eqSW-v;*z4ul?+8JKnXDMOJ6@DKQ~psA~O+4W$KkD=B4YqB^H;Y7Wt)?=;!9A iq~;Xs$H!;pWtPOp>lIYq;;;b?GIXeJ1dwGxUDLgE$i7x1tT=MC|&jKsq}0746q`F*FV zdwRy>4G*bSojT_`_jA7U`!1*5i3wZ5^Cv&~5<7cNQT~+@(aAM)9kXdlnjYjkR@0JkBPew2rY+;SK|$*RbeGIaYtbjp0+W+tv44ynPgL-Ol6csP|9o?lbkJL#=E^MZoDoEao1Ui`@O&u6EW|HEhp^qjvF|2 zRpfgvk9{{l)VS;o~@x@H}YzJ7{zW7)H>D2CF^V>v7_aV4Fg z)9QvdpKBRo{ZO2^in@!|5yZ;2va9Z4ClfW%7L`PCG{lq*ZJy$KY;5ExMK28nKb;x( zOyrq~&T^X?Zy+y^v=z>RVuErVl!BxfvHdQlf??$w`_$<^I9XY}kEMUxccW%L3jCHI zwnZW81%B+b+_+v8xv1asxUd|@4?%Q9f%%ZQEmK6>XK&Ri&q=W9@@g?;X>TkgnCPu+>84>Y-vO$3R$ ztL!OT*vefs!4@#(J&j>YH#GXDDGJw&1!eCuN?br|S21fkW4Tt)4Lv@GF8B&YoHVPi67|rl0ypf4O!R%JG!KuSD8|_5O2Z!cF%$mb1=k!%XVr2s(r8(f$+ma#g z>EF?|v@IR;G!ku3-O^%ZH-Ec5E(P7zW~-1kDnsg)($rJ*j|dK-4IvG-&CwHsshb9WIyMqxTMf-P zw`=YZ`sA^Vz?HawP1mc+wz^e_a~n2Ng$##`B%c(v)x_LZWDZIWbK1t14O%g=->0@p z@dWB=iM36AP9`~Em%;xYC8m;GT;82d)IGHdDai8osMiWuYzE(IXdzamn8Y!w(Z)pN zBROi7Pa?qy)~-Q5OmOc;-{)TBw7JXbC-^kw(kYjWCkmaQ=WrKdg42=ZClCnhH3ro2 zG-!KjDq#RS3n+Kr&w?3a6la(+&EbD7Y;MM`~Tz zBw@4oM2|#|v-XY?-|l&0k|w?GGt3eg+DR8d*5ZV62{dpBPKXN$h+f7UJ&hm%SO7Ng1#A#+ z5L7C=kbisl%@KG4Iye=r>zn{cE(ZTa#O~{3=wL#${q0TD&JOz^XC5+K( zaB7!7OTmG#H~_B|Wc(c7A$UDgHaXE+cn>|ane;>izyBY7N$N)?B!MaHOK#-1uEuWL zYe@xMwgh&=ccdKAI1k`zN7+$#v>koN*vajfJNY#$)yrZn(YDpE5j5GczF}lwlao-P zH(CS>!-vj0Ehb6L=otiU;L=;QEj3o|s&{jDjl1By1?8@O*SxFT%`@em^@rLG14CA^ zs>hs4{vsOT7b$p&f=dV>;Ap+-n$VWd3)R1GrFpVC9p$u=JlTXWX?3cZ?gz20urCDA zi(B1J?}aU-BLX0^sQp)V>~IjX*nbbcaIlu6qqlqklE4k37Z4e?Q#TKgP~Wk}5%RL1(vPXGPK0A21y@I&;d>(g;dy(jIH&wnNk*)jS0&SVZgazBnlo)jAT-J4vvvV-$z?1 z^I-dCp`Dks!OX#;jF|p-<{7E4RWu`+N2=o_U&f`2#=nJp{;L!`ijO{|fuwv?1|N+L zA>$+dD^&eBRDBZ}e>AKPKCw7aK36^|$??4I@ix?u7EOEjP<+HGUq|97r!cA9Np690 znQ@CDx#a?>hNGbfrA9* zgw68v&;zQ_8$gFKf^Z6msW|0$8YYc}(*QGNqr^W>rb4pUEqN{~tibF$N<6b$WyNG7 zK0#Qzr%U}~wykW<#k15pX(VsGzcnAvWj)SkeVOQEegQxPqi2?C!y_>Np0YJlFC>M;KGNS5o499C`5QmN zYAq&n(iA(HOk<`?XkqCCmH!96r;t9~hMVwXT8}ev4YV_I7S~|iFK(So7FlsqL+O8t zAKQ3*_X#$|l)W^KJqoMIRMzuiI#cLlORSun{DJb3wuRPrpG;0AOM7scexTm?Fua2H zpQ1h?fw0@VPqX}|^-_rqS`wmiw~sS6{=e+`-Z+Y~e@_;m^hsUA`{>6j2SMs$Fsx>+Kz zL!O~jwUpul-57rCb?O=?eCAJ5a3DvdCi6OI`*vF%czSepM_6~9;wMjJy)dS~ zUZLinr{F*zl{otn(MXqo>&2n?bqb{BO8KCwL?BGyZ3O$Igf#8dH{Se)bNS-cYtKo5 zPYv?=$`NHj6fY6HH=ri0Fn*HS2q+-&1hDWfe^V60KD>DB zd8kxKWrOTgQKAxSo(qQ@%FwKYDHYd9%2<&}7^!EZCb<>BE!@MF3O(v~c!LH(YMU_K zUe5~|Cj`#a;Dz!5cs^>CA1dwM9wBvU2s)sUcj)lpQ`-FTf-cf6Tj2Zqu)v__8n7fz^lN=|^ zO}L8N*mlI&zu&BlVDw@9sFK#^0jXh;%Sz z)`lb0(hLfv;$Ub7EUMJiF^`z35A7^XE&Y#GFxBz{(=gOYwG6w9oFGq+>@U-{^+`|+ zP$pIFQ{#aN_lPNbu+@rmomA0wMMID1t)d!mnwSsZOnG4FB{-c=LzjH`Bp>ofkcve} z@-p7&?-0cBNyO@gwyp6?v7V?K(9)pi16{{*J^?+|`9DEfb2l&3I$>}aX5}p86xOJn z?;UREXVhKE>e{GVlyx6!f7GAB4C+tfYp&7$ZuM_o{g=V_Uj*RkQOqQq5Rl;c$&2-p zu>DA0*@VDbQW^MN3TW!WOu1DWB0x)AONat|TwsYXcG4S&XR}jNxJ>>q0vb_xm3R9+ ziUM1gs2#O)6j^@{#(zTpRLfAL_4jvli^J5@ki1ZZ-n{uvR{ zZOF;Bfg6B695QqhAivtK2F)5?^bO+&xJ3L&C&?B5IU}t@y{SZvuPY4tNS2@bNZ(eW z3#IL-oXMEJpls=3Nw%r-9{f~#oP*w?NhhklWiTr-ZYul(=ouEu=E7N4kd%)>DM$)j zzFWB@w*{?e*Gx=i?`e?u`7JBXL&M2$6Hnz?32xirK29_SCmY=w4)B+=6I{!XMBc&; zPMxhuI_!`dwui^HHQw#iq81PV4uAXL>TdAd8)0y}hRdcN+;_F8=e7K`+qLUgM%Zv2 zS9rDSL)?<7pQ<%n5A^!*u$bwspeS|R9u6D5K29;bxoVp z%};HEF0U-rfLqptgK&6>1zgi?AQ!wIvj_Y;4*iFC_YlfRzo#;C&1Ob3beGIM3#XZm z`ySkm${QZK@fn%a@O!3;lF4sjygZ>`hk`l+kzWhkIQByRyF@z9+I|liS82XvlPDTp z&e06vW$(;o|D9sn)Q65!Ir|D$%OzLSkC#k5KkvAW!`ThDe}+( zFmukon--L8L%JSr3Hp%Ny3cO$Kc9DY{#?~^yIN&9ij=2X9aCe!fb)#7p( zN+Hs$#D1rEtJC}xkU}zT8lKt36yM!)8Y294L{~>UL%L!GQg>^S_WI0j9 z{Wow>UVZZ)B2$>J%bQ7g)g;}@Qc;zPZK|cxtj9RyF-ks8HLVNjrREDXM|qh8?!es# aX&i(V7O-L%r?jnC&Q!iqd8#s1nfgCq?)K3D diff --git a/cv/classification/fasternet/pytorch/models/__pycache__/model_api.cpython-39.pyc b/cv/classification/fasternet/pytorch/models/__pycache__/model_api.cpython-39.pyc deleted file mode 100644 index 4b49b41b9b94ff443ee54b5d4e66254dec79c33d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4800 zcmbVQ&2JpH6`!x2o&D5GR%AQzhaAUg*JNQyK_i==iE1W<&uG16j?VmexKrIF_= zBv-bC)ul2Tpn!m$dMOHMi(dS{^e^DGhc>77TqHn$kF&d43GSsU@bQs+eB?Yn{@$bF zPN!+%_s4&~#@@JMS%0U-;x9nseH7`~mc=Y)r&d_ic4(Wn6FS`5b5A`(Yuq{YQR)+G zV$)w3Oh*Io4Q@lS$t>QOKq2NkY3pHCx2JW-)OOkpyGH*~*hB56%h^h}V&-`1rEE1^ zHGD07AzKUAvdiIR)ArLV+12o>;p^#(*-PO|h7Zzf+4b}Gh=@Xd5RyA|F7 z-(u~jR`@dOurBJ`A6smR^`2U+$9sFP9J}EiW`Az=m%kzFZ1rtz-vz0CnmiemVA=!0 zW5uJaU_9+R`o+z7o2Q>=MWJ?+eCNI>r2H^fq9_ma+ULbkJ&eT;SBw47(wl0LgI&%> zDHjWUMX8c3IW&DiJQ$2bJUGDk_01&bvG`>yvQc@zkZ667qbJ3(o4+6h4-%=8G>uhK zIgV}9g`6=fe=M|OS#J&t%)xl}Xf#719Jd3&`}e}eHb znZ@1u2d0`IR&2=GclYbMmXV2sk3rEPQUlR7Rfxf^cJf^J7L7prgZVsIN9x8vB#H}c z`z%UQ?7%vne)gqoWrb|C>}};#Yd@+ZRVZ?(Br^l-j<+q5VV(mpj*aFQJj{$F}!J{(4MwB(^i(`S^PwM zr6{&_OFmB2U^g-ikG@T&1J+Y470SztwXrJ_xUx09nkSBD$wuUytDLf5Am$}Ttt@T)q`KW7bg$1nf)DC^t zWG(d6S(|lG2dvAMP&ZhQEu(IJZFyGM!g*ZM!Dga9rTaUWtw(E;<6c6cJ_*pVlyz*K z+7rvhIiKPzCpOT-9y@#Pz9mxS5rw(nDEBSwXpk zOSU|=qSbtLt}QUWgDV)Vsu#x2G5MRbw}$o_)y#Y3h`)?!{Br(i3tG}V|8hw?z4n6c0r1=KQ&0~0QbXl$M z-8y}Fg0GHlt5?R(*gl4bM|YS7>ovD@V`wg7&Q-ss8(CULf*?mXc(%=1#F9+=jF)Ox z>Sigp5;35P=~|AVecc)YKSzQaxn>!YZ%e?PZclk768L!QY~)SdSsZ$^^2oI`KHwsf zgE-|;k|!$KkJAy?T?XupFkzRr#dR|;L>3ug-GJ9l*-kkq^8IM|I8p~C?*sR6?3HFO zFLHi(c6UMa#V7mgQ(hA zq*rCU&!b(eB+6LC83&NTI!0rZqb&%B#BCz45V=FdZ0UQ%eV<65$Xz0@5%~d;9}?Lh za*xRCMBV@a8k2(?ywl5UAuyQl73Ao;R*EE7x-=X|@EL+nR6$-8odJ;e5k$xmavOw@ziBstI^J{t7W)6yT&-HpcYz<+0cHhm z&&+f{oo{`=jo!dun9*i>4wq+8vN1dBbJ68o(4{Z~B(cWGmT;47Bp2ex=!5fpfJ)m> zF2ZSjScu25U^^I=CTiJ-z4?mM!E;fbA`Qje`!wSn5QHNNVF+B}E$~hixc2N*k6|0k zxoRETfD{@-oF5~ZqjU+|bGNh|eM9>Cb@4M)h+LyoCDo0?QI3S*xr%sMAilfgNHtle ziPH7z#tXd$$Kfh6&4|S+PKy}91)ojdd+}pei+n0-R7O(8LhV6N5;9we8`qpeBtaE) zZ#+*L*#?2lIanvF&n@y#G{*Lq&XEgfbddcx;x1Xp*asXA2aq^%rV@bvu{*Jk0J26_ zkp+-Eoa%kNmuAT2-MlXHnr(Ef%@f(*`6Mfu3|Jp9NcbO-qW$Sjqafb8>)8S{3(Y3{0VS@A9@HX!1r z#g2HNnhhd!OAnmheIlBTLn>AP(bcpJ$a@c~Y|cI4!qYWx=OpB*G| zJNA&0dZ42}FmJHFr#rxCyvZskq_7@8nej{0Ap>SnDs-KzI6{Jt`#?`_gRJ5w;DDa= z7!-t8f?!Yk1_x!>nCif6A2UhIrL97Jl9egX0KuGnC`2KUk(e9Sm_H!#KAXKSFCOwL zvY%nHLwVR-T>b&8O1fwkE>Ihx&aeKy4FYcwdY?BJpiW@ZZ&TJo8BG-FW<)6kp10uJ zQS{X)POA|Urp3pQ7j!!2;)nrpLn6CG6o~FjWBh=p=`7A0BzQm~^yCn?Kqvu{J&?d| zzZ1BD-&_kk)UFvtLgo}wyYfKldXmeM4-_6($Pjg%C4#o3>+!a%dhl2uCMnXFrb|>)eXGE#vj9GwR^KBrGF-`H2Ire+MI3wQ*+kF|j_ mgZC)Y zFku-YXsJRKy}>J%fxg`kf@vSLQ$X}%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HXenx(7s(wXg zB9O||D^JWz*LO=SE=eu&OD)kaEy>I&){l?R%*!l^kJl@xyv1RYo1apelWGSt=Q9v9 F004As9>f3u diff --git a/cv/classification/fasternet/pytorch/utils/__pycache__/fuse_conv_bn.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/fuse_conv_bn.cpython-39.pyc deleted file mode 100644 index d820a0ad768fbfb5ce0e021d4915faf53d69701a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1675 zcmbtUy>A;g6eoGq>2$UQqi_-f=|FU<&_D(<1%^@N!wAr!LXm7j3zfQ~taDC0ndDiK zahj5Up&g10_Sn6D4cAWDI(Kp3qin%0x|IihzxR8O@BQA%ot>0G`}MDH@?YA7{E3^p zjl==K7JhMbZWgOTR6rsg58bn4h;)X-CYMOQcz z*tcMgp|>BAEBctMxJxcO4Qu#i3OZXk!|wz%_TauDBNFZd%06lM9sym7x^M>_e2y;u zcwJj1&|x8UF2-6E+Et>`O3bRfE>%BG1+*9D#2$tf?t=W+TKB&XGQC6b3K2kYti%Km z^ZrH_An!@O9Nd=+f^R~c?pWAh9}4s^-*|)O2cId#t+(ytg(^;_&hv30t#7%?WK*AB zC{x){S-ewz+tgYY`eZayQhRRCjPqN!XXn!RNX@NhTKmoq(#V-|%J{ZXb}HwfUDa-s zO{LbVw7r(WG@1woA7cbYi<^1uF>XU=l(gOHE zxr5pjr9HqfjRMSA_vcH$GrD^c1B~5+fuu3rqx_mj`!uFsTqo>HY97IPkNJ3=B7`8HL2iwcg7$gCSG0*%3{JN|mr`=J8`#F=Z{Xw` zmDR=;=c-%=s{D(5LT*wWm~mVi$RDtBqKwj+dLrBuIi@pLR9c#)s3u}8T{acEGBZ)i zr7~6&R$%1;ajMBA0F7%0v<9Q7k8}ux2M!2XBHeHEETmBaDfdJyrUk&N_w&jsz?-T7 zgo2qu5@W(d;l!eF(*Qd+DpNW78!F_+7m&2_9II?Lubo7{EgBDKwwTS!VzLxkxkY8( z3F}Oqf$z%xXX&j|e!ryFRrvqQ3M#6rp$KvyeNpBRZ=V*n(AMFLO&5sd+iM4`?}VUZ z%zZj~i3u3sdgtv@XPa$cs!v9@O38P*(ynkzALAe6Y3{f0vc4CaeK0cYlu#_8IELNL za)hpV9>!L1(5I*j-U3u8y!G%9Ak0@VJce#@LAsoBwo5tfUUQaEMpK%yE)>)@oW(4q wK_1K}AncRyBk60sesa8yZ+J_PyJHK>-Jn6A9IYSuE&e4eR$xN6qx}c}0DpSaiU0rr diff --git a/cv/classification/fasternet/pytorch/utils/__pycache__/loss.cpython-39.pyc b/cv/classification/fasternet/pytorch/utils/__pycache__/loss.cpython-39.pyc deleted file mode 100644 index 6af4a40087c6eedd26fd2d1019c1f38dc410ca1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2060 zcmaJ?&u<(x6t?Hr&Q5mQ6h$I!C1fEXb=xQ@H&met1S%?mT!@4ightNTyE~iNnZ@=r zKQy_}NIg|Z960rm9D9O4gulR7PQ7siF7TdrlWZv9mEYK&H=m!M-}f!=_Y(r`$KURW zNuQ8kakAV3n0x?T-v=W|N(2>NNmB|>zx1Yl8c^~H5rGI#hzKQ}gp=s0pLT@z1sOy~ z8_DD8tdvt(8O_XCvc0O_FQphsCJJqevgD?yD^}K8C$C@+vOS%7cyZMj8@ ziGBzJNgxuEdV;3D3~=v-?Z{Zh!g~=uBSVN(1Sh?;D?$;SkTiKl0+Oykd>y;`@lq6@ zK@dkjB@EimxX^4`i>8!pU-6k{oN2==!IfaSDvVSZHY_kM1iY=7JTQv?-}%_?p~E(O zuc$@)wa&7auX?$m(U1)J!g+@{<9`F&tuIo*7JtM!8kvHu73g3ddHB3 zQ+T%inRgr-dg`5#?{7iw$f@7bGkP3-2?PqD{GR%hRIBeolJ7%q@%I(xm`noU?Rn}4 z7=_0j6HTzkkloI0f@S>NbMxqOjzujx&%vYZtdTX+2B+OKa+@5-)msiP2E3n5beaH4 zG+A*d6yl59P{7?ydh7UAjH5O3COPi5UAVt4e?bXx6^4BHP>uA1iy5vI)vPi40Wd|f zS{0)L$huerqI0NQCD~9)!A$L#f2G>5K-GOGj7?ewk@Yga!uB)lbX32Fdsr?2_-w64Hq%^D!Gjz&J&AUuw=pMB550 z@DrrO78cCy8(6#UQWJ6P{d~7>aosAS1O9aH4 zw)ByW_R35YPwWaJAcd#=z=l;bm8I?H3W$_}s;hc-Xd}Rfw~o7mL?NeaG%pa_SzM@% z=Eq8t#X`0x(ymi3BxQR2T(r*p=}vl8xzNo9Xw?naVQ${Qy*iMpeUO)%Fwu9wkZut6 zx(U65%=QDi8mv-}dVd6Q^t%T=>Lql|Tc=0suW@|=HRz#4ReUP5%qAI1Df}0}xR+($ zHoRQC>13Ixb5OB$jKixc8-4CP;Vz7_;jpZ^acZO9L681IuyR?J@YUrxP>d8FMxplN z&1xqwGzdVJ{#s4k`XE*V^l`hz?g}@nN}*({TWId0xrYW}mhjz9E?M#W^Rqle4~?1| J_%ZGIe*?c@F5&G`z1>)q@pG=#$rS$RKB!9pleA|oUi0&5a73L4s7<(b~?>7G>A z>|(1eA$hNXhyw?rNVY@{5l2q^2k{ulHV6y{~%j#oca; z;rso+-VkqIX6)~@SpEVm-a;$?fle^NGd85r$=H++Ij>>P(6Kmo=-JU9`gRP40Y*1# zOv7QgplwcD!?vA!S!dcEcJ18HdefER%5-(Oigh3w&)INIgrbS@lK7fvi_UXCye!$# z`Z1GT(G|Vt?2sSw;guRDR>UenhF2HsHF3$VUt6rdF0P8#p3{zN;+nXQbFYgV;wHu$ z;+D9L@uuL9SU);}q-@aV#>sQ^%|SesG5p@`)`Dpjbm zADC8Jrg^F3JdwsNwK85YlezKs;%R1@WxOj#SrH3GEcRXFCc9(fPWEPo?|#YD8lYdj zac@#g<-K2}F@|*GS)7mWZN()-9Y}p|uG6fn`;FP23F)*EPU(`Y*3Y=dTfE2ba0O>$ ziG%L+^D*(ztYW^62`S}}LkSQJqYD9@FL>pC!4Evmt-xL_@Rxi5OL$LXRo2Y=#*5Xs zR6QI6S48s=Z|yDu?JYNF?1 z872Y^8l&ZLTU zp^THI=Xnf4^pH-tjnhif6yxh$MHpXlFmg81t7WT$Nv%hEWv8rgV$QCdT}>UGQ$lKb={qfxV$4KRW9?3lgFe(}~v&VfsYf=0X}_t-vG!Jl~Q zzV<4w;*~?btbLlp^Ftj}ta1UhKK^k??0)GC6v@+Xm|l)21#g<9nNaXrHig=Ow04V37&n*C49`sf5$BmaC%?J_!Z*=sr*&5O zy3=u5j)lME10?&I5Bw5~T7JmIj~sf(kdq&KyX3|$-_}JJ=*%=kKZfr z{HVVf8Mc3E0kq+$hC-2^d>UuQhnFQ2;~}02MN$w%$C>&D=88l*)mJOcXLCI&(|u_I zE%OrY>F*-wl_sc9KBqmiI+l85DMmHH4{%&b4~;pYa|sck!&?sC6?*j@K)1I}{)!=K z5Xs`Bm~p0Aa_GwWl&em~$-kfve#B`M@UO@2V{hbF>~S4A`2no(I1ui2cF?F?^*&Y& zP=&(#gm8Rm#Vb!ehRvGCj4*cOx+VNW4j=9ugs>m1!r8|PC$OV7-KjfA9nd#*s|sGB z`@<`ApsE_{tZG%wYYaAT!=`o)Sb%j$cSWOWe8xmrwLfE@dvxC!tXXw{X?+fkAa%Ry zkQbavU-_av=g`X??Hu(g|Cnf&WCv#Zze^8_i{$TExq2_;|CB=m=jDDG|GNeLf0ws= zfxNwouK}S`ofY>r_!XjmNUwjCSru$=zsjH+r^=wV`V>vcod``|tg1GkP}B z6RDzkDI=_x(a9vv5j{%18HrfOquoMHW4%l3!i27)zWP+4hymoEB-+7USSJ(v z45R(a5w0la;|X47ROHckHjnmKqb$bzO!m$oZZs_iCzNC{RdZ8!NSg7ZGxLTRYxST7>8diND;+pa!bgUED{NHjAsZhD}@OuQY>lRf8fYZ2& zf1O`NbPEZBR1sL}dVdFWL`(fCrFw+(6S`#iJImX*0M(2_T-l+j6mtjjYcv;>2He5c zHYx{HGbkxKX*r6Y#%UJsWYYAoO7m2waR!BpC2^^QQxu2IZP3uxdfNy|V0p`*K(eUU zLMySy)dzt6XMX8W%?`24a*O15jP%_{`rZJh@7nEZ8*|g6?C`8mnXt}$5qs+AApA30 zNg06g08Cie|I2{-7Ph~1dq}ra5r5&mWct6LE#FJ9K3CUi@VB?N25OV0x9sy!WHI9u zcpdOd)VxkUQ&e;*%6TS4MTuxtN?VqiHJfxdNbxG&nQJLbdudVY=jLqBl8v%-JkdE~ z!v@vWu%|2)m3_nJ?o&$k8+mRsx6RhJp0;JGtq4scFGgd9V*YhvhUyucX|3DU#vmOl z67C{RnDD!GW%NBNHp=_x$b+dGwiU7U=2bVu*SZpLhj+Yyw^q?s0^a!vz`?%(5Y1rq -- Gitee From bbdb308d311dd77f6f30fe45a5b721eee69ccf3a Mon Sep 17 00:00:00 2001 From: "xiaomei.wang" Date: Mon, 17 Apr 2023 12:10:57 +0800 Subject: [PATCH 4/9] Add FasterNet --- cv/classification/fasternet/pytorch/{README.MD => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cv/classification/fasternet/pytorch/{README.MD => README.md} (100%) diff --git a/cv/classification/fasternet/pytorch/README.MD b/cv/classification/fasternet/pytorch/README.md similarity index 100% rename from cv/classification/fasternet/pytorch/README.MD rename to cv/classification/fasternet/pytorch/README.md -- Gitee From e049722247029974584d31b08870b1e08e09ddf7 Mon Sep 17 00:00:00 2001 From: may Date: Mon, 17 Apr 2023 06:35:45 +0000 Subject: [PATCH 5/9] update cv/classification/fasternet/pytorch/README.md. Signed-off-by: may --- cv/classification/fasternet/pytorch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index 643d79826..930741fcf 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -44,7 +44,7 @@ python3 train_test.py -g 0,1,2,3,4,5,6,7 --num_nodes 1 -n 4 -b 4096 -e 2000 \ --model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml ``` -FasterNet-T0 training on ImageNet-1K with a 8-GPU node: +FasterNet-T0 training on ImageNet-1K with a 1-GPU node: ``` python3 train_test.py -g 0 --num_nodes 1 -n 4 -b 4096 -e 2000 \ --data_dir ../../data/imagenet --pin_memory --wandb_project_name fasternet \ -- Gitee From 9e29e660a39f3f1651ea5b5ed8dff98a99e2261a Mon Sep 17 00:00:00 2001 From: may Date: Mon, 17 Apr 2023 06:39:47 +0000 Subject: [PATCH 6/9] update cv/classification/fasternet/pytorch/README.md. Signed-off-by: may --- cv/classification/fasternet/pytorch/README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index 930741fcf..24aff44ef 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -24,15 +24,11 @@ Download the [ImageNet-1K](http://image-net.org/) classification dataset and str ``` /path/to/imagenet-1k/ train/ - class1/ - img1.jpeg - class2/ - img2.jpeg + n01440764/ + n01440764_10026.JPEG val/ - class1/ - img3.jpeg - class2/ - img4.jpeg + n01440764/ + ILSVRC2012_val_00000293.JPEG ``` ## Step 2: Training -- Gitee From 934772b81ebf8a4b8192cb16720c89bee9148676 Mon Sep 17 00:00:00 2001 From: may Date: Thu, 20 Apr 2023 03:22:35 +0000 Subject: [PATCH 7/9] update cv/classification/fasternet/pytorch/README.md. Signed-off-by: may --- cv/classification/fasternet/pytorch/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index 24aff44ef..6baca53bb 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -35,6 +35,7 @@ Download the [ImageNet-1K](http://image-net.org/) classification dataset and str FasterNet-T0 training on ImageNet-1K with a 8-GPU node: ``` +# You can change the dataset path '--data_dir' according to your own dataset path !!! python3 train_test.py -g 0,1,2,3,4,5,6,7 --num_nodes 1 -n 4 -b 4096 -e 2000 \ --data_dir /home/datasets/cv/imagenet --pin_memory --wandb_project_name fasternet \ --model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml @@ -42,8 +43,9 @@ python3 train_test.py -g 0,1,2,3,4,5,6,7 --num_nodes 1 -n 4 -b 4096 -e 2000 \ FasterNet-T0 training on ImageNet-1K with a 1-GPU node: ``` +# You can change the dataset path '--data_dir' according to your own dataset path !!! python3 train_test.py -g 0 --num_nodes 1 -n 4 -b 4096 -e 2000 \ ---data_dir ../../data/imagenet --pin_memory --wandb_project_name fasternet \ +--data_dir /home/datasets/cv/imagenet --pin_memory --wandb_project_name fasternet \ --model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml ``` -- Gitee From 9a6b52de2d1301d37e74df4ae6f95279d375aa82 Mon Sep 17 00:00:00 2001 From: majorli Date: Sun, 23 Apr 2023 09:42:57 +0000 Subject: [PATCH 8/9] Update cv/classification/fasternet/pytorch/README.md --- cv/classification/fasternet/pytorch/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index 6baca53bb..d1bb4c3f8 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -32,6 +32,7 @@ Download the [ImageNet-1K](http://image-net.org/) classification dataset and str ``` ## Step 2: Training +**Remark**: Training will prompt wondb visualization options, you'll need a W&B account to visualize, choose "3" if you don't need to. FasterNet-T0 training on ImageNet-1K with a 8-GPU node: ``` -- Gitee From f3f046a57fe6ec1f0e2295da7fbc85d32778bbc9 Mon Sep 17 00:00:00 2001 From: majorli Date: Sun, 23 Apr 2023 09:44:03 +0000 Subject: [PATCH 9/9] Update cv/classification/fasternet/pytorch/README.md --- cv/classification/fasternet/pytorch/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cv/classification/fasternet/pytorch/README.md b/cv/classification/fasternet/pytorch/README.md index d1bb4c3f8..96d08a377 100644 --- a/cv/classification/fasternet/pytorch/README.md +++ b/cv/classification/fasternet/pytorch/README.md @@ -45,7 +45,7 @@ python3 train_test.py -g 0,1,2,3,4,5,6,7 --num_nodes 1 -n 4 -b 4096 -e 2000 \ FasterNet-T0 training on ImageNet-1K with a 1-GPU node: ``` # You can change the dataset path '--data_dir' according to your own dataset path !!! -python3 train_test.py -g 0 --num_nodes 1 -n 4 -b 4096 -e 2000 \ +python3 train_test.py -g 0 --num_nodes 1 -n 4 -b 512 -e 2000 \ --data_dir /home/datasets/cv/imagenet --pin_memory --wandb_project_name fasternet \ --model_ckpt_dir ./model_ckpt/$(date +'%Y%m%d_%H%M%S') --cfg cfg/fasternet_t0.yaml ``` -- Gitee