一. 概述
在邊緣運算的重點技術之中,除了 模組輕量化網路架構 與 模組量化 技術之外。另一項技術就是將各家神經網路框架 進行所謂的 模組轉換 技術,能幫助開發者快速部屬至不同的神經網路框架中。故這裡想跟各位讀者探討關於各種模型格式轉換為 TensorFlow Lite 的方式,依序分為 TensorFlow 各模組格式轉換、 Pytorch 與 ONNX 格式轉換、以及 逆轉換 TensorFlow Lite 三個章節。
本篇章將介紹 TensorFlow 各模組格式 (ckpt/savedmodel/pb/h5/TF Slim/TF Hub 等等) 轉換成 TensorFlow Lite 模組的方式,如圖下所示。此外模組來源可以至官方提供的 TensorFlow Model Garden 與 範例應用程式 。
各模組轉換至 TensorFlow Lite 格式示意圖
如下圖所示,本系列是隸屬於 機器學習開發環境 eIQ 之 推理引擎層 (Inference Engines Layer) 中的 TensorFlow Lite 進階系列,故後續將向讀者介紹 “模組轉換(一)”
若新讀者欲理解更多人工智慧、機器學習以及深度學習的資訊,可點選查閱下方博文。
大大通精彩博文 【ATU Book-i.MX8系列】博文索引
TensorFlow Lite 進階系列博文-文章架構示意圖
二. 模組轉換
Check Point -> TensorFlow Lite
Check Point (.ckpt) 檔案為 TensorFlow 1.x 主要存取模組的格式之一,包含儲存計算圖結構的 .meta 格式、記錄變數索引的 .index 格式以及儲存權重資料 .deta 格式組成,或是合併為一個 .ckpt 的檔案。其核心用途就是為了方便快速回到重新訓練階段,故須搭配原生的模組架構才能進行模組轉換。
代碼 :
# TensorFlow Lite Converter ( .ckpt to .tflite )
import tensorflow as tf
from src import transform # 讀取模組架構
g = tf.compat.v1.Graph()
soft_config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
soft_config.gpu_options.allow_growth = True
with g.as_default(), tf.compat.v1.Session(config=soft_config) as sess:
img_placeholder = tf.compat.v1.placeholder(tf.float32, shape=[1, 474, 712, 3], name='img_placeholder')
preds = transform.net(img_placeholder)
saver = tf.compat.v1.train.Saver()
saver.restore(sess, "model.ckpt" )
converter = tf.compat.v1.lite.TFLiteConverter.from_session(sess, [img_placeholder], [preds])
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile( "model.tflite", 'wb') as f:
f.write(tflite_model)
print("tranfer done!!")
Frozen Graph -> TensorFlow Lite
Frozen Graph (.pb) 檔案為 TensorFlow 1.x 主要存取模組的格式之一,與上述的 ckpt 格式最大的不同就是其核心用途為模組訓練完所生成的格式。故模組其包含了模組架構的資訊,以及整合輸出訓練中的權重。故此格式無法回到重新訓練的階段,稱作凍結圖(Frozen Graph)。
代碼 :
# TensorFlow Lite Converter ( .pb to .tflite )
import tensorflow as tf
tf.compat.v1.enable_eager_execution()
# Weight Quantization - Input/Output=float32
input_arrays=["normalized_input_image_tensor"]
output_arrays=['TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1',
'TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3']
input_tensor={"normalized_input_image_tensor":[1,300,300,3]}
converter = tf.compat.v1.lite.TFLiteConverter.from_frozen_graph("model.pb", input_arrays,output_arrays,input_tensor)
converter.optimizations = [tf.lite.Optimize.OPTIMIZE_FOR_SIZE]
converter.allow_custom_ops = True
tflite_quant_model = converter.convert()
with open('model.tflite', 'wb') as w:
w.write(tflite_quant_model)
print("tranfer done!!")
SavedModel -> TensorFlow Lite
SavedModel 格式為 TensorFlow 2.x 主要存取模組的格式之一,可以很好的解決上述兩種格式的問題,使用者更能輕鬆的部屬與調用。其組成為保存網路架構的 saved_model.pb 以及 variables 資料夾內的權重與參數而構成。目前以成為 TensorFlow 的主流格式,能夠輕易於 TensorFlow Lite / TensorFlow JS / TensorFlow Serving / TensorFlow Hub 應用。
代碼 :
# TensorFlow Lite Converter ( savemodel to .tflite )
import tensorflow as tf
import numpy as np
converter = tf.lite.TFLiteConverter.from_saved_model("SavedModel_Path")
converter.optimizations = [tf.lite.Optimize. DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile( "model.tflite" , 'wb') as f:
f.write(tflite_model)
print("tranfer done!!")
Check Point -> SavedModel -> TensorFlow Lite
Check Point (.ckpt) 格式屬於 TensorFlow 較早期的格式,若欲轉換 TensorFlow Lite 的形式,則可能會遇到比較多問題,因此這裡提出另一種轉換方案,就是先轉成 SavedModel 的形式,隨後再量化成 TensorFlow Lite 模組。
代碼 :
# TensorFlow Lite Converter ( .ckpt -> savemodel -> .tflite )
import tensorflow as tf
import tf_slim as slim
import numpy as np
from magenta.models.arbitrary_image_stylization import arbitrary_image_stylization_build_model as build_model
from magenta.models.image_stylization import image_utils
with tf.Graph().as_default(), tf.Session() as sess:
style_image_tensor = tf.placeholder(tf.float32, shape=[1, 256, 256, 3], name='style_image')
#load_checkpoint
model_saver = tf.train.Saver(tf.global_variables())
model_saver.restore(sess, "model.ckpt")
# checkpoint to SavedModel
tf.saved_model.simple_save(sess,
"arbitrary_style_transfer/predict",
inputs={style_image_tensor.name: style_image_tensor},
outputs={'style_bottleneck': bottleneck_feat})
# TensorFlow Lite Converter ( savemodel to .tflite )
converter = tf.lite.TFLiteConverter.from_saved_model("arbitrary_style_transfer/predict")
converter.optimizations = [tf.lite.Optimize. DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile( "model.tflite" , 'wb') as f:
f.write(tflite_model)
print("tranfer done!!")
Keras -> TensorFlow Lite
Keras 為一套 Machine Learning上層的 API ,目前以合併至 TensorFlow 2.x 的系列中。其儲存格是為層級資料格式( Hierarchical Data Format, HDF5 (.h5) ),適合儲存大量資料的一種格式。
代碼 :
# TensorFlow Lite Converter ( .h5 to .tflite )
import tensorflow as tf
converter = tf.compat.v1.lite.TFLiteConverter.from_keras_model_file( 'model.h5' )
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile( "model.tflite" , 'wb') as f:
f.write(tflite_model)
print("tranfer done!!")
TensorFlow Hub
TensorFlow Hub 是官方提供的已訓練完成模型數據庫與範例,其模組皆可已進行微調。
官方網站 : https://www.tensorflow.org/hub?hl=zh-tw
安裝方式 :
$ pip install --upgrade tensorflow-hub
代碼 :
# TensorFlow Lite Converter ( .h5 to .tflite )
# Load the model.
import tensorflow_hub as hub
hub_model = hub.load('https://tfhub.dev/tensorflow/faster_rcnn/inception_resnet_v2_640x640/1')
model = hub.load('https://tfhub.dev/google/yamnet/1')
# Tensorlfow Hub to TFLite
import tensorflow as tf
run_model = tf.function(lambda x : model(x))
concrete_func = run_model.get_concrete_function(tf.TensorSpec(shape=[None], dtype=tf.float32))
# Convert the model
converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func])
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS]
tflite_quant_model = converter.convert()
with open('/root/yamnet.tflite', 'wb') as w:
w.write(tflite_quant_model)
print("tranfer done!!")
TensorFlow JS
TensorFlow JavaScript 是官方提供的已訓練完成模型數據庫與範例,專用於網頁。簡稱 TensorFlow.js。這裡將告訴各位該如何利用 Google APIs 所發布的 TensorFlow.js 模組來轉換為 TensorFlow Lite 的形式。
模組資源 : https://storage.googleapis.com/tfjs-models/
安裝方式 :
$ pip install tfjs-graph-converter
代碼 :
# TensorFlow Lite Converter ( .json to .tflite )
# Load the model.
import tensorflow_hub as hub
hub_model = hub.load('https://tfhub.dev/tensorflow/faster_rcnn/inception_resnet_v2_640x640/1')
model = hub.load('https://tfhub.dev/google/yamnet/1')
# Convert the model of savedmodel
import tfjs_graph_converter.api as tfjs
tfjs.graph_model_to_saved_model( "model.json" , "savedmodel_path" )
# Convert the model
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model( "savedmodel_path )
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile( "model.tflite" , 'wb') as f:
f.write(tflite_model)
print("tranfer done!!")
TensorFlow Slim
TensorFlow Sim 是一套官方定義與訓練神經網路架構、以及評估模型的高級資料庫,簡稱 TF-Slim。此資料庫的 API 能夠高度相容於原生的 TensorFlow 1.x 框架並輕易進行整合 ! 提供開發者大量模組架構之函數資源 !! TF-Slim 函式庫包含建立神經網路階層 layers 、 評估模型 evaluation、常用損失函數 loss 與評估指標 metrics、或是熱門的模組 nets 等等模組化函式,其中亦有 微調(Fine-Tuning) 現有模型的方式。
第一步,安裝必要套件
(1) TensorFlow Model Zoo下載 : https://github.com/tensorflow/models.git
$ git clone https://github.com/tensorflow/models.git # download Model Garden for TensorFlow
$ cd /root/models/research/
$ protoc object_detection/protos/*.proto --python_out=. # gernate *.proto
$ python setup.py build
(2) TensorFlow Slim 安裝 :
$ pip install tf_slim
(3) Mask RCNN模組下載 : https://github.com/tensorflow/models.git
$ git clone https://github.com/matterport/Mask_RCNN/
$ wget http://download.tensorflow.org/models/object_detection/mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
$ tar -zxvf mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
$ rm mask_rcnn_inception_v2_coco_2018_01_28.tar.gz
$ mkdir -p /root/mask_rcnn_inception_v2_coco_2018_01_28/export
第二步,設定環境變數
import os
os.environ['PYTHONPATH'] +=\
':/root/models/research/:/root/models/research/slim/:/root/models/research/object_detection/utils/:/root/models/research/object_detection'
!export PYTHONPATH=`pwd`:`pwd`/slim:$PYTHONPATH
第三步,TensorFlow Slim 使用測試
$ python object_detection/builders/model_builder_test.py
※ tips 分享 : 若測試失敗則表示環境變數未設置成功
第四步,ckpt 轉換 SavedModel
# ckpt to SavedModel 指令方式
# 此處可以任意調用輸入尺寸
$ python3 /root/models/research/object_detection/export_inference_graph.py \
--input_type=image_tensor \
--pipeline_config_path=/root/mask_rcnn_inception_v2_coco_2018_01_28/pipeline.config \
--trained_checkpoint_prefix=/root/mask_rcnn_inception_v2_coco_2018_01_28/model.ckpt \
--output_directory=/root/mask_rcnn_inception_v2_coco_2018_01_28/test \
--input_shape=1,256,256,3 \
--write_inference_graph=True
第五步,SavedModel轉換 TensorFlow Lite
# TensorFlow Lite Converter ( SavedModel to .tflite )
import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model("/root/mask_rcnn_inception_v2_coco_2018_01_28/test/saved_model ")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
with tf.io.gfile.GFile("mask_rcnn_inception_v2_coco_weight_quant.tflite ", 'wb') as f:
f.write(tflite_model)
print("Quantization complete! ")
※ tips 分享 : 目前實測成功,TF-Slim 轉成能夠全整數的 TensorFlow Lite 模組
TensorFlow Convert Tool
官方也提供一套 Command Line Tool 讓使用者可以快速轉換模組,或可以直接參考此網站。
(1) Convert a TensorFlow Frozen Graph
$ tflite_convert \
--output_file=model.tflite \
--graph_def_file=frozen_graph.pb \
--input_arrays=input \
--output_arrays=MobilenetV1/Predictions/Reshape_1
(2) Convert a TensorFlow SavedModel
$ tflite_convert \
--output_file= model.tflite \
--saved_model_dir=saved_model
(3) Convert a TensorFlow SavedModel
$ tflite_convert \
--output_file= model.tflite \
--keras_model_file=keras_model.h5
三. 結語
模組轉換是一項相當實用的技術,但取決於各家神經網路框架的版本不同,仍會出現無法轉換成功的問題。況且各家神經網路都是不斷再優化自身的框架,就如同最傳統的 Check Point格式而言,部分的運算元(Operator),可能就無法順利轉換為 TensorFlow Lite 的格式。因此這項技術是需要一些經驗累加與除錯能力,以及各家神經網路版本所對應的資訊才能順利轉換完成。網路上也有許多工程師一起分享如何解決相似的問題,此外若有任何模組轉換的問題,可以至下方留言所遇到的問題,讓我們一起互相切磋,一起成長!! 下一篇文章,將會以 Pytorh 與 ONNX 轉換至 TensorFlow Lite 的模組為主,敬啟期待 !!
四. 參考文件
[1] 官方文件 - i.MX Machine Learning User's Guide pd
[2] 官方文件 -TensorFlow Lite 轉換工具
[3] 官方文件 -Post-training quantization
[4] 官方文件 -TensorFlow API
[5] 第三方文件 -Tensorflow模型量化(Quantization)原理及其实现方法
[6] 官方文件 - TensorFlow Lite 現有應用資源
[7] 官方文件 - TensorFlow Lite Hub
[8] 官方文件 - TensorFlow Lite Slim
[9] 官方文件 -TensorFlow Model Garden
[10] 官方文件 -TensorFlow Model JS
[11] 官方文件 -Keras
[12] 官方文件 -TensorFlow - Using the SavedModel Format
[13] 第三方文件 -TensorFlow 模型導出總結
[14] 官方文件 -TensorFlow Model Garden
[15] 官方文件 -Megnta github
如有任何相關 TensorFlow Lite 進階技術問題,歡迎至博文底下留言提問 !!
接下來還會分享更多 TensorFlow Lite 進階的技術文章 !!敬請期待 【ATU Book-i.MX8系列 – TFLite 進階】 !!
評論