91精品国产综合久久四虎久久_国产成人午夜高潮毛片_99er视频精品免费观看_2020亚洲熟女在线观看_日本女优人体写真_国内黄色毛片_年轻的老师中文版在线_丰满女邻居做爰_久久久久久精品成人免费图片

用TensorFlow為圖片添加字幕
如何使用TensorFlow來構(gòu)建和訓(xùn)練一個圖片字幕生成器
編者注:讀者請注意,本文相應(yīng)的Python代碼和iPython notebook都在GitHub上,我們邀請你去訪問。

更多內(nèi)容可以參考Strata北京2017的相關(guān)議題

圖片字幕生成模型結(jié)合了近年來計(jì)算機(jī)視覺和機(jī)器翻譯方面的進(jìn)步,通過使用神經(jīng)網(wǎng)絡(luò)來生成現(xiàn)實(shí)圖片的字幕。對于一個給定的輸入圖片,神經(jīng)圖像字幕模型被訓(xùn)練來最大化生成一個字幕的可能性。可以被用來產(chǎn)生新穎的圖像描述。例如,下面是用MS COCO數(shù)據(jù)集訓(xùn)練的一個神經(jīng)圖像字幕生成器所產(chǎn)生的字幕。

image-01-02645f9489ca3cc6d9a89298561a9d0b

圖1. 來源:Paul Puri。圖片來自MS COCO數(shù)據(jù)集

在這篇文章里,我們會介紹一個中級程度的教程,教大家如何使用谷歌的“Show and Tell”模型的一種變形和Flickr30k數(shù)據(jù)集來訓(xùn)練一個圖片字幕生成器。我們使用TensorFlow的框架來構(gòu)建、訓(xùn)練和測試我們的模型,因?yàn)樗鄬θ菀资褂枚乙灿幸粋€日益龐大的在線社區(qū)。

為什么要生成字幕?

近年來在計(jì)算機(jī)視覺和自然語言處理任務(wù)上應(yīng)用深度神經(jīng)網(wǎng)絡(luò)的成功激勵著AI研究人員去探索新的研究機(jī)會,交叉連接這些之前互相獨(dú)立的領(lǐng)域。字幕生成模型就必須去對視覺線索和自然語言的理解進(jìn)行平衡。

這兩個傳統(tǒng)上無關(guān)的領(lǐng)域的交叉有可能在更大的范圍內(nèi)產(chǎn)生變革。這一技術(shù)現(xiàn)在已經(jīng)有一些很直接的應(yīng)用。比如,為YouTube視頻自動生成摘要或是標(biāo)注未標(biāo)記的圖片。而更多的有創(chuàng)造力的應(yīng)用則會大幅度提高一個更廣泛的人群的生活質(zhì)量。與傳統(tǒng)的計(jì)算機(jī)視覺試圖去讓計(jì)算機(jī)能更好地接觸和理解這個世界一樣,這一新技術(shù)具有進(jìn)一步讓這個世界對人類更加可達(dá)與可理解的潛力。它可以是一個導(dǎo)游,甚至可以成為日常生活的一個視覺幫助服務(wù)。比如意大利的AI公司Eyra所開發(fā)的Horus可穿戴設(shè)備所展示的這個場景。

需要一些安裝工作

在我們正式開始前,需要先做一些整理工作。

首先,你需要安裝TensorFlow。如果這是你第一次使用TensorFlow,我們推薦你先看看這篇文章《你好,TensorFlow!從零開始構(gòu)建和訓(xùn)練你的第一個TensorFlow圖

你需要安裝pandas、OpenCV2和Jupyter庫來保證相關(guān)的代碼可以運(yùn)行。不過為了簡化安裝的過程,我們強(qiáng)烈推薦你使用與本文關(guān)聯(lián)的GitHub庫里的這個Docker安裝指南。

你還需要下載Flickr30k圖片文件和圖片字幕數(shù)據(jù)集。我們的GitHub庫里有也提供了下載鏈接。

現(xiàn)在,讓我們開始吧!

圖片字幕生成模型

image-02-946136968ac62fa1138aab6263098455

圖2. 來源:Shannon Shih獲取自加州大學(xué)伯克利分校機(jī)器學(xué)習(xí)組織。馬的圖片來自MS COCO

概括來看,這就是我們將要訓(xùn)練的模型。每張圖片都可以被一個深度卷積神經(jīng)網(wǎng)絡(luò)編碼成一個4096維的向量表示。一個語言生成RNN(循環(huán)神經(jīng)網(wǎng)絡(luò))將會對這個表示按順序解碼,并生成自然語言的描述。

字幕生成是圖像分類的一種擴(kuò)展

作為計(jì)算機(jī)視覺的一個任務(wù),圖片分類有著很長的歷史,且有非常多好的模型。分類需要模型能把圖像里與形狀和物體相關(guān)的視覺信息拼接在一起,然后把這個圖片分入一個類別。其他的計(jì)算機(jī)視覺的機(jī)器學(xué)習(xí)模型,諸如物體檢查圖片分割等,則不僅對呈現(xiàn)的信息進(jìn)行識別,還通過學(xué)習(xí)如何解讀二維的空間,并把這兩種理解融合起來,從而能判斷出圖片里分布的物體信息。對于字幕生成,有兩個主要的問題:

  1. 在獲取圖片里的重要信息時,我們?nèi)绾位趫D像分類模型的成功結(jié)果?
  2. 我們的模型如何能學(xué)習(xí)去融合對于語言的理解和對于圖片的理解?

利用遷移學(xué)習(xí)

我們可以利用已有的模型來幫助實(shí)現(xiàn)圖片生成字幕。遷移學(xué)習(xí)讓我們可以把從其他任務(wù)上訓(xùn)練出來的神經(jīng)網(wǎng)絡(luò)的數(shù)據(jù)變換應(yīng)用到我們自己的數(shù)據(jù)上。在我們的這個場景里,VGG-16圖片分類模型是把224 x224像素的圖片作為輸入,產(chǎn)生4096維度的特征向量表示,用于分類圖片。

我們可以利用這些VGG-16模型生成的表示(也叫做圖向量)來訓(xùn)練我們的模型。限于本文的篇幅,我們省略了VGG-16的架構(gòu),而是直接用已經(jīng)計(jì)算出來的4096維的特征來加快訓(xùn)練的過程。

導(dǎo)入VGG圖片特征和圖片字幕是相當(dāng)?shù)煤唵沃苯樱?/p>

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

理解字幕

現(xiàn)在我們已經(jīng)有了圖片的表示了,還需要我們的模型能學(xué)會把這些表示解碼成能被理解的字幕。因?yàn)槲淖痔焐男蛄刑匦?,我們會利用一個RNN/LSTM網(wǎng)絡(luò)里的循環(huán)特點(diǎn)(想了解更多,請參考這篇“理解LSTM網(wǎng)絡(luò)”)。這些網(wǎng)絡(luò)被訓(xùn)練來預(yù)測在給定的一系列前置詞匯和圖片表示的情況下的下一個詞。

長短期記憶(LSTM)單元能讓這個模型能更好地選擇什么樣的信息可以用于字幕詞匯序列,什么需要記憶,什么信息需要忘掉。TensorFlow提供了一個封裝的功能可以對于給定的輸入和輸出維度生成一個LSTM層。

為了把詞匯能變化成適合LSTM的固定長度表示的輸入,我們使用一個向量層來把詞匯映射成256維的特征(也叫詞向量)。詞向量幫助我們把詞匯表示成向量,同時相似的詞向量在語義上也相似。想了解更多關(guān)于詞向量如何獲取不同詞匯之間的關(guān)系,請看這篇《用深度學(xué)習(xí)來獲取文本語義》。

在這個VGG-16圖片分類器里,卷積層抽取出了4096維表示,然后送入最后的softmax層來做分類。因?yàn)長STM單元需要的是256維的文本輸入,我們需要把圖片表示轉(zhuǎn)化成目標(biāo)字幕所需的這種表示。為了實(shí)現(xiàn)這個目標(biāo),我們需要加入另外一個向量層來學(xué)習(xí)把4096維的圖片特征映射成256維的文本特征空間。

構(gòu)建和訓(xùn)練這個模型

全合在一起,Show and Tell模型就大概像這個樣子:

image-03-65bc895a46de9bfcd5131103c1918cad

圖3. 來源《Show and Tell:2015 MSCOCO圖片字幕大賽所獲得的經(jīng)驗(yàn)教訓(xùn)》

圖3中,{s0,?s1, …,?sN}表示我們試著去預(yù)測的字幕詞匯,{wes0,?wes1,?…,?wesN-1}是每個詞的詞向量。LSTM的輸出{p1,?p2, …,?pN}是這個模型產(chǎn)生的句子里下一個詞的概率分布。模型的訓(xùn)練目標(biāo)是最小化對所有的詞概率取對數(shù)后求和的負(fù)值。

def build_model(self):

# declaring the placeholders for our extracted image feature vectors, our caption, and our mask

# (describes how long our caption is with an array of 0/1 values of length `maxlen`

img = tf.placeholder(tf.float32, [self.batch_size, self.dim_in])

caption_placeholder = tf.placeholder(tf.int32, [self.batch_size, self.n_lstm_steps])

mask = tf.placeholder(tf.float32, [self.batch_size, self.n_lstm_steps])

 

# getting an initial LSTM embedding from our image_imbedding

image_embedding = tf.matmul(img, self.img_embedding) + self.img_embedding_bias

 

# setting initial state of our LSTM

state = self.lstm.zero_state(self.batch_size, dtype=tf.float32)

total_ loss = 0.0

with tf.variable_scope(“RNN”):

for i in range(self.n_lstm_steps):

if i > 0:

#if this isn’t the first iteration of our LSTM we need to get the word_embedding corresponding

# to the (i-1)th word in our caption

with tf.device(“/cpu:0”):

current_embedding = tf.nn.embedding_lookup(self.word_embedding, caption_placeholder[:,i-1]) + self.embedding_bias

else:

#if this is the first iteration of our LSTM we utilize the embedded image as our input

current_embedding = image_embedding

if i > 0:

# allows us to reuse the LSTM tensor variable on each iteration

tf.get_variable_scope().reuse_variables()

out, state = self.lstm(current_embedding, state)

print (out,self.word_encoding,self.word_encoding_bias)

 

if i > 0:

#get the one-hot representation of the next word in our caption

labels = tf.expand_dims(caption_placeholder[:, i], 1)

ix_range=tf.range(0, self.batch_size, 1)

ixs = tf.expand_dims(ix_range, 1)

concat = tf.concat([ixs, labels],1)

onehot = tf.sparse_to_dense(

concat, tf.stack([self.batch_size, self.n_words]), 1.0, 0.0)

#perform a softmax classification to generate the next word in the caption

logit = tf.matmul(out, self.word_encoding) + self.word_encoding_bias

xentropy = tf.nn.softmax_cross_entropy_with_logits(logits=logit, labels=onehot)

xentropy = xentropy * mask[:,i]

loss = tf.reduce_sum(xentropy)

total_loss += loss

total_loss = total_loss / tf.reduce_sum(mask[:,1:])

return total_loss, img,? caption_placeholder, mask

使用推斷來生成字幕

完成訓(xùn)練后,我們就獲得了一個在給定圖片和所有的前置詞匯的前提下,可以給出字幕里下一個詞概率的模型。那么我們怎么用這個模型來生成字幕?

最簡單的方法就是把一張圖片作為輸入,循環(huán)輸出下一個概率最大的詞,由此生成一個字幕。

def build_generator(self, maxlen, batchsize=1):

#same setup as `build_model` function

img = tf.placeholder(tf.float32, [self.batch_size, self.dim_in])

image_embedding = tf.matmul(img, self.img_embedding) + self.img_embedding_bias

state = self.lstm.zero_state(batchsize,dtype=tf.float32)

#declare list to hold the words of our generated captions

all_words = []

print (state,image_embedding,img)

with tf.variable_scope(“RNN”):

# in the first iteration we have no previous word, so we directly pass in the image embedding

# and set the `previous_word` to the embedding of the start token ([0]) for the future iterations

output, state = self.lstm(image_embedding, state)

previous_word = tf.nn.embedding_lookup(self.word_embedding, [0]) + self.embedding_bias

for i in range(maxlen):

tf.get_variable_scope().reuse_variables()

out, state = self.lstm(previous_word, state)

# get a one-hot word encoding from the output of the LSTM

logit = tf.matmul(out, self.word_encoding) + self.word_encoding_bias

best_word = tf.argmax(logit, 1)

with tf.device(“/cpu:0”):

# get the embedding of the best_word to use as input to the next iteration of our LSTM

previous_word = tf.nn.embedding_lookup(self.word_embedding, best_word)

previous_word += self.embedding_bias

all_words.append(best_word)

return img, all_words

很多情況下,這個方法都能用。但是“貪婪”地使用下一個概率最大的詞可能并不能產(chǎn)生總體上最合適的字幕。

規(guī)避這個問題的一個可行的方法就是“束搜索(Beam Search)”。這個算法通過遞歸的方法在最多長度為t的句子里尋找k個最好的候選者來生成長度為t+1的句子,且每次循環(huán)都僅僅保留最好的那k個結(jié)果。這樣就可以去探索一個更大的最佳的字幕空間,同時還能讓推斷在可控的計(jì)算規(guī)模內(nèi)。在下圖的例子里,算法維護(hù)了在每個垂直時間步驟里的一系列k=2的候選句子(用粗體字表示)。

image-04-b22aa68369e1353eeb9e038debf13547

圖4 來源:Daniel Ricciardelli

局限和討論

神經(jīng)圖片字幕生成器給出了一個有用的框架,能學(xué)習(xí)從圖片到人能理解的圖片字幕間的映射。通過訓(xùn)練大量的圖片-字幕對,這個模型學(xué)會提取從視覺特征到相關(guān)語義信息的關(guān)系。

但是,對于一個靜態(tài)圖片,我們的字幕生成器是關(guān)注圖片里有利于分類的特征,而這并不一定是有利于字幕生成的特征。為了改進(jìn)每個特征里與字幕相關(guān)的信息量,我們可以把這個圖片向量模型(這個用來編碼特征的VGG-16模型)作為整個字幕生成模型的一部分。這就可以讓我們能更精細(xì)地調(diào)優(yōu)圖片編碼器來更好地承擔(dān)字幕生成的角色。

而且,如果我們?nèi)プ屑?xì)地觀察生成的字幕,就會發(fā)現(xiàn)它們其實(shí)相當(dāng)?shù)哪:c普通化。用下面這個圖片-字幕對為例:

image-05-af8ab207e1291331af004f7c73db1eae

圖5. 來源:Raul Puri,圖片來自MS COCO數(shù)據(jù)集

這個圖片當(dāng)然是“長頸鹿站立在樹旁邊”。但是如果看看其他的圖片,我們就可能注意到它會對于任何有長頸鹿的圖片都生成“長頸鹿站立在樹旁邊”,因?yàn)樵谟?xùn)練集里,長頸鹿通常都出現(xiàn)在樹的附近。

下一步工作

首先,如果你想改進(jìn)這里介紹的模型,請閱讀以下谷歌的開源“Show and Tell網(wǎng)絡(luò)”。它可以用Inception-v3圖片向量和MS COCO數(shù)據(jù)集來訓(xùn)練。

目前最前沿的圖片字幕模型包含了一個視覺注意力機(jī)制??梢宰屇P驮谏a(chǎn)字幕時,發(fā)現(xiàn)圖片里的引起興趣的區(qū)域來有選擇地關(guān)注圖片內(nèi)容。

同時,如果你有對最前沿的字幕生成器的實(shí)現(xiàn)感興趣,請閱讀這個論文《展示、關(guān)注和說出:使用視覺注意力的神經(jīng)圖片字幕生成

注意:別忘了訪問GitHub上與這篇文章對應(yīng)的Python代碼和iPython notebook

這篇博文是O’Reilly和TensorFlow的合作產(chǎn)物。請閱讀我們的編輯獨(dú)立聲明。

Raul Puri

Paul Puri是加州大學(xué)伯克利分校CO 2017屆畢業(yè)的本科生研究人員。Raul已經(jīng)對多個領(lǐng)域的研究項(xiàng)目做出了貢獻(xiàn),包括但不限于:機(jī)器人和自動化、計(jì)算機(jī)視覺、醫(yī)療成圖、生物記憶設(shè)備等。不過所有這些研究工作都專注于機(jī)器學(xué)習(xí)和機(jī)器學(xué)習(xí)系統(tǒng)在安全、自主駕駛、自然語言處理、計(jì)算機(jī)視覺和機(jī)器人里面的應(yīng)用。Raul也非常熱情于通過教授應(yīng)用機(jī)器學(xué)習(xí)概念課程來回饋社會。他還是多門伯克利分校機(jī)器學(xué)習(xí)課程的助教和講師。

Daniel Ricciardelli

Dan Ricciardelli是加州大學(xué)伯克利分校的一名本科生研究員。他的研究方向包括用于金融和工業(yè)的自然語言處理、計(jì)算機(jī)視覺、深度主動學(xué)習(xí)和自動知識發(fā)現(xiàn)。Dan在伯克利機(jī)器學(xué)習(xí)組織里非常熱心于讓機(jī)器學(xué)習(xí)能為技術(shù)及非技術(shù)學(xué)生和專業(yè)人員所接觸。

The image caption generation model. (source: Shannon Shih from Machine Learning at Berkeley. Horse Image sourced from MS COCO.)