天天看點

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

玩過圖像分類的開發者不少,許多人或許對圖像分割(image segmentation)也不陌生,但圖像注解(image caption)的難度,無疑比前兩者更進一步。

原因無他:利用神經網絡來生成貼合實際的圖像注釋,需要結合最新的計算機視覺和機器翻譯技術,缺一不可。對于為輸入圖像生成文字注解,訓練神經圖像注解模型能使其成功幾率最大化,并能生成新奇的圖像描述。舉個例子,下圖便是在 ms coco 資料集上訓練的神經圖像注解生成器,所輸出的潛在注解。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

左圖注解:一個灰衣男子揮舞棒子,黑衣男子旁觀;右圖注解:一輛大巴車“坐”在一個人旁邊

本文是一篇中級教程,旨在教給大家如何在 flickr30k 資料集上訓練圖像注解生成模型,使用的是谷歌 show and tell 模型的變體。我們使用  tensorflow 架構來建立、訓練、測試模型,因為 tensorflow 相對容易使用,并且有不斷增長的龐大使用者社群。

近來深度學習在 cv(計算機視覺)和 nlp(自然語言處理)領域的成功,激發了 ai 研究人員在這兩者的交叉領域探索新的應用。而作為結果的注解生成模型,需要平衡對視覺線索和自然語言的了解。

這兩門傳統上泾渭分明、并不相關的領域之間所産生的交集,有潛力在業内産生廣泛的影響。該技術有一些直接應用場景,比如為 youtube 視訊生成簡介,又比如為無标簽圖像做注解,但其價值遠不止于此。類似于傳統的 cv 技術試圖讓現實世界變得讓計算機更容易接觸更容易了解,該技術有潛力讓現實世界變得對于我們來說更容易了解。它可以作為我們的導遊、日常生活的視覺輔助,比如意大利 ai 公司 eyra 的為視覺障礙患者開發的可穿戴裝置 horus (古埃及神話中的荷魯斯之眼)。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

首先,你需要安裝 tensorflow。

你還需要下載下傳 flickr30k 資料集的圖像注解和 image embeddings。下載下傳連結也在 github 資源庫裡。

現在教程開始。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

在高層級,這就是我們将要訓練的模型。每一幅圖像将會用深度 cnn 編碼成 4,096 維的矢量表示。一個語言生成 rnn 會随後對其按次序解碼,成為自然語言描述。

作為一個曆史悠久的 cv 任務,圖像分類背後有許多強大模型。圖像分類能把圖像中相關聯的形狀、物體的視覺資訊拼湊到一起,把圖像放入物體類别中。針對其他 cv 任務的機器學習模型,建立在圖像分類的基礎之上,比如物體識别和圖像分割。它們不僅能對提供的資訊進行識别,還能學習如何解讀 2d 空間,調和兩種了解,并決定圖像中物體資訊的位置分布。

對于注釋生成,這引發了兩個問題:

我們如何充分利用圖像分類模型的成功,從圖像提取重要資訊?

我們的模型,該如何調和對語言和圖像的了解?

我們可以利用已有的模型,推動圖像注解。遷移學習使得——在不同任務上訓練神經網絡而學習到的資料變形,能用于我們的資料。在我們的例子中,vgg-16 圖像分類模型導入 224x224 分辨率的圖像,生成對分類圖像非常有用的 4,096 維特征矢量。

我們可以把 vgg-16 模型的表示(即 image embedding)用于訓練其他模型上面。受篇幅限制,本文對 vgg-16 的架構不欲詳述,并預先計算好了 4,096 維特征,來加速訓練。

載入 vgg 圖像特征和圖像注解比較直接:

def get_data(annotation_path, feature_path):    annotations = pd.read_table(annotation_path, sep='\t', header=none, names=['image', 'caption'])    return np.load(feature_path,'r'), annotations['caption'].values

了解注解

有了圖像表示,我們需要模型來學習把它解碼為可了解的注解。由于文本的序列本質,我們需利用 rnn/lstm 中的循環。對于序列中的給定詞語,這些網絡被訓練,用以預測下一個詞語以及圖像表示。

lstm 單元允許模型在注解詞語序列中,更好地選擇使用哪條資訊、記憶什麼、又要忘記什麼。tensorflow 提供了一個 wrapper 函數,來對給定輸入、輸出次元生成 lstm 層。

為了把詞語轉換成适合 lstm 輸入的固定長度表示,我們使用了一個 embedding 層,它能學習把詞語映射到 256 維的特征(或 word-embedding)。word-embedding 幫助我們把詞語表示為矢量,相近的詞語矢量在語義上也是近似的。

在 vgg-16 圖像分類器裡,卷積層提取了 4,096 維表示,傳入最終的 softmax 層進行分類。由于 lstm 單元需要 256 維文本特征作為輸入,我們需要把圖像表示轉譯為針對目标注解的表示。為實作這一點,我們使用了另一個 embedding 層,學習把 4,096 維圖像特征映射到 256 維文本特征的空間。

整體上,這就是谷歌 show and tell 模型看起來的樣子:

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

上圖中, {s0, s1, ..., sn}代表了注解中我們想要預測的詞語, {wes0, wes1, ..., wesn-1} 是每個詞的 word embedding 矢量。lstm 的輸出 {p1, p2, ..., pn} 是模型生成的機率分布,針對句子中的下一個詞。該模型被訓練來最小化每個詞語對數機率(log probabilities )的負數總和。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!
在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

訓練之後,我們有了一個模型。給定圖像和所有此前的詞語,它能給出下一步某個詞出現在注解中的機率。如何用它來生成新注解呢?

最簡單的辦法,是拿來一個輸入圖像,輸出下一個可能性最高的詞語,建立一個簡單的圖像注解。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

這在許多情況下會奏,但“貪婪”地使用每一個機率最大的詞語,未必能獲得整體上機率最大的注解。

繞過這個難題的一個潛在方案,是采用一個名為"beam search"的方法。該算法會對長度 t 以内的 k 個最佳語句集反複考量,作為候選來生成 t + 1 大小的句子,隻保留結果中的 k 個最佳選擇。這允許開發者探索一個較大的優質注解空間,同時讓推理在計算上可追蹤。在下面的例子裡,算法保持了一個 k = 2 的候選句子清單,即每個垂直時間步到每個加粗詞語的路線。

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

對于學習把圖像映射到人類級别的文字注解,該神經圖像注解生成器提供了一個十分有用的架構。銅鼓偶在大量圖像—注解成對資料上訓練,該模型學會了通過視覺特征抓取相關語義資訊。

但對于靜态圖檔而言,嵌入我們的注解生成器,将會聚焦于圖像中對分類有用的特征,而不是對注解生成有用的特征。為提升每個特征裡涵蓋的與任務相關的資訊,我們可以訓練圖像嵌入模型(用來對特征進行編碼的 vgg-16 網絡)作為注解生成模型的一部分。這使得我們能為圖像編碼器調參,以更符合注解生成器的角色。

另外,如果我們仔細觀察生成的注解,會發現它們基本是日常、常見的情形。下圖便是例子:

在玩圖像分類和圖像分割?來挑戰基于 TensorFlow 的圖像注解生成!

幾乎可以肯定,這圖檔是“長頸鹿站在一棵樹旁邊”。但是,如果我們看看其他圖檔,會立刻發現無論對于哪一張生成的注解都是“長頸鹿站在一棵樹旁邊”。這是因為訓練集中的長頸鹿都出現在樹旁邊。

現有的前沿圖像注解模型會包含一個視覺注意力機制(visual attention mechanism),使得模型能發現圖像中感興趣的部分,因而能在生成注解時選擇性地聚焦。

====================================分割線================================

本文作者:三川

繼續閱讀