TensorFlow圖像分類教程
點(diǎn)擊下方卡片,關(guān)注“新機(jī)器視覺”公眾號
重磅干貨,第一時間送達(dá)
來源:阿里云云棲號
導(dǎo)讀:深度學(xué)習(xí)算法與計(jì)算機(jī)硬件性能的發(fā)展,使研究人員和企業(yè)在圖像識別、語音識別、推薦引擎和機(jī)器翻譯等領(lǐng)域取得了巨大的進(jìn)步。六年前,視覺模式識別領(lǐng)域取得了第一個超凡的成果。兩年前,Google大腦團(tuán)隊(duì)開發(fā)了TensorFlow,并將深度學(xué)習(xí)巧妙的應(yīng)用于各個領(lǐng)域。現(xiàn)在,TensorFlow則超越了很多用于深度學(xué)習(xí)的復(fù)雜工具。
利用TensorFlow,你可以獲得具有強(qiáng)大能力的復(fù)雜功能,其強(qiáng)大的基石來自于TensorFlow的易用性。
在這個由兩部分組成的系列中,我將講述如何快速的創(chuàng)建一個應(yīng)用于圖像識別的卷積神經(jīng)網(wǎng)絡(luò)。
TensorFlow計(jì)算步驟是并行的,可對其配置進(jìn)行逐幀視頻分析,也可對其擴(kuò)展進(jìn)行時間感知視頻分析。
本系列文章直接切入關(guān)鍵的部分,只需要對命令行和Python有最基本的了解,就可以在家快速地創(chuàng)建一些令你激動不已的項(xiàng)目。本文不會深入探討TensorFlow的工作原理,如果你想了解更多,我會提供大量額外的參考資料。本系列所有的庫和工具都是免費(fèi)開源的軟件。
工作原理
本教程旨在把一個事先被放到訓(xùn)練過的類別里的圖片,通過運(yùn)行一個命令以識別該圖像具體屬于哪個類別。步驟如下圖所示:
標(biāo)注:管理訓(xùn)練數(shù)據(jù)。例如花卉,將雛菊的圖像放到“雛菊”目錄下,將玫瑰放到“玫瑰”目錄下等等,將盡可能多的不同種類的花朵按照類別不同放在不同的目錄下。如果我們不標(biāo)注“蕨類植物”,那么分類器永遠(yuǎn)也不會返回“蕨類植物”。這需要每個類型的很多樣本,因此這一步很重要,并且很耗時。(本文使用預(yù)先標(biāo)記好的數(shù)據(jù)以提高效率)
訓(xùn)練:將標(biāo)記好的數(shù)據(jù)(圖像)提供給模型。有一個工具將隨機(jī)抓取一批圖像,使用模型猜測每種花的類型,測試猜測的準(zhǔn)確性,重復(fù)執(zhí)行,直到使用了大部分訓(xùn)練數(shù)據(jù)為止。最后一批未被使用的圖像用于計(jì)算該訓(xùn)練模型的準(zhǔn)確性。
分類:在新的圖像上使用模型。例如,輸入:IMG207.JPG,輸出:雛菊。這個步驟快速簡單,且衡量的代價小。
訓(xùn)練和分類
本教程將訓(xùn)練一個用于識別不同類型花朵的圖像分類器。深度學(xué)習(xí)需要大量的訓(xùn)練數(shù)據(jù),因此,我們需要大量已分類的花朵圖像。值得慶幸的是,另外一個模型在圖像收集和分類這方面做得非常出色,所以我們使用這個帶有腳本的已分類數(shù)據(jù)集,它有現(xiàn)成且完全訓(xùn)練過的圖像分類模型,重新訓(xùn)練模型的最后幾層以達(dá)到我們想要的結(jié)果,這種技術(shù)稱為遷移學(xué)習(xí)。
我們重新訓(xùn)練的模型是Inception v3,最初是在2015年12月發(fā)表的論文“重新思考計(jì)算機(jī)視覺的Inception架構(gòu)”中有做論述。
直到我們做了這個約20分鐘的訓(xùn)練,Inception才知道如何識別雛菊和郁金香,這就是深度學(xué)習(xí)中的“學(xué)習(xí)”部分。
安裝
首先,在所選的平臺上安裝Docker。
在很多TensorFlow教程中最先且唯一依賴的就是Docker(應(yīng)該表明這是個合理的開始)。我也更喜歡這種安裝TensorFlow的方法,因?yàn)椴恍枰惭b一系列的依賴項(xiàng),這可以保持主機(jī)(筆記本或桌面)比較干凈。
Bootstrap TensorFlow
安裝Docker后,我們準(zhǔn)備啟動一個訓(xùn)練和分類的TensorFlow容器。在硬盤上創(chuàng)建一個2GB空閑空間的工作目錄,創(chuàng)建一個名為local的子目錄,并記錄完整路徑。
docker run -v /path/to/local:/notebooks/local --rm -it --name tensorflow
tensorflow/tensorflow:nightly /bin/bash
下面是命令解析:
-v /path/to/local:/notebooks/local將剛創(chuàng)建的local目錄掛載到容器中適當(dāng)?shù)奈恢谩H绻褂肦HEL、Fedora或其他支持SELinux的系統(tǒng),添加:Z允許容器訪問目錄。
--rm 退出時令docker刪除容器
-it 連接輸入輸出,實(shí)現(xiàn)交互。
--name tensorflow將容器命名為tensorflow,而不是sneaky_chowderhead或任何Docker定義的隨機(jī)名字。
tensorflow/tensorflow:nightly從Docker Hub (公共圖像存儲庫)運(yùn)行tensorflow/tensorflow的nightly 圖像,而不是最新的圖像(默認(rèn)為最近建立/可用圖像)。使用nightly圖像而不是latest圖像,是因?yàn)椋ㄔ趯懭霑r)latest包含的一個bug會破壞TensorBoard,這是我們稍后需要的一個數(shù)據(jù)可視化工具。
/bin/bash指定運(yùn)行Bash shell,而不運(yùn)行系統(tǒng)默認(rèn)命令。
訓(xùn)練模型
在容器中運(yùn)行下述命令,對訓(xùn)練數(shù)據(jù)進(jìn)行下載和完整性檢查。
curl -O http://download.tensorflow.org/example_images/flower_photos.tgz
echo 'db6b71d5d3afff90302ee17fd1fefc11d57f243f flower_photos.tgz' | sha1sum -c
如果沒有看到“flower_photos.tgz”信息:說明文件不正確。如果上訴curl 或sha1sum步驟失敗,請手動下載訓(xùn)練數(shù)據(jù)包并解壓(SHA-1 校驗(yàn)碼:db6b71d5d3afff90302ee17fd1fefc11d57f243f)到本地主機(jī)的local目錄下。
現(xiàn)在把訓(xùn)練數(shù)據(jù)放好,然后對再訓(xùn)練腳本進(jìn)行下載和完整性檢查。
mv flower_photos.tgz local/
cd local
curl -O https://raw.githubusercontent.com/tensorflow/tensorflow/10cf65b48e1b2f16eaa82
6d2793cb67207a085d0/tensorflow/examples/image_retraining/retrain.py
echo 'a74361beb4f763dc2d0101cfe87b672ceae6e2f5 retrain.py' | sha1sum -c
確認(rèn)retrain.py有正確的內(nèi)容,你應(yīng)該看到retrain.py: OK.。
最后,開始學(xué)習(xí)!運(yùn)行再訓(xùn)練腳本。
python retrain.py --image_dir flower_photos --output_graph output_graph.pb
--output_labels output_labels.txt
如果遇到如下錯誤,忽略它:
TypeError: not all arguments converted during string formatting Logged from file
tf_logging.py, line 82.
隨著retrain.py 的運(yùn)行,訓(xùn)練圖像會自動的分批次訓(xùn)練、測試和驗(yàn)證數(shù)據(jù)集。
在輸出上,我們希望有較高的“訓(xùn)練精度”和“驗(yàn)證精度”,以及較低的“交叉熵”。有關(guān)這些術(shù)語的詳細(xì)解釋,請參照“如何就新圖片類型再訓(xùn)練Inception的最后一層”。在當(dāng)前的硬件上的訓(xùn)練約30分鐘。
請注意控制臺輸出的最后一行:
INFO:tensorflow:Final test accuracy = 89.1% (N=340)
這說明我們已經(jīng)得到了一個模型:給定一張圖像,10次中有9次可正確猜出是五種花朵類型中的哪一種。由于提供給訓(xùn)練過程的隨機(jī)數(shù)不同,分類的精確度也會有所不同。
分類
再添加一個小腳本,就可以將新的花朵圖像添加到模型中,并輸出測試結(jié)果。這就是圖像分類。
將下述腳本命名為 classify.py保存在本地local目錄:
import tensorflow as tf, sys
image_path = sys.argv[1]
graph_path = 'output_graph.pb'
labels_path = 'output_labels.txt'
# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()
# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
in tf.gfile.GFile(labels_path)]
# Unpersists graph from file
with tf.gfile.FastGFile(graph_path, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(graph_def, name='')
# Feed the image_data as input to the graph and get first prediction
with tf.Session() as sess:
softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')
predictions = sess.run(softmax_tensor,
{'DecodeJpeg/contents:0': image_data})
# Sort to show labels of first prediction in order of confidence
top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]
for node_id in top_k:
human_string = label_lines[node_id]
score = predictions[0][node_id]
print('%s (score = %.5f)' % (human_string, score))
為了測試你自己的圖像,保存在local目錄下并命名為test.jpg,運(yùn)行(在容器內(nèi)) python classify.py test.jpg。輸出結(jié)果如下:
sunflowers (score = 0.78311)
daisy (score = 0.20722)
dandelion (score = 0.00605)
tulips (score = 0.00289)
roses (score = 0.00073)
數(shù)據(jù)說明了一切!模型確定圖像中的花朵是向日葵的準(zhǔn)確度為78.311%。數(shù)值越高表明匹配度越高。請注意,只能有一個匹配類型。多標(biāo)簽分類則需要另外一個不同的方法。
分類腳本中的圖表加載代碼已經(jīng)被破壞,在這里,我用graph_def = tf.GraphDef()等作為圖表加載代碼。
利用零基礎(chǔ)知識和一些代碼,我們建了一個相當(dāng)好的花卉圖像分類器,在現(xiàn)有的筆記本電腦上每秒大約可以處理5張圖像。
希望你能夠繼續(xù)關(guān)注系列其他博文。
以上為譯文。本文由阿里云云棲社區(qū)組織翻譯。
文章原標(biāo)題《Learn how to classify images with TensorFlow》,譯者:Mags,審校:袁虎。
本文僅做學(xué)術(shù)分享,如有侵權(quán),請聯(lián)系刪文。

