閱讀997 返回首頁    go 阿裏雲 go 技術社區[雲棲]


準確率98%的深度學習交通標誌識別是如何做到的?

1.jpeg

交通標誌是道路基礎設施的重要組成部分,它們為道路使用者提供了一些關鍵信息,並要求駕駛員及時調整駕駛行為,以確保遵守道路安全規定。如果沒有交通標誌,可能會發生更多的事故,因為司機無法獲知最高安全速度是多少,不了解道路狀況,比如急轉彎、學校路口等等。現在,每年大約有130萬人死在道路上。如果沒有這些道路標誌,這個數字肯定會更高。

當然,自動駕駛車輛也必須遵守交通法規,因此需要_識別_和_理解_交通標誌。

從傳統上來說,可以使用標準的計算機視覺的方法來對交通標誌進行檢測和分類,但同時也需要耗費相當多的時間來手工處理圖像中的重要特征。現在,我們引入深度學習技術來解決這個問題。我們可以創建一個能夠對交通標誌進行分類的模型,並且讓模型自己學習識別這些交通標誌中最關鍵的特征。在這篇文章中,我將演示如何創建一個深度學習架構,這個架構在交通標誌測試集上的識別準確率達到了98%。

項目設置

數據集可分為訓練集、測試集和驗證集,具有以下特點:

  • 圖像為32(寬)×32(高)×3(RGB彩色通道)
  • 訓練集由34799張圖片組成
  • 驗證集由4410個圖像組成
  • 測試集由12630個圖像組成
  • 共有43個種類(例如限速20公裏/小時、禁止進入、顛簸路等等)

此外,我們將使用Python 3.5與Tensorflow來編寫代碼。

圖像及其分布

你可以在下圖中看到數據集中的一些示例圖像,圖像的標簽顯示在相應行的上方。其中一些非常暗,稍後我們會調整它們的對比度。

2.png

訓練集中各個種類圖像的數量明顯不平衡,如下圖所示。某些種類的圖片少於200張,而其他的則有2000多張。這意味著我們的模型可能會偏向於代表性過高的種類,特別是當它的預測無法確定時。我們稍後會看到如何使用數據增強來緩解這個問題。

3.png

預處理步驟

我們首先要對圖像應用兩個預處理步驟:

灰度化

把三通道的圖像轉換為單通道灰度圖像,如下圖所示。

4.png

歸一化

我們通過用數據集平均值減去每個圖像並除以其標準偏差來確定圖像數據集分布的中心。這有助於提高模型在處理圖像時的一致性。生成的圖像如下所示:

5.png

模型的架構

交通標誌分類器架構的靈感來自於Yann Le Cun的這篇論文。我們在他的基礎上做了一些調整,並創建了一個模塊化的代碼庫,它允許我們嚐試不同的過濾器大小、深度和卷積層的數量,以及完全連接層的維度。為了向Le Cun致敬,我們稱這樣的網絡為**_EdLeNet_** :)。

我們將主要嚐試5x5和3x3大小的過濾器(又名內核),並且卷積層的深度從32開始。 EdLeNet的3x3架構如下所示:

6.png

該網絡由3個卷積層組成,內核大小為3x3,下一層的深度加倍,使用ReLU作為激活函數,每一層的後麵是最大2×2的池操作。最後3層完全連接,最後一層能產生43個結果(可能的標簽總數),使用SoftMax作為激活函數。這個網絡使用附帶Adam優化器的迷你批次隨機梯度下降算法進行訓練。我們編寫了高度模塊化的基礎代碼,這使得我們能夠_動態_創建模型,示例代碼片段如下:

mc_3x3 = ModelConfig(EdLeNet, "EdLeNet_Norm_Grayscale_3x3_Dropout_0.50", [32, 32, 1], [3, 32, 3], [120, 84], n_classes, [0.75, 0.5])
mc_5x5 = ModelConfig(EdLeNet, "EdLeNet_Norm_Grayscale_5x5_Dropout_0.50", [32, 32, 1], [5, 32, 2], [120, 84], n_classes, [0.75, 0.5])

me_g_norm_drpt_0_50_3x3 = ModelExecutor(mc_3x3)
me_g_norm_drpt_0_50_5x5 = ModelExecutor(mc_5x5)

ModelConfig包含了模型的相關信息,比如:

  • 模型的函數(例如:EdLeNet
  • 模型的名稱
  • 輸入的格式(例如:灰度等級為[32,32,1]),
  • 卷積層的配置[過濾器大小、起始深度、層數],
  • 完全連接層的大小(例如:[120,84])
  • 種類的數量
  • dropout(丟棄)百分比值[p-conv,p-fc]

ModelExecutor負責_訓練_、_評估_、_預測_,以及生成_激活_映射的可視化效果。

為了更好地隔離模型,並確保它們不是全部都在相同的Tensorflow圖下,我們使用下麵這個比較有用的結構:

self.graph = tf.Graph()
with self.graph.as_default() as g:
    with g.name_scope( self.model_config.name ) as scope:

...

with tf.Session(graph = self.graph) as sess:

這樣,我們就能為_每個_模型創建單獨的圖,並確保沒有混入變量、占位符。這為我解決了很多麻煩。

我們實際上是以卷積深度為16開始的,但在深度為32的時候獲得了更好的結果並最終確定了這個值。我們還比較了彩色與灰度圖像、標準和歸一化的圖像,最後發現灰度圖往往優於彩色圖。不幸的是,我們在3x3或5x5的模型上最高勉強達到了93%的測試準確率,而後來一直沒有達到這個準確率。你可以在下圖中看到針對不同模型配置的一些指標圖。

7.png
在顏色歸一化圖像上的模型性能

8.png
在灰度歸一化圖像上的模型性能

Dropout(丟棄)算法

為了提高模型的可靠性,我們需要使用dropout算法,這個算法是指在深度學習網絡的訓練過程中,對於神經網絡單元,按照一定的概率將其暫時從網絡中丟棄。這樣可以防止模型過度擬合。Dropout算法最早是由深度學習領域的先驅Geoffrey Hinton提出來的。要更好地理解背後地動機,務必閱讀一下這篇論文

在論文中,作者根據層類型的不同應用不同概率值進行丟棄。因此,我決定采用類似的方法,定義兩個級別的dropout,一個用於卷積層,另一個用於完全連接層:

p-conv: probability of keep weight in convolutional layer
p-fc: probability of keeping weight in fully connected layer

此外,隨著進入到更深層次的網絡,作者逐漸開始采用更積極的dropout值。所以我也決定這樣:

p-conv >= p-fc

這樣做的原因是,我們把網絡看作是一個漏鬥,當我們深入到層中時,希望逐漸收緊它:我們不想在開始的時候丟棄太多的信息,因為其中的一些相當有價值。此外,在卷積層中應用MaxPooling的時候,我們已經失去了一些信息。

我們嚐試過不同的參數,但最終結果是_p-conv = 0.75_和_p-fc = 0.5_,這使得我們可以使用3x3的模型在歸一化灰度圖上實現97.55%的測試集準確率。有趣的是,我們在驗證集上的準確率達到了98.3%以上:

Training EdLeNet_Norm_Grayscale_3x3_Dropout_0.50 [epochs=100, batch_size=512]...

[1] total=5.222s | train: time=3.139s, loss=3.4993, acc=0.1047 | val: time=2.083s, loss=3.5613, acc=0.1007
[10]    total=5.190s | train: time=3.122s, loss=0.2589, acc=0.9360 | val: time=2.067s, loss=0.3260, acc=0.8973
...
[90]    total=5.193s | train: time=3.120s, loss=0.0006, acc=0.9999 | val: time=2.074s, loss=0.0747, acc=0.9841
[100]   total=5.191s | train: time=3.123s, loss=0.0004, acc=1.0000 | val: time=2.068s, loss=0.0849, acc=0.9832
Model ./models/EdLeNet_Norm_Grayscale_3x3_Dropout_0.50.chkpt saved
[EdLeNet_Norm_Grayscale_3x3_Dropout_0.50 - Test Set]    time=0.686s, loss=0.1119, acc=0.9755

9.png
引入dropout算法後,在灰度歸一化圖像上的模型性能

上麵的圖表顯示,這個模型更為_平滑_。我們已經在測試集上實現了準確率超過93%這個目標分數。下麵,我們將探索一些用於處理每一個點的技術。

直方圖均衡化

直方圖均衡化是一種計算機視覺技術,用於增強圖像的對比度。由於一些圖像受到了低對比度(模煳、黑暗)的影響,因此我們將通過應用OpenCV的對比度限製自適應直方圖均衡來提高可視性。

我們再次嚐試了各種配置,並找到了最好的結果,**測試精度達到了97.75%**,在3x3的模型上使用以下dropout值:_p-conv = 0.6_,_p-fc = 0.5_。

Training EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50 [epochs=500, batch_size=512]...
[1] total=5.194s | train: time=3.137s, loss=3.6254, acc=0.0662 | val: time=2.058s, loss=3.6405, acc=0.0655
[10]    total=5.155s | train: time=3.115s, loss=0.8645, acc=0.7121 | val: time=2.040s, loss=0.9159, acc=0.6819
...
[480]   total=5.149s | train: time=3.106s, loss=0.0009, acc=0.9998 | val: time=2.042s, loss=0.0355, acc=0.9884
[490]   total=5.148s | train: time=3.106s, loss=0.0007, acc=0.9998 | val: time=2.042s, loss=0.0390, acc=0.9884
[500]   total=5.148s | train: time=3.104s, loss=0.0006, acc=0.9999 | val: time=2.044s, loss=0.0420, acc=0.9862
Model ./models/EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50.chkpt saved
[EdLeNet_Grayscale_CLAHE_Norm_Take-2_3x3_Dropout_0.50 - Test Set]   time=0.675s, loss=0.0890, acc=0.9775

盡管做了直方圖均衡化,但有些圖像仍然非常模煳,並且有些圖像似乎是失真的。在我們的測試集中沒有足夠的圖像示例來改進模型的預測。另外,雖然97.75%的測試準確率已經相當不錯,但我們還有另外一個殺手鐧:數據增強。

數據增強

我們在早些時候曾經發現,43個種類的數據明顯不平衡。然而,它似乎並不是一個棘手的問題,因為即使這樣,我們也能夠達到非常高的準確度。我們也注意到測試集中有一些圖像是失真的。因此,我們將使用數據增強技術來嚐試:

  1. 擴展數據集,並在不同的照明條件和方向上提供其他圖片
  2. 提高模型的通用性
  3. 提高測試和驗證的準確性,特別是對失真的圖像

我們使用了一個名為imgaug的庫來創建擴展數據。我們主要應用仿射變換來增強圖像。代碼如下:

def augment_imgs(imgs, p):
    """
    Performs a set of augmentations with with a probability p
    """
    augs =  iaa.SomeOf((2, 4),
          [
              iaa.Crop(px=(0, 4)), # crop images from each side by 0 to 4px (randomly chosen)
              iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}),
              iaa.Affine(translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)}),
              iaa.Affine(rotate=(-45, 45)), # rotate by -45 to +45 degrees)
              iaa.Affine(shear=(-10, 10)) # shear by -10 to +10 degrees
          ])

    seq = iaa.Sequential([iaa.Sometimes(p, augs)])

    return seq.augment_images(imgs)

雖然種類數量的不平衡可能會在模型中引入偏差,但我們決定在現階段不解決這個問題,因為這會導致數據集數量的增加,延長訓練時間。相反,我們決定為每個種類增加10%的圖像。我們的新數據集如下。

12.png

圖像的分布當然不會發生顯著的變化,但是我們確實對圖像應用了灰度化、直方圖均衡化,以及歸一化等預處理步驟。我們訓練2000次,附加dropout算法(_p-conv = 0.6_,_p-fc = 0.5_),並在測試集上達到**97.86%的準確率:**

[EdLeNet] Building neural network [conv layers=3, conv filter size=3, conv start depth=32, fc layers=2]
Training EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50 [epochs=2000, batch_size=512]...

[1] total=5.824s | train: time=3.594s, loss=3.6283, acc=0.0797 | val: time=2.231s, loss=3.6463, acc=0.0687
...
[1970]  total=5.627s | train: time=3.408s, loss=0.0525, acc=0.9870 | val: time=2.219s, loss=0.0315, acc=0.9914
[1980]  total=5.627s | train: time=3.409s, loss=0.0530, acc=0.9862 | val: time=2.218s, loss=0.0309, acc=0.9902
[1990]  total=5.628s | train: time=3.412s, loss=0.0521, acc=0.9869 | val: time=2.216s, loss=0.0302, acc=0.9900
[2000]  total=5.632s | train: time=3.415s, loss=0.0521, acc=0.9869 | val: time=2.217s, loss=0.0311, acc=0.9902
Model ./models/EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50.chkpt saved

[EdLeNet_Augs_Grayscale_CLAHE_Norm_Take4_Bis_3x3_Dropout_0.50 - Test Set]   time=0.678s, loss=0.0842, acc=0.9786

這是迄今為止最好的結果!!!

13.gif

但是,看看訓練集上的損失指標,0.0521,我們很有可能還有一些改進的空間。未來,我們將執行更多的訓練次數,我們會報告最新成果的。

結論

本文探討了如何將深度學習應用於分類交通標誌,其中包含了各種預處理和歸一化技術,以及嚐試了不同的模型架構。我們的模型在測試集上達到了接近98%的準確率,在驗證集上達到了99%的準確率。你可以在這裏訪問代碼庫。

文章原標題《Recognising Traffic Signs With 98% Accuracy Using Deep-Learning》,作者:Eddie Forson,譯者:夏天,審校:主題曲。

文章為簡譯,更為詳細的你容,請查看原文

最後更新:2017-09-05 15:32:50

  上一篇:go  智能語音交互:阿裏的研究和實踐
  下一篇:go  數據管理DMS發布移動版,隨時隨地管理雲端數據