基于pytorch的CNN算法的實現
2.1.2卷積層:
卷積層的運算方式:
一種對圖像的二次轉化,使用filter,并提取feature(特征)。
圖片1 計算機圖片
圖片2 像素型圖片
計算機圖像,所展示的圖像為圖片1所示但是機器所真正看到只是各個像素點位置的值,平常圖像為RGB格式即為三通道,每個通道R(Red),G(Green),B(Blue),并且每個通道上的像素點都有對應的值0-255(可理解為權值),三通道混合后可展現彩色。由于本課題采用圖像為灰度圖如圖片2:1X28X28(單通道28X28像素的灰度圖)值為0-1。
圖片3卷積核
計算機利用卷積運算:利用圖片3:kernal size = 5X5進行運算每個從圖片2中抽出5X5的像素進行運算,運算完后再向右一列,一行完后再進行下一行.
圖片4 卷積運算
過程即對應相乘:
卷積每一步都會執行這樣的以kernal size = 5,stride=1運算最后再一次得到1X23X23,相比以前28X28少了5行5列的信息。
那么其中會用到補0為了盡可能的保留圖片信息,padding = 2在圖片最外圈補2行2列0值,那么卷積運算在每一行就多運算了5次,則輸出的圖像又變為1X28X28的圖像。
2.1.3激活層:
神經網絡的數學基礎是處處可微的,所以選取的激活函數要能保證數據輸入與輸出也是可微的,運算特征是不斷進行循環計算,所以在每代循環過程中,每個神經元的值也是在不斷變化的。 對于圖像,我們主要采用了卷積的方式來處理,也就是對每個像素點賦予一個權值,這個操作顯然就是線性的。
但是對于我們樣本來說,不一定是線性可分的,為了解決這個問題,我們可以進行線性變化,或者我們引入非線性因素,解決線性模型所不能解決的問題。
所以在課題中使用ReLU激活函數,構建稀疏矩陣,也就是稀疏性,這個特性可以去除數據中的冗余,最大可能保留數據的特征,也就是大多數為0的稀疏矩陣來表示。其實這個特性主要是對于Relu,它就是取的max(0,x),因為神經網絡是不斷反復計算,實際上變成了它在嘗試不斷試探如何用一個大多數為0的矩陣來嘗試表達數據特征,結果因為稀疏特性的存在,反而這種方法變得運算得又快效果又好了。目前大部分的卷積神經網絡中,基本上都是采用了ReLU 函數。
2.1.4池化層:
其實也是采樣層,提取關鍵特征,并用來降低特征的維度且保留有效信息,一定程度上避免過擬合,還可以減少參數過多導致運算量過大等問題。
池化操作一般有兩種,一種是Avy Pooling,一種是max Pooling。
即從中取出2X2的方格后進行平均化再給予下一層,那么圖像就會進行壓縮為原來的1/4。
即從中取出2X2的方格后取其中最大值再給予下一層,那么圖像就會進行壓縮為原來的1/4。
2.1.5優化器:
最基礎是反向傳遞:
前向傳遞的過程比較容易理解,進行,即可得出最終結果。
反向傳遞其實是鏈式法則:X,Y,Z為輸入量中間層為P結果層為F
則:(反向傳遞的基礎過程)
利用上述方法最后加入(最小二乘法)可以概括為反向傳遞基本方法。
利用損失函數(Target與prediction之間的差值)
利用這些加上Learning Rate(α值)和Loss值的不斷減小 可以慢慢擬合曲線等等。
采用的方法Adam算法:
Adam算法就是Momentum+RMSProp的結合,添加了慣性量。也就是在反向傳遞的過程中添加了部分動量使得尋找下降速度中可以找到最快的路徑。
神經網路的架構
數據集:MNIST手寫數字數據
第一層的CNN神經網絡:
nn.Conv2d(
in_channels = 1,
out_channels = 16
kernel_size = 5,
stride =1,
padding =2,
),
nn.ReLU(),
nn.MaxPool2d(2),
線性分類器:
self.out = nn.Linear(3277,10)
優化器(Adam):
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)
loss = nn.CrossEntropyLoss()
back = loss(output,b_y)
測試數據:
test_output, _ = cnn(test_x[:10])
pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
print(pred_y, ‘prediction number’)
print(test_y[:10].numpy(), ‘real number’)
import torch
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torchvision
import matplotlib.pyplot as plt
import os#Hyper parameters
EPOCH = 1 #traning data n times to save
BATCH_SIZE = 50
LR = 0.001
DOWNLOAD_MNIST = Falsetrain_data = torchvision.datasets.MNIST(root='./mnist/',train=True, # this is training datatransform=torchvision.transforms.ToTensor(), # Converts a PIL.Image or numpy.ndarray to # torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]download=DOWNLOAD_MNIST,
)train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)test_data = torchvision.datasets.MNIST(root='./mnist/', train=False)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)test_y = test_data.test_labels[:2000]class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Sequential( #1,28,28nn.Conv2d(in_channels = 1,out_channels = 16,#16,28,28kernel_size = 5,stride =1,padding =2,#16,14,14#if stride =1 ,padding = (kernel_size-1)/2=()),nn.ReLU(),nn.MaxPool2d(2),)self.conv2 = nn.Sequential( # input shape (16, 14, 14)nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14)nn.ReLU(), # activationnn.MaxPool2d(2), # output shape (32, 7, 7))self.out = nn.Linear(32*7*7,10) # fully connected layer, output 10 classes if use two layer CNN#self.out = nn.Linear(16*14*14,10) # fully connected layer, output 10 classes if use one layer CNNdef forward(self,x):x = self.conv1(x)# x = self.conv2(x)x = x.view(x.size(0),-1)output = self.out(x)return output,xcnn = CNN()
# print(cnn)
optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # optimize all cnn parameters
loss = nn.CrossEntropyLoss() # the target label is not one-hotted
# training and testing
for epoch in range(EPOCH):for step, (b_x, b_y) in enumerate(train_loader): # gives batch data, normalize x when iterate train_loaderoutput = cnn(b_x)[0] # cnn outputback = loss(output, b_y) # cross entropy lossoptimizer.zero_grad() # clear gradients for this training stepback.backward() # backpropagation, compute gradientsoptimizer.step() # apply gradientsif step % 50 == 0:test_output, last_layer = cnn(test_x)pred_y = torch.max(test_output, 1)[1].data.squeeze().numpy()accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0))print('Epoch: ', epoch, '| train loss: %.4f' % back.data.numpy(), '| test accuracy: %.2f' % accuracy)test_output, _ = cnn(test_x[:10])
pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
print(pred_y, 'prediction number')
print(test_y[:10].numpy(), 'real number')#show the train data no.1 image
# print(train_data.train_data.size()) #60000,28,28
# print(train_data.train_labels.size())
# plt.imshow(train_data.train_data[0].numpy(), cmap = 'gray')
# plt.title('%i' %train_data.train_labels[0])
# plt.show()
總結
以上是生活随笔為你收集整理的基于pytorch的CNN算法的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。