【ATU Book-i.MX8系列 - TFLite 進階】 模組轉換(一)

一.   概述

邊緣運算的重點技術之中,除了 模組輕量化網路架構模組量化 技術之外。另一項技術就是將各家神經網路框架 進行所謂的 模組轉換 技術,能幫助開發者快速部屬至不同的神經網路框架中。故這裡想跟各位讀者探討關於各種模型格式轉換為 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 進階 !!

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論