用 Pytorch 理解卷積網路

視學演算法發表於2020-04-06

點選上方“視學演算法”,選擇“星標”公眾號

重磅乾貨,第一時間送達用 Pytorch 理解卷積網路

原標題 | CONVOLUTIONAL NEURAL NETWORKS EXPLAINED: USING PYTORCH TO UNDERSTAND CNNS

作 者 | Vihar Kurama

翻 譯 | 天字一號、雪麗•斯梅德

轉 自 | AI開發者,審 校   | 鳶尾、唐裡

注:敬請點選文末【閱讀原文】訪問文中相關連結,PC檢視體驗更佳。

在當今時代,機器在理解和識別影像中的特徵和目標方面已經成功實現了99%的精度。我們每天都會看到這種情況-智慧手機可以識別相機中的面部;使用Google圖片搜尋特定照片的能力;從條形碼或書籍中掃描文字。藉助卷積神經網路(CNN),這一切都是可能的,卷積神經網路是一種特定型別的神經網路,也稱為卷積網路。

如果您是一名深度學習愛好者,那麼您可能已經聽說過卷積神經網路,也許您甚至自己開發了一些影像分類器。像Tensorflow和PyTorch這樣的現代深度學習框架使向機器學習影像變得容易,但是,仍然存在一些問題:資料如何通過神經網路的人工層傳遞?計算機如何從中學習?更好地解釋卷積神經網路的一種方法是使用PyTorch。因此,讓我們通過視覺化每個圖層的影像來深入研究CNN。

用 Pytorch 理解卷積網路

    卷積神經網路的解釋

用 Pytorch 理解卷積網路

什麼是卷積神經網路?

卷積神經網路(CNN)是一種特殊型別的神經網路,在影像上表現特別出色。卷積神經網路由Yan LeCun在1998年提出,可以識別給定輸入影像中存在的數字。

在開始使用卷積神經網路之前,瞭解神經網路的工作原理很重要。神經網路模仿人腦如何解決複雜的問題並在給定的資料集中找到模式。在過去的幾年中,神經網路席捲了許多機器學習和計算機視覺演算法。

神經網路的基本模型由組織在不同層中的神經元組成。每個神經網路都有一個輸入層和一個輸出層,並根據問題的複雜性增加了許多隱藏層。一旦資料通過這些層,神經元就會學習並識別模式。神經網路的這種表示稱為模型。訓練完模型後,我們要求網路根據測試資料進行預測。如果您不熟悉神經網路,那麼這篇有關使用Python進行深度學習的文章就是一個很好的起點。

另一方面,CNN是一種特殊的神經網路,在影像上表現特別出色。卷積神經網路由Yan LeCun在1998年提出,可以識別給定輸入影像中存在的數字。使用CNN的其他應用程式包括語音識別,影像分割和文字處理。在卷積神經網路之前,多層感知器(MLP)用於構建影像分類器。

影像分類是指從多波段光柵影像中提取資訊類別的任務。多層感知器需要更多的時間和空間來在圖片中查詢資訊,因為每個輸入功能都需要與下一層的每個神經元相連。CNN通過使用稱為本地連線的概念取代了MLP,該概念涉及將每個神經元僅連線到輸入體積的本地區域。通過允許網路的不同部分專門處理高階功能(如紋理或重複圖案),可以最大程度地減少引數數量。感到困惑?別擔心。讓我們比較一下影像如何通過多層感知器和卷積神經網路進行傳遞的,以更好地理解。

    比較MLPS和CNNS

考慮到MNIST資料集,由於輸入影像的大小為28x28 = 784,多層感知器輸入層的總數將為784。 網路應該能夠預測給定輸入影像中的數量,這意味著輸出可能屬於以下範圍中的任何一個,範圍從0到9(1、2、3、4、5、6、7、8、9 )。 在輸出層中,我們返回類別分數,例如,如果給定的輸入是具有數字“ 3”的影像,則在輸出層中,對應的神經元“ 3”比其他神經元具有更高的類別分數。 我們需要包含多少個隱藏層,每個層中應該包含多少個神經元?這是一個編碼MLP的示例:

用 Pytorch 理解卷積網路

上面的程式碼段是使用稱為Keras的框架實現的(暫時忽略語法)。它告訴我們在第一個隱藏層中有512個神經元,它們連線到形狀為784的輸入層。該隱藏層之後是一個隨機失活層,該層克服了過擬合的問題。0.2表示在第一個隱藏層之後不考慮神經元的可能性為20%。再次,我們在第二個隱藏層中新增了與第一個隱藏層中相同數量的神經元(512),然後新增了另一個隨機失活。最後,我們用包含10個類的輸出層結束這組層。具有最高值的此類將是模型預測結果。

這是定義所有層之後的網路多層外觀。這種多層感知器的一個缺點是全連線的以供網路學習,這需要更多的時間和空間。MLP僅接受向量作為輸入。

用 Pytorch 理解卷積網路

卷積層不使用全連線層,而是使用稀疏連線層,也就是說,它們接受矩陣作為輸入,這比MLP更具優勢。輸入特徵連線到本地編碼節點。在MLP中,每個節點負責獲得對整個畫面的理解。在CNN中,我們將影像分解為區域(畫素的區域性區域)。每個隱藏節點都必須輸出層報告,在輸出層,輸出層將接收到的資料組合起來以找到模式。下圖顯示了各層如何本地連線。

用 Pytorch 理解卷積網路

在我們瞭解CNN如何在圖片中找到資訊之前,我們需要了解如何提取特徵。卷積神經網路使用不同的圖層,每一層將儲存影像中的特徵。例如,考慮一張狗的照片。每當網路需要對狗進行分類時,它都應該識別所有特徵-眼睛,耳朵,舌頭,腿等。使用過濾器和核,這些特徵被分解並在網路的區域性層中識別出來。

    計算機如何看影像?

與人類通過用眼睛瞭解影像的計算機不同,計算機使用一組介於0到255之間的畫素值來了解圖片。計算機檢視這些畫素值並理解它們。乍一看,它不知道物體或顏色,只識別畫素值,這就是影像用於計算機的全部。

在分析畫素值之後,計算機會慢慢開始瞭解影像是灰度還是彩色。它知道差異,因為灰度影像只有一個通道,因為每個畫素代表一種顏色的強度。零表示黑色,255表示白色,黑色和白色的其他變化形式,即介於兩者之間的灰色。另一方面,彩色影像具有三個通道-紅色,綠色和藍色。它們代表三種顏色(3D矩陣)的強度,並且當值同時變化時,它會產生大量的顏色!確定顏色屬性後,計算機會識別影像中物件的曲線和輪廓。

可以使用PyTorch在卷積神經網路中探索此過程,以載入資料集並將濾波器應用於影像。下面是程式碼片段。(在GitHub上可找到此程式碼)

用 Pytorch 理解卷積網路  

用 Pytorch 理解卷積網路

現在,讓我們看看如何將單個影像輸入神經網路。

(在GitHub上可找到此程式碼)

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 0
        ax.annotate(str(val), xy=(y,x),
            color='white' if img[x][y]<thresh else 'black')

用 Pytorch 理解卷積網路 

這就是將數字“ 3”分解為畫素的方式。從一組手寫數字中,隨機選擇“ 3”,其中顯示畫素值。在這裡,ToTensor()歸一化實際畫素值(0–255)並將其限制為0到1。為什麼?因為,這使得以後的部分中的計算更加容易,無論是在解釋影像還是找到影像中存在的通用模式。

    建立自己的濾波器

在卷積神經網路中,影像中的畫素資訊被過濾。為什麼我們完全需要濾波器?就像孩子一樣,計算機需要經歷瞭解影像的學習過程。值得慶幸的是,這不需要幾年的時間!計算機通過從頭開始學習,然後逐步進行到整體來完成此任務。因此,網路必須首先知道影像中的所有原始部分,例如邊緣,輪廓和其他低層特徵。一旦檢測到這些,計算機便可以處理更復雜的功能。簡而言之,必須先提取低階功能,然後再提取中級功能,然後再提取高階功能。濾波器提供了一種提取資訊的方法。

可以使用特定的濾波器提取低階特徵,該濾波器也是類似於影像的一組畫素值。可以理解為連線CNN中各層的權重。將這些權重或濾波器與輸入相乘,得出中間影像,中間影像表示計算機對影像的部分理解。然後,這些副產品再與更多的濾波器相乘以擴充套件檢視。該過程以及對功能的檢測一直持續到計算機瞭解其外觀為止。

您可以根據自己的需要使用很多濾波器。您可能需要模糊,銳化,加深,進行邊緣檢測等-都是濾波器。

讓我們看一些程式碼片段,以瞭解濾波器的功能。

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

這是應用濾波器後影像的外觀。在這種情況下,我們使用了Sobel 濾波器 。

    完整的卷積神經網路(CNNS)

我們已經知道濾波器是如何從影像中提出特徵了,但是為了完成整個卷積神經網路我們需要理解用來設計CNN的各層。卷積神經網路中的各層分別叫做:

1.卷積層

2.池化層

3.全連線層

使用這3層,可以構造類似這樣的影像分類器:

用 Pytorch 理解卷積網路

CNN各層的作用

現在讓我們一起來看看各層是用來幹什麼的

卷積層——卷積層(CONV)使用過濾器執行卷積操作,同時掃描輸入影像的尺寸。它的超引數包括濾波器尺寸,通常設定為2x2,3x3,4x4,5x5(但並不僅限於這些尺寸),步長(S)。輸出結果(O)被稱為特徵圖或啟用圖,包含了輸入層和濾波器計算出的所有特性。下圖描述了應用卷積時產生的特徵圖:

用 Pytorch 理解卷積網路

卷積操作

池化層——池化層(POOL)用於特徵的降取樣,通常在卷積層之後應用 。常見的兩種池化操作為最大池化和平均池化,分別求取特徵的最大值和平均值。下圖描述了池化的基本原理:

用 Pytorch 理解卷積網路

最大池化

用 Pytorch 理解卷積網路

平均池化

全連線層——全連線層(FC)作用於一個扁平的輸入,其中每個輸入都連線到所有的神經元 。全連線層通常用於網路的末端,將隱藏層連線到輸出層,這有助於優化類分數。 

用 Pytorch 理解卷積網路

全連線層

    在Pytorch視覺化CNN

我們對CNN的函式有了更好的瞭解,現在讓我們使用Facebook的PyTorch框架來實現它。

步驟1:載入輸入影像。我們將使用Numpy和OpenCV。(在GitHub上可找到程式碼)

用 Pytorch 理解卷積網路  

用 Pytorch 理解卷積網路  

步驟2:視覺化濾波器,以更好地瞭解我們將使用的濾波器。(在GitHub上可找到程式碼)

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

步驟3:定義卷積神經網路。該CNN具有卷積層和最大池化層,並且權重使用上述濾波器進行初始化:(在GitHub上可找到程式碼)

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

步驟4:視覺化濾波器。快速瀏覽一下正在使用的濾波器。(在GitHub上可找到程式碼)

def viz_layer(layer, n_filters= 4):
    fig = plt.figure(figsize=(20, 20))    
    
    for i in range(n_filters):
        ax = fig.add_subplot(1, n_filters, i+1)
        ax.imshow(np.squeeze(layer[0,i].data.numpy()), cmap='gray')
        ax.set_title('Output %s' % str(i+1))
fig = plt.figure(figsize=(12, 6))
fig.subplots_adjust(left=0, right=1.5, bottom=0.8, top=1, hspace=0.05, wspace=0.05)
for i in range(4):
    ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])
    ax.imshow(filters[i], cmap='gray')
    ax.set_title('Filter %s' % str(i+1))
    
gray_img_tensor = torch.from_numpy(gray_img).unsqueeze(0).unsqueeze(1)

濾波器:

用 Pytorch 理解卷積網路

步驟5:跨層濾波器輸出。 在CONV和POOL層中輸出的影像如下所示。

viz_layer(activated_layer)
viz_layer(pooled_layer)

卷積層

用 Pytorch 理解卷積網路

池化層

用 Pytorch 理解卷積網路

參考:CS230 CNNs(https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-convolutional-neural-networks).

可以在這裡檢視程式碼:https://github.com/vihar/visualising-cnns

via https://medium.com/better-programming/three-ways-to-use-the-walrus-operator-in-python-d5550f3a7dd

- END -

如果看到這裡,說明你喜歡這篇文章,請轉發、點贊掃描下方二維碼或者微信搜尋「perfect_iscas」,新增好友後即可獲得10套程式設計師全棧課程+1000套PPT和簡歷模板向我私聊「進群」二字即可進入高質量交流群。

掃描二維碼進群↓

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

用 Pytorch 理解卷積網路

在看 用 Pytorch 理解卷積網路

相關文章