[Docs] Update `getting_started.md` and `install.md` and rewrite `finetune.md` (#466)

* Disable auto line-wrap in docs.

* Add model_zoo.md and CONTRIBUTING.md in docs.

* Revise getting_started.md and install.md

* Rewrite finetune.md

* Fix typo

* Imporve `finetune.md`

* Fix `GitHub` link

* Fix a small typo.
pull/471/head
Ma Zerun 2021-09-28 18:05:50 +08:00 committed by GitHub
parent c076a97d54
commit 8b7d38b243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 453 additions and 128 deletions

View File

@ -75,7 +75,7 @@ If you find this project useful in your research, please consider cite:
## Contributing
We appreciate all contributions to improve MMClassification.
Please refer to [CONTRUBUTING.md](.github/CONTRIBUTING.md) for the contributing guideline.
Please refer to [CONTRUBUTING.md](docs/community/CONTRIBUTING.md) for the contributing guideline.
## Acknowledgement

View File

@ -61,7 +61,7 @@ MMClassification 是一款基于 PyTorch 的开源图像分类工具箱,是 [O
## 参与贡献
我们非常欢迎任何有助于提升 MMClassification 的贡献,请参考 [贡献指南](.github/CONTRIBUTING-zh_CN.md) 来了解如何参与贡献。
我们非常欢迎任何有助于提升 MMClassification 的贡献,请参考 [贡献指南](docs_zh-CN/community/CONTRIBUTING.md) 来了解如何参与贡献。
## 致谢

View File

@ -12,7 +12,7 @@ Collections:
Title: Mixed Precision Training
README: configs/fp16/README.md
Code:
URI: https://github.com/open-mmlab/mmclassification/blob/a41cb2fa938d957101cc446e271486206188bf5b/mmcls/core/fp16/hooks.py#L13
URL: https://github.com/open-mmlab/mmclassification/blob/a41cb2fa938d957101cc446e271486206188bf5b/mmcls/core/fp16/hooks.py#L13
Version: v0.15.0
Models:

View File

@ -4,3 +4,7 @@
height: 40px;
width: 204px;
}
pre {
white-space: pre;
}

View File

@ -28,11 +28,11 @@ We use the following tools for linting and formatting:
- [markdownlint](https://github.com/markdownlint/markdownlint): A linter to check markdown files and flag style issues.
- [docformatter](https://github.com/myint/docformatter): A formatter to format docstring.
Style configurations of yapf and isort can be found in [setup.cfg](../setup.cfg).
Style configurations of yapf and isort can be found in [setup.cfg](https://github.com/open-mmlab/mmclassification/blob/master/setup.cfg).
We use [pre-commit hook](https://pre-commit.com/) that checks and formats for `flake8`, `yapf`, `isort`, `trailing whitespaces`, `markdown files`,
fixes `end-of-files`, `double-quoted-strings`, `python-encoding-pragma`, `mixed-line-ending`, sorts `requirments.txt` automatically on every commit.
The config for a pre-commit hook is stored in [.pre-commit-config](../.pre-commit-config.yaml).
The config for a pre-commit hook is stored in [.pre-commit-config](https://github.com/open-mmlab/mmclassification/blob/master/.pre-commit-config.yaml).
After you clone the repository, you will need to install initialize pre-commit hook.
@ -62,7 +62,9 @@ Or refer to [this repo](https://github.com/innerlee/setup) and take [`zzruby.sh`
After this on every commit check code linters and formatter will be enforced.
>Before you create a PR, make sure that your code lints and is formatted by yapf.
```{important}
Before you create a PR, make sure that your code lints and is formatted by yapf.
```
### C++ and CUDA

View File

@ -83,7 +83,7 @@ html_theme_options = {
'menu': [
{
'name': 'GitHub',
'url': 'https://github.com/open-mmlab/mmcv'
'url': 'https://github.com/open-mmlab/mmclassification'
},
{
'name':

View File

@ -49,6 +49,10 @@ We provide scripts to inference a single image, inference a dataset and test a d
```shell
python demo/image_demo.py ${IMAGE_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE}
# Example
python demo/image_demo.py demo/demo.JPEG configs/resnet/resnet50_b32x8_imagenet.py \
https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth
```
### Inference and test a dataset
@ -81,7 +85,9 @@ Assume that you have already downloaded the checkpoints to the directory `checkp
Infer ResNet-50 on ImageNet validation set to get predicted labels and their corresponding predicted scores.
```shell
python tools/test.py configs/imagenet/resnet50_batch256.py checkpoints/xxx.pth --out result.pkl
python tools/test.py configs/resnet/resnet50_b16x8_cifar10.py \
https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_b16x8_cifar10_20210528-f54bfad9.pth \
--out result.pkl
```
## Train a model
@ -95,7 +101,7 @@ which is specified by `work_dir` in the config file.
By default we evaluate the model on the validation set after each epoch, you can change the evaluation interval by adding the interval argument in the training config.
```python
evaluation = dict(interval=12) # This evaluate the model per 12 epoch.
evaluation = dict(interval=12) # Evaluate the model per 12 epochs.
```
### Train with a single GPU
@ -191,29 +197,30 @@ Params: 25.56 M
==============================
```
**Note**: This tool is still experimental and we do not guarantee that the number is correct. You may well use the result for simple comparisons, but double check it before you adopt it in technical reports or papers.
(1) FLOPs are related to the input shape while parameters are not. The default input shape is (1, 3, 224, 224).
(2) Some operators are not counted into FLOPs like GN and custom operators. Refer to [`mmcv.cnn.get_model_complexity_info()`](https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/utils/flops_counter.py) for details.
```{warning}
This tool is still experimental and we do not guarantee that the number is correct. You may well use the result for simple comparisons, but double check it before you adopt it in technical reports or papers.
- FLOPs are related to the input shape while parameters are not. The default input shape is (1, 3, 224, 224).
- Some operators are not counted into FLOPs like GN and custom operators. Refer to [`mmcv.cnn.get_model_complexity_info()`](https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/utils/flops_counter.py) for details.
```
### Publish a model
Before you upload a model to AWS, you may want to
(1) convert model weights to CPU tensors
(2) delete the optimizer states
(3) compute the hash of the checkpoint file and append the hash id to the filename.
Before you publish a model, you may want to
1. Convert model weights to CPU tensors.
2. Delete the optimizer states.
3. Compute the hash of the checkpoint file and append the hash id to the filename.
```shell
python tools/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
python tools/convert_models/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
```
E.g.,
```shell
python tools/publish_model.py work_dirs/resnet50/latest.pth imagenet_resnet50_20200708.pth
python tools/convert_models/publish_model.py work_dirs/resnet50/latest.pth imagenet_resnet50.pth
```
The final output filename will be `imagenet_resnet50_20200708-{hash id}.pth`.
The final output filename will be `imagenet_resnet50_{date}-{hash id}.pth`.
## Tutorials

View File

@ -18,6 +18,7 @@ You can switch between Chinese and English documents in the lower-left corner of
:caption: Model zoo
modelzoo_statistics.md
model_zoo.md
.. toctree::
@ -40,6 +41,13 @@ You can switch between Chinese and English documents in the lower-left corner of
tools/model_serving.md
.. toctree::
:maxdepth: 1
:caption: Community
community/CONTRIBUTING.md
.. toctree::
:caption: API Reference

View File

@ -23,9 +23,11 @@ The compatible MMClassification and MMCV versions are as below. Please install t
| 0.7.0 | mmcv>=1.1.4 |
| 0.6.0 | mmcv>=1.1.4 |
Note: Since the `master` branch is under frequent development, the `mmcv`
```{note}
Since the `master` branch is under frequent development, the `mmcv`
version dependency may be inaccurate. If you encounter problems when using
the `master` branch, please try to update `mmcv` to the latest version.
```
## Install MMClassification
@ -42,8 +44,11 @@ b. Install PyTorch and torchvision following the [official instructions](https:/
conda install pytorch torchvision -c pytorch
```
Note: Make sure that your compilation CUDA version and runtime CUDA version match.
You can check the supported CUDA version for precompiled packages on the [PyTorch website](https://pytorch.org/).
```{note}
Make sure that your compilation CUDA version and runtime CUDA version match.
You can check the supported CUDA version for precompiled packages on the
[PyTorch website](https://pytorch.org/).
```
`E.g.1` If you have CUDA 10.1 installed under `/usr/local/cuda` and would like to install
PyTorch 1.5, you need to install the prebuilt PyTorch with CUDA 10.1.
@ -97,13 +102,12 @@ And then, install build requirements and install MMClassification.
pip install -e . # or "python setup.py develop"
```
Note:
1. Following the above instructions, MMClassification is installed on `dev` mode, any local modifications made to the code will take effect without the need to reinstall it (unless you submit some commits and want to update the version number).
2. If you would like to use `opencv-python-headless` instead of `opencv-python`,
you can install it before installing [mmcv](https://github.com/open-mmlab/mmcv).
```{note}
Following above instructions, MMClassification is installed on `dev` mode,
any local modifications made to the code will take effect without the need to
reinstall it (unless you submit some commits and want to update the version
number).
```
### Another option: Docker Image
@ -114,7 +118,9 @@ We provide a [Dockerfile](https://github.com/open-mmlab/mmclassification/blob/ma
docker build -f ./docker/Dockerfile --rm -t mmcls:torch1.6.0-cuda10.1-cudnn7 .
```
**Important:** Make sure you've installed the [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker).
```{important}
Make sure you've installed the [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker).
```
Run a container built from mmcls image with command:

View File

@ -1,94 +1,237 @@
# Tutorial 1: Finetuning Models
# Tutorial 1: Fine-tune Models
Classification models pre-trained on the ImageNet dataset has been demonstrated to be effective for other datasets and other downstream tasks.
This tutorial provides instruction for users to use the models provided in the [Model Zoo](../model_zoo.md) for other datasets to obtain better performance.
Classification models pre-trained on the ImageNet dataset have been demonstrated to be effective for other datasets and other downstream tasks.
This tutorial provides instructions for users to use the models provided in the [Model Zoo](../model_zoo.md) for other datasets to obtain better performance.
There are two steps to finetune a model on a new dataset.
There are two steps to fine-tune a model on a new dataset.
- Add support for the new dataset following [Tutorial 2: Adding New Dataset](new_dataset.md).
- Modify the configs as will be discussed in this tutorial.
Take the finetuning on CIFAR10 Dataset as an example, the users need to modify five parts in the config.
Assume we have a ResNet-50 model pre-trained on the ImageNet-2012 dataset and want
to take the fine-tuning on the CIFAR-10 dataset, we need to modify five parts in the
config.
## Inherit base configs
To reuse the common parts among different configs, we support inheriting configs from multiple existing configs. To finetune a ResNet-50 model, the new config needs to inherit
`_base_/models/resnet50.py` to build the basic structure of the model. To use the CIFAR10 Dataset, the new config can also simply inherit `_base_/datasets/cifar10.py`. For runtime settings such as training schedules, the new config needs to inherit `_base_/default_runtime.py`.
At first, create a new config file
`configs/tutorial/resnet50_finetune_cifar.py` to store our configs. Of course,
the path can be customized by yourself.
To reuse the common parts among different configs, we support inheriting
configs from multiple existing configs. To fine-tune a ResNet-50 model, the new
config needs to inherit `configs/_base_/models/resnet50.py` to build the basic
structure of the model. To use the CIFAR-10 dataset, the new config can also
simply inherit `configs/_base_/datasets/cifar10_bs16.py`. For runtime settings such as
training schedules, the new config needs to inherit
`configs/_base_/default_runtime.py`.
To inherit all above configs, put the following code at the config file.
```python
_base_ = [
'../_base_/models/resnet50.py',
'../_base_/datasets/cifar10.py', '../_base_/default_runtime.py'
'../_base_/datasets/cifar10_bs16.py', '../_base_/default_runtime.py'
]
```
Besides, users can also choose to write the whole contents rather than use inheritance, e.g. `configs/mnist/lenet5.py`.
Besides, you can also choose to write the whole contents rather than use inheritance,
like [`configs/lenet/lenet5_mnist.py`](https://github.com/open-mmlab/mmclassification/blob/master/configs/lenet/lenet5_mnist.py).
## Modify head
## Modify model
Then the new config needs to modify the head according to the class numbers of the new datasets. By only changing `num_classes` in the head, the weights of the pre-trained models are mostly reused except the final prediction head.
When fine-tuning a model, usually we want to load the pre-trained backbone
weights and train a new classification head.
To load the pre-trained backbone, we need to change the initialization config
of the backbone and use `Pretrained` initialization function. Besides, in the
`init_cfg`, we use `prefix='backbone'` to tell the initialization
function to remove the prefix of keys in the checkpoint, for example, it will
change `backbone.conv1` to `conv1`. And here we use an online checkpoint, it
will be downloaded during training, you can also download the model manually
and use a local path.
And then we need to modify the head according to the class numbers of the new
datasets by just changing `num_classes` in the head.
```python
_base_ = ['./resnet50.py']
model = dict(
pretrained=None,
head=dict(
type='LinearClsHead',
num_classes=10,
in_channels=2048,
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
))
backbone=dict(
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
```
```{tip}
Here we only need to set the part of configs we want to modify, because the
inherited configs will be merged and get the entire configs.
```
Sometimes, we want to freeze the first several layers' parameters of the
backbone, that will help the network to keep ability to extract low-level
information learnt from pre-trained model. In MMClassification, you can simply
specify how many layers to freeze by `frozen_stages` argument. For example, to
freeze the first two layers' parameters, just use the following config:
```python
model = dict(
backbone=dict(
frozen_stages=2,
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
```
```{note}
Not all backbones support the `frozen_stages` argument by now. Please check
[the docs](https://mmclassification.readthedocs.io/en/latest/api.html#module-mmcls.models.backbones)
to confirm if your backbone supports it.
```
## Modify dataset
The users may also need to prepare the dataset and write the configs about dataset. We currently support MNIST, CIFAR and ImageNet Dataset.
For fintuning on CIFAR10, its original input size is 32 and thus we should resize it to 224, to fit the input size of models pretrained on ImageNet.
When fine-tuning on a new dataset, usually we need to modify some dataset
configs. Here, we need to modify the pipeline to resize the image from 32 to
224 to fit the input size of the model pre-trained on ImageNet, and some other
configs.
```python
_base_ = ['./cifar10.py']
img_norm_cfg = dict(
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=True)
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=False,
)
train_pipeline = [
dict(type='RandomCrop', size=32, padding=4),
dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
dict(type='Resize', size=224)
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='ToTensor', keys=['gt_label']),
dict(type='Collect', keys=['img', 'gt_label'])
]
test_pipeline = [
dict(type='Resize', size=224)
dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img'])
]
dict(type='Collect', keys=['img']),
]
data = dict(
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
```
## Modify training schedule
The finetuning hyperparameters vary from the default schedule. It usually requires smaller learning rate and less training epochs.
The fine-tuning hyper parameters vary from the default schedule. It usually
requires smaller learning rate and less training epochs.
```python
# optimizer
# lr is set for a batch size of 128
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# learning policy
lr_config = dict(
policy='step',
step=[15])
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)
```
## Use pre-trained model
## Start Training
To use the pre-trained model, the new config add the link of pre-trained models in the `load_from`. The users might need to download the model weights before training to avoid the download time during training.
Now, we have finished the fine-tuning config file as following:
```python
load_from = 'https://s3.ap-northeast-2.amazonaws.com/open-mmlab/mmclassification/models/tbd.pth' # noqa
_base_ = [
'../_base_/models/resnet50.py',
'../_base_/datasets/cifar10_bs16.py', '../_base_/default_runtime.py'
]
# Model config
model = dict(
backbone=dict(
frozen_stages=2,
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
# Dataset config
img_norm_cfg = dict(
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=False,
)
train_pipeline = [
dict(type='RandomCrop', size=32, padding=4),
dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='ToTensor', keys=['gt_label']),
dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
]
data = dict(
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
# Training schedule config
# lr is set for a batch size of 128
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# learning policy
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)
```
Here we use 8 GPUs on your computer to train the model with the following
command:
```shell
bash tools/dist_train.sh configs/tutorial/resnet50_finetune_cifar.py 8
```
Also, you can use only one GPU to train the model with the following command:
```shell
python tools/train.py configs/tutorial/resnet50_finetune_cifar.py
```
But wait, an important config need to be changed if using one GPU. We need to
change the dataset config as following:
```python
data = dict(
samples_per_gpu=128,
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
```
It's because our training schedule is for a batch size of 128. If using 8 GPUs,
just use `samples_per_gpu=16` config in the base config file, and the total batch
size will be 128. But if using one GPU, you need to change it to 128 manually to
match the training schedule.

View File

@ -4,3 +4,7 @@
height: 40px;
width: 204px;
}
pre {
white-space: pre;
}

View File

@ -28,13 +28,13 @@
- [markdownlint](https://github.com/markdownlint/markdownlint): 一个对 markdown 文件进行格式检查与提示的工具。
- [docformatter](https://github.com/myint/docformatter): 一个 docstring 格式化工具。
yapf 和 isort 的格式设置位于 [setup.cfg](../setup.cfg)
yapf 和 isort 的格式设置位于 [setup.cfg](https://github.com/open-mmlab/mmclassification/blob/master/setup.cfg)
我们使用 [pre-commit hook](https://pre-commit.com/) 来保证每次提交时自动进行代
码检查和格式化,启用的功能包括 `flake8`, `yapf`, `isort`, `trailing
whitespaces`, `markdown files`, 修复 `end-of-files`, `double-quoted-strings`,
`python-encoding-pragma`, `mixed-line-ending`, 对 `requirments.txt`的排序等。
pre-commit hook 的配置文件位于 [.pre-commit-config](../.pre-commit-config.yaml)
pre-commit hook 的配置文件位于 [.pre-commit-config](https://github.com/open-mmlab/mmclassification/blob/master/.pre-commit-config.yaml)
在你克隆仓库后,你需要按照如下步骤安装并初始化 pre-commit hook。
@ -64,7 +64,9 @@ rvm install 2.7.1
在此之后,每次提交,代码规范检查和格式化工具都将被强制执行。
>在创建 PR 之前,请确保你的代码完成了代码规范检查,并经过了 yapf 的格式化。
```{important}
在创建 PR 之前,请确保你的代码完成了代码规范检查,并经过了 yapf 的格式化。
```
### C++ 和 CUDA

View File

@ -83,7 +83,7 @@ html_theme_options = {
'menu': [
{
'name': 'GitHub',
'url': 'https://github.com/open-mmlab/mmcv'
'url': 'https://github.com/open-mmlab/mmclassification'
},
{
'name':

View File

@ -49,6 +49,10 @@ MMClassification 提供了一些脚本用于进行单张图像的推理、数据
```shell
python demo/image_demo.py ${IMAGE_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE}
# Example
python demo/image_demo.py demo/demo.JPEG configs/resnet/resnet50_b32x8_imagenet.py \
https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth
```
### 数据集的推理与测试
@ -82,7 +86,9 @@ python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--metrics ${METRICS}] [-
在 ImageNet 验证集上,使用 ResNet-50 进行推理并获得预测标签及其对应的预测得分。
```shell
python tools/test.py configs/imagenet/resnet50_batch256.py checkpoints/xxx.pth --out result.pkl
python tools/test.py configs/resnet/resnet50_b16x8_cifar10.py \
https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_b16x8_cifar10_20210528-f54bfad9.pth \
--out result.pkl
```
## 模型训练
@ -187,30 +193,30 @@ Params: 25.56 M
==============================
```
**注意**:此工具仍处于试验阶段,我们不保证该数字正确无误。您最好将结果用于简单比较,但在技术报告或论文中采用该结果之前,请仔细检查。
```{warning}
此工具仍处于试验阶段,我们不保证该数字正确无误。您最好将结果用于简单比较,但在技术报告或论文中采用该结果之前,请仔细检查。
- FLOPs 与输入的尺寸有关,而参数量与输入尺寸无关。默认输入尺寸为 (1, 3, 224, 224)
- 一些运算不会被计入 FLOPs 的统计中,例如 GN 和自定义运算。详细信息请参考 [`mmcv.cnn.get_model_complexity_info()`](https://github.com/open-mmlab/mmcv/blob/master/mmcv/cnn/utils/flops_counter.py)
```
### 模型发布
上传模型至 AWS 之前,也许会需要
- 转换模型权重至 CPU 张量
- 删除优化器状态
- 计算模型权重文件的哈希值,并添加至文件名之后
发布模型之前,你也许会需要
1. 转换模型权重至 CPU 张量
2. 删除优化器状态
3. 计算模型权重文件的哈希值,并添加至文件名之后
```shell
python tools/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
python tools/convert_models/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
```
例如:
```shell
python tools/publish_model.py work_dirs/resnet50/latest.pth imagenet_resnet50_20200708.pth
python tools/convert_models/publish_model.py work_dirs/resnet50/latest.pth imagenet_resnet50.pth
```
最终输出的文件名将会是 `imagenet_resnet50_20200708-{hash id}.pth`
最终输出的文件名将会是 `imagenet_resnet50_{date}-{hash id}.pth`
## 详细教程

View File

@ -18,6 +18,7 @@ You can switch between Chinese and English documents in the lower-left corner of
:caption: 模型库
modelzoo_statistics.md
model_zoo.md
.. toctree::
@ -40,6 +41,13 @@ You can switch between Chinese and English documents in the lower-left corner of
tools/model_serving.md
.. toctree::
:maxdepth: 1
:caption: 社区
community/CONTRIBUTING.md
.. toctree::
:caption: API 参考文档

View File

@ -23,8 +23,10 @@ MMClassification 和 MMCV 的适配关系如下,请安装正确版本的 MMCV
| 0.7.0 | mmcv>=1.1.4 |
| 0.6.0 | mmcv>=1.1.4 |
提示:由于 `master` 分支处于频繁开发中,`mmcv` 版本依赖可能不准确。如果您在使用
```{note}
由于 `master` 分支处于频繁开发中,`mmcv` 版本依赖可能不准确。如果您在使用
`master` 分支时遇到问题,请尝试更新 `mmcv` 到最新版。
```
## 安装 MMClassification 步骤
@ -41,8 +43,10 @@ b. 按照 [官方指南](https://pytorch.org/) 安装 PyTorch 和 TorchVision
conda install pytorch torchvision -c pytorch
```
**注**:请确保 CUDA 编译版本和运行版本相匹配
用户可以参照 [PyTorch 官网](https://pytorch.org/) 对预编译包所支持的 CUDA 版本进行核对。
```{note}
请确保 CUDA 编译版本和运行版本相匹配。
可以参照 [PyTorch 官网](https://pytorch.org/) 对预编译包所支持的 CUDA 版本进行核对。
```
`例 1`:如果用户的 `/usr/local/cuda` 文件夹下已安装 CUDA 10.1 版本,并且想要安装 PyTorch 1.5 版本,
则需要安装 CUDA 10.1 下预编译的 PyTorch。
@ -94,11 +98,9 @@ cd mmclassification
pip install -e . # 或者 "python setup.py develop"
```
提示:
1. 按照以上步骤MMClassification 是以 `dev` 模式安装的,任何本地的代码修改都可以直接生效,无需重新安装(除非提交了一些 commit并且希望提升版本号
2. 如果希望使用 `opencv-python-headless` 而不是 `opencv-python`,可以在安装 [mmcv](https://github.com/open-mmlab/mmcv) 之前提前安装。
```{note}
按照以上步骤MMClassification 是以 `dev` 模式安装的,任何本地的代码修改都可以直接生效,无需重新安装(除非提交了一些 commit并且希望提升版本号
```
### 利用 Docker 镜像安装 MMClassification
@ -109,7 +111,9 @@ MMClassification 提供 [Dockerfile](https://github.com/open-mmlab/mmclassificat
docker build -f ./docker/Dockerfile --rm -t mmcls:torch1.6.0-cuda10.1-cudnn7 .
```
**注意:** 确保已经安装了 [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker).
```{important}
请确保已经安装了 [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker).
```
运行一个基于上述镜像的容器:

View File

@ -0,0 +1 @@
../docs/model_zoo.md

View File

@ -9,11 +9,20 @@
- 按照 [教程 2如何增加新数据集](new_dataset.md) 添加对新数据集的支持。
- 按照本教程中讨论的内容修改配置文件
以 CIFAR10 数据集的微调为例,用户需要修改配置文件中的五个部分。
假设我们现在有一个在 ImageNet-2012 数据集上训练好的 ResNet-50 模型,并且希望在
CIFAR-10 数据集上进行模型微调,我们需要修改配置文件中的五个部分。
## 继承基础配置
为了重用不同配置之间的通用部分,我们支持从多个现有配置中继承配置。要微调 ResNet-50 模型,新配置需要继承 `_base_/models/resnet50.py` 来搭建模型的基本结构。为了使用 CIFAR10 数据集,新的配置文件可以直接继承 `_base_/datasets/cifar10.py`。而为了保留运行相关设置,比如训练调整器,新的配置文件需要继承 `_base_/default_runtime.py`
首先,创建一个新的配置文件 `configs/tutorial/resnet50_finetune_cifar.py` 来保存我们的配置,当然,这个文件名可以自由设定。
为了重用不同配置之间的通用部分,我们支持从多个现有配置中继承配置。要微调
ResNet-50 模型,新配置需要继承 `_base_/models/resnet50.py` 来搭建模型的基本结构。
为了使用 CIFAR10 数据集,新的配置文件可以直接继承 `_base_/datasets/cifar10.py`
而为了保留运行相关设置,比如训练调整器,新的配置文件需要继承
`_base_/default_runtime.py`
要继承以上这些配置文件,只需要把下面一段代码放在我们的配置文件开头。
```python
_base_ = [
@ -22,52 +31,97 @@ _base_ = [
]
```
除此之外,用户也可以直接编写完整的配置文件,而不是使用继承,例如 `configs/mnist/lenet5.py`
除此之外,你也可以不使用继承,直接编写完整的配置文件,例如
[`configs/lenet/lenet5_mnist.py`](https://github.com/open-mmlab/mmclassification/blob/master/configs/lenet/lenet5_mnist.py)。
## 修改分类头
## 修改模型
接下来,新的配置文件需要按照新数据集的类别数目来修改分类头的配置。只需要修改分类头中的 `num_classes` 设置,除了最终分类头之外的绝大部分预训练模型权重都会被重用。
在进行模型微调是我们通常希望在主干网络backbone加载预训练模型再用我们的数据集训练一个新的分类头head
为了在主干网络加载预训练模型,我们需要修改主干网络的初始化设置,使用
`Pretrained` 类型的初始化函数。另外,在初始化设置中,我们使用
`prefix='backbone'` 来告诉初始化函数移除权重文件中键值名称的前缀,比如把
`backbone.conv1` 变成 `conv1`。方便起见,我们这里使用一个在线的权重文件链接,它
会在训练前自动下载对应的文件,你也可以提前下载这个模型,然后使用本地路径。
接下来,新的配置文件需要按照新数据集的类别数目来修改分类头的配置。只需要修改分
类头中的 `num_classes` 设置即可。
```python
_base_ = ['./resnet50.py']
model = dict(
pretrained=None,
head=dict(
type='LinearClsHead',
num_classes=10,
in_channels=2048,
loss=dict(type='CrossEntropyLoss', loss_weight=1.0),
))
backbone=dict(
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
```
```{tip}
这里我们只需要设定我们想要修改的部分配置,其他配置将会自动从我们的父配置文件中获取。
```
另外,有时我们在进行微调时会希望冻结主干网络前面几层的参数,这么做有助于在后续
训练中,保持网络从预训练权重中获得的提取低阶特征的能力。在 MMClassification 中,
这一功能可以通过简单的一个 `frozen_stages` 参数来实现。比如我们需要冻结前两层网
络的参数,只需要在上面的配置中添加一行:
```python
model = dict(
backbone=dict(
frozen_stages=2,
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
```
```{note}
目前还不是所有的网络都支持 `frozen_stages` 参数,在使用之前,请先检查
[文档](https://mmclassification.readthedocs.io/zh_CN/latest/api.html#module-mmcls.models.backbones)
以确认你所使用的主干网络是否支持。
```
## 修改数据集
用户可能还需要准备数据集并编写有关数据集的配置。我们目前支持 MNISTCIFAR 和 ImageNet 数据集。为了在 CIFAR10 数据集上进行微调,考虑到其原始输入大小为 32而在 ImageNet 上预训练模型的输入大小为 224因此我们应将其大小调整为 224。
当针对一个新的数据集进行微调时,我们通常都需要修改一些数据集相关的配置。比如这
里,我们就需要把 CIFAR-10 数据集中的图像大小从 32 缩放到 224 来配合 ImageNet 上
预训练模型的输入。这一需要可以通过修改数据集的预处理流水线pipeline来实现。
```python
_base_ = ['./cifar10.py']
img_norm_cfg = dict(
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=True)
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=False,
)
train_pipeline = [
dict(type='RandomCrop', size=32, padding=4),
dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
dict(type='Resize', size=224)
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='ToTensor', keys=['gt_label']),
dict(type='Collect', keys=['img', 'gt_label'])
]
test_pipeline = [
dict(type='Resize', size=224)
dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img'])
]
dict(type='Collect', keys=['img']),
]
data = dict(
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
```
## 修改训练调整设置
## 修改训练策略设置
用于微调任务的超参数与默认配置不同,通常只需要较小的学习率和较少的训练时间。
@ -75,18 +129,94 @@ train_pipeline = [
# 用于批大小为 128 的优化器学习率
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# 学习策略
lr_config = dict(
policy='step',
step=[15])
# 学习率衰减策略
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)
```
## 使用预训练模型
## 开始训练
为了使用预先训练的模型,新的配置文件中需要使用 `load_from` 添加预训练模型权重文件的链接。而为了避免训练过程中自动下载的耗时,用户可以在训练之前下载模型权重文件,并配置本地路径。
现在,我们完成了用于微调的配置文件,完整的文件如下:
```python
load_from = 'https://s3.ap-northeast-2.amazonaws.com/open-mmlab/mmclassification/models/tbd.pth' # noqa
_base_ = [
'../_base_/models/resnet50.py',
'../_base_/datasets/cifar10_bs16.py', '../_base_/default_runtime.py'
]
# 模型设置
model = dict(
backbone=dict(
frozen_stages=2,
init_cfg=dict(
type='Pretrained',
checkpoint='https://download.openmmlab.com/mmclassification/v0/resnet/resnet50_8xb32_in1k_20210831-ea4938fc.pth',
prefix='backbone',
)),
head=dict(num_classes=10),
)
# 数据集设置
img_norm_cfg = dict(
mean=[125.307, 122.961, 113.8575],
std=[51.5865, 50.847, 51.255],
to_rgb=False,
)
train_pipeline = [
dict(type='RandomCrop', size=32, padding=4),
dict(type='RandomFlip', flip_prob=0.5, direction='horizontal'),
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='ToTensor', keys=['gt_label']),
dict(type='Collect', keys=['img', 'gt_label']),
]
test_pipeline = [
dict(type='Resize', size=224),
dict(type='Normalize', **img_norm_cfg),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
]
data = dict(
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
# 训练策略设置
# 用于批大小为 128 的优化器学习率
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# 学习率衰减策略
lr_config = dict(policy='step', step=[15])
runner = dict(type='EpochBasedRunner', max_epochs=200)
log_config = dict(interval=100)
```
接下来,我们使用一台 8 张 GPU 的电脑来训练我们的模型,指令如下:
```shell
bash tools/dist_train.sh configs/tutorial/resnet50_finetune_cifar.py 8
```
当然,我们也可以使用单张 GPU 来进行训练,使用如下命令:
```shell
python tools/train.py configs/tutorial/resnet50_finetune_cifar.py
```
但是如果我们使用单张 GPU 进行训练的话,需要在数据集设置部分作如下修改:
```python
data = dict(
samples_per_gpu=128,
train=dict(pipeline=train_pipeline),
val=dict(pipeline=test_pipeline),
test=dict(pipeline=test_pipeline),
)
```
这是因为我们的训练策略是针对批次大小batch size为 128 设置的。在父配置文件中,
设置了 `samples_per_gpu=16`,如果使用 8 张 GPU总的批次大小就是 128。而如果使
用单张 GPU就必须手动修改 `samples_per_gpu=128` 来匹配训练策略。