Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleSlim
提交
08536fca
P
PaddleSlim
项目概览
PaddlePaddle
/
PaddleSlim
大约 2 年 前同步成功
通知
51
Star
1434
Fork
344
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
53
列表
看板
标记
里程碑
合并请求
16
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleSlim
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
53
Issue
53
列表
看板
标记
里程碑
合并请求
16
合并请求
16
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
08536fca
编写于
11月 22, 2019
作者:
I
itminner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add quantizaiton demo
上级
99599e57
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
274 addition
and
0 deletion
+274
-0
demo/quant/train.py
demo/quant/train.py
+274
-0
未找到文件。
demo/quant/train.py
0 → 100644
浏览文件 @
08536fca
import
os
import
sys
import
logging
import
paddle
import
argparse
import
functools
import
math
import
time
import
numpy
as
np
import
paddle.fluid
as
fluid
from
paddleslim.prune
import
AutoPruner
from
paddleslim.common
import
get_logger
from
paddleslim.analysis
import
flops
sys
.
path
.
append
(
sys
.
path
[
0
]
+
"/../"
)
from
paddleslim.quant
import
quant_aware
,
quant_post
,
convert
import
models
from
utility
import
add_arguments
,
print_arguments
quantization_model_save_dir
=
'./quantization_models/'
_logger
=
get_logger
(
__name__
,
level
=
logging
.
INFO
)
parser
=
argparse
.
ArgumentParser
(
description
=
__doc__
)
add_arg
=
functools
.
partial
(
add_arguments
,
argparser
=
parser
)
# yapf: disable
add_arg
(
'batch_size'
,
int
,
64
*
4
,
"Minibatch size."
)
add_arg
(
'use_gpu'
,
bool
,
True
,
"Whether to use GPU or not."
)
add_arg
(
'model'
,
str
,
"MobileNet"
,
"The target model."
)
add_arg
(
'pretrained_model'
,
str
,
"../pretrained_model/MobileNetV1_pretained"
,
"Whether to use pretrained model."
)
add_arg
(
'lr'
,
float
,
0.1
,
"The learning rate used to fine-tune pruned model."
)
add_arg
(
'lr_strategy'
,
str
,
"piecewise_decay"
,
"The learning rate decay strategy."
)
add_arg
(
'l2_decay'
,
float
,
3e-5
,
"The l2_decay parameter."
)
add_arg
(
'momentum_rate'
,
float
,
0.9
,
"The value of momentum_rate."
)
add_arg
(
'num_epochs'
,
int
,
120
,
"The number of total epochs."
)
add_arg
(
'total_images'
,
int
,
1281167
,
"The number of total training images."
)
parser
.
add_argument
(
'--step_epochs'
,
nargs
=
'+'
,
type
=
int
,
default
=
[
30
,
60
,
90
],
help
=
"piecewise decay step"
)
add_arg
(
'config_file'
,
str
,
None
,
"The config file for compression with yaml format."
)
add_arg
(
'data'
,
str
,
"mnist"
,
"Which data to use. 'mnist' or 'imagenet'"
)
add_arg
(
'log_period'
,
int
,
10
,
"Log period in batches."
)
add_arg
(
'test_period'
,
int
,
10
,
"Test period in epoches."
)
# yapf: enable
model_list
=
[
m
for
m
in
dir
(
models
)
if
"__"
not
in
m
]
def
piecewise_decay
(
args
):
step
=
int
(
math
.
ceil
(
float
(
args
.
total_images
)
/
args
.
batch_size
))
bd
=
[
step
*
e
for
e
in
args
.
step_epochs
]
lr
=
[
args
.
lr
*
(
0.1
**
i
)
for
i
in
range
(
len
(
bd
)
+
1
)]
learning_rate
=
fluid
.
layers
.
piecewise_decay
(
boundaries
=
bd
,
values
=
lr
)
optimizer
=
fluid
.
optimizer
.
Momentum
(
learning_rate
=
learning_rate
,
momentum
=
args
.
momentum_rate
,
regularization
=
fluid
.
regularizer
.
L2Decay
(
args
.
l2_decay
))
return
optimizer
def
cosine_decay
(
args
):
step
=
int
(
math
.
ceil
(
float
(
args
.
total_images
)
/
args
.
batch_size
))
learning_rate
=
fluid
.
layers
.
cosine_decay
(
learning_rate
=
args
.
lr
,
step_each_epoch
=
step
,
epochs
=
args
.
num_epochs
)
optimizer
=
fluid
.
optimizer
.
Momentum
(
learning_rate
=
learning_rate
,
momentum
=
args
.
momentum_rate
,
regularization
=
fluid
.
regularizer
.
L2Decay
(
args
.
l2_decay
))
return
optimizer
def
create_optimizer
(
args
):
if
args
.
lr_strategy
==
"piecewise_decay"
:
return
piecewise_decay
(
args
)
elif
args
.
lr_strategy
==
"cosine_decay"
:
return
cosine_decay
(
args
)
def
compress
(
args
):
############################################################################################################
# 1. quantization configs
############################################################################################################
quant_config
=
{
# weight quantize type, default is 'abs_max'
'weight_quantize_type'
:
'abs_max'
,
# activation quantize type, default is 'abs_max'
'activation_quantize_type'
:
'moving_average_abs_max'
,
# weight quantize bit num, default is 8
'weight_bits'
:
8
,
# activation quantize bit num, default is 8
'activation_bits'
:
8
,
# op of name_scope in not_quant_pattern list, will not quantized
'not_quant_pattern'
:
[
'skip_quant_dd'
],
# op of types in quantize_op_types, will quantized
'quantize_op_types'
:
[
'conv2d'
,
'depthwise_conv2d'
,
'mul'
],
# data type after quantization, default is 'int8'
'dtype'
:
'int8'
,
# window size for 'range_abs_max' quantization. defaulf is 10000
'window_size'
:
10000
,
# The decay coefficient of moving average, default is 0.9
'moving_rate'
:
0.9
,
# if set quant_weight_only True, then only quantize parameters of layers which need quantization,
# and insert anti-quantization op for parameters of these layers.
'quant_weight_only'
:
False
}
train_reader
=
None
test_reader
=
None
if
args
.
data
==
"mnist"
:
import
paddle.dataset.mnist
as
reader
train_reader
=
reader
.
train
()
val_reader
=
reader
.
test
()
class_dim
=
10
image_shape
=
"1,28,28"
elif
args
.
data
==
"imagenet"
:
import
imagenet_reader
as
reader
train_reader
=
reader
.
train
()
val_reader
=
reader
.
val
()
class_dim
=
1000
image_shape
=
"3,224,224"
else
:
raise
ValueError
(
"{} is not supported."
.
format
(
args
.
data
))
image_shape
=
[
int
(
m
)
for
m
in
image_shape
.
split
(
","
)]
assert
args
.
model
in
model_list
,
"{} is not in lists: {}"
.
format
(
args
.
model
,
model_list
)
image
=
fluid
.
layers
.
data
(
name
=
'image'
,
shape
=
image_shape
,
dtype
=
'float32'
)
label
=
fluid
.
layers
.
data
(
name
=
'label'
,
shape
=
[
1
],
dtype
=
'int64'
)
# model definition
model
=
models
.
__dict__
[
args
.
model
]()
out
=
model
.
net
(
input
=
image
,
class_dim
=
class_dim
)
cost
=
fluid
.
layers
.
cross_entropy
(
input
=
out
,
label
=
label
)
avg_cost
=
fluid
.
layers
.
mean
(
x
=
cost
)
acc_top1
=
fluid
.
layers
.
accuracy
(
input
=
out
,
label
=
label
,
k
=
1
)
acc_top5
=
fluid
.
layers
.
accuracy
(
input
=
out
,
label
=
label
,
k
=
5
)
train_prog
=
fluid
.
default_main_program
()
val_program
=
fluid
.
default_main_program
().
clone
(
for_test
=
True
)
place
=
fluid
.
CUDAPlace
(
0
)
if
args
.
use_gpu
else
fluid
.
CPUPlace
()
############################################################################################################
# 2. quantization transform programs (training aware)
# Make some quantization transforms in the graph before training and testing.
# According to the weight and activation quantization type, the graph will be added
# some fake quantize operators and fake dequantize operators.
############################################################################################################
val_program
=
quant_aware
(
val_program
,
place
,
quant_config
,
scope
=
None
,
for_test
=
True
)
compiled_train_prog
=
quant_aware
(
train_prog
,
place
,
quant_config
,
scope
=
None
,
for_test
=
False
)
opt
=
create_optimizer
(
args
)
opt
.
minimize
(
avg_cost
)
exe
=
fluid
.
Executor
(
place
)
exe
.
run
(
fluid
.
default_startup_program
())
if
args
.
pretrained_model
:
def
if_exist
(
var
):
return
os
.
path
.
exists
(
os
.
path
.
join
(
args
.
pretrained_model
,
var
.
name
))
fluid
.
io
.
load_vars
(
exe
,
args
.
pretrained_model
,
predicate
=
if_exist
)
val_reader
=
paddle
.
batch
(
val_reader
,
batch_size
=
args
.
batch_size
)
train_reader
=
paddle
.
batch
(
train_reader
,
batch_size
=
args
.
batch_size
,
drop_last
=
True
)
train_feeder
=
feeder
=
fluid
.
DataFeeder
([
image
,
label
],
place
)
val_feeder
=
feeder
=
fluid
.
DataFeeder
(
[
image
,
label
],
place
,
program
=
val_program
)
def
test
(
epoch
,
program
):
batch_id
=
0
acc_top1_ns
=
[]
acc_top5_ns
=
[]
for
data
in
val_reader
():
start_time
=
time
.
time
()
acc_top1_n
,
acc_top5_n
=
exe
.
run
(
program
,
feed
=
train_feeder
.
feed
(
data
),
fetch_list
=
[
acc_top1
.
name
,
acc_top5
.
name
])
end_time
=
time
.
time
()
if
batch_id
%
args
.
log_period
==
0
:
_logger
.
info
(
"Eval epoch[{}] batch[{}] - acc_top1: {}; acc_top5: {}; time: {}"
.
format
(
epoch
,
batch_id
,
np
.
mean
(
acc_top1_n
),
np
.
mean
(
acc_top5_n
),
end_time
-
start_time
))
acc_top1_ns
.
append
(
np
.
mean
(
acc_top1_n
))
acc_top5_ns
.
append
(
np
.
mean
(
acc_top5_n
))
batch_id
+=
1
_logger
.
info
(
"Final eval epoch[{}] - acc_top1: {}; acc_top5: {}"
.
format
(
epoch
,
np
.
mean
(
np
.
array
(
acc_top1_ns
)),
np
.
mean
(
np
.
array
(
acc_top5_ns
))))
return
np
.
mean
(
np
.
array
(
acc_top1_ns
))
def
train
(
epoch
,
compiled_train_prog
):
build_strategy
=
fluid
.
BuildStrategy
()
exec_strategy
=
fluid
.
ExecutionStrategy
()
compiled_train_prog
=
compiled_train_prog
.
with_data_parallel
(
loss_name
=
avg_cost
.
name
,
build_strategy
=
build_strategy
,
exec_strategy
=
exec_strategy
)
batch_id
=
0
for
data
in
train_reader
():
start_time
=
time
.
time
()
loss_n
,
acc_top1_n
,
acc_top5_n
=
exe
.
run
(
compiled_train_prog
,
feed
=
train_feeder
.
feed
(
data
),
fetch_list
=
[
avg_cost
.
name
,
acc_top1
.
name
,
acc_top5
.
name
])
end_time
=
time
.
time
()
loss_n
=
np
.
mean
(
loss_n
)
acc_top1_n
=
np
.
mean
(
acc_top1_n
)
acc_top5_n
=
np
.
mean
(
acc_top5_n
)
if
batch_id
%
args
.
log_period
==
0
:
_logger
.
info
(
"epoch[{}]-batch[{}] - loss: {}; acc_top1: {}; acc_top5: {}; time: {}"
.
format
(
epoch
,
batch_id
,
loss_n
,
acc_top1_n
,
acc_top5_n
,
end_time
-
start_time
))
batch_id
+=
1
############################################################################################################
# train loop
############################################################################################################
for
i
in
range
(
args
.
num_epochs
):
train
(
i
,
compiled_train_prog
)
if
i
%
args
.
test_period
==
0
:
test
(
i
,
val_program
)
############################################################################################################
# 3. Freeze the graph after training by adjusting the quantize
# operators' order for the inference.
# The dtype of float_program's weights is float32, but in int8 range.
############################################################################################################
float_program
,
int8_program
=
convert
(
val_program
,
fluid
.
global_scope
(),
place
,
quant_config
,
save_int8
=
True
)
############################################################################################################
# 4. Save inference model
############################################################################################################
model_path
=
os
.
path
.
join
(
quantization_model_save_dir
,
args
.
model
,
'act_'
+
quant_config
[
'activation_quantize_type'
]
+
'_w_'
+
quant_config
[
'weight_quantize_type'
])
float_path
=
os
.
path
.
join
(
model_path
,
'float'
)
int8_path
=
os
.
path
.
join
(
model_path
,
'int8'
)
if
not
os
.
path
.
isdir
(
model_path
):
os
.
makedirs
(
model_path
)
fluid
.
io
.
save_inference_model
(
dirname
=
float_path
,
feeded_var_names
=
[
image
.
name
],
target_vars
=
[
out
],
executor
=
exe
,
main_program
=
float_program
,
model_filename
=
float_path
+
'/model'
,
params_filename
=
float_path
+
'/params'
)
fluid
.
io
.
save_inference_model
(
dirname
=
int8_path
,
feeded_var_names
=
[
image
.
name
],
target_vars
=
[
out
],
executor
=
exe
,
main_program
=
int8_program
,
model_filename
=
int8_path
+
'/model'
,
params_filename
=
int8_path
+
'/params'
)
def
main
():
args
=
parser
.
parse_args
()
print_arguments
(
args
)
compress
(
args
)
if
__name__
==
'__main__'
:
main
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录