教 AI 學會看圖說話:Image Caption

教 AI 學會看圖說話:Image Caption

來自專欄 Russell Lab

每個人的小時候,幾乎都有這樣童年記憶:小學生的作文,看圖寫話,總有人腦洞大開,弄出各種啼笑皆非的故事

考場上,我和媽媽姐姐一起把爸爸埋了

事實上,看圖寫話,對於稍微大一點兒的孩子,都不是問題。但對於計算機,卻是一個十分大的問題。

自動描述圖像的內容,是連接計算機視覺和自然語言處理的一個基本問題。這個任務挑戰巨大,但同時,也可產生巨大的影響。例如:幫助視障人士更好地理解 web 上圖像的內容,或是開發各種早教機器。

回顧歷史,這個任務比研究圖像分類或目標識別要困難得多。事實上,描述不僅必須捕獲圖像中包含的對象,而且還必須表示這些對象如何相互關聯,以及它們的屬性和所涉及的活動。此外,以上的語義知識必須用自然語言來表達,這意味著除了視覺理解之外,還需要一種語言模型。

演算法背景

大多數先前的嘗試都建議,將上述子問題的現有解決方案拼接在一起,以便從一個圖像到它的描述。相比之下,2014年,谷歌在該領域的經典論文 Show and Tell: A Neural Image Caption Generator 則在這採用一個聯合模型。將一個圖像I 作為輸入,和經過訓練的最大化可能的 pleft( S | I 
ight)S 是目標的單詞序列)來充分描述圖像。

圖一:Show and Tell: A Neural Image Caption Generator 論文插圖

該工作的主要靈感來自於機器翻譯當時的最新進展——將用源語言編寫的句子 S ,轉換成目標語言中的 T ,通過最大化 p(T|S) ,實現翻譯效果。多年來,機器翻譯也是通過一系列獨立的任務,來完成的(如:翻譯單詞、對齊單詞、重新排序等)。

研究表明:使用遞歸神經網路(RNNs),可以用更簡單的方法進行翻譯,而且還能達到最優異的性能。一個「encoder」RNN 讀取源語句,並將其轉換為一個豐富的固定長度的向量表示,這反過來又被用作,生成目標句子的「decoder」RNN 的初始隱匿狀態。

在圖像描述問題上,他們也採用了此類方案。用一個深卷積神經網路(CNN)代替編碼器RNN 。CNNs 可以通過將輸入圖像嵌入到固定長度的向量中,從而產生豐富的輸入圖像,這種表示可以用於各種視覺任務。因此,使用CNN作為圖像的「encoder」是很自然的。

首先對圖像分類任務進行預處理,並將最後一個隱藏層作為輸入到 RNN 解碼器的輸入,生成句子(如圖一)。這種模型被稱之為 the Neural Image Caption 簡稱 NIC 。

具體的貢獻如下。首先,提出了一個針對這個問題的端到端系統。這是一個利用隨機梯度下降完全可訓練的神經網路。其次,模型結合了視覺和語言模型的子網路。這些可以在較大的語料庫上進行預先訓練,從而可以利用額外的數據。最後,與最先進的方法相比,它的性能顯著提高。例如,在 Pascal 數據集上,NIC 獲得了 59分 的 BLEU 評分,與當前的25分相比,而人的性能達到了 69。在 Flickr30k 數據集上,從 56 到66;在 SBU 數據集上,從19到28。

具體模型

在該文中,提出了一種基於神經網路和概率的框架,來從圖像中生成描述。在統計機器翻譯方面的進展表明,給定一個強大的序列模型,可以通過直接最大化正確翻譯的概率,來達到最好的結果。即以「端到端」的方式輸入句子。

這些模型利用一個遞歸神經網路,將可變長輸入,編碼到一個固定的維度向量中,並利用這個表示來「decode」它到期望的輸出句子。

因此,通過使用以下公式,直接最大化給定圖像的正確描述的概率:

 	heta^*=argmax_{	heta}sum_{(I,S)}log P(S|I;	heta)

模型的參數 	hetaI 是一個圖像, S 表示圖像對應的句子,其長度是無限。因此,將鏈式法則應用於 S_{0 } ,..., S_{N} 的聯合概率是很普遍的。N是這個例子的長度。

log p(S|I)=sum_{t=0}^Nlog p(S_t| I,S_0,...,S_{t-1}) \

為方便,去掉 	heta 。在訓練時, (S, I) 是一個訓練樣本對,我們利用隨機梯度下降法,對整個訓練集所描述的對數概率的和進行優化。

很自然的,對序列 p(St|I, S0,…) 採用遞歸神經網路 (RNN)。在此情況下,我們所處理的變數數量,由一個固定長度的隱藏狀態或記憶 ht 來表示。這個狀態,在輸入 x_t 後,使用一個非線性函數 f 得到:

h_{t+1} = f(h_t,x_t).

為了使上述的 RNN 更加具體,需要做出兩個關鍵的設計選擇: f 的確切形式是什麼,圖像和單詞是如何作為輸入的。對於 f ,我們使用了一個長短時網路(LSTM) ,它在諸如翻譯這樣的序列任務上的表現優異。

圖二:論文中的 LSTM 圖

對於圖像的表示,我們使用卷積神經網路 (CNN)。它們已經被廣泛地用於圖像任務,並且是目前用於目標識別和檢測的一大利器。它們還被證明可以通過遷移學習來推廣到其他任務,如場景分類。

圖三:論文中的整體模型介紹

模型體驗

RussellCloud 為讀者們準備了一份 Image Caption 代碼。該代碼由 pytorch 編寫,經平台工程師驗證,流暢運行,盡享絲滑。

RussellCloud \

操作過程

步驟一:平台準備

  • 搞定一個平台賬號,點我,創建名為ImageCaptioningpytorch-0.2:py2項目。

項目創建

  • 本地打開一個終端,運行:pip install -U russell-cli,安裝客戶端。

客戶端安裝

步驟二:實驗

  • 終端啟動

$ git clone git@github.com:RussellCloud/ImageCaptioning.pytorch.git$ cd ImageCaptioning.pytorch$ russell login# 允許彈出網頁,複製密匙進行認證。$ russell init ImageCaptioning$ russell run "python eval.py --model /input/pretrain/FC/fc-model.pth --infos_path /input/pretrain/FC/fc-infos.pkl --image_folder img --num_images 5" --data 78d1fdddf7074f8c9b647a56f7f1211a:pretrain --data 2e4189afbcb447a39ebc484854a489e8:weights --gpu

通過以上命令,我們導入了以下圖片,進行測試:

測試圖片

模型對上述圖片的結果輸出:

  • 網頁啟動

對於不熟悉終端的朋友,我們還提供了網頁端的啟動形式。

登陸 RussellCloud,進入項目頁,點擊創建任務。

進入創建頁,按需配置。

隨後,就可以在項目的任務記錄處,查看本次任務的情況。

在對應的項目 ID 下,點擊運行日誌,即可獲得本次日誌的輸出。

Russell 參數解讀:

  • russell run RussellCloud 的啟動指令。
  • "python ... num_images 5" 本次的執行命令。
  • --data 數據掛載標誌。
  • 78d1fdddf7...1211a 掛載的數據集 ID。
  • pretrain 掛載文件的別稱。數據集將掛載在 /input/pretrain/路徑下。
  • --data ... --data 多次掛載數據集。本例中掛載了不同來源的兩個數據集。
  • --gpu 使用 GPU 標識。表示本次將使用高性能 GPU。

進階技巧

修改 img 下的文件,即可對模型進行自定義測試。讓機器對你的圖片進行解讀。

高階技巧

查看README_detail.md下的詳細說明,即可進行自定義的訓練、評估,導出自己的模型權重。


參考資料

  • Image Caption | Kaggle
  • Show and Tell: A Neural Image Caption Generator
  • ruotianluo/ImageCaptioning.pytorch

推薦閱讀:

TAG:深度學習DeepLearning | 圖像識別 | 機器學習 |