作者:Alexey Perminov、Tatiana Khanova、Grigory Serebryakov
在之前的文章中,我們探討了如何將 Pytorch 模型轉換為 OpenVINO 並執行,以及OpenVINO 工具包中可用的深度學習模型最佳化工具。
今天,讓我們看看如何使用 TensorFlow 訓練的模型並部署到 OpenVINO 以進行執行。
概述
- 設定環境
- 準備 TensorFlow 模型
- 將模型轉換為中間表示格式
- 在 OpenVINO 中執行模型推理
- 結論
設定環境
首先,我們需要準備一個 python 環境:Python 3.5 或更高版本(根據系統要求),我們需要 virtualenv
python3 -m venv ~/venv/tf_openvino source ~/venv/tf_openvino/bin/activate
然後讓我們安裝所需的包
pip3 install --upgrade pip setuptools pip3 install -r requirements.txt
這裡 requirements.txt 包含以下包
numpy tqdm tensorflow-cpu==1.15 argparse scipy imageio moviepy
我們需要做的第二件事是使用官方安裝說明安裝最新版本的 OpenVINO 工具包(在我的情況下為 Linux)。請記住設定所需的環境變數
source /opt/intel/openvino/bin/setupvars.sh
將此操作新增到 shell 初始化指令碼或虛擬環境啟用指令碼中可能很有用,以便預設情況下觸發它。
或者,這裡您可以找到一個 Google Colab 筆記本,其中包含環境設定和文章中的主要復現步驟。
準備 TensorFlow 模型
曾經希望一位著名的藝術家為您的心愛的小貓畫一幅畫嗎?隨著深度神經網路中工具的演變——您做到了。最初在藝術風格的神經演算法中提出的神經風格遷移演算法可以實現您的願望。其想法是利用神經網路提取影像內容並將其與使用的表示(風格)分離。然後,我們將使用提取的風格並將其與任意影像組合,以獲得令人印象深刻的結果,這些結果由原始影像的內容和所需的藝術風格生成的合成影像。

影像風格遷移示例
在上面的示例中,您可以看到 J. M. W. 特納的“彌諾陶爾的沉船”繪畫的藝術風格是如何轉移到參考小貓影像(由Dương Nhân提供)。要執行此類技巧,我們需要一個經過訓練的 TensorFlow 模型。我們可以從頭開始準備和訓練模型,但讓我們獲取一個預訓練模型並使用此倉庫中的快速風格遷移模型。它非常適合我們的目的。
引用的儲存庫提供了多個模型檢查點,每個檢查點都針對不同的藝術風格影像進行了訓練,可以在這裡下載。通常,TensorFlow 檢查點包含訓練期間使用的模型權重和計算圖元資料。要將模型部署到生產環境中並將其用於推理,我們需要獲取凍結圖。讓我們克隆倉庫並使用一個簡單的 python 指令碼來做到這一點
def main(checkpoint_path, input_shape, out_graph_name):
# Init graph and session to be used
g = tf.Graph()
soft_config = tf.compat.v1.ConfigProto(allow_soft_placement=True)
with g.as_default(), g.device('/cpu'), tf.compat.v1.Session(config=soft_config) as sess:
# Placeholder variable for graph input
img_placeholder = tf.compat.v1.placeholder(tf.float32, shape=input_shape, name='img_placeholder')
# The model from the repo
transform.net(img_placeholder)
# Restore model from checkpoint
saver = tf.compat.v1.train.Saver()
saver.restore(sess, checkpoint_path)
# Freeze graph from the session.
# "add_37" is the actual last operation of graph
frozen = tf.compat.v1.graph_util.convert_variables_to_constants(sess, sess.graph_def, ["add_37"])
# Write frozen graph to a file
graph_io.write_graph(frozen, './', out_graph_name, as_text=False)
print(f'Frozen graph {out_graph_name} is saved!')
指令碼的完整程式碼可以在這裡下載。
只需將指令碼放在模型倉庫的根資料夾中,並使用以下引數執行它
python get_frozen_graph.py --checkpoint models/wreck.ckpt
在上面的程式碼片段中,我們執行了所需的 TensorFlow 圖預初始化,並使用tf.Saver()從檢查點恢復模型資料。然後我們將轉換後的凍結圖寫入檔案。
請注意,凍結圖轉換需要輸出圖操作的名稱,在本例中為“add_37”。對於任意模型,您可以透過簡單地列印網路節點或在Netron之類的工具中瀏覽模型來找到輸出操作。
將模型轉換為中間表示格式
好的,現在我們有了凍結圖,接下來是什麼?至於PyTorch 模型,要在 OpenVINO 推理引擎中執行推理,我們必須將模型轉換為中間表示 (IR) 格式。幸運的是,OpenVINO 模型最佳化器內建了對 TensorFlow 模型轉換的支援。您可以在此OpenVINO 頁面上檢視當前支援的 TensorFlow 操作集。
在開始之前,我們應該配置模型最佳化器(如果您在 OpenVINO 安裝過程中跳過了此步驟)。您可以在此處找到配置說明。
由於我們準備好的凍結圖已經包含了有關模型的所有必要資訊,例如所需的輸入形狀和輸出節點名稱,因此我們可以使用預設引數執行模型最佳化器
mo_tf.py --input_model inference_graph.pb
如果轉換成功,我們將獲得包含結果 IR 模型描述的`inference_graph.xml`和包含模型權重資料的`inference_graph.bin`。如果轉換不成功,最好從檢查目標框架(在本例中為 TensorFlow)的支援層開始。可能需要稍微更改模型架構或為 OpenVINO實現自定義層。
在 OpenVINO 中執行模型推理
讓我們準備一個使用 OpenVINO 推理引擎初始化、IR 模型載入和對提供的影像進行推理的簡單 python 指令碼。此指令碼的完整版本也可在這裡找到。
首先,我們匯入所需的包並定義一個用於引數解析的函式。
import os
import cv2
import argparse
import time
import numpy as np
from openvino.inference_engine import IECore
from tqdm import tqdm
IMG_EXT = ('.png', '.jpg', '.jpeg', '.JPG', '.JPEG')
def parse_args():
"""Parses arguments."""
parser = argparse.ArgumentParser(description='OpenVINO inference script')
parser.add_argument('-i', '--input', type=str, default='',
help='Directory to load input images, path to a video or '
'skip to get stream from the camera (default).')
parser.add_argument('-m', '--model', type=str, default='./models/inference_graph.xml',
help='Path to IR model')
return parser.parse_args()
下一個函式用於 OpenVINO 推理初始化和中間表示模型載入。我們獲取 .xml 和 .bin 模型檔案的路徑,讀取它們並將模型載入到推理引擎中。之後,我們可以將其用於推理。
def load_to_IE(model):
# Getting the *.bin file location
model_bin = model[:-3] + "bin"
# Loading the Inference Engine API
ie = IECore()
# Loading IR files
net = ie.read_network(model=model, weights=model_bin)
input_shape = net.inputs["img_placeholder"].shape
# Loading the network to the inference engine
exec_net = ie.load_network(network=net, device_name="CPU")
print("IR successfully loaded into Inference Engine.")
return exec_net, input_shape
OpenVINO 允許我們使用兩種推理請求:同步——每個後續請求僅在先前請求完成後執行,非同步——多個請求由多個執行器同時執行。在本例中,我們使用同步推理請求介面
def sync_inference(exec_net, image):
input_blob = next(iter(exec_net.inputs))
return exec_net.infer({input_blob: image})
在主函式中,我們首先準備將用於風格遷移的影像列表,然後初始化推理引擎
def main(args):
if os.path.isdir(args.input):
# Create a list of test images
image_filenames = [os.path.join(args.input, f) for f in os.listdir(args.input) if
os.path.isfile(os.path.join(args.input, f)) and f.endswith(IMG_EXT)]
image_filenames.sort()
else:
image_filenames = [args.input]
exec_net, net_input_shape = load_to_IE(args.model)
# We need dynamically generated key for fetching output tensor
output_key = list(exec_net.outputs.keys())[0]
對於每個輸入影像,我們將其調整為網路的輸入大小並使用 cv2.dnn.blobFromImage 轉換為所需的張量格式。然後,最有趣的部分——推理請求,然後進行簡單的後處理。
for image_num in tqdm(range(len(image_filenames))):
image = cv2.imread(image_filenames[image_num])
image = cv2.resize(image, (net_input_shape[3], net_input_shape[2]))
X = cv2.dnn.blobFromImage(image, swapRB=True)
out = sync_inference(exec_net, image=X)
result_image = np.squeeze(np.clip(out[output_key], 0, 255).astype(np.uint8), axis=0).transpose((1, 2, 0))
最後,我們顯示結果影像。
cv2.imshow("Out", cv2.cvtColor(result_image, cv2.COLOR_RGB2BGR))
cv2.waitKey(0)
cv2.destroyWindow("Out")
if __name__ == "__main__":
main(parse_args())
讓我們執行指令碼,指定要應用風格遷移的影像的輸入目錄和轉換後的 IR 模型
python openvino_inference.py -i ./images/ -m ./models/inference_graph.xml
帶有轉移風格的結果影像將顯示在彈出視窗中。
效能比較
作為最後一步,讓我們比較原始 TensorFlow 和轉換為 OpenVINO 推理管道的推理時間。為此,我在推理呼叫周圍添加了時間戳測量:在 TensorFlow 的情況下為會話執行呼叫,在 OpenVINO 的情況下為同步推理請求。在 100 個相同大小(720x1024x3)的影像上平均,每個影像的效能結果非常相似(以秒為單位,CPU:Intel® Core™ i5-8265U CPU @ 1.60GHz x 8)
OpenVINO_CPU Inference time: Mean: 1.554 Min: 1.444 Max: 1.979 TensorFlow_Cpu Inference time: Mean: 1.933 Min: 1.827 Max: 2.080
結論
在這篇簡短的文章中,我們瞭解瞭如何輕鬆地轉換 TensorFlow 模型並在 OpenVINO 推理引擎環境中執行。此外,我們還了解了神經風格遷移演算法的應用,並嘗試將其應用於任意影像。我們已經證明,OpenVINO 提供了相當大的加速,並允許我們在相當普通的硬體上執行即使是最苛刻的 DL 演算法。我們希望這是一次有趣且有益的旅程。
________________________________________
獲取英特爾® OpenVINO™ 工具套件
貢獻——如果您有任何關於如何改進產品的想法,我們歡迎您為開源的 OpenVINO™ 工具套件做出貢獻。
想了解更多資訊?加入對話,討論英特爾的社群論壇中所有關於深度學習和 OpenVINO™ 工具套件的內容。
英特爾、英特爾標識和其他英特爾商標是英特爾公司或其子公司的商標。
效能因使用、配置和其他因素而異。在www.Intel.com/PerformanceIndex瞭解更多資訊。
________________________________________
效能結果基於截至顯示在配置中的日期的測試,可能無法反映所有公開發布的更新。請參閱備份以瞭解配置詳細資訊。沒有任何產品或元件可以絕對安全。
測試日期:2020 年 12 月 23 日
完整的系統配置詳細資訊:Ubuntu 18.04,Intel® Core™ i5-8265U CPU @ 1.60GHz x 8
設定詳細資訊:OpenVINO™ 工具套件版本 2020.4
誰進行了測試:Alexey Perminov,OpenCV.AI
英特爾技術可能需要啟用硬體、軟體或服務啟用。
________________________________________
© 英特爾公司。英特爾、英特爾標識和其他英特爾商標是英特爾公司或其子公司的商標。






