PyTorch可视化理解卷积神经网络
如今,機(jī)器已經(jīng)能夠在理解、識(shí)別圖像中的特征和對(duì)象等領(lǐng)域?qū)崿F(xiàn)99%級(jí)別的準(zhǔn)確率。生活中,我們每天都會(huì)運(yùn)用到這一點(diǎn),比如,智能手機(jī)拍照的時(shí)候能夠識(shí)別臉部、在類似于谷歌搜圖中搜索特定照片、從條形碼掃描文本或掃描書籍等。造就機(jī)器能夠獲得在這些視覺(jué)方面取得優(yōu)異性能可能是源于一種特定類型的神經(jīng)網(wǎng)絡(luò)——卷積神經(jīng)網(wǎng)絡(luò)(CNN)。如果你是一個(gè)深度學(xué)習(xí)愛(ài)好者,你可能早已聽(tīng)說(shuō)過(guò)這種神經(jīng)網(wǎng)絡(luò),并且可能已經(jīng)使用一些深度學(xué)習(xí)框架比如caffe、TensorFlow、pytorch實(shí)現(xiàn)了一些圖像分類器。然而,這仍然存在一個(gè)問(wèn)題:數(shù)據(jù)是如何在人工神經(jīng)網(wǎng)絡(luò)傳送以及計(jì)算機(jī)是如何從中學(xué)習(xí)的。為了從頭開(kāi)始獲得清晰的視角,本文將通過(guò)對(duì)每一層進(jìn)行可視化以深入理解卷積神經(jīng)網(wǎng)絡(luò)。
卷積神經(jīng)網(wǎng)絡(luò)
在學(xué)習(xí)卷積神經(jīng)網(wǎng)絡(luò)之前,首先要了解神經(jīng)網(wǎng)絡(luò)的工作原理。神經(jīng)網(wǎng)絡(luò)是模仿人類大腦來(lái)解決復(fù)雜問(wèn)題并在給定數(shù)據(jù)中找到模式的一種方法。在過(guò)去幾年中,這些神經(jīng)網(wǎng)絡(luò)算法已經(jīng)超越了許多傳統(tǒng)的機(jī)器學(xué)習(xí)和計(jì)算機(jī)視覺(jué)算法。“神經(jīng)網(wǎng)絡(luò)”是由幾層或多層組成,不同層中具有多個(gè)神經(jīng)元。每個(gè)神經(jīng)網(wǎng)絡(luò)都有一個(gè)輸入和輸出層,根據(jù)問(wèn)題的復(fù)雜性增加隱藏層的個(gè)數(shù)。一旦將數(shù)據(jù)送入網(wǎng)絡(luò)中,神經(jīng)元就會(huì)學(xué)習(xí)并進(jìn)行模式識(shí)別。一旦神經(jīng)網(wǎng)絡(luò)模型被訓(xùn)練好后,模型就能夠預(yù)測(cè)測(cè)試數(shù)據(jù)。
另一方面,CNN是一種特殊類型的神經(jīng)網(wǎng)絡(luò),它在圖像領(lǐng)域中表現(xiàn)得非常好。該網(wǎng)絡(luò)是由YanLeCunn在1998年提出的,被應(yīng)用于數(shù)字手寫體識(shí)別任務(wù)中。其它應(yīng)用領(lǐng)域包括語(yǔ)音識(shí)別、圖像分割和文本處理等。在CNN被發(fā)明之前,多層感知機(jī)(MLP)被用于構(gòu)建圖像分類器。圖像分類任務(wù)是指從多波段(彩色、黑白)光柵圖像中提取信息類的任務(wù)。MLP需要更多的時(shí)間和空間來(lái)查找圖片中的信息,因?yàn)槊總€(gè)輸入元素都與下一層中的每個(gè)神經(jīng)元連接。而CNN通過(guò)使用稱為局部連接的概念避免這些,將每個(gè)神經(jīng)元連接到輸入矩陣的局部區(qū)域。這通過(guò)允許網(wǎng)絡(luò)的不同部分專門處理諸如紋理或重復(fù)模式的高級(jí)特征來(lái)最小化參數(shù)的數(shù)量。下面通過(guò)比較說(shuō)明上述這一點(diǎn)。
比較MLP和CNN
因?yàn)檩斎雸D像的大小為28x28=784(MNIST數(shù)據(jù)集),MLP的輸入層神經(jīng)元總數(shù)將為784。網(wǎng)絡(luò)預(yù)測(cè)給定輸入圖像中的數(shù)字,輸出數(shù)字范圍是0-9。在輸出層,一般返回的是類別分?jǐn)?shù),比如說(shuō)給定輸入是數(shù)字“3”的圖像,那么在輸出層中,相應(yīng)的神經(jīng)元“3”與其它神經(jīng)元相比具有更高的類別分?jǐn)?shù)。這里又會(huì)出現(xiàn)一個(gè)問(wèn)題,模型需要包含多少個(gè)隱藏層,每層應(yīng)該包含多少神經(jīng)元?這些都是需要人為設(shè)置的,下面是一個(gè)構(gòu)建MLP模型的例子:
Num_classes = 10 Model = Sequntial() Model.add(Dense(512, activation=’relu’, input_shape=(784, ))) Model.add(Dropout(0.2)) Model.add(Dense(512, activation=’relu’)) Model.add(Dropout(0.2)) Model.add(Dense(num_classes, activation=’softmax’))上面的代碼片段是使用Keras框架實(shí)現(xiàn)(暫時(shí)忽略語(yǔ)法錯(cuò)誤),該代碼表明第一個(gè)隱藏層中有512個(gè)神經(jīng)元,連接到維度為784的輸入層。隱藏層后面加一個(gè)dropout層,丟棄比例設(shè)置為0.2,該操作在一定程度上克服過(guò)擬合的問(wèn)題。之后再次添加第二個(gè)隱藏層,也具有512谷歌神經(jīng)元,然后再添加一個(gè)dropout層。最后,使用包含10個(gè)類的輸出層完成模型構(gòu)建。其輸出的向量中具有最大值的該類將是模型的預(yù)測(cè)結(jié)果。
這種多層感知器的一個(gè)缺點(diǎn)是層與層之間完全連接,這導(dǎo)致模型需要花費(fèi)更多的訓(xùn)練時(shí)間和參數(shù)空間。并且,MLP只接受向量作為輸入。
卷積使用稀疏連接的層,并且其輸入可以是矩陣,優(yōu)于MLP。輸入特征連接到局部編碼節(jié)點(diǎn)。在MLP中,每個(gè)節(jié)點(diǎn)都有能力影響整個(gè)網(wǎng)絡(luò)。而CNN將圖像分解為區(qū)域(像素的小局部區(qū)域),每個(gè)隱藏節(jié)點(diǎn)與輸出層相關(guān),輸出層將接收的數(shù)據(jù)進(jìn)行組合以查找相應(yīng)的模式。
計(jì)算機(jī)如何查看輸入的圖像?
看著圖片并解釋其含義,這對(duì)于人類來(lái)說(shuō)很簡(jiǎn)單的一件事情。我們生活在世界上,我們使用自己的主要感覺(jué)器官(即眼睛)拍攝環(huán)境快照,然后將其傳遞到視網(wǎng)膜。這一切看起來(lái)都很有趣。現(xiàn)在讓我們想象一臺(tái)計(jì)算機(jī)也在做同樣的事情。
在計(jì)算機(jī)中,使用一組位于0到255范圍內(nèi)的像素值來(lái)解釋圖像。計(jì)算機(jī)查看這些像素值并理解它們。乍一看,它并不知道圖像中有什么物體,也不知道其顏色。它只能識(shí)別出像素值,圖像對(duì)于計(jì)算機(jī)來(lái)說(shuō)就相當(dāng)于一組像素值。之后,通過(guò)分析像素值,它會(huì)慢慢了解圖像是灰度圖還是彩色圖。灰度圖只有一個(gè)通道,因?yàn)槊總€(gè)像素代表一種顏色的強(qiáng)度。0表示黑色,255表示白色,二者之間的值表明其它的不同等級(jí)的灰灰色。彩色圖像有三個(gè)通道,紅色、綠色和藍(lán)色,它們分別代表3種顏色(三維矩陣)的強(qiáng)度,當(dāng)三者的值同時(shí)變化時(shí),它會(huì)產(chǎn)生大量顏色,類似于一個(gè)調(diào)色板。之后,計(jì)算機(jī)識(shí)別圖像中物體的曲線和輪廓。。
下面使用PyTorch加載數(shù)據(jù)集并在圖像上應(yīng)用過(guò)濾器:
# Load the libraries import torch import numpy as npfrom torchvision import datasets import torchvision.transforms as transforms# Set the parameters num_workers = 0 batch_size = 20# Converting the Images to tensors using Transforms transform = transforms.ToTensor()train_data = datasets.MNIST(root='data', train=True,download=True, transform=transform) test_data = datasets.MNIST(root='data', train=False,download=True, transform=transform)# Loading the Data train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size,num_workers=num_workers) test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, num_workers=num_workers)import matplotlib.pyplot as plt %matplotlib inlinedataiter = iter(train_loader) images, labels = dataiter.next() images = images.numpy()# Peeking into dataset fig = plt.figure(figsize=(25, 4)) for image in np.arange(20):ax = fig.add_subplot(2, 20/2, image+1, xticks=[], yticks=[])ax.imshow(np.squeeze(images[image]), cmap='gray')ax.set_title(str(labels[image].item()))?
下面看看如何將單個(gè)圖像輸入神經(jīng)網(wǎng)絡(luò)中:
img = np.squeeze(images[7])fig = plt.figure(figsize = (12,12)) ax = fig.add_subplot(111) ax.imshow(img, cmap='gray') width, height = img.shape thresh = img.max()/2.5 for x in range(width):for y in range(height):val = round(img[x][y],2) if img[x][y] !=0 else 0ax.annotate(str(val), xy=(y,x),color='white' if img[x][y]<thresh else 'black')上述代碼將數(shù)字'3'圖像分解為像素。在一組手寫數(shù)字中,隨機(jī)選擇“3”。并且將實(shí)際像素值(0-255 )標(biāo)準(zhǔn)化,并將它們限制在0到1的范圍內(nèi)。歸一化的操作能夠加快模型訓(xùn)練收斂速度。
構(gòu)建過(guò)濾器
過(guò)濾器,顧名思義,就是過(guò)濾信息。在使用CNN處理圖像時(shí),過(guò)濾像素信息。為什么需要過(guò)濾呢,計(jì)算機(jī)應(yīng)該經(jīng)歷理解圖像的學(xué)習(xí)過(guò)程,這與孩子學(xué)習(xí)過(guò)程非常相似,但學(xué)習(xí)時(shí)間會(huì)少的多。簡(jiǎn)而言之,它通過(guò)從頭學(xué)習(xí),然后從輸入層傳到輸出層。因此,網(wǎng)絡(luò)必須首先知道圖像中的所有原始部分,即邊緣、輪廓和其它低級(jí)特征。檢測(cè)到這些低級(jí)特征之后,傳遞給后面更深的隱藏層,提取更高級(jí)、更抽象的特征。過(guò)濾器提供了一種提取用戶需要的信息的方式,而不是盲目地傳遞數(shù)據(jù),因?yàn)橛?jì)算機(jī)不會(huì)理解圖像的結(jié)構(gòu)。在初始情況下,可以通過(guò)考慮特定過(guò)濾器來(lái)提取低級(jí)特征,這里的濾波器也是一組像素值,類似于圖像。可以理解為連接卷積神經(jīng)網(wǎng)絡(luò)中的權(quán)重。這些權(quán)重或?yàn)V波器與輸入相乘以得到中間圖像,描繪了計(jì)算機(jī)對(duì)圖像的部分理解。之后,這些中間層輸出將與多個(gè)過(guò)濾器相乘以擴(kuò)展其視圖。然后提取到一些抽象的信息,比如人臉等。
就“過(guò)濾”而言,我們有很多類型的過(guò)濾器。比如模糊濾鏡、銳化濾鏡、變亮、變暗、邊緣檢測(cè)等濾鏡。
下面用一些代碼片段來(lái)理解過(guò)濾器的特征:
?
# 轉(zhuǎn)換為灰度圖 gray = cv2.cvtColor(image, cv2.COLOR_RB2GRAY)# 定義sobel過(guò)濾器 sobel = np.array([-1, -2, -1], [0, 0, 0], [1, 2, 1])) # 應(yīng)用sobel過(guò)濾器 Filtered_image = cv2.filter2D(gray, -1, sobel_y) # 畫圖 Plt.imshow(filtered_image, cmp=’gray’)?
以上是應(yīng)用sobel邊緣檢測(cè)濾鏡后圖像的樣子, 可以看到檢測(cè)出輪廓信息。
完整的CNN結(jié)構(gòu)
? ? ? ? 到目前為止,已經(jīng)看到了如何使用濾鏡從圖像中提取特征。現(xiàn)在要完成整個(gè)卷積神經(jīng)網(wǎng)絡(luò),cnn使用的層是:
- 1.卷積層(Convolutional layer)
- 2.池層(Pooling layer)
- 3.全連接層(fully connected layer)
典型的cnn網(wǎng)絡(luò)結(jié)構(gòu)是由上述三類層構(gòu)成:
下面讓我們看看每個(gè)圖層起到的的作用:
* 卷積層(CONV)——使用過(guò)濾器執(zhí)行卷積操作。因?yàn)樗鼟呙栎斎雸D像的尺寸。它的超參數(shù)包括濾波器大小,可以是2x2、3x3、4x4、5x5(或其它)和步長(zhǎng)S。結(jié)果輸出O稱為特征映射或激活映射,具有使用輸入層計(jì)算的所有特征和過(guò)濾器。下面描繪了應(yīng)用卷積的工作過(guò)程:
- ?池化層(POOL)——用于特征的下采樣,通常在卷積層之后應(yīng)用。池化處理方式有多種類型,常見(jiàn)的是最大池化(max pooling)和平均池化(ave pooling),分別采用特征的最大值和平均值。下面描述了池化的工作過(guò)程:
?
- ?全連接層(FC)——在展開(kāi)的特征上進(jìn)行操作,其中每個(gè)輸入連接到所有的神經(jīng)元,通常在網(wǎng)絡(luò)末端用于將隱藏層連接到輸出層,下圖展示全連接層的工作過(guò)程:
在PyTorch中可視化CNN
在了解了CNN網(wǎng)絡(luò)的全部構(gòu)件后,現(xiàn)在讓我們使用PyTorch框架實(shí)現(xiàn)CNN。
步驟1:加載輸入圖像:
?
步驟2:可視化過(guò)濾器
對(duì)過(guò)濾器進(jìn)行可視化,以更好地了解將使用哪些過(guò)濾器:
步驟3:定義CNN模型
本文構(gòu)建的CNN模型具有卷積層和最大池層,并且使用上述過(guò)濾器初始化權(quán)重:
Net(
(conv): Conv2d(1, 4, kernel_size=(4, 4), stride=(1, 1), bias=False)
(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
步驟4:可視化過(guò)濾器
快速瀏覽一下所使用的過(guò)濾器
?
步驟5:每層過(guò)濾器的輸出
在卷積層和池化層輸出的圖像如下所示:
卷積層:
池化層:
可以看到不同層結(jié)構(gòu)得到的效果會(huì)有所差別,正是由于不同層提取到的特征不同,在輸出層集合到的特征才能很好地抽象出圖像信息。
?
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的PyTorch可视化理解卷积神经网络的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 蚂蚁金服金融级容器引擎实践之路
- 下一篇: 理解卷积神经网络的利器:9篇重要的深度学