歡迎你們前往騰訊雲技術社區,獲取更多騰訊海量技術實踐乾貨哦~node
做者:付越 python
Tensorflow在更新1.0版本以後多了不少新功能,其中放出了不少用tf框架寫的深度網絡結構(github.com/tensorflow/… ),大大下降了開發難度,利用現成的網絡結構,不管fine-tuning仍是從新訓練方便了很多。最近筆者終於跑通TensorFlow Object Detection API的ssd_mobilenet_v1模型,這裏記錄下如何完整跑通數據準備到模型使用的整個過程,相信對本身和一些同窗能有所幫助。git
Object Detection API提供了5種網絡結構的預訓練的權重,所有是用COCO數據集進行訓練,這五種模型分別是SSD+mobilenet、SSD+inception_v二、R-FCN+resnet10一、faster RCNN+resnet10一、faster RCNN+inception+resnet101。各個模型的精度和計算所需時間以下。下面及介紹下如何使用Object Detection去訓練本身的模型。github
這裏TensorFlow的安裝就再也不說明了,網上的教程一大把,你們能夠找到很詳盡的安裝TensorFlow的文檔。算法
使用protobuf來配置模型和訓練參數,因此API正常使用必須先編譯protobuf庫,這裏能夠下載直接編譯好的pb庫(github.com/google/prot… ),解壓壓縮包後,把protoc加入到環境變量中:api
$ cd tensorflow/models
$ protoc object_detection/protos/*.proto --python_out=.複製代碼
(我是把protoc加到環境變量中,遇到找不到*.proto文件的報錯,後來把protoc.exe放到models/object_detection目錄下,從新執行才能夠)瀏覽器
而後將models和slim(tf高級框架)加入python環境變量:bash
PYTHONPATH=$PYTHONPATH:/your/path/to/tensorflow/models:/your/path/to/tensorflow/models/slim複製代碼
數據集須要轉化成PASCAL VOC結構,API提供了create_pascal_tf_record.py,把VOC結構數據集轉換成.record格式。不過咱們發現更簡單的方式,Datitran提供一種更簡單生產.record格式的方法。網絡
首先須要先要標註圖像相應標籤,這裏可使用labelImg工具。每標註一張樣本,即生成一個xml的標註文件。而後,把這些標註的xml文件,按訓練集與驗證集分別放置到兩個目錄下,在Datitran提供了xml_to_csv.py腳本。這裏只要指定標註的目錄名便可。接下來,而後須要咱們把對應的csv格式轉換成.record格式。架構
def main():
# image_path = os.path.join(os.getcwd(), 'annotations')
image_path = r'D:\training-sets\object-detection\sunglasses\label\test'
xml_df = xml_to_csv(image_path)
xml_df.to_csv('sunglasses_test_labels.csv', index=None)
print('Successfully converted xml to csv.')複製代碼
調用generate_tfrecord.py,注意要指定--csv_input與--output_path這兩個參數。執行下面命令:
python generate_tfrecord.py --csv_input=sunglasses_test_labels.csv --output_path=sunglass_test.record複製代碼
這樣就生成了訓練及驗證用的train.record與test.record。接下來指定標籤名稱,仿照models/ object_detection/data/ pet_label_map.pbtxt,從新建立一個文件,指定標籤名。
item {
id: 1
name: 'sunglasses'
}複製代碼
根據本身的須要,選擇一款用coco數據集預訓練的模型,把前綴model.ckpt放置在待訓練的目錄,這裏meta文件保存了graph和metadata,ckpt保存了網絡的weights,這幾個文件表示預訓練模型的初始狀態。
打開ssd_mobilenet_v1_pets.config文件,並作以下修改:
其餘參數均保持默認參數。
準備好上述文件後就能夠直接調用train文件進行訓練。
python object_detection/train.py \
--logtostderr \
--pipeline_config_path= D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config \
--train_dir=D:/training-sets/data-translate/training複製代碼
經過tensorboard工具,能夠監控訓練過程,輸入西面指令後,在瀏覽器輸入localhost:6006(默認)便可。
tensorboard --logdir= D:/training-sets/data-translate/training複製代碼
這裏面有不少指標曲線,甚至有模型網絡架構,筆者對於這裏面不少指標含義尚未弄明白,不過感受出TensorBoard這個工具應該是極其強大。不過咱們能夠經過Total_Loss來看總體訓練的狀況。
從總體上看,loss曲線確實是收斂的,總體的訓練效果仍是滿意的。另外,TensorFlow還提供了訓練過程當中利用驗證集驗證準確性的能力,可是筆者在調用時,仍有些問題,這裏暫時就不詳細說明了。
查看模型實際的效果前,咱們須要把訓練的過程文件導出,生產.pb的模型文件。原本,tensorflow/python/tools/freeze_graph.py提供了freeze model的api,可是須要提供輸出的final node names(通常是softmax之類的最後一層的激活函數命名),而object detection api提供提供了預訓練好的網絡,final node name並很差找,因此object_detection目錄下還提供了export_inference_graph.py。
python export_inference_graph.py \
--input_type image_tensor
--pipeline_config_path D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config \
--trained_checkpoint_prefix D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config /model.ckpt-* \
--output_directory D:/training-sets /data-translate/training/result複製代碼
導出完成後,在output_directory下,會生成frozen_inference_graph.pb、model.ckpt.data-00000-of-0000一、model.ckpt.meta、model.ckpt.data文件。
目錄下自己有一個調用的例子,稍微改造以下:
import cv2
import numpy as np
import tensorflow as tf
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util
class TOD(object):
def __init__(self):
self.PATH_TO_CKPT = r'D:\lib\tf-model\models-master\object_detection\training\frozen_inference_graph.pb'
self.PATH_TO_LABELS = r'D:\lib\tf-model\models-master\object_detection\training\sunglasses_label_map.pbtxt'
self.NUM_CLASSES = 1
self.detection_graph = self._load_model()
self.category_index = self._load_label_map()
def _load_model(self):
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(self.PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
return detection_graph
def _load_label_map(self):
label_map = label_map_util.load_labelmap(self.PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map,
max_num_classes=self.NUM_CLASSES,
use_display_name=True)
category_index = label_map_util.create_category_index(categories)
return category_index
def detect(self, image):
with self.detection_graph.as_default():
with tf.Session(graph=self.detection_graph) as sess:
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
image_np_expanded = np.expand_dims(image, axis=0)
image_tensor = self.detection_graph.get_tensor_by_name('image_tensor:0')
boxes = self.detection_graph.get_tensor_by_name('detection_boxes:0')
scores = self.detection_graph.get_tensor_by_name('detection_scores:0')
classes = self.detection_graph.get_tensor_by_name('detection_classes:0')
num_detections = self.detection_graph.get_tensor_by_name('num_detections:0')
# Actual detection.
(boxes, scores, classes, num_detections) = sess.run(
[boxes, scores, classes, num_detections],
feed_dict={image_tensor: image_np_expanded})
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(
image,
np.squeeze(boxes),
np.squeeze(classes).astype(np.int32),
np.squeeze(scores),
self.category_index,
use_normalized_coordinates=True,
line_thickness=8)
cv2.namedWindow("detection", cv2.WINDOW_NORMAL)
cv2.imshow("detection", image)
cv2.waitKey(0)
if __name__ == '__main__':
image = cv2.imread('image.jpg')
detecotr = TOD()
detecotr.detect(image)複製代碼
下面是一些圖片的識別效果:
[ I am Jarvis ] :聊聊 FaceID 背後的深度學習視覺算法
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處原文連接:https://cloud.tencent.com/community/article/351424