零基礎(chǔ)也能會(huì):利用卷積神經(jīng)網(wǎng)絡(luò)(CNN)可視化特征圖和濾波器
為讓大家能夠從零掌握深度學(xué)習(xí)的相關(guān)知識(shí),學(xué)姐開(kāi)啟了pytorch構(gòu)建深度學(xué)習(xí)模型系列知識(shí)整理。前面已經(jīng)更新過(guò)兩篇,錯(cuò)過(guò)的可要回去看一看哦——《用Pytorch理解深度學(xué)習(xí)模型中的張量維度》《AI入門(mén)必讀|Pytorch神經(jīng)網(wǎng)絡(luò)設(shè)計(jì)的基本概念綜述》,今天我們來(lái)學(xué)習(xí)第三篇。
咳咳,干貨開(kāi)始,不要眨眼!

初步認(rèn)識(shí)CNN
卷積神經(jīng)網(wǎng)絡(luò)是一種特殊類型的人工神經(jīng)網(wǎng)絡(luò),廣泛應(yīng)用于圖像識(shí)別。這種架構(gòu)的成功始于 2015年,當(dāng)時(shí)憑借這種方法贏得ImageNet圖像分類挑戰(zhàn)。
你可能知道,這些方法在進(jìn)行預(yù)測(cè)方面非常強(qiáng)大,但同時(shí),它們很難理解。
比如說(shuō),有一些模型不可知的方法,如LIME和部分依賴圖,可以應(yīng)用于任何模型。但在這種情況下,應(yīng)用專為神經(jīng)網(wǎng)絡(luò)開(kāi)發(fā)的可解釋方法更有意義。與ML模型不同的是,卷積神經(jīng)網(wǎng)絡(luò)從原始圖像像素學(xué)習(xí)抽象特征。
在這篇文章中,通過(guò)逐步學(xué)習(xí)特征的可視化來(lái)說(shuō)明卷積神經(jīng)網(wǎng)絡(luò)如何學(xué)習(xí)特征。在用Pythorch實(shí)現(xiàn)之前,首先會(huì)簡(jiǎn)單解釋CNN是如何工作的,然后可視化CNN分類任務(wù)訓(xùn)練學(xué)習(xí)到的Feature map和Receptive fields(感受野)。
01?什么是CNN?

CNN由構(gòu)建塊組成:卷積層、池化層和全連接層。卷積層使用來(lái)自數(shù)據(jù)集的多個(gè)濾波器,來(lái)實(shí)現(xiàn)其主要功能——提取特征或所謂的特征圖。
來(lái)自卷積操作的特征圖的維數(shù)被池化層降低。最常用的池化操作是Maxpooling,它在特征圖的每個(gè)濾波器補(bǔ)丁中選擇最重要的像素值。因此,這兩種類型的層對(duì)于執(zhí)行特征提取很有用。
與卷積層和池化層不同的是,全連接層將提取的特征映射到最終輸出中,例如,將MNIST 的圖像分類為10位數(shù)字之一。
在數(shù)字圖像中,二維網(wǎng)格存儲(chǔ)像素值,可以被看作是一個(gè)數(shù)字?jǐn)?shù)組;內(nèi)核是一個(gè)小網(wǎng)格,通常大小為3x3,應(yīng)用于圖像的每個(gè)位置,隨著進(jìn)入更深的層次,這些功能會(huì)變得越來(lái)越復(fù)雜。
該模型的性能是使用損失函數(shù)獲得的,損失函數(shù)是輸出和目標(biāo)標(biāo)簽之間的差異,通過(guò)在訓(xùn)練集上進(jìn)行前向傳播,并且使用梯度下降算法通過(guò)反向傳播更新參數(shù),例如權(quán)重和偏差。
02?在MNIST數(shù)據(jù)集上定義和訓(xùn)練CNN
首先導(dǎo)入庫(kù)和數(shù)據(jù)集。torch是一個(gè)為一維或多維張量提供數(shù)據(jù)結(jié)構(gòu)的模塊。
重要的庫(kù)有:
torchvision?包括流行的數(shù)據(jù)集,著名的模型架構(gòu)和常見(jiàn)的圖像轉(zhuǎn)換。在本文的例子中,它提供了MNIST數(shù)據(jù)集。
torch.nn?用來(lái)構(gòu)建卷積神經(jīng)網(wǎng)絡(luò)的類和函數(shù)。
torch.optim提供所有優(yōu)化器,如Adam。
torch.nn.functional?用于導(dǎo)入函數(shù),如dropout、卷積、pooling、非線性激活函數(shù)和loss函數(shù)。
下載訓(xùn)練和測(cè)試數(shù)據(jù)集,并將圖像數(shù)據(jù)集轉(zhuǎn)換為T(mén)ensor(張量),不需要對(duì)圖像進(jìn)行標(biāo)準(zhǔn)化,因?yàn)閿?shù)據(jù)集已經(jīng)包含灰度圖像。在將訓(xùn)練數(shù)據(jù)集分為訓(xùn)練集和驗(yàn)證集之后,random_split為這兩個(gè)集合提供了一個(gè)隨機(jī)劃分分區(qū)。
DataLoader用于為訓(xùn)練、驗(yàn)證和測(cè)試集創(chuàng)建數(shù)據(jù)加載器,這些數(shù)據(jù)加載器被分成小批。batchsize是模型訓(xùn)練期間一次迭代中使用的樣本數(shù)。

定義CNN架構(gòu):
print CNN 快速預(yù)覽一下:

可以看到有兩個(gè)卷積層和兩個(gè)完全連接的層,每個(gè)卷積層后面是ReLU激活函數(shù)和maxpooling層。view function()將數(shù)據(jù)重塑為一維數(shù)組,該數(shù)組將被傳遞給線性層;第二個(gè)全連接層,也稱為輸出層,將圖像分類為 10 個(gè)數(shù)字之一。
定義用于訓(xùn)練CNN的構(gòu)建塊:
torch.device 使用GPU等硬件加速器訓(xùn)練模型
CNN network, 被移動(dòng)到設(shè)備
交叉熵?fù)p失函數(shù)和Adam優(yōu)化器
Now, 在訓(xùn)練集上訓(xùn)練網(wǎng)絡(luò)并在驗(yàn)證集上對(duì)其進(jìn)行評(píng)估:

訓(xùn)練代碼可以分為兩部分
前向傳播:
我們將輸入圖像傳遞給帶有model(images)的網(wǎng)絡(luò)。
損失是通過(guò)調(diào)用criterion(outputs,labels)其中輸出構(gòu)成預(yù)測(cè)類和標(biāo)簽構(gòu)成目標(biāo)類來(lái)計(jì)算的。
反向傳播:
梯度被清除,以確保我們不會(huì)用optimizer.zero_grad()累積其他值。
loss.backward()用于執(zhí)行Back Propagation,并根據(jù)損失計(jì)算梯度。
optimizer.step()總是在梯度計(jì)算之后。它迭代所有參數(shù)并更新它們的值。
為訓(xùn)練集和驗(yàn)證集計(jì)算損失函數(shù)和準(zhǔn)確性。
03?在測(cè)試集上評(píng)估模型
模型訓(xùn)練好后,我們可以評(píng)估測(cè)試集上的性能:

將測(cè)試代碼分解來(lái)看:
torch.no_grad() 用來(lái)禁用梯度跟蹤,我們不再需要計(jì)算梯度,因?yàn)槟P鸵呀?jīng)訓(xùn)練好了。
將輸入圖像傳遞給網(wǎng)絡(luò)。
通過(guò)添加loss.item()*images.size(0)來(lái)計(jì)算測(cè)試損失。
通過(guò)添加(predicted==labels).sum().item()來(lái)計(jì)算測(cè)試精度。
04?可視化濾波器
我們可以可視化學(xué)習(xí)到的濾波器,CNN 使用這些濾波器來(lái)卷積包含從前一層提取的特征的特征圖。可以通過(guò)迭代模型的所有層來(lái)獲得這些濾波器, list(model.children())。
如果該層是卷積層,我們可以將權(quán)重存儲(chǔ)在model_weights列表中,該列表將包含在兩個(gè)卷積層中使用的濾波器。

下面是找到的濾波器的形狀:

現(xiàn)在, 可視化第一個(gè)卷積層的學(xué)習(xí)濾波器:

下面可視化第二個(gè)卷積層的濾波器:

05?可視化特征圖
Feature Map,也稱為Activation Map,是通過(guò)卷積操作得到的,并使用filter/kernel應(yīng)用于輸入數(shù)據(jù)。下面,定義一個(gè)函數(shù)來(lái)提取應(yīng)用激活函數(shù)后得到的特征。
從訓(xùn)練數(shù)據(jù)集中,獲取代表數(shù)字9的圖像,并在第一個(gè)卷積層中可視化為該圖像獲得的特征圖。

下面在第二個(gè)卷積層中為同一圖像獲得的特征圖可視化:

END?總結(jié)
如果你能看到這里,那真的是很強(qiáng)了!至少在忍耐枯燥的學(xué)習(xí)這方面,已經(jīng)慢慢轉(zhuǎn)變?yōu)闃?lè)趣了!
如果你跟著練習(xí)了一遍,那大概率你已經(jīng)掌握了使用Pytorch將CNN學(xué)習(xí)到的特征可視化。網(wǎng)絡(luò)在其卷積層中學(xué)習(xí)新的和日益復(fù)雜的特征。從第一個(gè)卷積層到第二個(gè)卷積層,你可以看到這些特征的差異。在卷積層中走得越遠(yuǎn),特征就越抽象。
學(xué)習(xí)難題,職業(yè)規(guī)劃,缺少資料,打比賽組隊(duì)來(lái)找學(xué)姐!

代碼:
https://github.com/eugeniaring/Pytorch-tutorial/blob/main/CNN_mnist.ipynb
原文:
https://medium.com/dataseries/visualizing-the-feature-maps-and-filters-by-convolutional-neural-networks-e1462340518e
參考文檔:
https://christophm.github.io/interpretable-ml-book/cnn-features.html#feature-visualization
https://insightsimaging.springeropen.com/articles/10.1007/s13244-018-0639-9
https://github.com/eugeniaring/Pytorch-tutorial/blob/main/CNN_mnist.ipynb
三連一下,鼓勵(lì)學(xué)姐一下吧!如果文中有錯(cuò)誤歡迎指出鴨!