【ATU Book-i.MX8系列 - Colab】 利用 Colab 打造 AI 學(xué)習(xí)庫

一.? ?概述

本文將介紹一套非常好用的一個免費(fèi)資源,由 Google 所提供的 Colab 這項(xiàng)雲(yún)端服務(wù)。

延續(xù)上一章節(jié)的理念,此系列的目的為工具書導(dǎo)向,這裡將介紹如何利用 Colab 建立一套物件辨識應(yīng)用,讀者僅須要依照步驟,按部就班即可完成實(shí)作!! 時不宜遲,趕緊動手操作吧!! 如下圖文章架構(gòu)圖所示,此架構(gòu)圖隸屬於 i.MX8M Plus 的方案博文中,並屬於 Third Party 軟體資源的 Google Colab 密技大公開 之部分,目前章節(jié)介紹 “利用 Colab 打造 AI 學(xué)習(xí)庫”。

?

若新讀者欲理解更多人工智慧、機(jī)器學(xué)習(xí)以及深度學(xué)習(xí)的資訊,可點(diǎn)選查閱下方博文
?大大通精彩博文???【ATU Book-i.MX8系列】博文索引

?

?

Colab 系列博文-文章架構(gòu)示意圖

?

二.? 利用 Colab 打造 AI 學(xué)習(xí)庫

如下圖所示,本文章會先由 Google 提供的 Colab 之 GPU 資源訓(xùn)練出一套關(guān)於物件識別模組,接著將訓(xùn)練完成的模組移植至 NXP i.MX8M Plus 開發(fā)板中運(yùn)行



?(1) 透過 Colab 訓(xùn)練出物件識別模組 :?

開啟 Colab 筆記本一步一步運(yùn)行代碼,即可完成實(shí)作 !!
結(jié)合遷移學(xué)習(xí)方法與 TF-Slim資料庫實(shí)現(xiàn) TOTORO 物件檢測器(Object Detector)
PS :? 灰底為程式儲存格的代碼,複製貼上至 Colab 即可使用 !!

第一步 : 開啟 Colab 設(shè)定環(huán)境

 %tensorflow_version 1.x
!python -c 'import matplotlib as tf; print(tf.__version__)' # Check the version of the tensorflow

?

第二步 : TensorFlow Model Garden 下載與安裝

%cd root
!git clone https://github.com/tensorflow/models.git
%cd root/models/research/
!protoc object_detection/protos/*.proto --python_out=. # gernate *.proto
!python setup.py build # 建置 TensorFlow Model Garden 檔案

?

第三步 : TensorFlow Slim 下載與安裝

import os
os.environ['PYTHONPATH'] += ':/root/models/research/:/root/models/research/slim/:/root/models/research/object_detection/utils/:/root/models/research/object_detection'
!pip install tf_slim # 安裝 TensorFlow Slim
!python object_detection/builders/model_builder_test.py # TensorFlow Slim 模組建立是否成功測試

?

第四步 : 下載資料庫

常見的物件識別的資料庫為 COCO DataSets

讀者也可以更換資料庫就可以訓(xùn)練出不同的識別應(yīng)用。

%cd /root/models/
!git clone https://github.com/fllay/totoro.git #Download TOTORO



第五步 : 數(shù)據(jù)特徵處理

解析紀(jì)錄物件之位置特徵與分類的 XML 檔案,如代碼所示。

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET

# 將 xml 檔資料轉(zhuǎn)換成 DataFrame 形式
def xml_to_csv(path):
xml_list = []
for xml_file in glob.glob(path + '/*.xml'):
tree = ET.parse(xml_file)
root = tree.getroot()
for member in root.findall('object'):
value = (root.find('filename').text,
int(root.find('size')[0].text),
int(root.find('size')[1].text),
member[0].text,
int(member[4][0].text),
int(member[4][1].text),
int(member[4][2].text),
int(member[4][3].text)
)
xml_list.append(value)
column_name = ['filename', 'width', 'height', 'class', 'xmin', 'ymin', 'xmax', 'ymax']
xml_df = pd.DataFrame(xml_list, columns=column_name)
return xml_df

# 將 xml 資料轉(zhuǎn)換成 train_labels.csv 與 test_labels.csv 兩個檔案
def main():
image_path = os.path.join(os.getcwd(), 'totoro/images/train')
xml_df = xml_to_csv(image_path)
xml_df.to_csv('totoro/data/train_labels.csv', index=None)
image_path = os.path.join(os.getcwd(), 'totoro/images/test')
xml_df = xml_to_csv(image_path)
xml_df.to_csv('totoro/data/test_labels.csv',index=None)

main()

?

第六步 : 製作 TensorFlow Record

欲了解 TensorFlow Record 介紹,可參考 TensorFlow 官方網(wǎng)站資訊,或是 github 作者所撰寫的 generate_tfrecord.py 用法。

%cd /root/models/totoro/tfrecord
!python generate_tfrecord.py --csv_input=/root/models/totoro/data/train_labels.csv \
--output_path=train.record --image_dir=/root/models/totoro/images/train
!python generate_tfrecord.py --csv_input=/root/models/totoro/data/test_labels.csv\
--output_path=test.record --image_dir=/root/models/totoro/images/test

PS :? 執(zhí)行後,將於 models/ totoro/tfrecord 資料夾內(nèi)產(chǎn)出 train.record & test.record' 檔案

第七步 : 下載訓(xùn)練過的 MobileNet 模組

此步驟利用之前訓(xùn)練過的模組資源重新訓(xùn)練,即?遷移學(xué)習(xí)(Transfer Learning)?的技術(shù),未來將有系列博文專門介紹,敬請期待 !!

%cd ~/models
import shutil
import tarfile
from requests import get
MODEL = 'ssd_mobilenet_v1_coco_2017_11_17'
MODEL_FILE = MODEL + '.tar.gz'
DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/'
DEST_DIR = 'pretrained_model'
# 下載mobilenet 模組
if not (os.path.exists(MODEL_FILE)):
with open(MODEL_FILE, "wb") as file:
response = get(DOWNLOAD_BASE + MODEL_FILE)
file.write(response.content)

# 解壓縮 mobilenet 模組
tar = tarfile.open(MODEL_FILE)
tar.extractall()
tar.close()
os.remove(MODEL_FILE)
if (os.path.exists(DEST_DIR)):
shutil.rmtree(DEST_DIR)
os.rename(MODEL, DEST_DIR)

# 移動 mobilenet.config" 資訊
shutil.move( "/root/models/research/object_detection/samples/configs/ssd_mobilenet_v1_coco.config", "/root/models" )

?

第八步 : 修改 Config 檔案

%cd /root/models/research/
# 編輯Pipeline 資訊
import tensorflow as tf
from google.protobuf import text_format
from object_detection.protos import pipeline_pb2
pipeline = pipeline_pb2.TrainEvalPipelineConfig()
config_path = '/root/models/ssd_mobilenet_v1_coco.config'

with tf.gfile.GFile( config_path, "r") as f:
proto_str = f.read()
text_format.Merge(proto_str, pipeline)
pipeline.train_input_reader.tf_record_input_reader.input_path[:] = ['/root/models/totoro/tfrecord/train.record'] # train data
pipeline.train_input_reader.label_map_path = '/root/models/totoro/data/object-detection.pbtxt'
pipeline.eval_input_reader[0].tf_record_input_reader.input_path[:] = ['/root/models/totoro/tfrecord/test.record'] # test data
pipeline.eval_input_reader[0].label_map_path = '/root/models/totoro/data/object-detection.pbtxt' # network
pipeline.train_config.fine_tune_checkpoint = '/root/models/pretrained_model/model.ckpt' # weight
pipeline.train_config.num_steps = 500 # training step
pipeline.model.ssd.num_classes = 2 # classes num
pipeline.eval_config.num_examples = 5 # test image number
config_text = text_format.MessageToString(pipeline)
with tf.gfile.Open( config_path, "wb") as f:
f.write(config_text)

?

第九步 : 進(jìn)行訓(xùn)練

!python /root/models/research/object_detection/legacy/train.py \
--logtostderr \
--train_dir=/root/models/trained \
--pipeline_config_path=/root/models/ssd_mobilenet_v1_coco.config

PS :? 訓(xùn)練完成後,將於 models/trained/ 資料夾內(nèi)產(chǎn)出 model.ckpt-500 檔案

第十步 : 產(chǎn)生 Frozen Graph

此步驟可以調(diào)整模組輸出大小,比如說將原本輸入大小 224x224 改成 96x96 。

PS :? 訓(xùn)練完成後,將於 models/fine_tuned_model / 資料夾內(nèi)產(chǎn)出 tflite_graph.pb 檔案

!python /root/models/research/object_detection/export_tflite_ssd_graph.py \
--pipeline_config_path=/root/models/ssd_mobilenet_v1_coco.config \
--output_directory=/root/models/fine_tuned_model \
--trained_checkpoint_prefix=/root/models/trained/model.ckpt-500

?

第十一步 : TensorFlow Lite 轉(zhuǎn)換

PS :? 訓(xùn)練完成後,將於 models/fine_tuned_model / 資料夾內(nèi)產(chǎn)出 mobilenetssd_totoro_uint8.tflite 檔案

# 此處以指令方式進(jìn)行轉(zhuǎn)換,亦可使用上述文章所介紹代碼方式。
! tflite_convert \
--output_file=/root/models/fine_tuned_model/ mobilenetssd_totoro_uint8.tflite \
--graph_def_file=/root/models/fine_tuned_model/tflite_graph.pb \
--inference_type=QUANTIZED_UINT8 \
--input_arrays=normalized_input_image_tensor \
--input_shapes=1,300,300,3 \
--output_arrays= 'TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3’ \
--default_ranges_min=0 \
--default_ranges_max=6 \
--mean_values=128 \
--std_dev_values=127 \
--allow_custom_ops

?

第十二步 : Object Detection 範(fàn)例實(shí)現(xiàn)

建立 app.py 開始撰寫 python 代碼,如下:

import cv2
import numpy as np
from tflite_runtime.interpreter import Interpreter
# 解析 tensorflow lite 檔案
interpreter = Interpreter(model_path='mobilenetssd_totoro_uint8.tflite') # 記得將模組移動至 i.MX8 平臺
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
width = input_details[0]['shape'][2]
height = input_details[0]['shape'][1]

# 讀取測試資料,並設(shè)置於解譯器中
frame = cv2.imread(' test.jpg’)
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(frame_rgb, (width, height))
input_data = np.expand_dims(frame_resized, axis=0)
interpreter.set_tensor(input_details[0]['index'], input_data)

# 進(jìn)行推理
interpreter.invoke()

# 取得輸出資料
detection_boxes = interpreter.get_tensor(output_details[0]['index']) # 輸出位置資訊
detection_classes = interpreter.get_tensor(output_details[1]['index']) # 輸出類別資訊
detection_scores = interpreter.get_tensor(output_details[2]['index']) # 輸出分?jǐn)?shù)資訊
num_boxes = interpreter.get_tensor(output_details[3]['index'])

# 標(biāo)示物件
for i in range(10):
if detection_scores[0, i] > .5: # 預(yù)測值大於 0.5則顯示
x = detection_boxes[0, i, [1, 3]] * frame_rgb.shape[1]
y = detection_boxes[0, i, [0, 2]] * frame_rgb.shape[0]
class_id = detection_classes[0, i]
cv2.rectangle(frame_rgb, (x[0], y[0]), (x[1], y[1]), (0, 255, 0), 2)

cv2.imshow('TOTORO',frame_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()

?

?(2) 於 NXP i.MX8M Plus 實(shí)作 Object Detection 範(fàn)例實(shí)現(xiàn) :?

開啟 NXP i.MX8M Plus 開發(fā)板後,即可將 模組(mobilenetssd_totoro_uint8.tflite)、測試圖檔(test.jpg)、程式碼(app.py) 傳送至開發(fā)板中。

# 利用網(wǎng)路將檔案傳至開發(fā)板中
$ scp mobilenetssd_totoro_uint8.tflite root@xx.xx.xx.xx:~
$ scp test.jpg root@xx.xx.xx.xx:~
$ scp app.py root@xx.xx.xx.xx:~


接上螢?zāi)唬\(yùn)行物件識別 DEMO。

$ python3 app.py


如下圖所示,成功檢測出豆豆龍(物件) !! 在 i.MX8M Plus 的 NPU 處理器,推理時間(Inference Time) 約 9 ms

?

三.? 結(jié)語

本文主要目的是推廣 Colab 的實(shí)用性為主,其用意是希望讀者可以將此系列博文當(dāng)作一套工具書來查閱,來達(dá)到快速應(yīng)用之目的。本文介紹了如何利用 Colab 與遷移學(xué)習(xí)的方式來客製化屬於自己的 AI 模型,那本篇是以豆豆龍作呈現(xiàn),後續(xù)讀者若是想創(chuàng)造不同的物件識別目的時,僅須要更換訓(xùn)練的資料庫來源即可,像是識別人臉或是手部皆可以這種方式實(shí)現(xiàn) !! 筆者這麼推崇 Colab 作為機(jī)器學(xué)的入門必學(xué)項(xiàng)目,其理由是 Colab 不須花費(fèi)自身電腦資源之外,更看中的是結(jié)合 Google Drive 的這項(xiàng)應(yīng)用,每當(dāng)建立一套筆記本或是新的應(yīng)用時,就能自動儲存至該使用者帳戶中,實(shí)為方便 !! 利用這項(xiàng)特點(diǎn),不斷累積新的技術(shù)就能打造自身的 AI 學(xué)習(xí)庫了!!

?

四.??參考文件

[1] 官方文件 - Colaboratory 官網(wǎng)
[2] 第三方文件 -鳥哥的首頁

如有任何相關(guān)?Colab?技術(shù)問題,歡迎至博文底下留言提問?!!
接下來還會分享更多 Colab?的技術(shù)文章?!!敬請期待?【ATU Book-i.MX8 系列 - Colab
?!!

?

★博文內(nèi)容均由個人提供,與平臺無關(guān),如有違法或侵權(quán),請與網(wǎng)站管理員聯(lián)繫。

★文明上網(wǎng),請理性發(fā)言。內(nèi)容一周內(nèi)被舉報5次,發(fā)文人進(jìn)小黑屋喔~

參考來源

評論