FPGA得益于其高可編程性以及低延遲,低功耗的特點(diǎn),在機(jī)器學(xué)習(xí)的推理領(lǐng)域已獲得了廣泛的關(guān)注。在過去,F(xiàn)PGA對于軟件開發(fā)人員來說有較高的開發(fā)門檻,把一部分開發(fā)者擋在了門外。如今越來越完善的高階工具以及軟件堆棧使得開發(fā)者可以充分利用FPGA優(yōu)點(diǎn)對關(guān)鍵應(yīng)用進(jìn)行加速,同時(shí)不需花費(fèi)時(shí)間去了解FPGA的底層實(shí)現(xiàn)。
Xilinx Vitis AI 是用于 Xilinx 硬件平臺上的 AI 推理的開發(fā)堆棧。它由優(yōu)化的 IP(DPU)、工具、庫、模型和示例設(shè)計(jì)組成,使用Xilinx ZynqMP SOC或者Versal ACAP器件并借助強(qiáng)大的Vitis AI堆棧,已大大降低了FPGA上部署機(jī)器學(xué)習(xí)應(yīng)用的門檻。
本文將使用Tensorflow 2.0從零搭建并訓(xùn)練一個(gè)簡單的CNN模型來進(jìn)行數(shù)字手勢識別,并部署運(yùn)行在ZynqMP開發(fā)板上,來熟悉Vitis AI的工作流程。
我們首先用Tensorflow 2.0創(chuàng)建模型并針對目標(biāo)數(shù)據(jù)集進(jìn)行訓(xùn)練,然后使用Vitis AI 工具對模型進(jìn)行量化/編譯等處理,獲得運(yùn)行DPU所需要的xmodel文件。最后需要編寫調(diào)用Vitis AI runtime的主機(jī)應(yīng)用,該應(yīng)用運(yùn)行在CPU上,進(jìn)行必要的預(yù)處理/后處理以及對DPU進(jìn)行調(diào)度。
1Vitis AI環(huán)境配置
Vitis AI支持業(yè)界通用的Pytorch/Tensorflow/Caffe訓(xùn)練框架。模型創(chuàng)建和訓(xùn)練工作完全在通用框架下進(jìn)行開發(fā)。開始工作之前需要先在Host機(jī)器上配置好Vitis-AI Docker環(huán)境,這部分完全參考https://github.com/Xilinx/Vitis-AI Guide即可。以下所有在Host機(jī)器上完成的步驟(訓(xùn)練/量化/編譯)都是在Vitis AI docker 及vitis-ai-tensorflow2 conda env環(huán)境下完成。
2數(shù)據(jù)集
本實(shí)例使用的數(shù)字手勢數(shù)據(jù)集:
https://github.com/ardamavi/Sign-Language-Digits-Dataset (感謝開源數(shù)據(jù)集作者Arda Mavi )
3源碼說明
本項(xiàng)目的工程文件保存在 Github目錄:
https://github.com/lobster1989/Handsign-digits-classification-on-KV260
有4個(gè)主要文件夾:
1. code:
此處包含所有源代碼,包括用于訓(xùn)練/量化/編譯任務(wù)的腳本,以及在 ARM 內(nèi)核上運(yùn)行的主機(jī)應(yīng)用程序。
2. output:
生成的模型文件。
3. Sign-Language-Digits-Dataset:
數(shù)據(jù)集應(yīng)該下載并放在這里。
4. target_zcu102_zcu104_kv260:
準(zhǔn)備復(fù)制到目標(biāo)板運(yùn)行的文件。
4創(chuàng)建/訓(xùn)練模型
Host機(jī)器上運(yùn)行 "train.py" 腳本,train.py腳本中包含了模型的創(chuàng)建和訓(xùn)練過程。模型的創(chuàng)建主要代碼如下,使用Keras的function式 API(注意sequential 式API目前Vitis AI不支持)。創(chuàng)建的模型包含4個(gè)連續(xù)的Conv2D+Maxpolling層,然后跟隨一個(gè)flatten layer,一個(gè)dropout layer,以及兩個(gè)全連接層。
這個(gè)模型僅僅作為示例,各位也可以嘗試使用其它的CNN模型或進(jìn)行優(yōu)化。
# Function: create a custom CNN model
def customcnn():
inputs = keras.Input(shape=image_shape)
x = layers.Conv2D(32, (3,3), activation='relu', input_shape=image_shape)(inputs)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Conv2D(64, (3,3), activation='relu')(x)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Conv2D(128, (3,3), activation='relu')(x)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Conv2D(128, (3,3), activation='relu')(x)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(512, activation='relu')(x)
outputs = layers.Dense(10, activation='softmax')(x)
model = keras.Model(inputs=inputs, outputs=outputs, name='customcnn_model')
model.summary()
# Compile the model
model.compile(optimizer="rmsprop",
loss="categorical_crossentropy",
metrics=['acc']
)
return model
該模型在第 10 個(gè)epoch在驗(yàn)證數(shù)據(jù)集上獲得了 0.7682 的精確度。
5模型量化
訓(xùn)練完Tensorflow2.0模型后,下一步是使用Vitis AI quantizer工具對模型進(jìn)行量化。量化過程將 32 位浮點(diǎn)權(quán)重轉(zhuǎn)換為 8 位整型 (INT8),定點(diǎn)模型需要更少的內(nèi)存帶寬,從而提供更快的速度和更高的運(yùn)行效率。如果需要進(jìn)一步優(yōu)化計(jì)算量級,還可以使用Vitis AI提供的剪枝(pruning)工具。
運(yùn)行quantize.py腳本進(jìn)行量化,運(yùn)行結(jié)束后將生成量化后的模型''quantized_model.h5''。
進(jìn)行quantize的代碼部分如下,調(diào)用VitisQuantizer,需要提供的輸入包括上個(gè)步驟生成的float模型,以及一部分圖片(推薦為100~1000張)作為calibration的輸入。Calibration操作使用提供的圖片進(jìn)行正向運(yùn)算,不需要提供label
# Run quantization
quantizer = vitis_quantize.VitisQuantizer(float_model)
quantized_model = quantizer.quantize_model(
calib_dataset=train_generator
)
6評估量化后模型
我們可以測試評估下量化后的模型是否有精度的損失。量化模型的評估可以直接在 python 腳本中利用TensorFlow框架完成。讀入模型,重新compile, 然后調(diào)用evaluation相關(guān) API對模型進(jìn)行評估。主要代碼部分如下
# Load the quantized model
path = os.path.join(MODEL_DIR, QAUNT_MODEL)
with vitis_quantize.quantize_scope():
model = models.load_model(path)
# Compile the model
model.compile(optimizer="rmsprop",
loss="categorical_crossentropy",
metrics=['accuracy']
)
# Evaluate model with test data
loss, acc = model.evaluate(val_generator) # returns loss and metrics
運(yùn)行“eval_quantize.py”腳本即可完成評估。通過評估發(fā)現(xiàn),量化后的模型沒有發(fā)生精度損失。當(dāng)然實(shí)際并不總是如此,有時(shí)候量化后的模型會有些許精度損失,這和不同的模型有關(guān)系。這時(shí)候我們可以使用Vitis AI提供finetuning來精調(diào)模型 。
7編譯模型
模型的編譯需要用到Vitis AI compiler(VAI_C)。這個(gè)步驟實(shí)際上是把量化后的模型轉(zhuǎn)化為可以在DPU上運(yùn)行的指令序列。VAI_C 框架的簡化流程如下圖所示,包含模型解析,優(yōu)化和代碼生成三個(gè)階段。模型解析步驟對模型的拓?fù)溥M(jìn)行解析,生成用Xilinx的中間表示層(Intermediate Representation)表示的計(jì)算圖(computation graph)。然后是執(zhí)行一些優(yōu)化操作,例如計(jì)算節(jié)點(diǎn)融合或者提高數(shù)據(jù)重用。最后的步驟是生成DPU架構(gòu)上運(yùn)行的指令序列。
運(yùn)行compile.sh腳本即可完成編譯過程。主要代碼如下,使用vai_c_tensorflow2命令。注意需要提供目標(biāo)DPU配置的arch.json文件作為輸入(--arch選項(xiàng))。編譯步驟完成后會生成DPU推理用的xmodel文件。
compile() {
vai_c_tensorflow2
--model $MODEL
--arch $ARCH
--output_dir $OUTDIR
--net_name $NET_NAME
}
8主機(jī)程序
DPU作為神經(jīng)網(wǎng)絡(luò)加速引擎,還需要CPU主機(jī)對其進(jìn)行控制和調(diào)度,提供給DPU數(shù)據(jù)輸入/輸出。另外還需要對這部分運(yùn)行在ARM或Host CPU上的應(yīng)用而言, Vitis AI提供了Vitis AI Runtime (VART) 以及Vitis AI Library來方便應(yīng)用開發(fā)。VART比較底層,提供更大的自由度。Vitis AI library屬于高層次API,構(gòu)建于 VART 之上,通過封裝許多高效、高質(zhì)量的神經(jīng)網(wǎng)絡(luò),提供更易于使用的統(tǒng)一接口。
VART具有C++和Python兩套API。多數(shù)機(jī)器學(xué)習(xí)開發(fā)者習(xí)慣用Python來開發(fā)和訓(xùn)練模型,在部署階段甚至可以不用切換語言。本例子中提供了使用Python接口的host程序app_mt.py。使用Python API的簡化流程如下。
# Preprocess
dpu_runner = runner.Runner(subgraph,"run")
# Populate input/out tensors
jid = dpu_runner.execute_async(fpgaInput, fpgaOutput)
dpu_runner.wait(jid)
# Post process
9開發(fā)板上運(yùn)行
如果使用的是 Xilinx zcu102/zcu104/KV260 官方 Vitis AI 啟動文件,則3 塊板上的 DPU 配置都相同。可以在 3 個(gè)平臺上運(yùn)行相同的xmodel文件,主機(jī)上的所有步驟完成后,將以下文件復(fù)制到目標(biāo)板上。共需要xmodel文件,主機(jī)程序,以及一些用來測試的圖片。
啟動開發(fā)板并運(yùn)行 app_mt.py ,用 -d指定圖片路徑,-m指定xmodel文件,-t 指定CPU上運(yùn)行的線程數(shù)。
很幸運(yùn),10張測試圖片的推理結(jié)果都是正確的。
root@xilinx-zcu102-2021_1:/home/petalinux/Target_zcu102_HandSignDigit#python3 app_mt.py -d Examples/ -m customcnn.xmodel
Pre-processing 10 images...
Starting 1 threads...
Throughput=1111.96 fps, total frames = 10, time=0.0090 seconds
Correct:10, Wrong:0, Accuracy:1.0000
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1630文章
21791瀏覽量
605095 -
手勢識別
+關(guān)注
關(guān)注
8文章
225瀏覽量
47823 -
AI
+關(guān)注
關(guān)注
87文章
31443瀏覽量
269836 -
Zynq
+關(guān)注
關(guān)注
10文章
610瀏覽量
47250 -
Vitis
+關(guān)注
關(guān)注
0文章
147瀏覽量
7475
原文標(biāo)題:使用Vitis AI 在Zynq MP上實(shí)現(xiàn)手勢識別
文章出處:【微信號:HXSLH1010101010,微信公眾號:FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論