丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開發(fā)者 正文
發(fā)私信給三川
發(fā)送

0

從原理到實(shí)戰(zhàn) 英偉達(dá)教你用PyTorch搭建RNN(上)

本文作者: 三川 2017-05-05 16:55
導(dǎo)語:動(dòng)態(tài)計(jì)算圖加持,PyTorch 相比 TensorFlow 是否有優(yōu)勢?

從原理到實(shí)戰(zhàn) 英偉達(dá)教你用PyTorch搭建RNN(上)

雷鋒網(wǎng)按:本文原載于英偉達(dá)博客,雷鋒網(wǎng)編譯。

從 Siri 到谷歌翻譯,深度神經(jīng)網(wǎng)絡(luò)大步推動(dòng)了機(jī)器對自然語言的理解。

迄今為止,大多數(shù)模型把語言看作是字詞的平面序列(flat sequence),使用時(shí)間遞歸神經(jīng)網(wǎng)絡(luò)(recurrent neural network)來處理。但語言學(xué)家認(rèn)為,這并不是看待語言的最佳方式,應(yīng)把其理解為由短語組成的的分層樹狀結(jié)構(gòu)( hierarchical tree of phrases)。由于對該類結(jié)構(gòu)的支持,大量深度學(xué)習(xí)研究投入到結(jié)構(gòu)遞歸神經(jīng)網(wǎng)絡(luò)(recursive neural network)之中。在業(yè)內(nèi),這些模型有非常難以執(zhí)行、運(yùn)行起來效率低下的名聲。

但對于今年 Facebook 開源的新深度學(xué)習(xí)框架 PyTorch ,業(yè)內(nèi)人士人認(rèn)為它的一大貢獻(xiàn)是:搭建結(jié)構(gòu)遞歸神經(jīng)網(wǎng)絡(luò)以及其它復(fù)雜自然語言處理模型,變得更簡便。

結(jié)構(gòu)遞歸神經(jīng)網(wǎng)絡(luò),是展示 PyTorch 靈活性的一個(gè)不錯(cuò)的例子。但同時(shí),PyTorch 是一個(gè)對于各類深度學(xué)習(xí)任務(wù)有完備功能的框架,雖然特別適于計(jì)算機(jī)視覺問題。它誕生于 Facebook AI 研究院 FAIR 的研究人員之手,PyTorch 把 Torch7 中高效、靈活的 GPU 加速后端算法庫,和直覺性的 Python 前端結(jié)合到一起,并具有快速創(chuàng)建原型機(jī)的能力、高度可讀性的代碼、以及對于各類深度學(xué)習(xí)模型的支持。

SPINNing Up

本文將帶領(lǐng)大家在 PyTorch 上,實(shí)現(xiàn)一個(gè)有 recurrent tracker 和 TreeLSTM 節(jié)點(diǎn)的結(jié)構(gòu)遞歸神經(jīng)網(wǎng)絡(luò),即 SPINN。對于相當(dāng)多的主流深度學(xué)習(xí)框架,這是一個(gè)很難搭建的自然語言處理模型。這里我描述的實(shí)現(xiàn)部分做了 batch,所以能夠利用 GPU 加速的性能,比不用 batch 的版本要快得多。

SPINN 模型的全稱是“Stack-augmented Parser-Interpreter Neural Network”,它作為一種解決了自然語言推理任務(wù)的方案,隨 Bowman et al. (2016) 論文面世,當(dāng)時(shí)使用的是斯坦福的 SNLI 數(shù)據(jù)集。

這里的任務(wù),是把成對的語句分類為三組類別:假設(shè)第一個(gè)句子是對某幅用戶無法看到的圖像的準(zhǔn)確注解,第二個(gè)句子同樣是對該圖像的注解,那么第二句話到底是 (a) 絕對準(zhǔn)確 (b) 可能準(zhǔn)確還是 (c) 絕對不準(zhǔn)確的?舉個(gè)例子,假設(shè)第一句話是 “two dogs are running through a field”(兩條狗穿過一片農(nóng)田)。那么,讓這組語句“絕對正確”的句子可以是““there are animals outdoors”(戶外有動(dòng)物);讓它們“可能準(zhǔn)確”的,可以是“some puppies are running to catch a stick”(一群幼犬跑著去接一個(gè)木棒);讓它們“絕對不準(zhǔn)確”的可以是 “the pets are sitting on a couch”(寵物們坐在沙發(fā)上)。

導(dǎo)致 SPINN 誕生的研究,為實(shí)現(xiàn)其目標(biāo)要在決定句子之間的關(guān)系之前,把每句話編碼為固定長度的矢量表達(dá)(還有其他方式,比如注意力模型)。

數(shù)據(jù)集包含機(jī)器生成的語法樹( syntactic parse trees),后者把每句話里的詞組合為短語和子句,每一個(gè)都有獨(dú)立涵義,并且有兩個(gè)詞或 sub-phrases 組成。許多語言學(xué)家認(rèn)為,人類理解語言,是通過把涵義以層級(hierarchical)方式組合起來,就像這樣的樹狀結(jié)構(gòu)。因此,創(chuàng)建一個(gè)以同樣方式運(yùn)作的神經(jīng)網(wǎng)絡(luò)或許是必要的。下面的例子是一個(gè)數(shù)據(jù)集里的句子,它的語法樹以括號(hào)結(jié)構(gòu)表示:

  ( ( The church ) ( ( has ( cracks ( in ( the ceiling ) ) ) ) . ) )

用支持語法樹結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)對這個(gè)句子編碼,方法之一是創(chuàng)建一個(gè)神經(jīng)網(wǎng)絡(luò)層 Reduce,把詞組(以 GloVe 這樣的 word embedding 來表示)或短語組合起來,然后將這一層循環(huán)應(yīng)用,把上一個(gè) Reduce 操作的結(jié)果,作為句子的編碼:

X = Reduce(“the”, “ceiling”)
Y = Reduce(“in”, X)
... etc.

但如果,我想讓神經(jīng)網(wǎng)絡(luò)以更“人性化”的方式運(yùn)作呢?能從左到右閱讀,保持語境,同時(shí)使用語法樹把短語組合起來?或者,如果我想要訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò),讓它在看到這句子時(shí),基于讀到的詞語創(chuàng)建它自己的語法樹?這是一個(gè)同樣的語法樹,只是寫出來的方式稍稍有區(qū)別:

  The church ) has cracks in the ceiling ) ) ) ) . ) )

第三種方法,仍然是一回事:

WORDS:  The church   has cracks in the ceiling         .
PARSES: S   S      R S   S      S  S   S       R R R R S R R

我所做的,僅僅是去除括號(hào),用“S” 代表“shift”來標(biāo)記詞語, 并用“R”代表“reduce”替代右括號(hào)?,F(xiàn)在,信息可作為操作堆棧(stack) 和類似堆棧的 buffer 的一系列指令從左讀到右,與上文描述的循環(huán)方式有同樣的結(jié)果:

  1. 將文本導(dǎo)入 buffer。

  2. 從 buffer 的首詞“The” pop 出去,把 push 入棧,這時(shí)“The”應(yīng)該在“church”前面。

  3. Pop 最上面的兩個(gè)堆棧值,應(yīng)用 Reduce,把結(jié)果 push 入棧。

  4. 從 buffer pop 出“has”,push 到入棧,隨后 “cracks”,再“in”,再“the”,再“ceiling”。

  5. 重復(fù)四次:pop 最前面的兩個(gè)堆棧值,應(yīng)用 Reduce,push 結(jié)果。

  6. 從緩存 pop 出“.”再 push 入棧。

  7. 重復(fù)兩次:pop 最前面的兩個(gè)堆棧值,應(yīng)用 Reduce,push 結(jié)果。

  8. Pop 剩下的堆棧值,作為句子編碼返回。

我還想維持語境,照顧到其他信息——句子中系統(tǒng)已讀取的部分,并在句子的之后部分上進(jìn)行 Reduce 操作。所以,我將把兩個(gè)參數(shù)(two-argument)的 Reduce 函數(shù),用三個(gè)參數(shù)的函數(shù)來替代,后者導(dǎo)入左子樹、右子樹短語以及當(dāng)前語境狀態(tài)。該狀態(tài)由第二個(gè)神經(jīng)網(wǎng)絡(luò)層生成——一個(gè)名為 Tracker 的循環(huán)單位。給定現(xiàn)有句子語境狀態(tài),Tracker 在堆棧操作的每一步生成一個(gè)新狀態(tài)(讀取每個(gè)詞語和右括號(hào)之后),buffer 最頂端的 entry b 和堆棧中最頂端的兩個(gè) entries s1、s2:

context[t+1] = Tracker(context[t], b, s1, s2)

可以想象一下用你最喜歡的編程語言寫這些東西:對于需要處理的每個(gè)句子,它會(huì)從 buffer 中加載下一個(gè)詞,運(yùn)行 Tracker,檢查是否要 push 入棧或者進(jìn)行 Reduce,操作后不斷重復(fù),直到整個(gè)句子處理完畢。當(dāng)應(yīng)用在單個(gè)句子上面,這個(gè)過程由大且復(fù)雜的深度神經(jīng)網(wǎng)絡(luò)運(yùn)行,網(wǎng)絡(luò)上的兩個(gè)可訓(xùn)練層一遍遍按照 stack manipulation 規(guī)定的方式執(zhí)行。

但如果你對 TensorFlow、Theano 等傳統(tǒng)深度學(xué)習(xí)框架很熟悉,你就知道執(zhí)行這類動(dòng)態(tài)過程有多么費(fèi)勁。這值得我們花點(diǎn)時(shí)間多想想,為什么它們處理這種任務(wù)力不從心,以及 PyTorch 是否能提供不一樣的東西。

圖理論

從原理到實(shí)戰(zhàn) 英偉達(dá)教你用PyTorch搭建RNN(上)

本質(zhì)上,深度神經(jīng)網(wǎng)路只是有海量參數(shù)的復(fù)雜函數(shù)。深度學(xué)習(xí)的目標(biāo)也僅僅是通過計(jì)算 partial derivatives(梯度)、衡量損失來優(yōu)化這些參數(shù)。如果該函數(shù)以計(jì)算圖結(jié)構(gòu)來表示,反著運(yùn)行能去除計(jì)算梯度的不必要工作。所有現(xiàn)代深度學(xué)習(xí)框架都是基于這一反向傳播概念,作為結(jié)果,每個(gè)框架都需要找到一種方式來表示計(jì)算圖。

大多數(shù)的主流深度學(xué)習(xí)框架,比如 TensorFlow、Theano、Keras 以及 Torch7 的 nngraph 算法庫,它們的計(jì)算圖都是事先創(chuàng)建好的靜態(tài)物體。該圖由看起來像是數(shù)學(xué)表達(dá)的代碼來定義,但它的變量其實(shí)是還沒有賦予任何數(shù)值的占位符(placeholder)。由占位符標(biāo)量組成的圖,編譯為一個(gè)函數(shù),然后重復(fù)在訓(xùn)練數(shù)據(jù) batch 上運(yùn)行,生成輸出和梯度。

這種靜態(tài)計(jì)算圖在 CNN 上的效果很好,后者的結(jié)構(gòu)一般是固定的。但對于許多應(yīng)用,開發(fā)者需要讓神經(jīng)網(wǎng)絡(luò)圖的機(jī)構(gòu)能隨數(shù)據(jù)修改。在自然語言處理中,研究人員通常希望把時(shí)間遞歸神經(jīng)網(wǎng)絡(luò)展開,最好輸入有多少詞,就有多少時(shí)間步(timestep)。上文提到的 SPINN 模型的 stack manipulation,非常倚賴控制流,比如“for”和“if”statement,來定義某個(gè)特定句子的計(jì)算圖結(jié)構(gòu)。在更復(fù)雜的例子里,你也許想要搭建結(jié)構(gòu)取決于子網(wǎng)絡(luò)輸出的模型。

有的想法可以被硬塞進(jìn)靜態(tài)圖系統(tǒng),但不是全部 ,而且?guī)缀蹩偸且愿愕耐该鞫?、看不懂的代碼作為代價(jià)??蚣苄枰o計(jì)算圖添加代表了編程基本指令(loops and conditionals)的特殊節(jié)點(diǎn),用戶需要學(xué)習(xí)、使用這些節(jié)點(diǎn),而不是程序語言中的 “for”和“if” statement。這是因?yàn)槿魏纬绦騿T使用的控制流 statement  均只能使用一次,在創(chuàng)建圖時(shí)寫死(hard coding)一條計(jì)算通道。

比如說,詞語(從初始狀態(tài) h0 開始)中的矢量上,運(yùn)行一個(gè)時(shí)間遞歸神經(jīng)網(wǎng)絡(luò)(rnn_unit)需要 tf.while_loop,一個(gè)特殊的控制流節(jié)點(diǎn)。在 TensorFlow 運(yùn)行時(shí)獲取詞語長度需要一個(gè)額外特殊節(jié)點(diǎn),這是由于代碼運(yùn)行的時(shí)候它只是一個(gè)占位符。

# TensorFlow
# (this code runs once, during model initialization)
# “words” is not a real list (it’s a placeholder variable) so
# I can’t use “l(fā)en”
cond = lambda i, h: i < tf.shape(words)[0]
cell = lambda i, h: rnn_unit(words[i], h)
i = 0
_, h = tf.while_loop(cond, cell, (i, h0))

一個(gè)在根本上與之區(qū)別的方式,是動(dòng)態(tài)計(jì)算圖,這在幾十年前的學(xué)界就已展開研究,又被稱為“define-by-run”。哈佛大學(xué)研發(fā)出來的 Kayak 、autograd,以及研究導(dǎo)向的框架 Chainer and DyNet 都基于動(dòng)態(tài)計(jì)算圖。在這樣的框架中,計(jì)算圖在運(yùn)行時(shí)才被創(chuàng)建出來或重新創(chuàng)建。進(jìn)行前饋通道運(yùn)算的代碼,也為反向傳播創(chuàng)建所需的數(shù)據(jù)結(jié)構(gòu)。該方式生成更直觀的代碼,因?yàn)榭刂屏魇褂脴?biāo)準(zhǔn)的“for”和“if”來寫。修補(bǔ)漏洞也變得更簡單,因?yàn)檫\(yùn)行時(shí)的斷點(diǎn)、堆棧蹤跡(stack trace)讓你直接找到寫的代碼,而不是執(zhí)行引擎里的編譯函數(shù)。同樣變量長度的時(shí)間遞歸神經(jīng)網(wǎng)絡(luò),可用簡單的 Python “for”循環(huán)在動(dòng)態(tài)框架里實(shí)現(xiàn)。

# PyTorch (also works in Chainer)
# (this code runs on every forward pass of the model)
# “words” is a Python list with actual values in it
h = h0
for word in words:
   h = rnn_unit(word, h)

PyTorch  是第一個(gè)在性能、靈活性上媲美靜態(tài)圖框架的 “define-by-run”深度學(xué)習(xí)框架。這使它適合于開發(fā)幾乎所有模型,從標(biāo)準(zhǔn)的卷積網(wǎng)絡(luò)到最離譜的強(qiáng)化學(xué)習(xí)想法。下篇中,我們將一起看看 SPINN 的代碼實(shí)現(xiàn)。

未完待續(xù),請關(guān)注雷鋒網(wǎng)后續(xù)文章。

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知

從原理到實(shí)戰(zhàn) 英偉達(dá)教你用PyTorch搭建RNN(上)

分享:
相關(guān)文章

用愛救世界
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡介
為了您的賬戶安全,請驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說