當前位置:
首頁 > 知識 > 如何用 Python 和深度神經網路尋找近似圖片?

如何用 Python 和深度神經網路尋找近似圖片?

本文作者 王樹義,本文首發於知乎專欄【玉樹芝蘭】,AI 研習社獲其授權轉載。

給你 10 萬張圖片,讓你找出與其中某張圖片最為近似的 10 張,你會怎麼做?不要輕言放棄,也不用一張張瀏覽。使用 Python,你也可以輕鬆搞定這個任務。


疑問

《如何用 Python 和深度神經網路識別圖像?》一文寫完後,我收到了不少讀者的反饋。其中一個很普遍的疑問是:

識別相同或相似的圖像,有什麼好的方法么?

我雖然樂於幫助讀者解決問題,但實話實說,一開始不太理解這種需求。

我文章里的樣例圖片(哆啦 a 夢和瓦力),都是從網路搜集來的。如果你需要從網上找到跟某張圖片近似的圖像,可以使用 Google 的 「以圖搜圖」 功能啊。

很快,我突然醒悟過來。

這種需求,往往不是為了從互聯網上大海撈針,尋找近似圖片。而是在一個私有海量圖片集合中,找到近似圖像。

這種圖片集合,也許是你團隊的科研數據。例如你研究鳥類。某天瀏覽野外拍攝設備傳回來的圖像時,突然發現一個新奇品種。

你於是很想搞清楚這種鳥類的出現時間、生活狀態等。這就需要從大量圖片里,找到與其近似的圖片(最有可能是拍到了同一種鳥)。

這種圖片集合,也許是社會安全數據。例如你在反恐部門,系統突然發現某個疑似恐怖分子出現在敏感區域。這傢伙每一次現身,都伴隨著惡性刑事案件的發生,給人民群眾的生命財產安全帶來嚴重威脅。

這時候無論對其衣著、外貌還是交通工具的相似度搜索,就顯得至關重要了。

上述例子中,因為你都沒有把圖像上傳到互聯網,Google 的 「以圖搜圖」 引擎功能再強大,也無能為力。

好吧,解決這個問題,很有意義。

下一個問題自然是:這種需求,解決起來複雜嗎?

是不是需要跨過很高的技術門檻才能實現?是不是需要花大量經費僱傭專家才能完成?

本文,我為你展示如何用 10 幾行 Python 代碼,解決這個問題。


數據

為了講解的方便,我們依然採用《如何用 Python 和深度神經網路識別圖像?》一文中使用過的哆啦 a 夢和瓦力圖片集合。

我給你準備好了 119 張哆啦 a 夢的照片,和 80 張瓦力的照片。圖片已經上傳到了Github 項目http://t.cn/RQjqfdo。

請點擊http://t.cn/RQjq8al,下載壓縮包。然後在本地解壓。作為咱們的演示目錄

解壓後,你會看到目錄下有個 image 文件夾,其中包含兩個子目錄,分別是 doraemon 和 walle。

doraemon 的目錄下,都是各式各樣的藍胖子圖片。

瓦力目錄下的圖片是這個樣子的:

數據已經有了,下面我們來準備一下環境配置。


環境

本文中,我們需要使用到蘋果公司的機器學習框架 TuriCreate。

請注意 TuriCreate 發布時間不久,目前支持的操作系統列表如下:

這就意味著,如果你用的操作系統是 Windows 7 及以下版本,那麼目前 TuriCreate 還不支持。如需使用,有兩種辦法:

第一種,請升級到 Windows 10,並且使用 WSL。關於如何使用 WSL,我幫你找到了一個中文教程(http://t.cn/RQj5cA8)。請按照教程一步步完成安裝。

第二種,採用虛擬機。推薦採用 Virtualbox 虛擬機,開源免費。同樣地,我也幫你找到了很詳盡的 Virtualbox 安裝 Ubuntu Linux 的中文教程。你可以參照它安裝好 Linux。

解決了系統兼容性問題,下面我們在 TuriCreate 支持的系統中,安裝 Python 集成運行環境 Anaconda。

請到https://www.anaconda.com/download/下載最新版的 Anaconda。下拉頁面,找到下載位置。根據你目前使用的系統,網站會自動推薦給你適合的版本下載。我使用的是 macOS,下載文件格式為 pkg。

下載頁面區左側是 Python 3.6 版,右側是 2.7 版。請選擇 2.7 版本。

雙擊下載後的 pkg 文件,根據中文提示一步步安裝即可。

裝好 Anaconda 後,我們安裝 TuriCreate。

請到你的 「終端」 下面,進入咱們剛剛下載解壓後的樣例目錄。

執行以下命令,我們來創建一個 Anaconda 虛擬環境,名字叫做 turi。如果你之前跟隨我在《如何用 Python 和深度神經網路識別圖像?》一文中創立過這個虛擬環境,此處請跳過。

然後,我們激活 turi 虛擬環境。

在這個環境中,我們安裝(或者升級到)最新版的 TuriCreate。

安裝完畢後,執行:

這樣就進入到了 Jupyter 筆記本環境。我們新建一個 Python 2 筆記本。

瀏覽器里出現了一個空白筆記本。

點擊左上角筆記本名稱,修改為有意義的筆記本名 「demo-python-image-similarity」。

準備工作完畢,下面我們就可以開始編寫程序了。


代碼

首先,我們讀入 TuriCreate 軟體包。

我們指定圖像所在的文件夾 image。讓 TuriCreate 讀取所有的圖像文件,並且存儲到 data 數據框。

我們來看看,data 數據框的內容:

data 包含兩列信息,第一列是圖片的地址,第二列是圖片的長寬描述。

下面我們要求 TuriCreate 給數據框中每一行添加一個行號。這將作為圖片的標記,好在後面查找圖片時使用。

再看看此時的 data 數據框內容:

我們來看看數據框裡面的這些信息對應的圖片。

TuriCreate 會彈出一個頁面,給我們展示數據框裡面的內容。

把滑鼠懸停在某張縮略圖上面,就可以看到對應清晰大圖。

第一張圖片,是哆啦 a 夢:

第二張圖片,是瓦力:

下面,是重頭戲。我們讓 TuriCreate 根據輸入的圖片集合,建立圖像相似度判別模型。

這個語句執行起來,可能需要一些時間。如果你是第一次使用 TuriCreate,它可能還需要從網上下載一些數據。請耐心等待。

注意這裡的提示,TuriCreate 自動幫我們做了圖片尺寸調整等預處理工作,並且對每一張圖片,都做了特徵提取。

經過或長或短的等待,模型已經成功建立。

下面,我們來嘗試給模型一張圖片,讓 TuriCreate 幫我們從目前的圖片集合里,挑出最為相似的 10 張來。

為了方便,我們就選擇第一張圖片作為查詢輸入。

我們利用函數展示一下這張圖片。

確認無誤,還是那張哆啦 a 夢。

下面我們來查詢,我們讓模型尋找出與這張圖片最相似的 10 張。

很快,系統提示我們,已經找到了。

我們把結果存儲在了變數裡面,下面我們來看看其中都有哪些圖片。

返回的結果一共有 10 行。跟我們的要求一致。

每一行數據,包含 4 列。分別是:

查詢圖片的標記

獲得結果的標記

結果圖片與查詢圖片的距離

結果圖片與查詢圖片近似程度排序值

有了這些信息,我們就可以查看到底哪些圖片與輸入查詢圖片最為相似了。

注意其中的第一張結果圖片,其實就是我們的輸入圖片本身。考慮它沒有意義。

我們提取全部結果圖片的標記(索引)值,忽略掉第一張(自身)。

剩餘 9 張圖片的標記都在結果中:

下面我們希望 TuriCreate 能夠可視化幫我們展示這 9 張圖片的內容。

我們要把上面 9 張圖片的標記在所有圖片的索引列表中過濾出來:

看看過濾後的索引結果:

你可以自己數一數,其中標為 1 的那些圖片位置,和我們存儲在中的數字是否一致。

驗證完畢以後,請執行以下語句。我們再次調用 TuriCreate 的函數,展現相似度查詢結果圖片。

系統會彈出以下對話框:

我們可以看到,全部查詢結果圖片中,只出現了哆啦 a 夢。瓦力的圖片,一張都沒有出現。

近似圖片查找成功!

隨著本文操作樣例數據後,你不妨換用自己的數據,來動手嘗試一番。


原理

展示了如何用 10 幾行 Python 代碼幫你查找相似圖形後,我們來聊聊這種強大、簡潔背後的原理。

如果你對原理不感興趣,請跳過這一部分,看 「小結」。

雖然我們剛剛只是用了一條語句構建模型:

然而實際上,TuriCreate 在後台為我們做了很多事情。

首先,它調用了一個非常複雜的,在龐大數據集上訓練好的模型。

《如何用 Python 和深度神經網路識別圖像?》一文中,我們介紹過,這個模型就是上圖中的最後一行。它的名字叫做 Resnet-50,足足有 50 層,訓練的圖片數以百萬計,訓練時長也很久。

這裡,機智的你一定會問個問題:那些數以百萬計的預訓練圖片裡面,是否有哆啦 a 夢和瓦力呢?

沒有。

那就怪了,不是嗎?

如果這個複雜的模型之前根本就沒有見過哆啦 a 夢和瓦力,那它怎麼知道如何區分它們呢?又怎麼能夠判別兩張哆啦 a 夢之間的差別,就一定比哆啦 a 夢和瓦力之間更小呢?

《如何用 Python 和深度神經網路識別圖像?》一文里,我已經提示給你一個關鍵詞:遷移學習(transfer learning)。

這裡咱們就不深入技術細節了。我只給你在概念層次講解一下。

還記得這張描述計算機視覺(卷積神經網路)的示意圖嗎?

在全連接層(Fully Connected Layer)之前,你可能進行了多次的卷積、抽樣、卷積、抽樣…… 這些中間層次,幫我們描繪了圖片的一些基本特徵,例如邊緣大概是個什麼形狀,某個區塊主要的顏色是哪些等。

到了全連接層,你只剩下了一組數據,這組數據可能很長,它抽取了你輸入數據的全部特徵。

如果你的輸入是一隻貓,此時的全連接層里就描述了這隻貓的各種信息,例如毛髮顏色、面部組成部分排列方式、邊緣的形狀……

這個模型可以幫你提取貓的特徵,但它並不知道 「貓」 的概念是什麼。

你自然可以用它幫你提取一條狗的特徵。

同理,哆啦 a 夢的照片,與貓咪的照片一樣,都是二維圖片,都是用不同顏色分層。

那用其他圖片訓練的模型,能否提取哆啦 a 夢照片里的特徵呢?

當然也可以!

使用遷移學習的關鍵,在於凍結中間過程的全部訓練結果,直接把一幅圖,利用在其他圖片集合上訓練的模型,轉化為一個特徵描述結果。

後面的工作,只把這個最後的特徵描述(全連接層),用來處理分類和相似度計算。

前面的好幾十層參數迭代訓練,統統都被省卻了。

難怪可以利用這麼小的數據集獲得如此高的準確度;也難怪可以在這麼短的時間裡,就獲得整合後的模型結果。

把在某種任務上積累下的經驗與認知,遷移到另一種近似的新任務上,這種能力就叫做遷移學習。

比起機器來,人的遷移學習能力更為強大。

雨果獎作者郝景芳在最近的一篇文章里,描述了人的這種強大學習能力:

小孩子可以快速學習,進行小數據學習,而且可以得到「類」的概念。小孩子輕易分得清「鴨子」這個概念,和每一隻具體不同的鴨子,有什麼不同。前者是抽象的「類」,後者是具體的東西。小孩子不需要看多少張鴨子的照片,就能得到「鴨子」這個抽象「類」的概念。

用成語來描述,大概就是 「觸類旁通」 吧。

如果人類不善於遷移學習,把生活中的所有事物,全都當成新的東西從頭學起,那後果簡直不堪設想。對比我們一生中所能處理的信息總量,這種認知負荷將是無法承受的。

回到我們的問題里,如果模型可以幫我們把每一張圖片,都變成全連接層上的那一長串數字(特徵),那麼我們分辨這些圖片的相似程度,就變得太簡單了。因為這變成了一個簡單的空間向量距離問題。

處理這種簡單的數值計算,我們人類可能覺得很繁瑣。但是計算機算起來,那就很歡快了。

根據距離大小排序,找出其中最小的幾個向量,它們描述的圖片,就被模型判定為相似度最高的。


小結

在《如何用 Python 和深度神經網路識別圖像?》一文的基礎上,本文進一步介紹了以下內容:

如何利用 TuriCreate 快速構建圖片相似度模型;

如何查詢與某張圖片最為相似的 k 張圖片;

如何可視化展示查詢圖片集合結果;

TuriCreate 圖形分類與相似度計算背後的原理;

遷移學習的基礎概念。

如果你沒有讀過《如何用 Python 和深度神經網路識別圖像?》,強烈建議你讀一讀。閱讀過程可以幫助你更好地理解基於深度神經網路的計算機視覺工作原理。


討論

你之前遭遇過大海撈針,尋找近似圖片的工作嗎?你是如何處理的?使用過哪些好的工具與方法?與本文相比較,它們的優勢有哪些?歡迎留言,把你的經驗和思考分享給大家,我們一起交流討論。

如果本文可能對你身邊的親友有幫助,也歡迎你把本文通過微博或朋友圈分享給他們。讓他們一起參與到我們的討論中來。

NLP工程師入門實踐班:基於深度學習的自然語言處理

三大模塊,五大應用,手把手快速入門NLP

海外博士講師,豐富項目經驗

演算法+實踐,搭配典型行業應用

隨到隨學,專業社群,講師在線答疑

新人福利

關注 AI 研習社(okweiwu),回復1領取

【超過 1000G 神經網路 / AI / 大數據,教程,論文】

如何用 Python 和深度神經網路識別圖像?


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

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


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

第 14 彈:斯坦福Serena Yeung教你深度增強學習

TAG:AI研習社 |