Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
1d3b8e71
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
1 年多 前同步成功
通知
116
Star
4999
Fork
1114
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
6
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleClas
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
6
合并请求
6
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
1d3b8e71
编写于
4月 17, 2020
作者:
W
wangshipeng01
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add finetune doc
上级
e33baa2b
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
156 addition
and
44 deletion
+156
-44
dataset/flower102/generate_flower_list.py
dataset/flower102/generate_flower_list.py
+14
-16
docs/zh_CN/tutorials/data.md
docs/zh_CN/tutorials/data.md
+26
-14
docs/zh_CN/tutorials/finetune.md
docs/zh_CN/tutorials/finetune.md
+110
-0
docs/zh_CN/tutorials/getting_started.md
docs/zh_CN/tutorials/getting_started.md
+6
-14
未找到文件。
dataset/generate_flower_list.py
→
dataset/
flower102/
generate_flower_list.py
浏览文件 @
1d3b8e71
...
...
@@ -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
)
docs/zh_CN/tutorials/data.md
浏览文件 @
1d3b8e71
...
...
@@ -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 |
[
ImageNet
1k
](
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
...
...
docs/zh_CN/tutorials/finetune.md
0 → 100644
浏览文件 @
1d3b8e71
# 模型微调
本文档将介绍如何使用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%
docs/zh_CN/tutorials/getting_started.md
浏览文件 @
1d3b8e71
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录