當前位置:
首頁 > 知識 > 如何使用900萬張開放圖像訓練600類圖片分類器

如何使用900萬張開放圖像訓練600類圖片分類器

原標題 |How to classify photos in 600 classes using nine million Open Images

作者 |Aleksey Bilogur

譯者 | chesc、JadenNeal、小先生愛你

如果你正在嘗試構建一個圖片分類器,但是需要訓練集,你最好的選擇是查看 Google Open Images 。

這個龐大的圖像集包含了超過3000萬張圖片和1500萬個邊界框(標籤),那是18TB的圖像數據!

此外,Open Image相比其他同規模的圖像數據集更加開放、更加容易獲取。例如 ImageNet 具有限制性許可。

但是,對於開發者來說在單個機器上篩選這麼多的數據是困難的。你需要下載和處理多個元數據的文件,遍歷他們的存儲空間(或申請訪問Google Cloud bucket)。

另一方面,除此之外沒有太多的開源的可用訓練圖像集,坦白地來說,創造和分享它們其實是一種痛苦的事情。

在這篇文章中,我們將會利用Open Images構建和分布一個簡單的端到端的機器學習管道。

我們將看到如何利用Open Images邊界框數據中包含的600個標籤中的任何一個創建自己的數據集。

我們將通過建立「開放三明治」來展示我們的工作。這些都是簡單、可重複的圖像分類器,只為了回答一個古老的問題:漢堡包是三明治嗎?

想看代碼?你可以在GitHub上的存儲庫中進行操作。

下載數據

在使用之前,我們需要下載相關數據。

在使用Google Open Images(或任何外部數據集)時,下載數據是核心挑戰。沒有簡單的方法來下載數據的子集。我們需要編寫一個腳本來為我們實現這份工作。

我寫了一個Python腳本,用於在Open Images數據集中搜索你指定的關鍵字的元數據。它找到相應圖像(在Flickr上)的原始URL,然後將它們下載到磁碟。

這也證明了Python的強大能力,只需50行的代碼,即可完成所有這些工作:

有關代碼的注釋和使用說明,請參閱在原文的GitHub存儲庫。

該腳本可以下載原始圖像的子集,其中包含我們選擇類別的任意子集的邊界框信息:

類別以分層的方式組織。

例如,三明治和漢堡都是食品的子標籤(但漢堡不是三明治的子標籤 )。

我們可以使用 Vega 將實體可視化為徑向樹:

你可以在原文查看此圖表的互動式注釋版本(並下載其代碼)。

在Open Image中,並非所有類別都有與之關聯的邊界框數據。

但是這個腳本可以下載600個標籤的任何子集。這是一種可能的情況:

足球、玩具、鳥、貓、花瓶、吹風機、袋鼠、刀子、公文包、鉛筆盒、網球、釘子、高跟鞋、壽司、摩天大樓、樹、卡車、小提琴、葡萄酒、輪子、鯨魚、披薩刀、麵包、直升機、檸檬、狗、大象、鯊魚、花、傢具、飛機、勺子、凳子、天鵝、花生、照相機、長笛、頭盔、石榴、王冠……

正如本文的目的,我們將限制在兩項上:漢堡包和三明治。

清理,裁剪

一旦我們運行腳本並對把圖像下載到本地,我們就可以使用 matplotlib 檢查它們,看看我們得到了什麼:

來自Google Open Images V4的五個示例圖象。

這些圖像不容易訓練。使用公共網路的外部源構建的數據集擁有的所有問題,它們都會有。

這裡的小樣本示例展示了目標類中可能存在的不同大小、方向和遮擋。

在案例中,我們甚至沒有成功下載實際圖像。相反,我們有一個佔位符告訴我們,我們想要的圖像已被刪除!

下載這些數據會讓我們看到幾千個像這樣的樣本圖像。下一步是利用邊界框信息將我們的圖像剪切成只有三明治-y,漢堡包-y的部分。

下面是另一個圖像數組,這次包含了邊界框,來展示需要什麼內容:

邊界框。注意:(1)數據集包括「描述」(2)原始圖像可以包含許多目標實例。

在GitHub存儲庫中的帶注釋的Jupyter notebook完成了這項工作。

我在這裡不展示代碼,因為它有點複雜。尤其是我們還需要(1)重構我們的圖像元數據以匹配裁剪的圖像輸出,以及(2)提取已經刪除的圖像。如果您想查看代碼,請務必查看notebook。

運行notebook代碼後,我們在磁碟上將會有一個包含所有裁剪圖像的images_cropped文件夾。

構建模型

下載完數據,並且清洗數據之後,就可以準備訓練模型了。

我們將在數據上訓練一個卷積神經網路(CNN)。

CNN是一種特殊類型的神經網路,其在圖像中常見的像素組中一步步構建更高級別的特徵。

然後對這些不同特徵上的圖像分數進行加權以生成最終分類結果。

這種架構非常有效,因為它利用了局部性。這是因為任何一個像素與其附近的像素所擁有的共同點可能遠遠超過遠處的像素。

CNN還具有其他吸引人的特性,如雜訊容限和尺度不變性(在一定程度上)。這進一步改善了它們的分類屬性。

如果你對CNN不熟悉,我建議先看看Brandon Rohrer的「神經網路是怎樣工作的」,以了解它們。

我們將會訓練一個非常簡單的卷積神經網路,來看看在我們的問題上得到的不錯的結果。我使用keras來定義和訓練模型。

我們從將圖片放到特定的路徑結構下開始:

然後,我們使用以下代碼將Keras指向此文件夾:

Keras將檢查輸入文件夾,並確定我們的分類問題中有兩個類。它將根據子文件夾名稱分配類名,並從這些文件夾中創建「圖像生成器」。

但我們不只是返回圖像本身。相反,我們返回經過隨機二次採樣、傾斜和縮放處理後的圖像(通過 train_datagen.flow_from_directory)。

這是一個實際應用中數據增強的例子。

數據增強,是把經過隨機裁剪和扭曲處理的輸入數據集送入圖像分類器。這有助於我們解決小規模數據集。我們可以在單個圖像上多次訓練我們的模型。每次我們以稍微不同的方式進行圖像預處理,並使用一個稍微不同的圖像片段。

在定義了數據輸入後,下一步是定義模型本身:

這是一個簡單的卷積神經網路模型。它只包含三個卷積層:在輸出層之前的單個密集連接的後處理層,強正則化形式的dropout層,和relu激活層。

所有這些因素共同作用,使得這個模型更難過擬合。這一點很重要,因為我們的輸入數據集規模很小。

最後,最後一步實際上是擬合模型。

這個代碼選擇的迭代步數大小,是由我們的圖像樣本大小和所選的批次大小(16)決定的。然後它在該數據上訓練50次迭代。

EarlyStopping 回調可能會提前暫停訓練。如果在前四次迭代內沒有看到驗證分數的提高,則在50次迭代限制之前返回表現最佳的模型。

我們選擇了如此大的 patience 值,因為在模型驗證損失中存在大量的可變性。

這種簡單的訓練方案可以使模型具有約75%的準確度:

有趣的是,我們的模型在對漢堡包(0類)進行分類時缺乏自信,但在對三明治(1類)進行分類時過於自信。

90%被歸類為漢堡包的圖片實際上是漢堡包。但只有59%的漢堡包是正確分類的。

另一方面,只有64%被歸類為三明治的圖像實際上是三明治。但92%的三明治是正確分類的。

Francois Chollet通過將一個非常相似的模型應用於一個同樣大小的經典貓對狗數據集的子集,獲得80%的準確率,我們的實驗結果與這個準確率一致。

這種差異可能主要是由於Google Open Images v4數據集中的遮擋和雜訊級別增加所致。

數據集還包括插圖和攝影圖像。這些有時會帶來巨大的藝術自由,但也使得分類更加困難。您可以在構建模型時選擇刪除它們。

使用遷移學習技術可以進一步提高這種性能。要了解更多信息,請查看Keras作者Francois Chollet的博客文章「使用非常少的數據構建強大的圖像分類模型」。

發布模型

現在我們已經構建了一個自定義數據集並訓練了一個模型,如果我們不共享它,那就太可惜了。

機器學習項目應該是可重複的。我在前一篇文章「用四行代碼復現機器學習模型」中概述了以下策略。

將依賴項分離為數據,代碼和環境三部分。

數據依賴項版本控制(1)模型定義和(2)訓練數據。將這些保存到版本控制的blob存儲,例如帶有Quilt T4的Amazon S3。

代碼依賴項版本控制用於訓練模型的代碼(使用git)。

環境依賴項版本控制用於訓練模型的環境。在生產環境中,這可能是一個docker文件,但您可以在本地使用pip或conda。

為了向別人提供模型的可重新訓練的副本,給他們相應的元組。

遵循這些原則,你就可以把所有需要用來訓練自己的模型的東西,放進幾行代碼里:

要了解有關的更多信息,請參閱原文的GitHub存儲庫或相應的文章。

結論

在本文中,我們演示了端到端圖像分類的機器學習流程。我們介紹了從下載/轉換數據集到訓練模型的所有內容。然後我們以一種允許其他人在以後自行重建它的方式發布它。

由於自定義數據集很難生成和發布,隨著時間的推移,出現了一系列示例數據集,可以在任何地方使用。這不是因為他們真的那麼好(他們不好)。相反,這是因為它們很容易。

例如,谷歌最近發布的機器學習速成課程大量使用加州住房數據集。這些數據現在差不多已有二十年了!

考慮改為探索新的視野。使用來自互聯網的真實圖像進行有趣的分類細分。這與你僅僅想像相比會更加容易!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 AI研習社 的精彩文章:

多圖演示高效的神經架構搜索
機器學習 101:一文帶你讀懂梯度下降

TAG:AI研習社 |