1. 程式人生 > >grad-cam 、cam 和熱力圖,基於keras的實現

grad-cam 、cam 和熱力圖,基於keras的實現

abs guide ring 不一定 作用 自然 team 拍攝 類別

http://bindog.github.io/blog/2018/02/10/model-explanation/

http://www.sohu.com/a/216216094_473283

https://jacobgil.github.io/deeplearning/class-activation-maps

https://github.com/keras-team/keras/issues/8447

憑什麽相信你,我的CNN模型?(篇一:CAM和Grad-CAM)

0x00 背景

在當前深度學習的領域,有一個非常不好的風氣:一切以經驗論,好用就行,不問為什麽,很少深究問題背後的深層次原因。從長遠來看,這樣做就埋下了隱患。舉個例子,在1980年左右的時候,美國五角大樓啟動了一個項目:用神經網絡模型來識別坦克(當時還沒有深度學習的概念),他們采集了100張隱藏在樹叢中的坦克照片,以及另100張僅有樹叢的照片。一組頂尖的研究人員訓練了一個神經網絡模型來識別這兩種不同的場景,這個神經網絡模型效果拔群,在測試集上的準確率竟然達到了100%!於是這幫研究人員很高興的把他們的研究成果帶到了某個學術會議上,會議上有個哥們提出了質疑:你們的訓練數據是怎麽采集的?後來進一步調查發現,原來那100張有坦克的照片都是在陰天拍攝的,而另100張沒有坦克的照片是在晴天拍攝的……也就是說,五角大樓花了那麽多的經費,最後就得到了一個用來區分陰天和晴天的分類模型。

當然這個故事應該是虛構的,不過它很形象的說明了什麽叫“數據泄露”,這在以前的Kaggle比賽中也曾經出現過。大家不妨思考下,假如我們手裏現在有一家醫院所有醫生和護士的照片,我們希望訓練出一個圖片分類模型,能夠準確的區分出醫生和護士。當模型訓練完成之後,準確率達到了99%,你認為這個模型可靠不可靠呢?大家可以自己考慮下這個問題。

好在學術界的一直有人關註著這個問題,並引申出一個很重要的分支,就是模型的可解釋性問題。那麽本文從就從近幾年來的研究成果出發,談談如何讓看似黑盒的CNN模型“說話”,對它的分類結果給出一個解釋。註意,本文所說的“解釋”,與我們日常說的“解釋”內涵不一樣:例如我們給孩子一張貓的圖片,讓他解釋為什麽這是一只貓,孩子會說因為它有尖耳朵、胡須等。而我們讓CNN模型解釋為什麽將這張圖片的分類結果為貓,只是讓它標出是通過圖片的哪些像素作出判斷的。(嚴格來說,這樣不能說明模型是否真正學到了我們人類所理解的“特征”,因為模型所學習到的特征本來就和人類的認知有很大區別。何況,即使只標註出是通過哪些像素作出判斷就已經有很高價值了,如果標註出的像素集中在地面上,而模型的分類結果是貓,顯然這個模型是有問題的)

0x01 反卷積和導向反向傳播

關於CNN模型的可解釋問題,很早就有人開始研究了,姑且稱之為CNN可視化吧。比較經典的有兩個方法,反卷積(Deconvolution)和導向反向傳播(Guided-backpropagation),通過它們,我們能夠一定程度上“看到”CNN模型中較深的卷積層所學習到的一些特征。當然這兩個方法也衍生出了其他很多用途,以反卷積為例,它在圖像語義分割中有著非常重要的作用。從本質上說,反卷積和導向反向傳播的基礎都是反向傳播,其實說白了就是對輸入進行求導,三者唯一的區別在於反向傳播過程中經過ReLU層時對梯度的不同處理策略。在這篇論文中有著非常詳細的說明,如下圖所示:

技術分享圖片

雖然過程上的區別看起來沒有非常微小,但是在最終的效果上卻有很大差別。如下圖所示:

技術分享圖片

使用普通的反向傳播得到的圖像噪聲較多,基本看不出模型的學到了什麽東西。使用反卷積可以大概看清楚貓和狗的輪廓,但是有大量噪聲在物體以外的位置上。導向反向傳播基本上沒有噪聲,特征很明顯的集中貓和狗的身體部位上。

雖然借助反卷積和導向反向傳播我們“看到”了CNN模型神秘的內部,但是卻並不能拿來解釋分類的結果,因為它們對類別並不敏感,直接把所有能提取的特征都展示出來了。在剛才的圖片中,模型給出的分類結果是貓,但是通過反卷積和導向反向傳播展示出來的結果卻同時包括了狗的輪廓。換句話說,我們並不知道模型到底是通過哪塊區域判斷出當前圖片是一只貓的。要解決這個問題,我們必須考慮其他辦法。

(ps:目前網上有一些關於反卷積的文章,我感覺沒有說的特別到位的,當然也有可能是大家理解的角度不同,但是另外一些解讀那就是完全錯誤的了,包括某乎。不得不說,真正要深入理解反卷積還是要去啃論文,很多人嫌麻煩總是看些二手的資料,得到的認識自然是有問題的。當然這些都是題外話,我也有寫一篇關於反卷積的文章的計劃。看以後的時間安排)

0x02 CAM

大家在電視上應該都看過熱成像儀生成的圖像,就像下面這張圖片。

技術分享圖片

圖像中動物或人因為散發出熱量,所以能夠清楚的被看到。接下來要介紹的CAM(Class Activation Mapping)產生的CAM圖與之類似,當我們需要模型解釋其分類的原因時,它以熱力圖(Saliency Map,我不知道怎麽翻譯最適合,叫熱力圖比較直觀一點)的形式展示它的決策依據,如同在黑夜中告訴我們哪有發熱的物體。

對一個深層的卷積神經網絡而言,通過多次卷積和池化以後,它的最後一層卷積層包含了最豐富的空間和語義信息,再往下就是全連接層和softmax層了,其中所包含的信息都是人類難以理解的,很難以可視化的方式展示出來。所以說,要讓卷積神經網絡的對其分類結果給出一個合理解釋,必須要充分利用好最後一個卷積層。

技術分享圖片

CAM借鑒了很著名的論文Network in Network中的思路,利用GAP(Global Average Pooling)替換掉了全連接層。可以把GAP視為一個特殊的average pool層,只不過其pool size和整個特征圖一樣大,其實說白了就是求每張特征圖所有像素的均值。

技術分享圖片

GAP的優點在NIN的論文中說的很明確了:由於沒有了全連接層,輸入就不用固定大小了,因此可支持任意大小的輸入;此外,引入GAP更充分的利用了空間信息,且沒有了全連接層的各種參數,魯棒性強,也不容易產生過擬合;還有很重要的一點是,在最後的 mlpconv層(也就是最後一層卷積層)強制生成了和目標類別數量一致的特征圖,經過GAP以後再通過softmax層得到結果,這樣做就給每個特征圖賦予了很明確的意義,也就是categories confidence maps。如果你當時不理解這個categories confidence maps是個什麽東西,結合CAM應該就能很快理解。

我們重點看下經過GAP之後與輸出層的連接關系(暫不考慮softmax層),實質上也是就是個全連接層,只不過沒有了偏置項,如圖所示:

技術分享圖片

從圖中可以看到,經過GAP之後,我們得到了最後一個卷積層每個特征圖的均值,通過加權和得到輸出(實際中是softmax層的輸入)。需要註意的是,對每一個類別C,每個特征圖kk的均值都有一個對應的ww,記為wckwkc。CAM的基本結構就是這樣了,下面就是和普通的CNN模型一樣訓練就可以了。訓練完成後才是重頭戲:我們如何得到一個用於解釋分類結果的熱力圖呢?其實非常簡單,比如說我們要解釋為什麽分類的結果是羊駝,我們把羊駝這個類別對應的所有wckwkc取出來,求出它們與自己對應的特征圖的加權和即可。由於這個結果的大小和特征圖是一致的,我們需要對它進行上采樣,疊加到原圖上去,如下所示。

技術分享圖片

這樣,CAM以熱力圖的形式告訴了我們,模型是重點通過哪些像素確定這個圖片是羊駝了。

0x03 Grad-CAM方法

前面看到CAM的解釋效果已經很不錯了,但是它有一個致使傷,就是它要求修改原模型的結構,導致需要重新訓練該模型,這大大限制了它的使用場景。如果模型已經上線了,或著訓練的成本非常高,我們幾乎是不可能為了它重新訓練的。於是乎,Grad-CAM橫空出世,解決了這個問題。

Grad-CAM的基本思路和CAM是一致的,也是通過得到每對特征圖對應的權重,最後求一個加權和。但是它與CAM的主要區別在於求權重wckwkc的過程。CAM通過替換全連接層為GAP層,重新訓練得到權重,而Grad-CAM另辟蹊徑,用梯度的全局平均來計算權重。事實上,經過嚴格的數學推導,Grad-CAM與CAM計算出來的權重是等價的。為了和CAM的權重做區分,定義Grad-CAM中第kk個特征圖對類別cc的權重為αckαkc,可通過下面的公式計算:

αck=1ZijycAkijαkc=1Z∑i∑j∂yc∂Aijk

其中,ZZ為特征圖的像素個數,ycyc是對應類別cc的分數(在代碼中一般用logits表示,是輸入softmax層之前的值),AkijAijk表示第kk個特征圖中,(i,j)(i,j)位置處的像素值。求得類別對所有特征圖的權重後,求其加權和就可以得到熱力圖。

LcGradCAM=ReLU(kαckAk)LGrad−CAMc=ReLU(∑kαkcAk)

Grad-CAM的整體結構如下圖所示:

技術分享圖片

註意這裏和CAM的另一個區別是,Grad-CAM對最終的加權和加了一個ReLU,加這麽一層ReLU的原因在於我們只關心對類別cc有正影響的那些像素點,如果不加ReLU層,最終可能會帶入一些屬於其它類別的像素,從而影響解釋的效果。使用Grad-CAM對分類結果進行解釋的效果如下圖所示:

技術分享圖片

除了直接生成熱力圖對分類結果進行解釋,Grad-CAM還可以與其他經典的模型解釋方法如導向反向傳播相結合,得到更細致的解釋。

技術分享圖片

這樣就很好的解決了反卷積和導向反向傳播對類別不敏感的問題。當然,Grad-CAM的神奇之處還不僅僅局限在對圖片分類的解釋上,任何與圖像相關的深度學習任務,只要用到了CNN,就可以用Grad-CAM進行解釋,如圖像描述(Image Captioning),視覺問答(Visual Question Answering)等,所需要做的只不過是把ycyc換為對應模型中的那個值即可。限於篇幅,本文就不展開了,更多細節,強烈建議大家去讀讀論文,包括Grad-CAM與CAM權重等價的證明也在論文中。如果你只是想在自己的模型中使用Grad-CAM,可以參考這個鏈接,熟悉tensorflow的話實現起來真的非常簡單,一看就明白。

0x04 擴展

其實無論是CAM還是Grad-CAM,除了用來對模型的預測結果作解釋外,還有一個非常重要的功能:就是用於物體檢測。大家都知道現在物體檢測是一個非常熱門的方向,它要求在一張圖片中準確的識別出多個物體,同時用方框將其框起來。物體檢測對訓練數據量的要求是非常高的,目前常被大家使用的有 PASCAL、COCO,如果需要更多數據,或者想要識別的物體在這些數據庫中沒有話,那就只能人工來進行標註了,工作量可想而知。

仔細想想我們不難發現,Grad-CAM在給出解釋的同時,不正好完成了標註物體位置的工作嗎?雖然其標註的位置不一定非常精確,也不一定完整覆蓋到物體的每一個像素。但只要有這樣一個大致的信息,我們就可以得到物體的位置,更具有誘惑力的是,我們不需要人工標註的方框就可以做到了。

順便吐槽下當前比較火的幾個物體檢測模型如Faster-RCNN、SSD等,無一例外都有一個Region Proposal階段,相當於“胡亂”在圖片中畫各種大小的方框,然後再來判斷方框中是否有物體存在。雖然效果很好,但是根本就是違背人類直覺的。相比之下,Grad-CAM這種定位方式似乎更符合人類的直覺。當然這些純屬我個人的瞎扯,業務場景中SSD還是非常好用的,肯定要比Grad-CAM這種弱監督條件下的定位要強的多。

0x05 小結

試想如果當時五角大樓的研究人員知道本文介紹的這些方法,並對他們的分類結果用熱力圖進行解釋,相信他們能很快發現熱力圖的紅色區域主要集中在天空上,顯然說明模型並沒有真正學到如何判別一輛坦克,最後也就不至於鬧笑話了。

回顧本文所介紹的這些方法,它們都有一個共同前提:即模型對我們來說是白盒,我們清楚的知道模型內部的所有細節,能夠獲取任何想要的數據,甚至可以修改它的結構。但如果我們面對的是一個黑盒,對其內部一無所知,只能提供一個輸入並得到相應的輸出值(比如別人的某個模型部署在線上,我們只有使用它的權利),在這種情況下,我們如何判斷這個模型是否靠譜?能不能像Grad-CAM那樣對分類結果給出一個解釋呢?歡迎關註下一篇文章,憑什麽相信你,我的CNN模型?(篇二:萬金油LIME)。

grad-cam 、cam 和熱力圖,基於keras的實現