談談機器學習模型的可解釋性

深度學習一直被認爲是一個黑盒子,可是試圖對模型的理解仍然是很是必要的。先從一個例子來講明解釋神經網絡的重要性:古代一個小鎮上的一匹馬可以作數學題,好比給它一個題目 2+3 ,它踏馬蹄 5 下後就會停下,這匹馬被當地稱做神馬漢斯。後來人們發現,漢斯其實並不會作數學題,它經過觀察主人的反應來判斷何時停下。所以當一個訓練好的網絡模型根據輸入來輸出他的答案時,有時候雖然也能獲得正確的結果,可是咱們更多時候還須要知道網絡輸出這個結果的緣由,這樣可以幫助咱們來判斷模型獲得的這個結果是否可靠。進一步地,咱們能夠憑藉解釋的結果來進一步優化咱們的模型,而不只僅是從結果層面來進行約束git

在以前的一篇研究中,網絡可以準確地將一幅大熊貓地圖片識別爲大熊貓,可是當這張圖片混有必定的噪聲時,網絡識別的結果是長臂猿。因而可知,網絡有時候只能根據數據集和損失函數來優化它的擬合過程,可是網絡具體作出決定依靠的是圖像的哪些特徵則很難進行判斷。就像考試的目的是爲了讓學生更好地掌握書本知識,而後取得高分,每每咱們會經過題海戰術來更方便快捷地總結出題規律,能達到更好的效果,這顯然與素質教育的本質背道而馳。github

筆者曾在2021年CVPR上發表過一篇關於圖像去噪的文章,裏面提到了「提升神經網絡的可解釋性」,最近在面試中常常被問到相關的問題,可是我回答的老是不能令面試官滿意,直到真正瞭解到針對神經網絡可解釋性的文章,我才明白其中的區別:面試

  1. 咱們文章的可解釋性是針對在網絡設計時網絡結構,模塊等都是經驗性地選取,所以咱們根據傳統的算法進行理論推導,而後使用神經網絡的擬合能力對理論進行建模,完成整個網絡的設計過程;
  2. 而本篇文章提到的可解釋性是對網絡輸出結果的緣由進行討論,試圖解釋網絡輸出結果的緣由,來幫助咱們判斷模型獲得的結果是否可靠。

Local Explanation主要解釋作出決定的緣由,好比一張圖片模型輸出是貓,那麼local explanation的目的就是解釋爲何它以爲這張圖片是貓?很容易想到關於Attention機制的一些研究,經過 Attention 機制可以給特徵賦予不一樣的空間和通道權重,從而使網絡更加劇視重要信息。一般在解釋Attention的效果時,會採用 Salience Map 來表示。以下圖所示:算法

在 Salience Map 中,較亮的部分表明對網絡影響最重要的區域。好比在分類任務中,判斷是不是猴子網絡主要感興趣的區域確實是猴子,而不是其餘的內容。所以,Salience Map 就至關於網絡作出決定所給出的理由。那麼 Salience Map 是怎麼得出來的呢?

想象一下:若是我對圖片的某個區域作干擾,那麼若是干擾後影響了網絡的判斷結果,證實該干擾區域在網絡作出判斷時是重要的,反之則不重要。數學描述爲:對於輸入 \(X = [x_{1},x_{2},...x_{n}]\),其中 \(x_{i}\) 表明了每一個輸入,對於圖片而言就是每一個像素點。若是判斷 \(x_{i}\) 對輸出 \(y\) 的影響,那麼能夠給 \(x_{i}\) 增長一個擾動 \(\Delta x_{i}\),相應地輸出結果的變化量爲 \(\Delta y\),因而 \(x_{i}\) 的重要程度就能夠描述爲:網絡

\[\dfrac{\Delta y}{\Delta x_{i}} = \dfrac{\partial y}{ \partial x_{i}} \]

計算 Salience Map 的PyTorch代碼以下:函數

def compute_saliency_maps(X, y, model):
    """
    X表示圖片, y表示分類結果, model表示使用的與訓練好的分類模型
    輸出爲salience map: A Tensor of shape (N, H, W)
    """
    # 確保model是test模式
    model.eval()
    # 確保X是須要gradient
    X.requires_grad_()
    saliency = None
    logits = model.forward(X)
    logits.backward(torch.FloatTensor([1.]))  # 計算梯度
    saliency = abs(X.grad.data)  # 返回X的梯度絕對值大小
    saliency, _ = torch.max(saliency, dim=1)
    return saliency.squeeze()

輸出結果以下:學習

可是 Salience Map 會存在一些問題,好比判斷一個動物是不是大象,長鼻子是其中一個很是明顯的特徵,可是當鼻子長到必定程度時,再增長鼻子的長度絲絕不會改變網絡的判斷結果,此時鼻子的長度對網絡判斷的貢獻就很小。

除了 Salience Map 外,類激活的熱力圖也能夠顯示原始圖片的不一樣區域對某個CNN輸出結果的 「貢獻」 程度,以下圖所示:優化

類激活的熱力圖在文獻 "Grad-CAM: visual explanations from deep networks via gradient-based localization" 首次被提出,方法能夠總結爲:給定一張輸入圖像,對於一個卷積層的輸出特徵圖,用類別相對於通道的梯度對這個特徵圖中的每一個通道進行加權。直觀上來看,理解這個技巧的一種方法是,你是用 「每一個通道對類別的重要程度」 對 「輸入圖像對不一樣通道的激活強度」 的空間圖進行加權,從而獲得了 「輸入圖像對類別的激活強度」 的空間圖。參考代碼連接:https://github.com/jacobgil/pytorch-grad-cam

其實對於神經網絡而言,它所看到的只是一堆數據而已,經過損失函數可使模型將這一堆數據映射爲咱們想要的值,其實人是沒法真正理解機器想的是什麼的,這些只是想找一些合理的方法來將機器想的內容合理化爲人們所指望的那個樣子而已。因此對一些新入門的朋友而言,沒必要過度糾結於神經網絡究竟是怎麼實現特定的功能的,就像一位大佬說過:The question of whether machines could think was 「about as relevant as the question of whether Submarines Can Swim. 我的理解就是:思考和游泳都是人類具備的屬性,目的可以幫助咱們解決事情或者可以在水裏生存,可是反過來不必定成立,解決事情或者在水裏生存不必定非要是咱們人類具備的屬性,機器也能擁有這些,可是他們在以什麼樣的方式進行工做,咱們不得而知,討論這個問題也就沒什麼意義,咱們只須要關心結果是不是咱們所須要的就好了。ui

相關文章
相關標籤/搜索