Skip to content

Commit fdd40e1

Browse files
authored
Add keras saved_model examples (#1201)
1 parent e81b265 commit fdd40e1

File tree

45 files changed

+2288
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2288
-3
lines changed

examples/.config/model_params_tensorflow.json

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@
3636
"batch_size": 100,
3737
"new_benchmark": true
3838
},
39+
"resnet101_keras": {
40+
"model_src_dir": "image_recognition/keras_models/resnet101/quantization/ptq",
41+
"dataset_location": "/tf_dataset/dataset/imagenet",
42+
"input_model": "/tf_dataset2/models/tensorflow/resnet101_keras/saved_model/",
43+
"yaml": "resnet101.yaml",
44+
"strategy": "basic",
45+
"batch_size": 1,
46+
"new_benchmark": true
47+
},
3948
"resnet_v1_50_slim": {
4049
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq/slim",
4150
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -108,6 +117,15 @@
108117
"batch_size": 100,
109118
"new_benchmark": true
110119
},
120+
"inception_v3_keras": {
121+
"model_src_dir": "image_recognition/keras_models/inception_v3/quantization/ptq",
122+
"dataset_location": "/tf_dataset/dataset/imagenet",
123+
"input_model": "/tf_dataset2/models/tensorflow/inception_v3_keras/saved_model/",
124+
"yaml": "inception_v3.yaml",
125+
"strategy": "basic",
126+
"batch_size": 1,
127+
"new_benchmark": true
128+
},
111129
"inception_v3_slim": {
112130
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq/slim",
113131
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -144,6 +162,15 @@
144162
"batch_size": 100,
145163
"new_benchmark": true
146164
},
165+
"inception_resnet_v2_keras": {
166+
"model_src_dir": "image_recognition/keras_models/inception_resnet_v2/quantization/ptq",
167+
"dataset_location": "/tf_dataset/dataset/imagenet",
168+
"input_model": "/tf_dataset2/models/tensorflow/inception_resnet_v2_keras/saved_model/",
169+
"yaml": "inception_resnet_v2.yaml",
170+
"strategy": "basic",
171+
"batch_size": 1,
172+
"new_benchmark": true
173+
},
147174
"vgg16": {
148175
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq",
149176
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -261,6 +288,15 @@
261288
"batch_size": 100,
262289
"new_benchmark": true
263290
},
291+
"resnetv2_50_keras": {
292+
"model_src_dir": "image_recognition/keras_models/resnetv2_50/quantization/ptq",
293+
"dataset_location": "/tf_dataset/dataset/imagenet",
294+
"input_model": "/tf_dataset2/models/tensorflow/resnetv2_50_keras/saved_model",
295+
"yaml": "resnetv2_50.yaml",
296+
"strategy": "basic",
297+
"batch_size": 1,
298+
"new_benchmark": true
299+
},
264300
"resnetv2_101": {
265301
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq",
266302
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -279,6 +315,15 @@
279315
"batch_size": 100,
280316
"new_benchmark": true
281317
},
318+
"resnetv2_101_keras": {
319+
"model_src_dir": "image_recognition/keras_models/resnetv2_101/quantization/ptq",
320+
"dataset_location": "/tf_dataset/dataset/imagenet",
321+
"input_model": "/tf_dataset2/models/tensorflow/resnetv2_101_keras/saved_model",
322+
"yaml": "resnetv2_101.yaml",
323+
"strategy": "basic",
324+
"batch_size": 1,
325+
"new_benchmark": true
326+
},
282327
"resnetv2_152": {
283328
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq",
284329
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -315,6 +360,15 @@
315360
"batch_size": 100,
316361
"new_benchmark": true
317362
},
363+
"mobilenetv2_keras": {
364+
"model_src_dir": "image_recognition/keras_models/mobilenet_v2/quantization/ptq",
365+
"dataset_location": "/tf_dataset/dataset/imagenet",
366+
"input_model": "/tf_dataset2/models/tensorflow/mobilenet_v2_keras/saved_model/",
367+
"yaml": "mobilenet_v2.yaml",
368+
"strategy": "basic",
369+
"batch_size": 1,
370+
"new_benchmark": true
371+
},
318372
"mobilenetv3": {
319373
"model_src_dir": "image_recognition/tensorflow_models/quantization/ptq",
320374
"dataset_location": "/tf_dataset/dataset/imagenet",
@@ -2412,6 +2466,15 @@
24122466
"strategy": "basic",
24132467
"batch_size": 64,
24142468
"new_benchmark": false
2469+
},
2470+
"xception": {
2471+
"model_src_dir": "image_recognition/keras_models/xception/quantization/ptq",
2472+
"dataset_location": "/tf_dataset/dataset/imagenet",
2473+
"input_model": "/tf_dataset2/models/tensorflow/xception_keras/saved_model/",
2474+
"yaml": "xception.yaml",
2475+
"strategy": "basic",
2476+
"batch_size": 1,
2477+
"new_benchmark": true
24152478
}
24162479
}
24172480
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Step-by-Step
2+
============
3+
4+
This document is used to enable Tensorflow Keras models using Intel® Neural Compressor.
5+
6+
7+
## Prerequisite
8+
9+
### 1. Installation
10+
```shell
11+
# Install Intel® Neural Compressor
12+
pip install neural-compressor
13+
```
14+
### 2. Install Intel Tensorflow
15+
```shell
16+
pip install intel-tensorflow
17+
```
18+
> Note: Supported Tensorflow [Version](../../../../../../../README.md).
19+
20+
### 3. Prepare Pretrained model
21+
22+
The pretrained model is provided by [Keras Applications](https://keras.io/api/applications/). prepare the model, Run as follow:
23+
```
24+
python prepare_model.py --output_model=/path/to/model
25+
```
26+
`--output_model ` the model should be saved as SavedModel format or H5 format.
27+
28+
## Run Command
29+
```shell
30+
bash run_tuning.sh --config=inception_resnet_v2.yaml --input_model=./path/to/model --output_model=./result --eval_data=/path/to/evaluation/dataset --calib_data=/path/to/calibration/dataset
31+
bash run_benchmark.sh --config=inception_resnet_v2.yaml --input_model=./path/to/model --mode=performance --eval_data=/path/to/evaluation/dataset
32+
```
33+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#
2+
# Copyright (c) 2021 Intel Corporation
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
version: 1.0
17+
18+
model: # mandatory. used to specify model specific information.
19+
name: inception_resnet_v2
20+
framework: tensorflow # mandatory. supported values are tensorflow, pytorch, pytorch_ipex, onnxrt_integer, onnxrt_qlinear or mxnet; allow new framework backend extension.
21+
22+
quantization: # optional. tuning constraints on model-wise for advance user to reduce tuning space.
23+
calibration:
24+
sampling_size: 50, 100 # optional. default value is 100. used to set how many samples should be used in calibration.
25+
model_wise: # optional. tuning constraints on model-wise for advance user to reduce tuning space.
26+
activation:
27+
algorithm: minmax
28+
29+
evaluation: # optional. required if user doesn't provide eval_func in neural_compressor.Quantization.
30+
accuracy:
31+
performance: # optional. used to benchmark performance of passing model.
32+
iteration: 100
33+
configs:
34+
cores_per_instance: 4
35+
num_of_instance: 7
36+
37+
tuning:
38+
accuracy_criterion:
39+
relative: 0.01 # optional. default value is relative, other value is absolute. this example allows relative accuracy loss: 1%.
40+
exit_policy:
41+
timeout: 0 # optional. tuning timeout (seconds). default value is 0 which means early stop. combine with max_trials field to decide when to exit.
42+
random_seed: 9527 # optional. random seed for deterministic tuning.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#
2+
# -*- coding: utf-8 -*-
3+
#
4+
# Copyright (c) 2018 Intel Corporation
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
import time
19+
import shutil
20+
import numpy as np
21+
from argparse import ArgumentParser
22+
from neural_compressor import data
23+
import tensorflow as tf
24+
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
25+
26+
flags = tf.compat.v1.flags
27+
FLAGS = flags.FLAGS
28+
29+
## Required parameters
30+
flags.DEFINE_string(
31+
'input_model', None, 'Run inference with specified pb graph.')
32+
33+
flags.DEFINE_string(
34+
'output_model', None, 'The output model of the quantized model.')
35+
36+
flags.DEFINE_string(
37+
'mode', 'performance', 'define benchmark mode for accuracy or performance')
38+
39+
flags.DEFINE_bool(
40+
'tune', False, 'whether to tune the model')
41+
42+
flags.DEFINE_bool(
43+
'benchmark', False, 'whether to benchmark the model')
44+
45+
flags.DEFINE_string(
46+
'config', 'bert.yaml', 'yaml configuration of the model')
47+
48+
flags.DEFINE_string(
49+
'calib_data', None, 'location of calibration dataset')
50+
51+
flags.DEFINE_string(
52+
'eval_data', None, 'location of evaluate dataset')
53+
54+
from neural_compressor.experimental.metric.metric import TensorflowTopK
55+
from neural_compressor.experimental.data.transforms.transform import ComposeTransform
56+
from neural_compressor.experimental.data.datasets.dataset import TensorflowImageRecord
57+
from neural_compressor.experimental.data.transforms.imagenet_transform import LabelShift
58+
from neural_compressor.experimental.data.dataloaders.default_dataloader import DefaultDataLoader
59+
from neural_compressor.data.transforms.imagenet_transform import BilinearImagenetTransform
60+
61+
eval_dataset = TensorflowImageRecord(root=FLAGS.eval_data, transform=ComposeTransform(transform_list= \
62+
[BilinearImagenetTransform(height=299, width=299)]))
63+
if FLAGS.benchmark and FLAGS.mode == 'performance':
64+
eval_dataloader = DefaultDataLoader(dataset=eval_dataset, batch_size=1)
65+
else:
66+
eval_dataloader = DefaultDataLoader(dataset=eval_dataset, batch_size=32)
67+
if FLAGS.calib_data:
68+
calib_dataset = TensorflowImageRecord(root=FLAGS.calib_data, transform=ComposeTransform(transform_list= \
69+
[BilinearImagenetTransform(height=299, width=299)]))
70+
calib_dataloader = DefaultDataLoader(dataset=calib_dataset, batch_size=10)
71+
72+
def evaluate(model, measurer=None):
73+
"""
74+
Custom Evaluate function to inference the model for specified metric on validation dataset.
75+
76+
Args:
77+
model ([tf.saved_model.load]): The model will be the class of tf.saved_model.load(quantized_model_path).
78+
measurer (object, optional): for precise benchmark measurement.
79+
80+
Returns:
81+
[float]: evaluation result, the larger is better.
82+
"""
83+
infer = model.signatures["serving_default"]
84+
output_dict_keys = infer.structured_outputs.keys()
85+
output_name = list(output_dict_keys )[0]
86+
postprocess = LabelShift(label_shift=1)
87+
metric = TensorflowTopK(k=1)
88+
89+
def eval_func(dataloader, metric):
90+
results = []
91+
for idx, (inputs, labels) in enumerate(dataloader):
92+
inputs = np.array(inputs)
93+
input_tensor = tf.constant(inputs)
94+
if measurer:
95+
measurer.start()
96+
predictions = infer(input_tensor)[output_name]
97+
if measurer:
98+
measurer.end()
99+
predictions = predictions.numpy()
100+
predictions, labels = postprocess((predictions, labels))
101+
metric.update(predictions, labels)
102+
return results
103+
104+
results = eval_func(eval_dataloader, metric)
105+
acc = metric.result()
106+
return acc
107+
108+
def main(_):
109+
if FLAGS.tune:
110+
from neural_compressor.experimental import Quantization, common
111+
quantizer = Quantization(FLAGS.config)
112+
quantizer.model = common.Model(FLAGS.input_model)
113+
quantizer.eval_func = evaluate
114+
quantizer.calib_dataloader = calib_dataloader
115+
q_model = quantizer.fit()
116+
q_model.save(FLAGS.output_model)
117+
118+
119+
if FLAGS.benchmark:
120+
from neural_compressor.experimental import Benchmark, common
121+
evaluator = Benchmark(FLAGS.config)
122+
evaluator.model = common.Model(FLAGS.input_model)
123+
evaluator.b_func = evaluate
124+
evaluator.b_dataloader = eval_dataloader
125+
evaluator(FLAGS.mode)
126+
127+
if __name__ == "__main__":
128+
tf.compat.v1.app.run()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import argparse
2+
import tensorflow as tf
3+
def get_inception_resnet_v2_model(saved_path):
4+
model = tf.keras.applications.InceptionResNetV2(weights='imagenet')
5+
model.save(saved_path)
6+
7+
if __name__ == "__main__":
8+
parser = argparse.ArgumentParser(
9+
description='Export pretained keras model',
10+
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
11+
parser.add_argument(
12+
'--output_model',
13+
type=str,
14+
help='path to exported model file')
15+
16+
args = parser.parse_args()
17+
get_inception_resnet_v2_model(args.output_model)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
set -x
3+
4+
function main {
5+
6+
init_params "$@"
7+
run_benchmark
8+
9+
}
10+
11+
# init params
12+
function init_params {
13+
for var in "$@"
14+
do
15+
case $var in
16+
--config=*)
17+
config=$(echo $var |cut -f2 -d=)
18+
;;
19+
--input_model=*)
20+
input_model=$(echo $var |cut -f2 -d=)
21+
;;
22+
--mode=*)
23+
mode=$(echo $var |cut -f2 -d=)
24+
;;
25+
--eval_data=*)
26+
eval_data=$(echo $var |cut -f2 -d=)
27+
;;
28+
esac
29+
done
30+
31+
}
32+
33+
# run_tuning
34+
function run_benchmark {
35+
36+
python main.py \
37+
--input_model ${input_model} \
38+
--config ${config} \
39+
--benchmark \
40+
--mode ${mode} \
41+
--eval_data ${eval_data}
42+
}
43+
44+
main "$@"

0 commit comments

Comments
 (0)