成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

揭開(kāi)迷霧,來(lái)一頓美味的「Capsule」盛宴 | 附代碼實(shí)現(xiàn) + 全新實(shí)驗(yàn)

NSFish / 1736人閱讀

摘要:本文試圖揭開(kāi)讓人迷惘的云霧,領(lǐng)悟背后的原理和魅力,品嘗這一頓盛宴。當(dāng)然,激活函數(shù)本身很簡(jiǎn)單,比如一個(gè)激活的全連接層,用寫(xiě)起來(lái)就是可是,如果我想用的反函數(shù)來(lái)激活呢也就是說(shuō),你得給我解出,然后再用它來(lái)做激活函數(shù)。

由深度學(xué)習(xí)先驅(qū) Hinton 開(kāi)源的 Capsule 論文 Dynamic Routing Between Capsules,無(wú)疑是去年深度學(xué)習(xí)界最熱點(diǎn)的消息之一。

得益于各種媒體的各種吹捧,Capsule 被冠以了各種神秘的色彩,諸如“拋棄了梯度下降”、“推倒深度學(xué)習(xí)重來(lái)”等字眼層出不窮,但也有人覺(jué)得 Capsule 不外乎是一個(gè)新的炒作概念。?

本文試圖揭開(kāi)讓人迷惘的云霧,領(lǐng)悟 Capsule 背后的原理和魅力,品嘗這一頓 Capsule 盛宴。同時(shí),筆者補(bǔ)做了一個(gè)自己設(shè)計(jì)的實(shí)驗(yàn),這個(gè)實(shí)驗(yàn)?zāi)鼙仍撐牡膶?shí)驗(yàn)更有力說(shuō)明 Capsule 的確產(chǎn)生效果了。

菜譜一覽:

Capsule 是什么?

Capsule 為什么要這樣做?

Capsule 真的好嗎?

我覺(jué)得 Capsule 怎樣?

若干小菜

前言

Capsule 的論文已經(jīng)放出幾個(gè)月了,網(wǎng)上已經(jīng)有很多大佬進(jìn)行解讀,也有大佬開(kāi)源實(shí)現(xiàn)了 CapsuleNet,這些內(nèi)容都加速了我對(duì) Capsule 的理解。然而,我覺(jué)得美中不足的是,網(wǎng)上多數(shù)的解讀,都只是在論文的翻譯上粉飾了一點(diǎn)文字,并沒(méi)有對(duì) Capsule 的原理進(jìn)行解讀。

比如“動(dòng)態(tài)路由”那部分,基本上就是照搬論文的算法,然后說(shuō)一下迭代3次就收斂了。但收斂出什么來(lái)?論文沒(méi)有說(shuō),解讀也沒(méi)有說(shuō),這顯然是不能讓人滿意的。也難怪知乎上有讀者評(píng)論說(shuō):

所謂的 Capsule 為 DL 又貢獻(xiàn)了一個(gè)花里胡哨的 trick 概念。說(shuō)它是 trick,因?yàn)?Hinton 沒(méi)有說(shuō)為什么 routing 算法為什么需要那么幾步,循環(huán)套著循環(huán),有什么理論依據(jù)嗎?還是就是湊出來(lái)的?

這個(gè)評(píng)論雖然過(guò)激,然而也是很中肯的:憑啥 Hinton 擺出來(lái)一套算法又不解釋,我們就要稀里糊涂的跟著玩?

Capsule 盛宴

宴會(huì)特色?

這次 Capsule 盛宴的特色是“vector in vector out”,取代了以往的“scaler in scaler out”,也就是神經(jīng)元的輸入輸出都變成了向量,從而算是對(duì)神經(jīng)網(wǎng)絡(luò)理論的一次革命。

然而真的是這樣子嗎?難道我們以往就沒(méi)有做過(guò)“vector in vector out”的任務(wù)了嗎?

有,而且多的是!NLP 中,一個(gè)詞向量序列的輸入,不就可以看成“vector in”了嗎?這個(gè)詞向量序列經(jīng)過(guò) RNN/CNN/Attention 的編碼,輸出一個(gè)新序列,不就是“vector out”了嗎?

在目前的深度學(xué)習(xí)中,從來(lái)不缺乏“vector in vector out”的案例,因此顯然這不能算是 Capsule 的革命。?

Capsule 的革命在于:它提出了一種新的“vector in vector out”的傳遞方案,并且這種方案在很大程度上是可解釋的。?

如果問(wèn)深度學(xué)習(xí)(神經(jīng)網(wǎng)絡(luò))為什么有效,我一般會(huì)這樣回答:神經(jīng)網(wǎng)絡(luò)通過(guò)層層疊加完成了對(duì)輸入的層層抽象,這個(gè)過(guò)程某種程度上模擬了人的層次分類做法,從而完成對(duì)最終目標(biāo)的輸出,并且具有比較好的泛化能力。

的確,神經(jīng)網(wǎng)絡(luò)應(yīng)該是這樣做的,然而它并不能告訴我們它確確實(shí)實(shí)是這樣做的,這就是神經(jīng)網(wǎng)絡(luò)的難解釋性,也就是很多人會(huì)將深度學(xué)習(xí)視為黑箱的原因之一。?

讓我們來(lái)看 Hinton 是怎么來(lái)通過(guò) Capsule 突破這一點(diǎn)的。

大盆菜

如果要用一道菜來(lái)比喻 Capsule,我想到了“大盆菜”:

盆菜作為客家菜的菜式出現(xiàn)由來(lái)以久,一般也稱為大盤(pán)菜,大盤(pán)菜源于客家人傳統(tǒng)的“發(fā)財(cái)大盤(pán)菜”,顧名思義就是用一個(gè)大大的盤(pán)子,將食物都放到里面,融匯出一種特有滋味。豐富的材料一層層疊進(jìn)大盤(pán)之中,最易吸收肴汁的材料通常放在下面。吃的時(shí)候每桌一盤(pán),一層一層吃下去,汁液交融,味道馥郁而香濃,令人大有漸入佳景之快。

Capsule 就是針對(duì)著這個(gè)“層層遞進(jìn)”的目標(biāo)來(lái)設(shè)計(jì)的,但坦白說(shuō),Capsule 論文的文筆真的不敢恭維,因此本文盡量不與論文中的符號(hào)相同,以免讀者再次云里霧里。讓我們來(lái)看個(gè)圖。

如圖所示,底層的膠囊和高層的膠囊構(gòu)成一些連接關(guān)系。等等,什么是“膠囊”?其實(shí),只要把一個(gè)向量當(dāng)作一個(gè)整體來(lái)看,它就是一個(gè)“膠囊”,是的,你沒(méi)看錯(cuò),你可以這樣理解:神經(jīng)元就是標(biāo)量,膠囊就是向量,就這么粗暴。

Hinton 的理解是:每一個(gè)膠囊表示一個(gè)屬性,而膠囊的向量則表示這個(gè)屬性的“標(biāo)架”。

也就是說(shuō),我們以前只是用一個(gè)標(biāo)量表示有沒(méi)有這個(gè)特征(比如有沒(méi)有羽毛),現(xiàn)在我們用一個(gè)向量來(lái)表示,不僅僅表示有沒(méi)有,還表示“有什么樣的”(比如有什么顏色、什么紋理的羽毛),如果這樣理解,就是說(shuō)在對(duì)單個(gè)特征的表達(dá)上更豐富了。?

說(shuō)到這里,我感覺(jué)有點(diǎn)像 NLP 中的詞向量,以前我們只是用 one hot 來(lái)表示一個(gè)詞,也就是表示有沒(méi)有這個(gè)詞而已?,F(xiàn)在我們用詞向量來(lái)表示一個(gè)詞,顯然詞向量表達(dá)的特征更豐富,不僅可以表示有沒(méi)有,還可以表示哪些詞有相近含義。詞向量就是NLP中的“膠囊”?這個(gè)類比可能有點(diǎn)牽強(qiáng),但我覺(jué)得意思已經(jīng)對(duì)了。?

那么,這些膠囊要怎么運(yùn)算,才能體現(xiàn)出“層層抽象”、“層層分類”的特性呢?讓我們先看其中一部分連接:

圖上只展示了 u1 的連接。這也就是說(shuō),目前已經(jīng)有了 u1 這個(gè)特征(假設(shè)是羽毛),那么我想知道它屬于上層特征 v1,v2,v3,v4(假設(shè)分別代表了雞、鴨、魚(yú)、狗)中的哪一個(gè)。

分類問(wèn)題我們顯然已經(jīng)是很熟悉了,不就是內(nèi)積后 softmax 嗎?于是單靠 u1 這個(gè)特征,我們推導(dǎo)出它是屬于雞、鴨、魚(yú)、狗的概率分別是:

我們當(dāng)然期望 p(1|1) 和 p(2|1) 會(huì)明顯大于 p(3|1) 和 p(4|1)。

不過(guò),單靠這個(gè)特征還不夠,我們還需要綜合各個(gè)特征,于是可以把上述操作對(duì)各個(gè) ui 都做一遍,繼而得到 [p(1|2),p(2|2),p(3|2),p(4|2)]、[p(1|3),p(2|3),p(3|3),p(4|3)]...

問(wèn)題是,現(xiàn)在得到這么多預(yù)測(cè)結(jié)果,那我究竟要選擇哪個(gè)呢?而且我又不是真的要做分類,我要的是融合這些特征,構(gòu)成更高級(jí)的特征。

于是 Hinton 認(rèn)為,既然 ui 這個(gè)特征得到的概率分布是 [p(1|i),p(2|i),p(3|i),p(4|i)],那么我把這個(gè)特征切成四份,分別為 [p(1|i)ui,p(2|i)ui,p(3|i)ui,p(4|i)ui],然后把這幾個(gè)特征分別傳給 v1,v2,v3,v4,最后 v1,v2,v3,v4 其實(shí)就是各個(gè)底層傳入的特征的累加,這樣不就好了?

從上往下看,那么 Capsule 就是每個(gè)底層特征分別做分類,然后將分類結(jié)果整合。這時(shí) vj 應(yīng)該盡量與所有 ui 都比較靠近,靠近的度量是內(nèi)積。

因此,從下往上看的話,可以認(rèn)為 vj 實(shí)際上就是各個(gè) ui 的某個(gè)聚類中心,而 Capsule 的核心思想就是輸出是輸入的某種聚類結(jié)果。

現(xiàn)在來(lái)看這個(gè) squashing 是什么玩意,它怎么來(lái)的呢?

濃縮果汁

squash 在英文中也有濃縮果汁之意,我們就當(dāng)它是一杯果汁品嘗吧。這杯果汁的出現(xiàn),是因?yàn)?Hinton 希望 Capsule 能有的一個(gè)性質(zhì)是:膠囊的模長(zhǎng)能夠代表這個(gè)特征的概率。

其實(shí)我不喜歡概率這個(gè)名詞,因?yàn)楦怕首屛覀兟?lián)想到歸一化,而歸一化事實(shí)上是一件很麻煩的事情。我覺(jué)得可以稱為是特征的“顯著程度”,這就好解釋了,模長(zhǎng)越大,這個(gè)特征越顯著。

而我們又希望有一個(gè)有界的指標(biāo)來(lái)對(duì)這個(gè)“顯著程度”進(jìn)行衡量,所以就只能對(duì)這個(gè)模長(zhǎng)進(jìn)行壓縮了,所謂“濃縮就是精華”嘛。Hinton 選取的壓縮方案是:

其中 x/‖x‖ 是很好理解的,就是將模長(zhǎng)變?yōu)?1,那么前半部分怎么理解呢?為什么這樣選擇?事實(shí)上,將模長(zhǎng)壓縮到 0-1 的方案有很多,比如:

等等,并不確定 Hinton 選擇目前這個(gè)方案的思路。也許可以每個(gè)方案都探索一下?事實(shí)上,我在一些實(shí)驗(yàn)中發(fā)現(xiàn):

選擇上述函數(shù)的效果要好一點(diǎn)。這個(gè)函數(shù)的特點(diǎn)是在模長(zhǎng)很接近于 0 時(shí)起到放大作用,而不像原來(lái)的函數(shù)那樣全局都?jí)嚎s。

然而,一個(gè)值得思考的問(wèn)題是:如果在中間層,那么這個(gè)壓縮處理是不是必要的呢?

因?yàn)橐呀?jīng)有了后面說(shuō)的動(dòng)態(tài)路由在里邊,因此即使去掉 squashing 函數(shù),網(wǎng)絡(luò)也已經(jīng)具有了非線性了,因此直覺(jué)上并沒(méi)有必要在中間層也引入特征壓縮,正如普通神經(jīng)網(wǎng)絡(luò)也不一定要用 sigmoid 函數(shù)壓縮到 0-1。我覺(jué)得這個(gè)要在實(shí)踐中好好檢驗(yàn)一下。

動(dòng)態(tài)路由

注意到(2)式,為了求 vj 需要求 softmax,可是為了求 softmax 又需要知道 vj,這不是個(gè)雞生蛋、蛋生雞的問(wèn)題了嗎?

這時(shí)候就要上“主菜”了,即“動(dòng)態(tài)路由”(Dynamic Routing),它能夠根據(jù)自身的特性來(lái)更新(部分)參數(shù),從而初步達(dá)到了 Hinton 的放棄梯度下降的目標(biāo)。?

這道“主菜”究竟是是不是這樣的呢?它是怎么想出來(lái)的?最終收斂到哪里去?讓我們先上兩道小菜,然后再慢慢來(lái)品嘗這道主菜。

小菜 1

讓我們先回到普通的神經(jīng)網(wǎng)絡(luò),大家知道,激活函數(shù)在神經(jīng)網(wǎng)絡(luò)中的地位是舉足輕重的。當(dāng)然,激活函數(shù)本身很簡(jiǎn)單,比如一個(gè) tanh 激活的全連接層,用 TensorFlow 寫(xiě)起來(lái)就是:

y = tf.matmul(W, x) + b

y = tf.tanh(y)

可是,如果我想用 x=y+cos y 的反函數(shù)來(lái)激活呢?也就是說(shuō),你得給我解出 y=f(x),然后再用它來(lái)做激活函數(shù)。

然而數(shù)學(xué)家告訴我們,這個(gè)東西的反函數(shù)是一個(gè)超越函數(shù),也就是不可能用初等函數(shù)有限地表示出來(lái)。那這樣不就是故意刁難么?不要緊,我們有迭代:

選擇 y0=x,代入上式迭代幾次,基本上就可以得到比較準(zhǔn)確的 y 了。假如迭代三次,那就是:

用 TensorFlow 寫(xiě)出來(lái)就是:

y = tf.matmul(W, x) + b

Y=y

for i in range(3):

? ? Y = y - tf.cos(Y)

如果讀者已經(jīng)“預(yù)習(xí)”過(guò) Capsule,那么就會(huì)發(fā)現(xiàn)這跟 Capsule 的動(dòng)態(tài)路由很像。?

小菜 2

再來(lái)看一個(gè)例子,這個(gè)例子可能在 NLP 中有很多對(duì)應(yīng)的情景,但圖像領(lǐng)域其實(shí)也不少??紤]一個(gè)向量序列 (x1,x2,…,xn),我現(xiàn)在要想辦法將這 n 個(gè)向量整合成一個(gè)向量 x(encoder),然后用這個(gè)向量來(lái)做分類。

也許讀者會(huì)想到用LSTM。但我這里僅僅想要將它表示為原來(lái)向量的線性組合,也就是:

這里的 λi 相當(dāng)于衡量了 x 與 xi 的相似度。然而問(wèn)題來(lái)了,在 x 出現(xiàn)之前,憑什么能夠確定這個(gè)相似度呢?這不也是一個(gè)雞生蛋、蛋生雞的問(wèn)題嗎?

解決這個(gè)問(wèn)題的一個(gè)方案也是迭代。首先我們也可以定義一個(gè)基于 softmax 的相似度指標(biāo),然后讓:

一開(kāi)始,我們一無(wú)所知,所以只好取 x 為各個(gè) xi 的均值,然后代入右邊就可以算出一個(gè) x,再把它代入右邊,反復(fù)迭代就行,一般迭代有限次就可以收斂,于是就可以將這個(gè)迭代過(guò)程嵌入到神經(jīng)網(wǎng)絡(luò)中了。

如果說(shuō)小菜 1 跟動(dòng)態(tài)路由只是神似,那么小菜 2 已經(jīng)跟動(dòng)態(tài)路由是神似+形似了。不過(guò)我并沒(méi)有看到已有的工作是這樣做的,這個(gè)小菜只是我的頭腦風(fēng)暴。

上主菜

其實(shí)有了這兩個(gè)小菜,動(dòng)態(tài)路由這道主菜根本就不神秘了。為了得到各個(gè) vj,一開(kāi)始先讓它們?nèi)嫉扔?ui 的均值,然后反復(fù)迭代就好。說(shuō)白了,輸出是輸入的聚類結(jié)果,而聚類通常都需要迭代算法,這個(gè)迭代算法就稱為“動(dòng)態(tài)路由”。

至于這個(gè)動(dòng)態(tài)路由的細(xì)節(jié),其實(shí)是不固定的,取決于聚類的算法,比如關(guān)于 Capsule 的新文章 MATRIX CAPSULES WITH EM ROUTING 就使用了 Gaussian Mixture Model 來(lái)聚類。?

理解到這里,就可以寫(xiě)出本文的動(dòng)態(tài)路由的算法了:

這里的 cij 就是前文的 p(j|i)。

“嘿,終于逮到個(gè)錯(cuò)誤了,我看過(guò)論文,應(yīng)該是 bij=bij+ui?vj 而不是 bij=ui?vj 吧”?

事實(shí)上,上述算法并沒(méi)有錯(cuò)——如果你承認(rèn)本文的推導(dǎo)過(guò)程、承認(rèn)(2)式的話,那么上述迭代過(guò)程就是沒(méi)有錯(cuò)的。

“難道是Hinton錯(cuò)了?就憑你也有資格向Hinton叫板”?別急別急,先讓我慢慢分析 Hinton 的迭代出現(xiàn)了什么問(wèn)題。

假如按照 Hinton 的算法,那么是 bij=bij+ui?vj,從而經(jīng)過(guò) r 次迭代后,就變成了:

由于會(huì)越來(lái)越接近真實(shí)的 vj,那么我們可以寫(xiě)出:

假如經(jīng)過(guò)無(wú)窮多次迭代(實(shí)際上算力有限,做不到,但理論上總可以做到的),那么 r→∞,這樣的話 softmax 的結(jié)果是非零即 1,也就是說(shuō),每個(gè)底層的膠囊僅僅聯(lián)系到一個(gè)上層膠囊。這時(shí)候 vj 已不再是聚類中心,而是距離它們聚類中心最近的那個(gè) ui。

這合理嗎?我覺(jué)得很不合理。不同的類別之間是有可能有共同的特征的,這就好比人和動(dòng)物雖然不一樣,但是都有眼睛。

對(duì)于這個(gè)問(wèn)題,有些朋友是這樣解釋的:r 是一個(gè)超參數(shù),不能太大,太大了就容易過(guò)擬合。首先我不知道 Hinton 是不是也是同樣的想法,但我認(rèn)為,如果認(rèn)為 r 是一個(gè)超參,那么這將會(huì)使得 Capsule 太丑陋了。

是啊,動(dòng)態(tài)路由被來(lái)已經(jīng)被很多讀者評(píng)價(jià)為“不知所云”了,如果加上完全不符合直覺(jué)的超參,不就更加難看了嗎?

相反,如果換成本文的(2)式作為出發(fā)點(diǎn),然后得到本文的動(dòng)態(tài)路由算法,才能符合聚類的思想,而且在理論上會(huì)好看些,因?yàn)檫@時(shí)候就是 r 越大越好了(看算力而定),不存在這個(gè)超參。

事實(shí)上,我改動(dòng)了之后,在目前開(kāi)源的 Capsule 源碼上跑,也能跑到同樣的結(jié)果。

至于讀者怎么選擇,就看讀者的意愿吧。我自己是有點(diǎn)強(qiáng)迫癥的,忍受不了理論上的不足。

模型細(xì)節(jié)

下面介紹 Capsule 實(shí)現(xiàn)的細(xì)節(jié),對(duì)應(yīng)的代碼在我的 Github 中,不過(guò)目前只有 Keras 版。相比之前實(shí)現(xiàn)的版本,我的版本是純 Keras 實(shí)現(xiàn)的(原來(lái)是半 Keras 半 TensorFlow),并通過(guò) K.local_conv1d 函數(shù)替代了 K.map_fn 提升了好幾倍的速度。

這是因?yàn)?K.map_fn 并不會(huì)自動(dòng)并行,要并行的話需要想辦法整合到一個(gè)矩陣運(yùn)算;其次我通過(guò) K.conv1d 實(shí)現(xiàn)了共享參數(shù)版的。代碼要在 Keras 2.1.0 以上版本運(yùn)行。

全連接版

先不管是 Hinton 版還是我的版本,按照這個(gè)動(dòng)態(tài)路由的算法,vj 能夠迭代地算出來(lái),那不就沒(méi)有參數(shù)了嗎?真的拋棄了反向傳播了?

非也非也,如果真的這樣的話,各個(gè) vj 都一樣了。前面已經(jīng)說(shuō)了,vj 是作為輸入 ui 的某種聚類中心出現(xiàn)的,而從不同角度看輸入,得到的聚類結(jié)果顯然是不一樣的。

那么為了實(shí)現(xiàn)“多角度看特征”,可以在每個(gè)膠囊傳入下一個(gè)膠囊之前,都要先乘上一個(gè)矩陣做變換,所以(2)式實(shí)際上應(yīng)該要變?yōu)椋?/p>

這里的 Wji 是待訓(xùn)練的矩陣,這里的乘法是矩陣乘法,也就是矩陣乘以向量。所以,Capsule 變成了下圖。

這時(shí)候就可以得到完整動(dòng)態(tài)路由了。

這樣的 Capsule 層,顯然相當(dāng)于普通神經(jīng)網(wǎng)絡(luò)中的全連接層。

共享版

眾所周知,全連接層只能處理定長(zhǎng)輸入,全連接版的 Capsule 也不例外。而 CNN 處理的圖像大小通常是不定的,提取的特征數(shù)目就不定了,這種情形下,全連接層的 Capsule 就不適用了。

因?yàn)樵谇耙粓D就可以看到,參數(shù)矩陣的個(gè)數(shù)等于輸入輸入膠囊數(shù)目乘以輸出膠囊數(shù)目,既然輸入數(shù)目不固定,那么就不能用全連接了。

所以跟 CNN 的權(quán)值共享一樣,我們也需要一個(gè)權(quán)值共享版的 Capsule。所謂共享版,是指對(duì)于固定的上層膠囊 j,它與所有的底層膠囊的連接的變換矩陣是共用的,即 Wji≡Wj。

如圖所示,共享版其實(shí)不難理解,就是自下而上地看,所有輸入向量經(jīng)過(guò)同一個(gè)矩陣進(jìn)行映射后,完成聚類進(jìn)行輸出,將這個(gè)過(guò)程重復(fù)幾次,就輸出幾個(gè)向量(膠囊)。

又或者自上而下地看,將每個(gè)變換矩陣看成是上層膠囊的識(shí)別器,上層膠囊通過(guò)這個(gè)矩陣來(lái)識(shí)別出底層膠囊是不是有這個(gè)特征。

因此很明顯,這個(gè)版本的膠囊的參數(shù)量并不依賴于輸入的膠囊個(gè)數(shù),因此可以輕松接在 CNN 后面。對(duì)于共享版,(2)式要變?yōu)椋?/p>

至于動(dòng)態(tài)路由算法就沒(méi)有改變了。

反向傳播?

盡管我不是很喜歡反向傳播這個(gè)名詞,然而這里似乎不得不用上這個(gè)名字了。?

現(xiàn)在又有了 Wji,那么這些參數(shù)怎么訓(xùn)練呢?答案是反向傳播。讀者也許比較暈的是:現(xiàn)在既有動(dòng)態(tài)路由,又有反向傳播了,究竟兩者怎么配合?

其實(shí)這個(gè)真的就最簡(jiǎn)單不過(guò)了。就好像“小菜 1”那樣,把算法的迭代幾步(論文中是 3 步),加入到模型中,從形式上來(lái)看,就是往模型中添加了三層罷了,剩下的該做什么還是什么,最后構(gòu)建一個(gè) loss 來(lái)反向傳播。?

這樣看來(lái),Capsule 里邊不僅有反向傳播,而且只有反向傳播,因?yàn)閯?dòng)態(tài)路由已經(jīng)作為了模型的一部分,都不算在迭代算法里邊了。?

做了什么?

是時(shí)候回顧一下了,Capsule 究竟做了什么?其實(shí)用一種最直接的方式來(lái)講,Capsule 就是提供了一種新的“vector in vector out”的方案,這樣看跟 CNN、RNN、Attention 層都沒(méi)太大區(qū)別了。

從 Hinton 的本意看,就是提供了一種新的、基于聚類思想來(lái)代替池化完成特征的整合的方案,這種新方案的特征表達(dá)能力更加強(qiáng)大。

實(shí)驗(yàn)

MNIST 分類

不出意外地,Capsule 首先被用在 MNIST 中做實(shí)驗(yàn),然后效果還不錯(cuò),通過(guò)擾動(dòng)膠囊內(nèi)的一些值來(lái)重構(gòu)圖像,確實(shí)發(fā)現(xiàn)這些值代表了某種含義,這也體現(xiàn)了 Capsule 初步完成了它的目標(biāo)。

Capsule 做分類模型,跟普通神經(jīng)網(wǎng)絡(luò)的一些區(qū)別是:Capsule 最后輸出 10 個(gè)向量(也就是 10 個(gè)膠囊),這 10 個(gè)向量各代表一類,每個(gè)向量的模長(zhǎng)代表著它的概率。

事實(shí)上,Capsule 做的事情就是檢測(cè)有沒(méi)有這個(gè)類,也就是說(shuō),它把一個(gè)多分類問(wèn)題轉(zhuǎn)化為多個(gè) 2 分類問(wèn)題。因此它并沒(méi)有用普通的交叉熵?fù)p失,而是用了:

其中 Tc 非零即 1,表明是不是這個(gè)類。當(dāng)然這個(gè)沒(méi)什么特殊性,也可以有多種選擇。論文中還對(duì)比了加入重構(gòu)網(wǎng)絡(luò)后的提升。?

總的來(lái)說(shuō),論文的實(shí)驗(yàn)有點(diǎn)粗糙,選擇 MNIST 來(lái)做實(shí)驗(yàn)顯得有點(diǎn)不給力(好歹也得玩玩 fashion MNIST 嘛),重構(gòu)網(wǎng)絡(luò)也只是簡(jiǎn)單粗暴地堆了兩層全連接來(lái)做。不過(guò)就論文的出發(fā)點(diǎn),應(yīng)該只要能證明這個(gè)流程能 work 就好了,因此差強(qiáng)人意吧。?

我的實(shí)驗(yàn)?

由于普通的卷積神經(jīng)網(wǎng)絡(luò)下,MNIST 的驗(yàn)證集準(zhǔn)確率都已經(jīng) 99%+ 了,因此如果就這樣說(shuō) Capsule 起作用了,難免讓人覺(jué)得不服氣。

這里我為 Capsule 設(shè)計(jì)了一個(gè)新實(shí)驗(yàn),雖然這個(gè)實(shí)驗(yàn)也是基于 MNIST,但這個(gè)實(shí)驗(yàn)很充分地說(shuō)明了 Capsule 具有良好的整合特征的能力。Capsule 不僅 work,還 work 得很漂亮。

具體實(shí)驗(yàn)如下:

1. 通過(guò)現(xiàn)有的 MNIST 數(shù)據(jù)集,訓(xùn)練一個(gè)數(shù)字識(shí)別模型,但最后不用 softmax 做 10 分類,而是轉(zhuǎn)化為 10 個(gè) 2 分類問(wèn)題;

2. 訓(xùn)練完模型后,用模型進(jìn)行測(cè)試。測(cè)試的圖片并不是原始的測(cè)試集,是隨機(jī)挑兩張測(cè)試集的圖片拼在一起,然后看模型能不能預(yù)測(cè)出這兩個(gè)數(shù)字來(lái)(數(shù)字對(duì)即可,不考慮順序)。

也就是說(shuō),訓(xùn)練集是 1 對(duì) 1 的,測(cè)試集是 2 對(duì) 2 的。

實(shí)驗(yàn)用 Keras 完成,完成的代碼可見(jiàn)我的 Github。這里僅僅展示核心部分。

Github: https://github.com/bojone/Capsule

首先是 CNN。公平起見(jiàn),大家的 CNN 模型都是一樣的。

#CNN部分,這部分兩個(gè)模型都一致

input_image = Input(shape=(None,None,1))

cnn = Conv2D(64, (3, 3), activation="relu")(input_image)

cnn = Conv2D(64, (3, 3), activation="relu")(cnn)

cnn = AveragePooling2D((2,2))(cnn)

cnn = Conv2D(128, (3, 3), activation="relu")(cnn)

cnn = Conv2D(128, (3, 3), activation="relu")(cnn)

然后先用普通的 Pooling + 全連接層進(jìn)行建模:

cnn = GlobalAveragePooling2D()(cnn)

dense = Dense(128, activation="relu")(cnn)

output = Dense(10, activation="sigmoid")(dense)

model = Model(inputs=input_image, outputs=output)

model.compile(loss=lambda y_true,y_pred: y_true*K.relu(0.9-y_pred)**2 + 0.25*(1-y_true)*K.relu(y_pred-0.1)**2,

? ? ? ? ? ? ? optimizer="adam",

? ? ? ? ? ? ? metrics=["accuracy"])

這個(gè)代碼的參數(shù)量約為 27 萬(wàn),能在 MNIST 的標(biāo)準(zhǔn)測(cè)試集上達(dá)到 99.3% 以上的準(zhǔn)確率,顯然已經(jīng)接近較佳狀態(tài)。

下面測(cè)試我們開(kāi)始制定的任務(wù),我們最后輸出兩個(gè)準(zhǔn)確率:第一個(gè)準(zhǔn)確率是取分?jǐn)?shù)較高的兩個(gè)類別;第二個(gè)準(zhǔn)確率是取得分較高的兩個(gè)類別,并且這兩個(gè)類別的分?jǐn)?shù)都要超過(guò) 0.5 才認(rèn)可(因?yàn)槭?2 分類)。代碼如下:

#對(duì)測(cè)試集重新排序并拼接到原來(lái)測(cè)試集,就構(gòu)成了新的測(cè)試集,每張圖片有兩個(gè)不同數(shù)字

idx = range(len(x_test))

np.random.shuffle(idx)

X_test = np.concatenate([x_test, x_test[idx]], 1)

Y_test = np.vstack([y_test.argmax(1), y_test[idx].argmax(1)]).T

X_test = X_test[Y_test[:,0] != Y_test[:,1]] #確保兩個(gè)數(shù)字不一樣

Y_test = Y_test[Y_test[:,0] != Y_test[:,1]]

Y_test.sort(axis=1) #排一下序,因?yàn)橹槐容^集合,不比較順序

Y_pred = model.predict(X_test) #用模型進(jìn)行預(yù)測(cè)

greater = np.sort(Y_pred, axis=1)[:,-2] > 0.5 #判斷預(yù)測(cè)結(jié)果是否大于0.5

Y_pred = Y_pred.argsort()[:,-2:] #取較高分?jǐn)?shù)的兩個(gè)類別

Y_pred.sort(axis=1) #排序,因?yàn)橹槐容^集合

acc = 1.*(np.prod(Y_pred == Y_test, axis=1)).sum()/len(X_test)

print u"不考慮置信度的準(zhǔn)確率為:%s"%acc

acc = 1.*(np.prod(Y_pred == Y_test, axis=1)*greater).sum()/len(X_test)

print u"考慮置信度的準(zhǔn)確率為:%s"%acc

經(jīng)過(guò)重復(fù)測(cè)試,如果不考慮置信度,那么準(zhǔn)確率大約為 40%,如果考慮置信度,那么準(zhǔn)確率是 10% 左右。這是一組保守的數(shù)據(jù),反復(fù)測(cè)試幾次的話,很多時(shí)候連這兩個(gè)都不到。

現(xiàn)在我們來(lái)看 Capsule 的表現(xiàn),將 CNN 后面的代碼替換成:

capsule = Capsule(10, 16, 3, True)(cnn)

output = Lambda(lambda x: K.sqrt(K.sum(K.square(x), 2)))(capsule)

model = Model(inputs=input_image, outputs=output)

model.compile(loss=lambda y_true,y_pred: y_true*K.relu(0.9-y_pred)**2 + 0.25*(1-y_true)*K.relu(y_pred-0.1)**2,

? ? ? ? ? ? ? optimizer="adam",

? ? ? ? ? ? ? metrics=["accuracy"])

這里用的就是共享權(quán)重版的 Capsule,最后輸出向量的模長(zhǎng)作為分?jǐn)?shù),loss 和 optimizer 都跟前面一致,代碼的參數(shù)量也約為 27 萬(wàn),在 MNIST 的標(biāo)準(zhǔn)測(cè)試集上的準(zhǔn)確率同樣也是 99.3% 左右,這部分兩者都差不多。

然而,讓人驚訝的是:在前面所定制的新測(cè)試集上,Capsule 模型的兩個(gè)準(zhǔn)確率都有 90% 以上。即使我們沒(méi)有針對(duì)性地訓(xùn)練,但 Capsule 仍以高置信度給出了輸入中包含的特征(即哪個(gè)數(shù)字)。

也就是說(shuō),我們訓(xùn)練了單個(gè)數(shù)字的識(shí)別模型,卻有可能直接得到一個(gè)同時(shí)識(shí)別多數(shù)字的模型,這顯然很符合人類的學(xué)習(xí)能力。

事實(shí)上我們還可以更細(xì)致地分析特征的流動(dòng)情況,確定數(shù)字的順序(而不單單是當(dāng)成一個(gè)集合來(lái)識(shí)別),從而構(gòu)成一個(gè)完整的多數(shù)字識(shí)別模型。這很大程度上得益于 Capsule 的可解釋性,也表明 Capsule 確確實(shí)實(shí)形成了良好的特征表達(dá),減少了信息損失。

思考

看起來(lái)還行

Capsule 致力于給出神經(jīng)網(wǎng)絡(luò)的可解釋的方案,因此,從這個(gè)角度來(lái)看,Capsule 應(yīng)該是成功的,至少作為測(cè)試版是很成功的。因?yàn)樗哪繕?biāo)并不是準(zhǔn)確率非常出眾,而是對(duì)輸入做一個(gè)優(yōu)秀的、可解釋的表征。

從我上面的實(shí)驗(yàn)來(lái)看,Capsule 也是很漂亮的,至少可以間接證明它比池化過(guò)程更接近人眼的機(jī)制。

事實(shí)上,通過(guò)向量的模長(zhǎng)來(lái)表示概率,這一點(diǎn)讓我想起了量子力學(xué)的波函數(shù),它也是通過(guò)波函數(shù)的范數(shù)來(lái)表示概率的。這告訴我們,未來(lái) Capsule 的發(fā)展也許可以參考一下量子力學(xué)的內(nèi)容。

亟待優(yōu)化

顯然,Capsule 可優(yōu)化的地方還有非常多,包括理論上的和實(shí)踐上的。我覺(jué)得整個(gè)算法中最不好看的部分并非動(dòng)態(tài)路由,而是那個(gè) squashing 函數(shù)。對(duì)于非輸出層,這個(gè)壓縮究竟是不是必要的?

還有,由于要用模長(zhǎng)并表示概率,模長(zhǎng)就得小于 1,而兩個(gè)模長(zhǎng)小于 1 的向量加起來(lái)后模長(zhǎng)不一定小于 1,因此需要用函數(shù)進(jìn)一步壓縮,這個(gè)做法的主觀性太強(qiáng)。

這也許需要借助流形上的分析工具,才能給出更漂亮的解決方案,或者也可以借鑒一下量子力學(xué)的思路,因?yàn)榱孔恿W(xué)也存在波函數(shù)相加的情況。

實(shí)踐角度來(lái)看,Capsule 顯然是太慢了。這是因?yàn)閷?dòng)態(tài)路由的迭代過(guò)程嵌入了神經(jīng)網(wǎng)絡(luò)中。從前向傳播來(lái)看,這并沒(méi)有增加多少計(jì)算量,但從反向傳播來(lái)看,計(jì)算量暴增了,因?yàn)閺?fù)合函數(shù)的梯度會(huì)更加復(fù)雜。

反向傳播好不好?

Hinton 想要拋棄反向傳播的大概原因是:反向傳播在生物中找不到對(duì)應(yīng)的機(jī)制,因?yàn)榉聪騻鞑バ枰^精確地求導(dǎo)數(shù)。

事實(shí)上,我并不認(rèn)同這種觀點(diǎn)。盡管較精確求導(dǎo)在自然界中很難存在,但這才意味著我們的先進(jìn)。

試想一下,如果不求導(dǎo),那么我們也可以優(yōu)化的,但需要“試探+插值”,比如將參數(shù) α 從 3 改為 5 后,發(fā)現(xiàn) loss 變小了,于是我們就會(huì)想著試試 α=7,如果這時(shí)候 loss 變大了,我們就會(huì)想著試試 α=6。

loss 變小/大就意味著(近似的)梯度為負(fù)/正,這個(gè)過(guò)程的思想跟梯度下降是一致的,但這個(gè)過(guò)程一次性只能調(diào)節(jié)一個(gè)參數(shù),而我們可能有數(shù)百萬(wàn)的參數(shù)要調(diào),需要進(jìn)行上百萬(wàn)次試驗(yàn)要才能完成每一個(gè)參數(shù)的調(diào)整。

而求梯度,就是一種比重復(fù)試探更加高明的技巧,何樂(lè)而不用呢?

池化好不好?

Hinton 因?yàn)榫矸e中的池化是不科學(xué)的,但我并不這樣認(rèn)為。也許對(duì)于 MNIST 這個(gè) 28*28 的數(shù)據(jù)集并不需要池化也能 work,但如果是 1000*1000 的大圖呢?越遠(yuǎn)的東西就越看不清,這難道不是池化的結(jié)果?

所以我認(rèn)為池化也是可取的,不過(guò)池化應(yīng)該對(duì)低層的特征進(jìn)行,高層的信息池化可能就會(huì)有問(wèn)題了。

退一步講,如果堅(jiān)決不用池化,那我用 stride=2 的卷積,不跟 stride=1 的卷積后接一個(gè)大小為 2 的池化是類似的嗎?筆者前面的 Capsule 實(shí)驗(yàn)中,也將池化跟 Capsule 配合使用了,效果也沒(méi)有變?cè)恪?/p>

結(jié)語(yǔ)

這應(yīng)該是到目前為止我寫(xiě)的最長(zhǎng)的單篇文章了,不知道大家對(duì)這個(gè) Capsule 飯局滿不滿意呢?

最后不得不吐槽一下,Hinton 真會(huì)起名字,把神經(jīng)網(wǎng)絡(luò)重新叫做深度學(xué)習(xí),然后深度學(xué)習(xí)就火了,現(xiàn)在把聚類的迭代算法放到神經(jīng)網(wǎng)絡(luò)中,稱之為做動(dòng)態(tài)路由,不知道會(huì)不會(huì)再次重現(xiàn)深度學(xué)習(xí)的輝煌呢?

歡迎加入本站公開(kāi)興趣群

商業(yè)智能與數(shù)據(jù)分析群

興趣范圍包括各種讓數(shù)據(jù)產(chǎn)生價(jià)值的辦法,實(shí)際應(yīng)用案例分享與討論,分析工具,ETL工具,數(shù)據(jù)倉(cāng)庫(kù),數(shù)據(jù)挖掘工具,報(bào)表系統(tǒng)等全方位知識(shí)

QQ群:81035754

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/4736.html

相關(guān)文章

  • 深夜放毒,AI 下面給你吃呀?

    摘要:因?yàn)槟愕臋C(jī)器人,正在烤制一份美味的披薩,放滿了你愛(ài)吃的焦香的培根,肥厚的香腸,還有滿滿的芝士,口感一流的餅皮。他們希望借此表明不僅不會(huì)搶人類飯碗,反而會(huì)成為人類的好助手。 By 超神經(jīng) 如果你此刻還在糾結(jié)要不要叫外賣,我勸你不要再看這篇文章了。 因?yàn)槟愕?AI 機(jī)器人,正在烤制一份美味的披薩,放滿了你愛(ài)吃的焦香的培根,肥厚的香腸,還有滿滿的芝士,口感一流的餅皮。而且這樣一份披薩,不需要...

    lijy91 評(píng)論0 收藏0
  • 深度學(xué)習(xí)精要之CapsuleNets理論與實(shí)踐(Python代碼

    摘要:摘要本文對(duì)膠囊網(wǎng)絡(luò)進(jìn)行了非技術(shù)性的簡(jiǎn)要概括,分析了其兩個(gè)重要屬性,之后針對(duì)手寫(xiě)體數(shù)據(jù)集上驗(yàn)證多層感知機(jī)卷積神經(jīng)網(wǎng)絡(luò)以及膠囊網(wǎng)絡(luò)的性能。這是一個(gè)非結(jié)構(gòu)化的數(shù)字圖像識(shí)別問(wèn)題,使用深度學(xué)習(xí)算法能夠獲得最佳性能。作者信息,數(shù)據(jù)科學(xué),深度學(xué)習(xí)初學(xué)者。 摘要: 本文對(duì)膠囊網(wǎng)絡(luò)進(jìn)行了非技術(shù)性的簡(jiǎn)要概括,分析了其兩個(gè)重要屬性,之后針對(duì)MNIST手寫(xiě)體數(shù)據(jù)集上驗(yàn)證多層感知機(jī)、卷積神經(jīng)網(wǎng)絡(luò)以及膠囊網(wǎng)絡(luò)的性...

    luffyZh 評(píng)論0 收藏0
  • Hinton膠囊理論代碼開(kāi)源,上線即受熱捧

    摘要:近日,該論文的一作終于在上公開(kāi)了該論文中的代碼。該項(xiàng)目上線天便獲得了個(gè),并被了次。 當(dāng)前的深度學(xué)習(xí)理論是由Geoffrey Hinton大神在2007年確立起來(lái)的,但是如今他卻認(rèn)為,CNN的特征提取層與次抽樣層交叉存取,將相同類型的相鄰特征檢測(cè)器的輸出匯集到一起是大有問(wèn)題的。去年9月,在多倫多接受媒體采訪時(shí),Hinton大神斷然宣稱要放棄反向傳播,讓整個(gè)人工智能從頭再造。10月,人們關(guān)注已久...

    tianlai 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<