本文主要演示了如何使用Inception v3模型進行影像識別。
01 – 簡單線性模型 | 02 – 卷積神經網路 | 03 – PrettyTensor | 04 – 儲存& 恢復
05 – 整合學習 | 06 – CIFAR 10
by Magnus Erik Hvass Pedersen / GitHub / Videos on YouTube
中文翻譯 thrillerist / Github
如有轉載,請附上本文連結。
介紹
這篇教程演示瞭如何用一個預訓練好的深度神經網路Inception v3來進行影像分類。
Inception v3模型在一臺配有 8 Tesla K40 GPUs,大概價值$30,000的野獸級計算機上訓練了幾個星期,因此不可能在一臺普通的PC上訓練。我們將會下載預訓練好的Inception模型,然後用它來做影像分類。
Inception v3模型大約有2500萬個引數,分類一張影像就用了50億的乘加指令。在一臺沒有GPU的現代PC上,分類一張影像轉眼就能完成。
這篇教程隱藏了TensorFlow程式碼,因此可能不要求很多的TensorFlow經驗,當然從之前的教程中學到一些對TensorFlow的基本理解還是很有幫助的,特別是在你想學習inception.py
檔案中的實現細節時。
流程圖
下面的流程圖顯示了Inception v3模型中的資料流向,這是一個帶有許多層的,有著複雜結構的卷積神經網路。這篇論文裡有Inception模型如何構造,以及為什麼這麼設計的更多細節。但作者也承認他們並不完全明白模型的工作原理。
注意,Inception模型有兩個softmax輸出。一個是在訓練神經網路時使用,另一個是訓練結束之後,在影像分類時使用,即推斷階段(inference)。
上週剛剛分佈了新的模型, 它比Inception v3更復雜,也得到了更好的分類準確率。
from IPython.display import Image, display
Image(`images/07_inception_flowchart.png`)複製程式碼
匯入
%matplotlib inline
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import os
# Functions and classes for loading and using the Inception model.
import inception複製程式碼
使用Python3.5.2(Anaconda)開發,TensorFlow版本是:
tf.__version__複製程式碼
`0.10.0rc0`
下載Inception模型
從網上下載Inception模型。這是你儲存資料檔案的預設資料夾。如果資料夾不存在就自動建立。
# inception.data_dir = `inception/`複製程式碼
如果資料夾中不存在Inception模型,就自動下載。
它有85MB。
inception.maybe_download()複製程式碼
Downloading Inception v3 Model …
Data has apparently already been downloaded and unpacked.
載入Inception模型
載入模型,為影像分類做準備。
注意這些warning資訊,以後可能會導致程式執行失敗。
model = inception.Inception()複製程式碼
/home/magnus/anaconda3/envs/tensorflow/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1811: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
result_shape.insert(dim, 1)
分類以及繪製影像的幫助函式
這是一個簡單的封裝函式,它可以展示影像,然後用Inception模型進行分類,最終列印出分類評分。
def classify(image_path):
# Display the image.
display(Image(image_path))
# Use the Inception model to classify the image.
pred = model.classify(image_path=image_path)
# Print the scores and names for the top-10 predictions.
model.print_scores(pred=pred, k=10, only_first_name=True)複製程式碼
熊貓
Inception資料檔案中包含了這張熊貓影像。Inception模型相當確定這張圖片上展示了熊貓,分類評分達到了89.23%,第二高的代表大狐猴的分數只有0.86%,這是另外一種外來動物。
image_path = os.path.join(inception.data_dir, `cropped_panda.jpg`)
classify(image_path)複製程式碼
89.23% : giant panda
0.86% : indri
0.26% : lesser panda
0.14% : custard apple
0.11% : earthstar
0.08% : sea urchin
0.05% : forklift
0.05% : soccer ball
0.05% : go-kart
0.05% : digital watch
分類評分的解釋
Inception模型的輸出是Softmax函式,這在之前教程中的神經網路中也有用到。
softmax輸出有時也稱為概率分佈(probabilities),因為它介於零到一之間,然後相加為一,與概率分佈相同。但它們並不是傳統語義上的概率分佈,因為並不是由重複試驗得來。
將神經網路的輸出值稱為分類評分或排名可能會更好,因為結果顯示了神經網路認為輸入影像是每個可能分類的強度。
在上面的熊貓樣本中, Inception模型給熊貓型別很高的分數—89.23%,同時其它999種類別的分數都在1%以下。這表示Inception模型十分確信影像展示了一隻熊貓,而剩下1%以下的應該視為噪聲。比如,排名第十高的分數是0.05%,代表電子手錶,但它更可能是由於神經網路的不精準而不是暗示著影像看起來有點像電子手錶。
有時Inception模型不確定影像屬於哪一個分類,因此結果中並沒有一個特別高的分數。下面會展示這種樣本。
鸚鵡(原始影像)
Inception模型十分確定(評分97.30%)這張影像展示了一種叫金剛鸚鵡的鸚鵡。
classify(image_path="images/parrot.jpg")複製程式碼
97.30% : macaw
0.07% : African grey
0.07% : toucan
0.05% : jacamar
0.04% : bee eater
0.04% : lorikeet
0.02% : sulphur-crested cockatoo
0.02% : jay
0.01% : kite
0.01% : sandbar
鸚鵡(調整影像)
Inception使用於299 x 299畫素的輸入影像。上面的鸚鵡影像實際上是320畫素寬、785畫素高的,因此它將由Inception模型自動縮放。
現在我們想看看被Inception模型調整過的影像。
首先我們實現一個幫助函式,用來從Inception模型內部獲取調整過的影像。
def plot_resized_image(image_path):
# Get the resized image from the Inception model.
resized_image = model.get_resized_image(image_path=image_path)
# Plot the image.
plt.imshow(resized_image, interpolation=`nearest`)
# Ensure that the plot is shown.
plt.show()複製程式碼
現在畫出調整過的鸚鵡圖。這是Inception模型中神經網路的真正輸入影像。我們可以看到它被壓縮成正方形,並且解析度降低了,因此影像看起來更畫素化和鋸齒狀。
這種情況下,影像仍然清晰地展示了一隻鸚鵡,但一些影像經過(模型內)原生的調整後會變得扭曲,因此你可能會想自己調整影像大小,再輸入到Inception模型。
plot_resized_image(image_path="images/parrot.jpg")複製程式碼
鸚鵡(裁剪影像,上方)
鸚鵡影像被手動裁剪成299 x 299畫素大小,然後輸入到Inception模型中,這時(模型)還是很確信(評分97.38%)輸入圖展示了一隻鸚鵡(金剛鸚鵡)。
classify(image_path="images/parrot_cropped1.jpg")複製程式碼
97.38% : macaw
0.09% : African grey
0.03% : sulphur-crested cockatoo
0.02% : toucan
0.02% : reflex camera
0.01% : comic book
0.01% : backpack
0.01% : bib
0.01% : vulture
0.01% : lens cap
鸚鵡(裁剪影像,中間)
這是鸚鵡圖的另一張裁剪影像,這次展示了鸚鵡的軀幹,不包含頭部和尾巴。Inception模型仍然很確定(評分93.94%)這是一隻金剛鸚鵡。
classify(image_path="images/parrot_cropped2.jpg")複製程式碼
93.94% : macaw
0.77% : toucan
0.55% : African grey
0.13% : jacamar
0.12% : bee eater
0.11% : sulphur-crested cockatoo
0.10% : magpie
0.09% : jay
0.07% : lorikeet
0.05% : hornbill
鸚鵡(裁剪影像,底部)
這次的裁剪影像只顯示了鸚鵡的尾巴。現在Inception模型相當困惑,認為影像可能顯示的是一隻鶲鴷(評分26.11%),這是另一種外來鳥,也可能是一隻草蜢(評分10.61%)。
Inception模型還認為影像有可能是一隻鋼筆(評分2%)。但這是一個很低的分數,應該解釋成不可靠的噪聲。
classify(image_path="images/parrot_cropped3.jpg")複製程式碼
26.11% : jacamar
10.61% : grasshopper
4.05% : chime
2.24% : bulbul
2.00% : fountain pen
1.60% : leafhopper
1.26% : cricket
1.25% : kite
1.13% : macaw
0.80% : torch複製程式碼
鸚鵡(填充影像)
對Inception模型來說,最好的輸入影像方式是先將影像填充成正方形,然後調整至299 x 299畫素,在這樣的鸚鵡樣本中,模型正確分類並且評分達到96.78%。
classify(image_path="images/parrot_padded.jpg")複製程式碼
96.78% : macaw
0.06% : toucan
0.06% : African grey
0.05% : bee eater
0.04% : sulphur-crested cockatoo
0.03% : king penguin
0.03% : jacamar
0.03% : lorikeet
0.01% : kite
0.01% : anemone fish
Elon Musk (299 x 299 畫素)
這張影像展示了Elon Musk——活著的傳奇,超級-書呆子-英雄。但Inception模型對影像顯示的東西很困惑,它預測影像可能是一件運動衫(評分19.73%),或者是一件阿拉伯長袍(評分16.82)。它也認為影像可能是一個乒乓球(3.05%)或一個棒球(評分1.86%)。Inception模型很困惑,並且分類評分不可靠。
classify(image_path="images/elon_musk.jpg")複製程式碼
19.73% : sweatshirt
16.82% : abaya
4.17% : suit
3.46% : trench coat
3.05% : ping-pong ball
1.92% : cellular telephone
1.86% : baseball
1.77% : jersey
1.54% : kimono
1.43% : water bottle
Elon Musk (100 x 100 畫素)
如果我們使用100 x 100畫素的Elon Mask影像,這時Inception模型認為它可能是一件運動衫(評分17.85%), 或是一隻牛仔靴(評分16.36%)。現在Inception模型做出了一些不同的預測,但仍然很困惑。
classify(image_path="images/elon_musk_100x100.jpg")複製程式碼
17.85% : sweatshirt
16.36% : cowboy boot
10.68% : balance beam
8.87% : abaya
5.36% : suit
4.57% : Loafer
2.94% : trench coat
2.65% : maillot
1.87% : jersey
1.42% : unicycle
Inception模型自動將影像從100 x 100放大至299 x 299畫素,如下所示。看看它是多麼畫素化和鋸齒狀,儘管人類可以輕易地看出這是一張雙臂交叉的男人的影像。
plot_resized_image(image_path="images/elon_musk_100x100.jpg")複製程式碼
查理和巧克力工廠 (Gene Wilder)
這張影像展示了在1971版電影《查理和巧克力工廠》中演員Gene Wilder飾演的角色。Inception模型很確定影像顯示了一個蝴蝶領結(評分97.22%),儘管這是對的,但人類很可能說這張圖片展示的是一個人。
原因可能是Inception模型在訓練時將戴蝴蝶結的人的影像分類成蝴蝶領結而不是一個人。因此,或許類別名稱應該改成“戴蝴蝶領結的人”而不只是“蝴蝶領結”。
classify(image_path="images/willy_wonka_old.jpg")複製程式碼
97.22% : bow tie
0.92% : cowboy hat
0.21% : sombrero
0.09% : suit
0.06% : bolo tie
0.05% : Windsor tie
0.04% : cornet
0.03% : flute
0.02% : banjo
0.02% : revolver
查理和巧克力工廠 (Johnny Depp)
這張影像展示了在2005版電影《查理和巧克力工廠》中演員Johnny Depp飾演的角色。Inception模型認為影像是“太陽鏡(sunglasses)”(評分31.48%)或“太陽鏡(sunglass)”(評分18.77)。實際上,第一個類別的全名是“太陽鏡,深色眼鏡,墨鏡”。出於某些原因,Inception模型被訓練成可以識別兩種相似的眼鏡。再一次,影像顯示了太陽鏡,這個結果是對的,但人類很可能會說影像展示的是一個人。
classify(image_path="images/willy_wonka_new.jpg")複製程式碼
31.48% : sunglasses
18.77% : sunglass
1.55% : velvet
1.02% : wig
0.77% : cowboy hat
0.69% : seat belt
0.67% : sombrero
0.62% : jean
0.46% : poncho
0.43% : jersey
關閉TensorFlow會話
現在我們已經用TensorFlow完成了任務,關閉session,釋放資源。注意,TensorFlow-session是在模型內部的,因此我們通過模型來關閉它。
# This has been commented out in case you want to modify and experiment
# with the Notebook without having to restart it.
# model.close()複製程式碼
總結
本教程說明了如何使用預訓練的Inception v3模型。它在一臺野獸級電腦上花了好幾周才訓練好。但我們可以從網上下載完成的模型,然後在一臺普通PC上用它來做影像分類。
不幸的是,Inception模型對識別人物很有問題。這可能是所使用訓練集的原因。新版的Inception模型也已經發布了,但它可能也是在同樣的訓練集上訓練,對於識別人物還是有問題。希望未來的模型會訓練來識別常見的物體,比如人類。
這篇教程中我們在inception.py
檔案中隱藏了TensorFlow的實現細節,因為它有點凌亂,我們可能在之後的教程中仍然會複用這個。希望TensorFlow的開發者會標準化、簡單化API,使得更簡單地載入這些預訓練模型,這樣,每個人只需要幾行程式碼就能使用一個強大的影像分類器。
練習
下面是一些可能會讓你提升TensorFlow技能的一些建議練習。為了學習如何更合適地使用TensorFlow,實踐經驗是很重要的。
在你對這個Notebook進行改變之前,可能需要先備份一下。
- 使用你自己的、或者在網上找到的影像。
- 裁剪,調整大小,扭曲影像,看看它如何影響分類準確率。
- 在程式碼的幾個不同地方加入列印資訊。你也可以直接執行除錯
inception.py
檔案。 - 試著使用這些剛釋出的新模型。它們的載入方式與Inception v3模型不同,實現起來可能更具挑戰性。
- 向朋友解釋程式如何工作。