基于卷积神经网络(cnn)的手写数字识别(PyTorch)
目錄
1.1 卷積神經(jīng)網(wǎng)絡(luò)簡介
1.2 神經(jīng)網(wǎng)絡(luò)
1.2.1?神經(jīng)元模型
?1.2.2 神經(jīng)網(wǎng)絡(luò)模型
1.3 卷積神經(jīng)網(wǎng)絡(luò)
1.3.1卷積的概念
1.3.2 卷積的計算過程
1.3.3?感受野
1.3.4?步長
1.3.5?輸出特征尺寸計算
?1.3.6?全零填充
1.3.7 標準化
1.3.7?池化層
?1.4 卷積神經(jīng)網(wǎng)絡(luò)的全過程
?1.5?PyTorch的卷積神經(jīng)網(wǎng)絡(luò)(cnn)手寫數(shù)字識別
1.5.1 代碼
1.1 卷積神經(jīng)網(wǎng)絡(luò)簡介
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks,簡稱:CNN)是深度學(xué)習(xí)當(dāng)中一個非常重要的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。它主要用于用在圖像圖片處理,視頻處理,音頻處理以及自然語言處理等等。
早在上世紀80年代左右,卷積神經(jīng)網(wǎng)絡(luò)的概念就已經(jīng)被提出來了。但其真正的崛起卻是在21世紀之后,21世紀之后,隨著深度學(xué)習(xí)理論的不斷完善,同時,由計算機硬件性能的提升,計算機算力的不斷發(fā)展,給卷積神經(jīng)網(wǎng)絡(luò)這種算法提供了應(yīng)用的空間。著名的AlphaGo,手機上的人臉識別,大多數(shù)都是采用卷積神經(jīng)網(wǎng)絡(luò)。因此可以說,卷積神經(jīng)網(wǎng)絡(luò)在如今的深度學(xué)習(xí)領(lǐng)域,有著舉足輕重的作用。
在了解卷積神經(jīng)網(wǎng)絡(luò)之前,我們務(wù)必要知道:什么是神經(jīng)網(wǎng)絡(luò)(Neural Networks),關(guān)于這個,我們已經(jīng)在深度學(xué)習(xí)簡介的 第二部分有所介紹。這里就不贅述了。在了解了神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)上,我們再來探究:卷積神經(jīng)網(wǎng)絡(luò)又是什么呢?當(dāng)中的“卷積”這個詞,又意味著什么呢?
?
1.2 神經(jīng)網(wǎng)絡(luò)
1.2.1?神經(jīng)元模型
人工神神經(jīng)網(wǎng)絡(luò)(neural networks)方面的研究很早就已出現(xiàn),今天“神經(jīng)網(wǎng)絡(luò)”?? ?已是一個相當(dāng)大的、多學(xué)科交叉的學(xué)科領(lǐng)域.各相關(guān)學(xué)科對神經(jīng)網(wǎng)絡(luò)的定義多種多樣。簡單單元組成的廣泛并行互連的網(wǎng)絡(luò),它的組織能夠模擬生物神經(jīng)系統(tǒng)對真實世界物體所作出的交互反應(yīng)” 。
神經(jīng)網(wǎng)絡(luò)中最基本的成分是神經(jīng)元(neuron)模型,即上述定義中的“簡單單元”,在生物神經(jīng)網(wǎng)絡(luò)中,每個神經(jīng)元與其他神經(jīng)元相連,當(dāng)它“興奮”時,就會向相連的神經(jīng)元發(fā)送化學(xué)物質(zhì),從而改變這些神經(jīng)元內(nèi)的電位;如果某神經(jīng)元的電位超過了一個“閾值”(threshold),那么它就會被激活,即“興奮”起來,向其他神經(jīng)元發(fā)送化學(xué)物質(zhì)。在這個模型中,神經(jīng)元接收到來自n個其他神經(jīng)元傳遞過來的輸入信號,這些輸入信號通過帶權(quán)重的連接(connection)進行傳遞,神經(jīng)元接收到的總輸入值將與神經(jīng)元的間值進行比較,然后通過激活函數(shù)處理,產(chǎn)生神經(jīng)元輸出。
?
?1.2.2 神經(jīng)網(wǎng)絡(luò)模型
?神經(jīng)網(wǎng)絡(luò)是一種運算模型,由大量的節(jié)點(或稱神經(jīng)元)之間相互聯(lián)接構(gòu)成。每個節(jié)點代表一種特定的輸出函數(shù),稱為激勵函數(shù)(activation function)。每兩個節(jié)點間的連接都代表一個對于通過該連接信號的加權(quán)值,稱之為權(quán)重,這相當(dāng)于人工神經(jīng)網(wǎng)絡(luò)的記憶。網(wǎng)絡(luò)的輸出則依網(wǎng)絡(luò)的連接方式,權(quán)重值和激勵函數(shù)的不同而不同。而網(wǎng)絡(luò)自身通常都是對自然界某種算法或者函數(shù)的逼近,也可能是對一種邏輯策略的表達。
?
1.3 卷積神經(jīng)網(wǎng)絡(luò)
1.3.1卷積的概念
卷積神經(jīng)網(wǎng)絡(luò)與普通神經(jīng)網(wǎng)絡(luò)的區(qū)別在于,卷積神經(jīng)網(wǎng)絡(luò)包含了一個由卷積層和子采樣層(池化層)構(gòu)成的特征抽取器。在卷積神經(jīng)網(wǎng)絡(luò)的卷積層中,一個神經(jīng)元只與部分鄰層神經(jīng)元連接。在CNN的一個卷積層中,通常包含若干個特征圖(featureMap),每個特征圖由一些矩形排列的的神經(jīng)元組成,同一特征圖的神經(jīng)元共享權(quán)值,這里共享的權(quán)值就是卷積核。卷積核一般以隨機小數(shù)矩陣的形式初始化,在網(wǎng)絡(luò)的訓(xùn)練過程中卷積核將學(xué)習(xí)得到合理的權(quán)值。共享權(quán)值(卷積核)帶來的直接好處是減少網(wǎng)絡(luò)各層之間的連接,同時又降低了過擬合的風(fēng)險。子采樣也叫做池化(pooling),通常有均值子采樣(mean pooling)和最大值子采樣(max pooling)兩種形式。子采樣可以看作一種特殊的卷積過程。卷積和子采樣大大簡化了模型復(fù)雜度,減少了模型的參數(shù)。
1.3.2 卷積的計算過程
假設(shè)我們輸入的是5*5*1的圖像,中間的那個3*3*1是我們定義的一個卷積核(簡單來說可以看做一個矩陣形式運算器),通過原始輸入圖像和卷積核做運算可以得到綠色部分的結(jié)果,怎么樣的運算呢?實際很簡單就是我們看左圖中深色部分,處于中間的數(shù)字是圖像的像素,處于右下角的數(shù)字是我們卷積核的數(shù)字,只要對應(yīng)相乘再相加就可以得到結(jié)果。例如圖中‘3*0+1*1+2*2+2*2+0*2+0*0+2*0+0*1+0*2=9’
計算過程如下動圖:
圖中最左邊的三個輸入矩陣就是我們的相當(dāng)于輸入d=3時有三個通道圖,每個通道圖都有一個屬于自己通道的卷積核,我們可以看到輸出(output)的只有兩個特征圖意味著我們設(shè)置的輸出d=2,有幾個輸出通道就有幾層卷積核(比如圖中就有FilterW0和FilterW1),這意味著我們的卷積核數(shù)量就是輸入d的個數(shù)乘以輸出d的個數(shù)(圖中就是2*3=6個),其中每一層通道圖的計算與上文中提到的一層計算相同,再把每一個通道輸出的輸出再加起來就是綠色的輸出數(shù)字。
1.3.3?感受野
感受野(Receptive Field):卷積神經(jīng)網(wǎng)絡(luò)各輸出層每個像素點在原始圖像上的映射區(qū)域大小。
下圖為感受野示意圖:
?當(dāng)我們采用尺寸不同的卷積核時,最大的區(qū)別就是感受野的大小不同,所以經(jīng)常會采用多層小卷積核來替換一層大卷積核,在保持感受野相同的情況下減少參數(shù)量和計算量。
例如十分常見的用2層3 * 3卷積核來替換1層5 * 5卷積核的方法,如下圖所示。
1.3.4?步長
每次卷積核移動的大小。
1.3.5?輸出特征尺寸計算
輸出特征尺寸計算:在了解神經(jīng)網(wǎng)絡(luò)中卷積計算的整個過程后,就可以對輸出特征圖的尺寸進行計算。如下圖所示,5×5的圖像經(jīng)過3×3大小的卷積核做卷積計算后輸出特征尺寸為3×3
?1.3.6?全零填充
當(dāng)卷積核尺寸大于 1 時,輸出特征圖的尺寸會小于輸入圖片尺寸。如果經(jīng)過多次卷積,輸出圖片尺寸會不斷減小。為了避免卷積之后圖片尺寸變小,通常會在圖片的外圍進行填充(padding),如下圖所示
全零填充(padding):為了保持輸出圖像尺寸與輸入圖像一致,經(jīng)常會在輸入圖像周圍進行全零填充,如下所示,在5×5的輸入圖像周圍填0,則輸出特征尺寸同為5×5。
當(dāng)padding=1和paadding=2時,如下圖所示:
1.3.7 標準化
使數(shù)據(jù)符合0均值,1為標準差的分布。
批標準化(Batch Normalization):對一小批數(shù)據(jù)(batch),做標準化處理。
?Batch Normalization將神經(jīng)網(wǎng)絡(luò)每層的輸入都調(diào)整到均值為0,方差為1的標準正態(tài)分布,其目的是解決神經(jīng)網(wǎng)絡(luò)中梯度消失的問題.
BN操作的另一個重要步驟是縮放和偏移,值得注意的是,縮放因子γ以及偏移因子β都是可訓(xùn)練參數(shù)。?
1.3.7?池化層
池化(Pooling)用于減少特征數(shù)據(jù)量。
最大值池化可提取圖片紋理,均值池化可保留背景特征
?1.4 卷積神經(jīng)網(wǎng)絡(luò)的全過程
?1.5?PyTorch的卷積神經(jīng)網(wǎng)絡(luò)(cnn)手寫數(shù)字識別
使用的框架為pytorch。
數(shù)據(jù)集:MNIST數(shù)據(jù)集,60000張訓(xùn)練圖像,每張圖像size為28*28。
可在http://yann.lecun.com/exdb/mnist/中獲取
1.5.1 代碼
import torch import torch.nn as nn import torchvision.datasets as dataset import torchvision.transforms as transforms import torch.utils.data as data_utils#獲取數(shù)據(jù)集 train_data=dataset.MNIST(root="D",train=True,transform=transforms.ToTensor(),download=True) test_data=dataset.MNIST(root="D",train=False,transform=transforms.ToTensor(),download=False) train_loader=data_utils.DataLoader(dataset=train_data, batch_size=100, shuffle=True) test_loader=data_utils.DataLoader(dataset=test_data, batch_size=100, shuffle=True)#創(chuàng)建網(wǎng)絡(luò) class Net(torch.nn.Module):def __init__(self):super().__init__()self.conv=nn.Conv2d(1, 32, kernel_size=5, padding=2)self.bat2d=nn.BatchNorm2d(32)self.relu=nn.ReLU()self.pool=nn.MaxPool2d(2)self.linear=nn.Linear(14 * 14 * 32, 70)self.tanh=nn.Tanh()self.linear1=nn.Linear(70,30)self.linear2=nn.Linear(30, 10)def forward(self,x):y=self.conv(x)y=self.bat2d(y)y=self.relu(y)y=self.pool(y)y=y.view(y.size()[0],-1)y=self.linear(y)y=self.tanh(y)y=self.linear1(y)y=self.tanh(y)y=self.linear2(y)return y cnn=Net() cnn=cnn.cuda()#損失函數(shù) los=torch.nn.CrossEntropyLoss()#優(yōu)化函數(shù) optime=torch.optim.Adam(cnn.parameters(), lr=0.01)#訓(xùn)練模型 for epo in range(10):for i, (images,lab) in enumerate(train_loader):images=images.cuda()lab=lab.cuda()out = cnn(images)loss=los(out,lab)optime.zero_grad()loss.backward()optime.step()print("epo:{},i:{},loss:{}".format(epo+1,i,loss))#測試模型 loss_test=0 accuracy=0 with torch.no_grad():for j, (images_test,lab_test) in enumerate(test_loader):images_test = images_test.cuda()lab_test=lab_test.cuda()out1 = cnn(images_test)loss_test+=los(out1,lab_test)loss_test=loss_test/(len(test_data)//100)_,p=out1.max(1)accuracy += (p==lab_test).sum().item()accuracy=accuracy/len(test_data)print("loss_test:{},accuracy:{}".format(loss_test,accuracy))總結(jié)
以上是生活随笔為你收集整理的基于卷积神经网络(cnn)的手写数字识别(PyTorch)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逻辑复制mysql_物理复制 vs 逻辑
- 下一篇: 卷积神经网络实战之LeNet5股票预测代