提交 1d3b8e71 编写于 作者: W wangshipeng01

add finetune doc

上级 e33baa2b
......@@ -3,21 +3,26 @@ import numpy as np
import os
import sys
""".mat files data format
imagelabel.mat
jpg_name 1 2 3 ...
label 32 12 66 ...
setid.mat
jpg_name(10 records in a class) 24 6 100 65 32 ...
label 4 ...
"""
Usage: python generate_flower_list.py ./jpg train > train_list.txt
python generate_flower_list.py ./jpg valid > val_list.txt
"""
Usage:
python generate_flower_list.py prefix_folder mode
python generate_flower_list.py jpg train > train_list.txt
python generate_flower_list.py jpg valid > val_list.txt
"""
data_path = sys.argv[1]
imagelabels_path='./imagelabels.mat'
setid_path='./setid.mat'
"""
imagelabel.mat
jpg_name 1 2 3 ...
label 32 12 66 ...
"""
labels = scipy.io.loadmat(imagelabels_path)
labels = np.array(labels['labels'][0])
setid = scipy.io.loadmat(setid_path)
......@@ -27,13 +32,6 @@ d['train'] = np.array(setid['trnid'][0])
d['valid'] = np.array(setid['valid'][0])
d['test']=np.array(setid['tstid'][0])
"""
setid.mat
jpg_name 24 6 100 65 32 ...
label 4 ...
"""
for id in d[sys.argv[2]]:
message = str(data_path)+"/image_"+str(id).zfill(5)+" "+str(labels[id-1])
message = str(data_path)+"/image_"+str(id).zfill(5)+".jpg "+str(labels[id-1])
print(message)
......@@ -3,23 +3,25 @@
---
## 1.简介
PaddleClas支持ImageNet1000和Flower数据分类任务
本文档介绍ImageNet1k和Flower102数据准备过程
PaddleClas提供了丰富的预训练模型,支持的模型列表请参考[模型库](../models/models_intro.md)
## 2.数据集准备
数据集 | 训练集大小 | 测试集大小 | 类别数 | 备注|
:------:|:---------------:|:---------------------:|:-----------:|:-----------:
Flowers|1k | 6k | 102 |
[ImageNet](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 |
[Flower102](https://www.robots.ox.ac.uk/~vgg/data/flowers/102/)|1k | 6k | 102 |
[ImageNet1k](http://www.image-net.org/challenges/LSVRC/2012/)|1.2M| 50k | 1000 |
数据格式
PaddleClas加载PaddleClas/dataset/中的数据,通过指定data_dir和file_list来进行加载
PaddleClas加载PaddleClas/dataset/中的数据,请将下载后的数据按下面格式组织放置到PaddleClas/dataset/中。
### ImageNet1k
从官方下载数据后,按如下组织数据
```bash
PaddleClas/dataset/imagenet
|_ train
PaddleClas/dataset/imagenet/
|_ train/
| |_ n01440764
| | |_ n01440764_10026.JPEG
| | |_ ...
......@@ -28,29 +30,39 @@ PaddleClas/dataset/imagenet
| |_ n15075141
| |_ ...
| |_ n15075141_9993.JPEG
|_ val
|_ val/
| |_ ILSVRC2012_val_00000001.JPEG
| |_ ...
| |_ ILSVRC2012_val_00050000.JPEG
|_ train_list.txt
|_ val_list.txt
```
### Flower
从VGG官方网站下载后的数据,解压后包括
jpg/
setid.mat
imagelabels.mat
将以上文件放置在PaddleClas/dataset/flower102/下
通过运行generate_flower_list.py生成train_list.txt和val_list.txt
```bash
PaddleClas/dataset/flower
|_ train
python generate_flower_list.py jpg train > train_list.txt
python generate_flower_list.py jpg valid > val_list.txt
```
按照如下结构组织数据:
```bash
PaddleClas/dataset/flower102/
|_ jpg/
| |_ image_03601.jpg
| |_ ...
| |_ image_07073.jpg
|_ val
| |_ image_04121.jpg
| |_ ...
| |_ image_02355.jpg
|_ train_list.txt
|_ val_list.txt
```
或是通过软链接将数据从实际地址链接到PaddleClas/dataset/下
```bash
......
# 模型微调
本文档将介绍如何使用PaddleClas进行模型微调(finetune)
模型微调使用PaddleClas提供的预训练模型,可以节省从头训练的计算资源和时间,并提高准确率。
> 在使用ResNet50_vd_ssld蒸馏模型对flower102数据进行模型微调,仅需要3分钟(V100 单卡)top1即可达到94.96%
模型微调大致包括如下四个步骤:
- 初始化预训练模型
- 剔除FC层
- 更新参数
- 新的训练策略
## 初始化预训练模型
这里我们以ResNet50_vd和ResNet50_vd_ssld预训练模型对flower102数据集进行微调
ResNet50_vd: 在ImageNet1k数据集上训练 top1 acc:79.1% 模型详细信息参考[模型库](https://paddleclas.readthedocs.io/zh_CN/latest/models/ResNet_and_vd.html)
ResNet50_vd_ssld: 在ImageNet1k数据集训练的蒸馏模型 top1: 82.4% 模型详细信息参考[模型库](https://paddleclas.readthedocs.io/zh_CN/latest/models/ResNet_and_vd.html)
flower数据集相关信息参考[数据文档](data.md)
指定pretrained_model参数初始化预训练模型
ResNet50_vd:
```bash
python -m paddle.distributed.launch \
--selected_gpus="0" \
tools/train.py \
-c ./configs/finetune/ResNet50_vd_finetune.yaml
-o pretrained_model= ResNet50_vd预训练模型
```
ResNet50_vd_ssld:
```bash
python -m paddle.distributed.launch \
--selected_gpus="0" \
tools/train.py \
-c ./configs/finetune/ResNet50_vd_ssld_finetune.yaml
-o pretrained_model= ResNet50_vd_ssld预训练模型
```
##剔除FC层
由于新的数据集类别数(Flower102:102类)和ImgaeNet1k数据(1000类)不一致,一般需要对分类网络的最后FC层进行调整,PaddleClas默认剔除所有形状不一样的层
```python
#excerpt from PaddleClas/ppcls/utils/save_load.py
def load_params(exe, prog, path):
# ...
ignore_set = set()
state = _load_state(path)
# 剔除预训练模型和模型间形状不一致的参数
all_var_shape = {}
for block in prog.blocks:
for param in block.all_parameters():
all_var_shape[param.name] = param.shape
ignore_set.update([
name for name, shape in all_var_shape.items()
if name in state and shape != state[name].shape
])
# 用于迁移学习的代码段已被省略 ...
if len(ignore_set) > 0:
for k in ignore_set:
if k in state:
# 剔除参数
del state[k]
fluid.io.set_program_state(prog, state)
```
在将shape不一致的层进行剔除正确加载预训练模型后,我们要选择需要更新的参数来让优化器进行参数更新。
## 更新参数
首先,分类网络中的卷积层大致可以分为
- ```浅层卷积层```:用于提取基础特征
- ```深层卷积层```:用于提取抽象特征
- ```FC层```:进行特征组合
其次,在衡量数据集大小差别和数据集的相似程度后,我们一般遵循如下的规则进行参数更新:
- 1. 新的数据集很小,在类别,具体种类上和原数据很像。由于新数据集很小,这里可能出现过拟合的问题;由于数据很像,可以认为预训练模型的深层特征仍然会起作用,只需要训练一个最终的```FC层```即可。
- 2. 新的数据集很大,在类别,具体种类上和原数据很像。推荐训练网络中全部层的参数。
- 3. 新的数据集很小但是和原数据不相像,可以冻结网络中初始层的参数更新```stop_gradient=True```,对较高层进行重新训练。
- 4. 新的数据集很大但是和原数据不相像,这时候预训练模型可能不会生效,需要从头训练。
PaddleClas模型微调默认更新所有层参数。
## 新的训练策略
1. 学习率
由于已经加载了预训练模型,对于从头训练的随机初始化参数来讲,模型中的参数已经具备了一定的分类能力,所以建议使用与从头训练相比更小的学习率,例如减小10倍。
2. 类别数和总图片数调整为新数据集数据
3. 调整训练轮数,由于不需要从头开始训练,一般相对减少模型微调的训练轮数
## 模型微调结果
在使用ResNet50_vd预训练模型对flower102数据进行模型微调后,top1 acc 达到 92.71%
在使用ResNet50_vd_ssld预训练模型对flower102数据进行模型微调后,top1 acc 达到94.96%
......@@ -16,15 +16,17 @@ export PYTHONPATH=path_to_PaddleClas:$PYTHONPATH
PaddleClas 提供模型训练与评估脚本:tools/train.py和tools/eval.py
### 2.1 模型训练
以flower102数据为例按如下方式启动模型训练,flower数据集准备请参考[数据集准备](./data.md)
```bash
# PaddleClas通过launch方式启动多卡多进程训练
# 通过设置FLAGS_selected_gpus 指定GPU运行卡号
python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50 \
--log_dir=log_ResNet50_vd \
tools/train.py \
-c ./configs/ResNet/ResNet50.yaml
-c ./configs/flower.yaml
```
- 输出日志示例如下:
......@@ -40,7 +42,7 @@ python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50_vd \
tools/train.py \
-c ./configs/ResNet/ResNet50_vd.yaml \
-c ./configs/flower.yaml \
-o use_mix=1
```
......@@ -54,18 +56,8 @@ epoch:0 train step:522 loss:1.6330 lr:0.100000 elapse:0.210
或是直接修改模型对应的yaml配置文件,具体配置参数参考[配置文档](config.md)
### 2.3 模型微调
模型微调请参照[模型微调文档](./finetune.md)
您可以通过如下命令进行模型微调,通过指定--pretrained_model参数加载预训练模型
```bash
python -m paddle.distributed.launch \
--selected_gpus="0,1,2,3" \
--log_dir=log_ResNet50_vd \
train.py \
-c ../configs/ResNet/ResNet50_vd.yaml \
-o pretrained_model= 预训练模型路径\
```
### 2.2 模型评估
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册