Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
4fc82eef
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
接近 2 年 前同步成功
通知
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看板
提交
4fc82eef
编写于
2月 25, 2022
作者:
G
gaotingquan
提交者:
Tingquan Gao
3月 01, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add the doc and demo about gallery2fc
add description doc and demo config
上级
1020f418
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
124 addition
and
6 deletion
+124
-6
deploy/lite_shitu/README.md
deploy/lite_shitu/README.md
+4
-1
docs/zh_CN/advanced_tutorials/gallery2fc.md
docs/zh_CN/advanced_tutorials/gallery2fc.md
+51
-0
ppcls/configs/GeneralRecognition/Gallery2FC_PPLCNet_x2_5.yaml
...s/configs/GeneralRecognition/Gallery2FC_PPLCNet_x2_5.yaml
+51
-0
ppcls/utils/gallery2fc.py
ppcls/utils/gallery2fc.py
+18
-5
未找到文件。
deploy/lite_shitu/README.md
浏览文件 @
4fc82eef
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
本教程将介绍基于
[
Paddle Lite
](
https://github.com/PaddlePaddle/Paddle-Lite
)
在移动端部署PaddleClas PP-ShiTu模型的详细步骤。
本教程将介绍基于
[
Paddle Lite
](
https://github.com/PaddlePaddle/Paddle-Lite
)
在移动端部署PaddleClas PP-ShiTu模型的详细步骤。
Paddle Lite是飞桨轻量化推理引擎,为手机、I
O
T端提供高效推理能力,并广泛整合跨平台硬件,为端侧部署及应用落地问题提供轻量化的部署方案。
Paddle Lite是飞桨轻量化推理引擎,为手机、I
o
T端提供高效推理能力,并广泛整合跨平台硬件,为端侧部署及应用落地问题提供轻量化的部署方案。
## 1. 准备环境
## 1. 准备环境
...
@@ -216,3 +216,6 @@ A1:如果已经走通了上述步骤,更换模型只需要替换 `.nb` 模
...
@@ -216,3 +216,6 @@ A1:如果已经走通了上述步骤,更换模型只需要替换 `.nb` 模
Q2:换一个图测试怎么做?
Q2:换一个图测试怎么做?
A2:替换 deploy 下的测试图像为你想要测试的图像,并重新生成json配置文件(或者直接修改图像路径),使用 ADB 再次 push 到手机上即可。
A2:替换 deploy 下的测试图像为你想要测试的图像,并重新生成json配置文件(或者直接修改图像路径),使用 ADB 再次 push 到手机上即可。
Q3:如果需要更换模型/预训练模型/底库数据集,需要怎么做:
A:请参考文档
[
基于分类方法的 PP-Shitu 移动端部署方案说明
](
./gallery2fc.md
)
。
docs/zh_CN/advanced_tutorials/gallery2fc.md
0 → 100644
浏览文件 @
4fc82eef
# 识别模型转分类模型
PaddleClas 提供了
`gallery2fc.py`
工具,帮助大家将识别模型转为分类模型。
## 一、模型转换说明
### 1.1 准备底库数据、预训练模型
#### 1. 底库数据集
首先需要准备好底库数据,下面以 PaddleClas 提供饮料数据集(drink_dataset_v1.0)为例进行说明,饮料数据集获取方法:
```
shell
cd
PaddleClas/
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/data/drink_dataset_v1.0.tar
tar
-xf
drink_dataset_v1.0.tar
```
饮料数据集的底库图片路径为
`drink_dataset_v1.0/gallery/`
,底库图片列表可在
`drink_dataset_v1.0/gallery/drink_label.txt`
中查看,关于底库数据格式说明,请参考文档
[
数据集格式说明
](
../data_preparation/recognition_dataset.md#1-数据集格式说明
)
。
#### 2. 预训练模型
在开始转换模型前,需要准备好预训练模型,下面以量化后的
`general_PPLCNet_x2_5`
模型为例,下载预训练模型:
```
shell
cd
PaddleClas/pretrained/
wget https://paddle-imagenet-models-name.bj.bcebos.com/dygraph/rec/models/pretrain/general_PPLCNet_x2_5_pretrained_v1.0_quant.pdparams
```
### 1.2 准备配置文件
在进行模型转换时,需要通过配置文件定义所需参数,本例中所用配置文件为
`ppcls/configs/GeneralRecognition/Gallery2FC_PPLCNet_x2_5.yaml`
,对于配置文件字段的说明,如下所示:
*
Global:
*
pretrained_model: 预训练模型路径,无需包含
`.pdparams`
后缀名;
*
image_shape: 模型输入数据尺寸,无需包含 batch size 维度;
*
save_inference_dir: 转换后模型的保存路径;
*
Arch: 模型结构相关定义,可参考
[
配置说明
](
../models_training/config_description.md#3-%E8%AF%86%E5%88%AB%E6%A8%A1%E5%9E%8B
)
;
*
IndexProcess: 底库数据集相关定义
*
image_root: 底库数据集路径;
*
data_file: 底库数据集列表文件路径;
### 1.3 转换特征提取模型
在完成上述准备工作后,即可进行模型转换,命令如下所示:
```
python
python
ppcls
/
utils
/
gallery2fc
.
py
-
c
ppcls
/
configs
/
GeneralRecognition
/
Gallery2FC_PPLCNet_x2_5
.
yaml
```
在上述命令执行完成后,转换并导出的模型保存在目录
`./inference/general_PPLCNet_x2_5_quant/`
下。在推理部署时,需要注意的是,模型的输出结果通常有多个,应选取分类结果作为模型输出,需要注意区分。
ppcls/configs/GeneralRecognition/Gallery2FC_PPLCNet_x2_5.yaml
0 → 100644
浏览文件 @
4fc82eef
# global configs
Global
:
pretrained_model
:
./pretrained/general_PPLCNet_x2_5_pretrained_v1.0_quant
# used for static mode and model export
image_shape
:
[
3
,
224
,
224
]
save_inference_dir
:
./inference/general_PPLCNet_x2_5_quant/inference
# for quantizaiton or prune model
Slim
:
## for prune
quant
:
name
:
pact
# model architecture
Arch
:
name
:
RecModel
Backbone
:
name
:
PPLCNet_x2_5
pretrained
:
False
use_ssld
:
True
BackboneStopLayer
:
name
:
"
flatten"
Neck
:
name
:
FC
embedding_size
:
1280
class_num
:
512
Head
:
name
:
ArcMargin
embedding_size
:
512
class_num
:
185341
margin
:
0.2
scale
:
30
# indexing engine config
IndexProcess
:
image_root
:
"
./drink_dataset_v1.0/gallery/"
data_file
:
"
./drink_dataset_v1.0/gallery/drink_label.txt"
delimiter
:
"
\t
"
batch_size
:
2
transform_ops
:
-
ResizeImage
:
resize_short
:
256
-
CropImage
:
size
:
224
-
NormalizeImage
:
scale
:
1.0/255.0
mean
:
[
0.485
,
0.456
,
0.406
]
std
:
[
0.229
,
0.224
,
0.225
]
order
:
'
'
-
ToCHWImage
:
ppcls/utils/gallery2fc.py
浏览文件 @
4fc82eef
...
@@ -12,10 +12,14 @@
...
@@ -12,10 +12,14 @@
# See the License for the specific language governing permissions and
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import
os
import
paddle
import
paddle
import
cv2
import
cv2
import
os
import
sys
__dir__
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
__dir__
,
'../../'
)))
from
ppcls.arch
import
build_model
from
ppcls.arch
import
build_model
from
ppcls.utils.config
import
parse_config
,
parse_args
from
ppcls.utils.config
import
parse_config
,
parse_args
from
ppcls.utils.save_load
import
load_dygraph_pretrain
from
ppcls.utils.save_load
import
load_dygraph_pretrain
...
@@ -51,12 +55,17 @@ class GalleryLayer(paddle.nn.Layer):
...
@@ -51,12 +55,17 @@ class GalleryLayer(paddle.nn.Layer):
self
.
gallery_images
.
append
(
image_file
)
self
.
gallery_images
.
append
(
image_file
)
gallery_docs
.
append
(
ori_line
.
strip
())
gallery_docs
.
append
(
ori_line
.
strip
())
gallery_labels
.
append
(
line
[
1
].
strip
())
gallery_labels
.
append
(
line
[
1
].
strip
())
self
.
gallery_layer
=
paddle
.
nn
.
Linear
(
embedding_size
,
len
(
self
.
gallery_images
),
bias_attr
=
False
)
self
.
gallery_layer
=
paddle
.
nn
.
Linear
(
embedding_size
,
len
(
self
.
gallery_images
),
bias_attr
=
False
)
self
.
gallery_layer
.
skip_quant
=
True
self
.
gallery_layer
.
skip_quant
=
True
output_label_str
=
""
output_label_str
=
""
for
i
,
label_i
in
enumerate
(
gallery_labels
):
for
i
,
label_i
in
enumerate
(
gallery_labels
):
output_label_str
+=
"{} {}
\n
"
.
format
(
i
,
label_i
)
output_label_str
+=
"{} {}
\n
"
.
format
(
i
,
label_i
)
output_path
=
configs
[
"Global"
][
"save_inference_dir"
]
+
"_label.txt"
output_path
=
configs
[
"Global"
][
"save_inference_dir"
]
+
"_label.txt"
save_dir
=
os
.
path
.
dirname
(
configs
[
"Global"
][
"save_inference_dir"
])
if
not
os
.
path
.
exists
(
save_dir
):
os
.
makedirs
(
save_dir
)
with
open
(
output_path
,
"w"
)
as
f
:
with
open
(
output_path
,
"w"
)
as
f
:
f
.
write
(
output_label_str
)
f
.
write
(
output_label_str
)
...
@@ -71,19 +80,23 @@ class GalleryLayer(paddle.nn.Layer):
...
@@ -71,19 +80,23 @@ class GalleryLayer(paddle.nn.Layer):
embedding_size
=
self
.
configs
[
"Arch"
][
"Head"
][
"embedding_size"
]
embedding_size
=
self
.
configs
[
"Arch"
][
"Head"
][
"embedding_size"
]
batch_index
=
0
batch_index
=
0
input_tensor
=
paddle
.
zeros
(
self
.
image_shape
)
input_tensor
=
paddle
.
zeros
(
self
.
image_shape
)
gallery_feature
=
paddle
.
zeros
((
len
(
self
.
gallery_images
),
embedding_size
))
gallery_feature
=
paddle
.
zeros
(
(
len
(
self
.
gallery_images
),
embedding_size
))
for
i
,
image_path
in
enumerate
(
self
.
gallery_images
):
for
i
,
image_path
in
enumerate
(
self
.
gallery_images
):
image
=
cv2
.
imread
(
image_path
)[:,
:,
::
-
1
]
image
=
cv2
.
imread
(
image_path
)[:,
:,
::
-
1
]
for
op
in
preprocess_ops
:
for
op
in
preprocess_ops
:
image
=
op
(
image
)
image
=
op
(
image
)
input_tensor
[
batch_index
]
=
image
input_tensor
[
batch_index
]
=
image
batch_index
+=
1
batch_index
+=
1
if
batch_index
==
self
.
batch_size
or
i
==
len
(
self
.
gallery_images
)
-
1
:
if
batch_index
==
self
.
batch_size
or
i
==
len
(
self
.
gallery_images
)
-
1
:
batch_feature
=
feature_extractor
(
input_tensor
)[
"features"
]
batch_feature
=
feature_extractor
(
input_tensor
)[
"features"
]
for
j
in
range
(
batch_index
):
for
j
in
range
(
batch_index
):
feature
=
batch_feature
[
j
]
feature
=
batch_feature
[
j
]
norm_feature
=
paddle
.
nn
.
functional
.
normalize
(
feature
,
axis
=
0
)
norm_feature
=
paddle
.
nn
.
functional
.
normalize
(
feature
,
axis
=
0
)
gallery_feature
[
i
-
batch_index
+
j
+
1
]
=
norm_feature
gallery_feature
[
i
-
batch_index
+
j
+
1
]
=
norm_feature
batch_index
=
0
self
.
gallery_layer
.
set_state_dict
({
"_layer.weight"
:
gallery_feature
.
T
})
self
.
gallery_layer
.
set_state_dict
({
"_layer.weight"
:
gallery_feature
.
T
})
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录