天天看點

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

本文代碼位址:

https://github.com/AINewHorizon/visualising-cnns

機器在了解和識别圖像中的特征和對象方面已經達到了99%的準确度。智能手機可以識别相機中的臉部;能夠使用Google圖像搜尋特定照片; 從條形碼或書籍掃描文本。所有這一切都歸功于卷積神經網絡(CNN),這是一種特殊類型的神經網絡,也稱為  convnet。

如果你是一個深度學習[1]愛好者,你可能已經聽說過卷積神經網絡,也許你自己甚至開發了一些圖像分類器。像Tensorflow和PyTorch這樣的現代深度學習架構可以很容易地向機器訓練圖像,但是,仍然存在一些問題,如資料如何通過神經網絡的人工層?計算機如何從中學習?如何更好地解釋卷積神經網絡。是以讓我們通過每一層可視化圖像,深入了解CNN。

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡

卷積神經網絡解釋

什麼是卷積神經網絡?

卷積神經網絡(CNN)是一種特殊類型的神經網絡,在圖像上工作得非常好。由Yan LeCun于1998年提出,卷積神經網絡可以識别給定輸入圖像中存在的數字。

在開始使用卷積神經網絡之前,了解神經網絡的工作原理非常重要。神經網絡模仿人類大腦如何解決複雜問題并在給定資料集中找到模式。在過去幾年中,神經網絡已經吞噬了許多機器學習和計算機視覺算法[2]。

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

另一方面,CNN是一種特殊類型的神經網絡,它在圖像上工作得非常好。由Yan LeCun于1998年提出,卷積神經網絡可以識别給定輸入圖像中存在的數字。使用CNN的其他應用包括語音識别,圖像分割和文本處理。在卷積神經網絡之前,多層感覺器(MLP)被用于建構圖像分類器。

圖像分類是指從多波段光栅圖像中提取資訊類的任務。多層感覺器需要更多時間和空間來查找圖檔中的資訊,因為每個輸入特征都需要與下一層中的每個神經元連接配接。CNN通過使用稱為局部連接配接的概念來超越MLP,該概念涉及将每個神經元連接配接到僅輸入音量的局部區域。這通過允許網絡的不同部分專門處理諸如紋理或重複模式的進階特征來最小化參數的數量。迷茫?别擔心。讓我們比較一下如何通過多層感覺器和卷積神經網絡發送圖像,以便更好地了解。

比較MLPS和CNNS

考慮到MNIST資料集,多層感覺器的輸入層的條目總數将為784,因為輸入圖像的大小為28x28 = 784。網絡應該能夠預測給定輸入圖像中的數字,這意味着輸出可能屬于以下任何類别,範圍從0-9(1,2,3,4,5,6,7,8,9) )。在輸出層,我們傳回類别分數,比如說給定輸入是一個數字為"3"的圖像,那麼在輸出層中,相應的神經元"3"與其他神經元相比具有更高的類别分數。**我們需要包含多少個隐藏層以及每個隐藏層應該包含多少個神經元?**這是一個編碼MLP的示例:

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡pytorch可視化mlp

上面的代碼片段使用名為Keras的架構實作(暫時忽略文法)。它告訴我們在第一個隐藏層中有512個神經元,它們連接配接到形狀784的輸入層。隐藏層後面是一個丢失層,它克服了過度拟合的問題**。**0.2表示在第一個隐藏層之後沒有考慮神經元的可能性為20%。同樣,我們添加了第二個隐藏層,其具有與第一個隐藏層(512)中相同數量的神經元,然後是另一個丢失層。最後,我們以包含10個類的輸出層結束這組圖層。具有最高值的該類将是模型預測的數量。

這是在定義所有層之後多層網絡的樣子。這種多層感覺器的一個缺點是連接配接完整(完全連接配接)以供網絡學習,這需要更多的時間和空間。MLP隻接受向量作為輸入。

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡pytorch可視化圖像分類器

卷積不使用全連接配接層,而是稀疏連接配接的層,即它們接受矩陣作為輸入,這是優于MLP的優勢。輸入功能連接配接到本地編碼節點。在MLP中,每個節點都有責任了解整個畫面。在CNN中,我們将圖像分解為區域(像素的小局部區域)。每個隐藏節點必須向輸出層報告,其中輸出層将接收的資料組合以查找模式。下圖顯示了各層如何在本地連接配接。

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡pytorch可視化cnn

在我們了解CNN如何在圖檔中查找資訊之前,我們需要了解如何提取這些功能。卷積神經網絡使用不同的層,每層儲存圖像中的特征。例如,考慮一張狗的照片。每當網絡需要對狗進行分類時,它應該識别所有特征 - 眼睛,耳朵,舌頭,腿等 - 并且使用濾波器和核心在網絡的本地層中分解和識别這些特征。

計算機如何了解圖像?

與通過用眼睛拍攝快照來了解圖像的人類不同,計算機使用0到255之間的一組像素值來了解圖像。計算機檢視這些像素值并了解它們。乍一看,它不知道對象或顔色,它隻是識别像素值,這是計算機的所有圖像。

在分析像素值之後,計算機慢慢開始了解圖像是灰階還是彩色。它知道差異,因為灰階圖像隻有一個通道,因為每個像素代表一種顔色的強度。零表示黑色,255表示白色,黑色和白色的其他變化,即灰色位于兩者之間。另一方面,彩色圖像有三個通道 - 紅色,綠色和藍色。這些代表三種顔色(3D矩陣)的強度,當值同時變化時,它會産生一組顔色!在計算出顔色屬性後,計算機會識别圖像中對象的曲線和輪廓。

可以在卷積神經網絡中使用PyTorch來加載資料集并對圖像應用濾波器來探索該過程。以下是代碼段。

# Load the libraries
import torch
import numpy as np

from 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 inline

dataiter = 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()))
           
通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡pytorch可視化輸入資料

現在讓我們看看如何将單個圖像輸入神經網絡。

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代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

單張圖檔像素可視化

這就是将數字"3"分解為像素的方式。在一組手寫數字中,随機選擇"3",其中示出了像素值。在這裡,ToTensor()将實際像素值(0-255)标準化,并将它們限制在0到1之間。為什麼?因為,它使得後面部分的計算更容易,無論是解釋圖像還是找到它們中存在的常見模式。

建構濾波器

在卷積神經網絡中,過濾圖像中的像素資訊。為什麼我們需要一個濾波器?就像孩子一樣,計算機需要經曆了解圖像的學習過程。值得慶幸的是,這不需要多年的時間!計算機通過從頭學習,然後繼續前進到整體來實作這一目标。是以,網絡必須首先知道圖像中的所有原始部分,如邊緣,輪廓和其他低級特征。一旦檢測到這些,計算機就可以處理更複雜的功能。簡而言之,必須首先提取低級功能,然後提取中級功能,然後是進階功能。濾波器提供了一種提取資訊的方法。

可以使用特定濾波器提取低級特征,該濾波器也是一組像素值,類似于圖像。可以了解為連接配接CNN中的層的權重。這些權重或濾波器與輸入相乘以得到中間圖像,其描繪了計算機對圖像的部分了解。之後,這些副産品将與多個濾波器相乘以擴充視圖。這個過程以及功能的檢測一直持續到計算機了解它所看到的内容為止。

根據您的需要,您可以使用許多濾波器。您可能想要模糊,銳化,變暗,進行邊緣檢測等 - 所有都是濾波器。

讓我們看一些代碼片段來了解濾波器的功能。

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

輸入圖像代碼段

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

輸入狗的圖像

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

定義一個濾波器

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

對輸入圖像狗進行濾波

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

完整的CNNS

到目前為止,我們已經看到濾波器如何用于從圖像中提取特征,但是為了完成整個卷積神經網絡,我們需要了解我們用來設計它的層。CNN中使用的層稱為:

  1. 卷積層
  2. 池化層
  3. 全連接配接層

使用這三個層,卷積圖像分類器如下所示:

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積神經網絡

現在讓我們看看每個層的作用:

卷積層 - 卷積層(CONV)使用濾波器執行卷積操作,同時掃描輸入圖像的尺寸。其超參數包括濾波器大小,可以是2x2,3x3,4x4,5x5(但不僅限于這些)和步幅(S)。生成的輸出(O)稱為  要素圖或激活圖,并具有使用輸入圖層和濾波器計算的所有要素。下圖描繪了應用卷積時特征貼圖的生成:

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積運算

池化層 - 該池化層(POOL)用于所述特征采樣和一個卷積層之後典型地施加。兩種類型的池化操作稱為最大和平均池,其中分别采用要素的最大值和平均值。下面,描述了池化操作的工作:

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

最大池化操作

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

平均池化操作

**全連接配接層 - **全連接配接層(FC)在平坦的輸入上操作,其中每個輸入連接配接到所有神經元。這些通常在網絡末端用于将隐藏層連接配接到輸出層,這有助于優化課程分數。

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

全連接配接層

在PYTORCH中可視化CNNS

現在我們已經更好地了解CNN如何運作,現在讓我們使用Facebook的PyTorch  架構實作一個CNN。

步驟1:  加載應通過網絡發送的輸入圖像。我們将使用Numpy和OpenCV。

import cv2
import matplotlib.pyplot as plt
%matplotlib inline
img_path = 'dog.jpg'
bgr_img = cv2.imread(img_path)
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)

# Normalise
gray_img = gray_img.astype("float32")/255
plt.imshow(gray_img, cmap='gray')
plt.show()
           
通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

可視化濾波器

第2步: 可視化濾波器以更好地了解我們将使用哪些濾波器。

import numpy as np
filter_vals = np.array([
  [-1, -1, 1, 1],
  [-1, -1, 1, 1],
  [-1, -1, 1, 1],
  [-1, -1, 1, 1]
])

print('Filter shape: ', filter_vals.shape)

# Defining the Filters

filter_1 = filter_vals
filter_2 = -filter_1
filter_3 = filter_1.T
filter_4 = -filter_3
filters = np.array([filter_1, filter_2, filter_3, filter_4])

# Check the Filters
fig = plt.figure(figsize=(10, 5))
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))
    width, height = filters[i].shape
    for x in range(width):
        for y in range(height):
            ax.annotate(str(filters[i][x][y]), xy=(y,x),
                        color='white' if filters[i][x][y]<0 else 'black')
           
通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

定義CNN

第3步: 定義CNN。該CNN具有卷積層和最大池化層,并且使用上述濾波器初始化權重:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):

    def __init__(self, weight):
        super(Net, self).__init__()
        # initializes the weights of the convolutional layer to be the weights of the 4 defined filters
        k_height, k_width = weight.shape[2:]
        # assumes there are 4 grayscale filters
        self.conv = nn.Conv2d(1, 4, kernel_size=(k_height, k_width), bias=False)
        # initializes the weights of the convolutional layer
        self.conv.weight = torch.nn.Parameter(weight)
        # define a pooling layer
        self.pool = nn.MaxPool2d(2, 2)

    def forward(self, x):
        # calculates the output of a convolutional layer
        # pre- and post-activation
        conv_x = self.conv(x)
        activated_x = F.relu(conv_x)

        # applies pooling layer
        pooled_x = self.pool(activated_x)

        # returns all layers
        return conv_x, activated_x, pooled_x

# instantiate the model and set the weights
weight = torch.from_numpy(filters).unsqueeze(1).type(torch.FloatTensor)
model = Net(weight)

# print out the layer in the network
print(model)
           
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步:  可視化濾波器。以下是對所用濾波器的快速浏覽。

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代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

濾波器

第5步:  跨層過濾輸出。在CONV和POOL層輸出的圖像如下所示。

viz_layer(activated_layer)
viz_layer(pooled_layer)
           

Conv Layers

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

卷積層

池化層

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

池化層

本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

請長按或掃描二維碼關注本公衆号

喜歡的話,請給我個在看吧!

通過Pytorch代碼可視化了解卷積神經網絡本文代碼位址:https://github.com/AINewHorizon/visualising-cnns

參考資料

[1]

深度學習: https://builtin.com/artificial-intelligence/deep-learning

[2]

機器學習和計算機視覺算法: https://builtin.com/data-science/tour-top-10-algorithms-machine-learning-newbies

[3]

Python深度學習的: https://builtin.com/data-science/deep-learning-python