基於pytorch的簡易卷積神經網絡結構搭建-卷積神經網絡(CNN)淺析


卷積神經網絡

卷積神經網絡是近些年逐步興起的一種人工神經網絡結構, 因為利用卷積神經網絡在圖像和語音識別方面能夠給出更優預測結果, 這一種技術也被廣泛的傳播可應用. 卷積神經網絡最常被應用的方面是計算機的圖像識別, 不過因為不斷地創新, 它也被應用在視頻分析, 自然語言處理, 葯物發現, 等等. 近期最火的 Alpha Go, 讓計算機看懂圍棋, 同樣也是有運用到這門技術.。

卷積 和 神經網絡

我們來具體說說卷積神經網絡是如何運作的吧, 舉一個識別圖片的例子, 我們知道神經網絡是由一連串的神經層組成,每一層神經層里面有存在有很多的神經元. 這些神經元就是神經網絡識別事物的關鍵. 每一種神經網絡都會有輸入輸出值, 當輸入值是圖片的時候, 實際上輸入神經網絡的並不是那些色彩繽紛的圖案,而是一堆堆的數字. 就比如說這個. 當神經網絡需要處理這么多輸入信息的時候, 也就是卷積神經網絡就可以發揮它的優勢的時候了. 那什么是卷積神經網絡呢?

我們先把卷積神經網絡這個詞拆開來看. “卷積” 和 “神經網絡”. 卷積也就是說神經網絡不再是對每個像素的輸入信息做處理了,而是圖片上每一小塊像素區域進行處理, 這種做法加強了圖片信息的連續性. 使得神經網絡能看到圖形, 而非一個點. 這種做法同時也加深了神經網絡對圖片的理解. 具體來說, 卷積神經網絡有一個批量過濾器, 持續不斷的在圖片上滾動收集圖片里的信息,每一次收集的時候都只是收集一小塊像素區域, 然后把收集來的信息進行整理, 這時候整理出來的信息有了一些實際上的呈現, 比如這時的神經網絡能看到一些邊緣的圖片信息, 然后在以同樣的步驟, 用類似的批量過濾器掃過產生的這些邊緣信息, 神經網絡從這些邊緣信息里面總結出更高層的信息結構,比如說總結的邊緣能夠畫出眼睛,鼻子等等. 再經過一次過濾, 臉部的信息也從這些眼睛鼻子的信息中被總結出來. 最后我們再把這些信息套入幾層普通的全連接神經層進行分類, 這樣就能得到輸入的圖片能被分為哪一類的結果了.

我們截取一段 google 介紹卷積神經網絡的視頻, 具體說說圖片是如何被卷積的. 下面是一張貓的圖片, 圖片有長, 寬, 高 三個參數. 對! 圖片是有高度的! 這里的高指的是計算機用於產生顏色使用的信息. 如果是黑白照片的話, 高的單位就只有1, 如果是彩色照片, 就可能有紅綠藍三種顏色的信息, 這時的高度為3. 我們以彩色照片為例子. 過濾器就是影像中不斷移動的東西, 他不斷在圖片收集小批小批的像素塊, 收集完所有信息后, 輸出的值, 我們可以理解成是一個高度更高,長和寬更小的”圖片”. 這個圖片里就能包含一些邊緣信息. 然后以同樣的步驟再進行多次卷積, 將圖片的長寬再壓縮, 高度再增加, 就有了對輸入圖片更深的理解. 將壓縮,增高的信息嵌套在普通的分類神經層上,我們就能對這種圖片進行分類了.

 

池化(pooling)

研究發現, 在每一次卷積的時候, 神經層可能會無意地丟失一些信息. 這時, 池化 (pooling) 就可以很好地解決這一問題. 而且池化是一個篩選過濾的過程, 能將 layer 中有用的信息篩選出來, 給下一個層分析. 同時也減輕了神經網絡的計算負擔 (具體細節參考). 也就是說在卷集的時候, 我們不壓縮長寬, 盡量地保留更多信息, 壓縮的工作就交給池化了,這樣的一項附加工作能夠很有效的提高准確性. 有了這些技術,我們就可以搭建一個屬於我們自己的卷積神經網絡啦.

 

流行的 CNN 結構

 

 

 

比較流行的一種搭建結構是這樣, 從下到上的順序, 首先是輸入的圖片(image), 經過一層卷積層 (convolution), 然后在用池化(pooling)方式處理卷積的信息, 這里使用的是 max pooling 的方式. 然后在經過一次同樣的處理, 把得到的第二次處理的信息傳入兩層全連接的神經層 (fully connected),這也是一般的兩層神經網絡層,最后在接上一個分類器(classifier)進行分類預測.

卷積神經網絡模型

CNN模型 

用一個 class 來建立 CNN 模型. 這個 CNN 整體流程是 卷積(Conv2d) -> 激勵函數(ReLU) -> 池化, 向下采樣 (MaxPooling) -> 再來一遍 -> 展平多維的卷積成的特征圖 -> 接入全連接層 (Linear) -> 輸出

訓練 

訓練, 將 x y 都用 Variable 包起來, 然后放入 cnn 中計算 output, 最后再計算誤差. 

--文章根據莫煩python教學而來,下面給出相應的minist手寫體訓練代碼。

  1 import os
  2 
  3 # third-party library
  4 import torch 5 import torch.nn as nn 6 import torch.utils.data as Data 7 import torchvision 8 import matplotlib.pyplot as plt 9 10 # torch.manual_seed(1) # reproducible 11 12 # Hyper Parameters 13 EPOCH = 1 # train the training data n times, to save time, we just train 1 epoch 14 BATCH_SIZE = 50 15 LR = 0.001 # learning rate 16 DOWNLOAD_MNIST = False 17 18 19 # Mnist digits dataset 20 if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'): 21 # not mnist dir or mnist is empyt dir 22 DOWNLOAD_MNIST = True 23 24 train_data = torchvision.datasets.MNIST( 25 root='./mnist/', 26 train=True, # this is training data 27 transform=torchvision.transforms.ToTensor(), # Converts a PIL.Image or numpy.ndarray to 28 # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0] 29 download=DOWNLOAD_MNIST, 30 ) 31 32 # plot one example 33 print(train_data.train_data.size()) # (60000, 28, 28) 34 print(train_data.train_labels.size()) # (60000) 35 plt.imshow(train_data.train_data[0].numpy(), cmap='gray') 36 plt.title('%i' % train_data.train_labels[0]) 37 plt.show() 38 39 # Data Loader for easy mini-batch return in training, the image batch shape will be (50, 1, 28, 28) 40 train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True) 41 42 # pick 2000 samples to speed up testing 43 test_data = torchvision.datasets.MNIST(root='./mnist/', train=False) 44 test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000]/255. # shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1) 45 test_y = test_data.test_labels[:2000] 46 47 48 class CNN(nn.Module): 49 def __init__(self): 50 super(CNN, self).__init__() 51 self.conv1 = nn.Sequential( # input shape (1, 28, 28) 52  nn.Conv2d( 53 in_channels=1, # input height gray just have one level 54 out_channels=16, # n_filters 55 kernel_size=5, # filter size 56 stride=1, # filter movement/step 57 padding=2, # if want same width and length of this image after con2d, padding=(kernel_size-1)/2 if stride=1 58 ), # output shape (16, 28, 28) 59 nn.ReLU(), # activation 60 nn.MaxPool2d(kernel_size=2), # choose max value in 2x2 area, output shape (16, 14, 14) 61  ) 62 self.conv2 = nn.Sequential( # input shape (16, 14, 14) 63 nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14) 64 nn.ReLU(), # activation 65 nn.MaxPool2d(2), # output shape (32, 7, 7) 66  ) 67 self.out = nn.Linear(32 * 7 * 7, 10) # fully connected layer, output 10 classes 68 69 def forward(self, x): 70 x = self.conv1(x) 71 x = self.conv2(x) 72 x = x.view(x.size(0), -1) # flatten the output of conv2 to (batch_size, 32 * 7 * 7) 73 output = self.out(x) 74 return output, x # return x for visualization 75 76 77 cnn = CNN() 78 print(cnn) # net architecture 79 80 optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # optimize all cnn parameters 81 loss_func = nn.CrossEntropyLoss() # the target label is not one-hotted 82 83 # # following function (plot_with_labels) is for visualization, can be ignored if not interested 84 # from matplotlib import cm 85 # try: from sklearn.manifold import TSNE; HAS_SK = True 86 # except: HAS_SK = False; print('Please install sklearn for layer visualization') 87 # def plot_with_labels(lowDWeights, labels): 88 # plt.cla() 89 # X, Y = lowDWeights[:, 0], lowDWeights[:, 1] 90 # for x, y, s in zip(X, Y, labels): 91 # c = cm.rainbow(int(255 * s / 9)); plt.text(x, y, s, backgroundcolor=c, fontsize=9) 92 # plt.xlim(X.min(), X.max()); plt.ylim(Y.min(), Y.max()); plt.title('Visualize last layer'); plt.show(); plt.pause(0.01) 93 # 94 # plt.ion() 95 # training and testing 96 for epoch in range(EPOCH): 97 for step, (b_x, b_y) in enumerate(train_loader): # gives batch data, normalize x when iterate train_loader 98 99 output = cnn(b_x)[0] # cnn output 100 loss = loss_func(output, b_y) # cross entropy loss 101 optimizer.zero_grad() # clear gradients for this training step 102 loss.backward() # backpropagation, compute gradients 103 optimizer.step() # apply gradients 104 105 if step % 50 == 0: 106 test_output, last_layer = cnn(test_x) 107 pred_y = torch.max(test_output, 1)[1].data.squeeze().numpy() 108 accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0)) 109 print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy) 110 # if HAS_SK: 111 # # Visualization of trained flatten layer (T-SNE) 112 # tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000) 113 # plot_only = 500 114 # low_dim_embs = tsne.fit_transform(last_layer.data.nump 115 # 116 # 117 # 118 # .y()[:plot_only, :]) 119 # labels = test_y.numpy()[:plot_only] 120 # plot_with_labels(low_dim_embs, labels) 121 # plt.ioff() 122 123 # print 10 predictions from test data 124 test_output, _ = cnn(test_x[:100]) 125 126 pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze() 127 print(pred_y, 'prediction number') 128 print(test_y[:100].numpy(), 'real number')

 后續會不定期更新各種關於CNN以及RNN等神經網絡,或者梯度處理算法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM