基于卷积神经网络(cnn)的手写数字识别(PyTorch)
目錄
1.1 卷積神經(jīng)網(wǎng)絡(luò)簡(jiǎn)介
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 卷積的計(jì)算過(guò)程
1.3.3?感受野
1.3.4?步長(zhǎng)
1.3.5?輸出特征尺寸計(jì)算
?1.3.6?全零填充
1.3.7 標(biāo)準(zhǔn)化
1.3.7?池化層
?1.4 卷積神經(jīng)網(wǎng)絡(luò)的全過(guò)程
?1.5?PyTorch的卷積神經(jīng)網(wǎng)絡(luò)(cnn)手寫數(shù)字識(shí)別
1.5.1 代碼
1.1 卷積神經(jīng)網(wǎng)絡(luò)簡(jiǎn)介
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks,簡(jiǎn)稱:CNN)是深度學(xué)習(xí)當(dāng)中一個(gè)非常重要的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)。它主要用于用在圖像圖片處理,視頻處理,音頻處理以及自然語(yǔ)言處理等等。
早在上世紀(jì)80年代左右,卷積神經(jīng)網(wǎng)絡(luò)的概念就已經(jīng)被提出來(lái)了。但其真正的崛起卻是在21世紀(jì)之后,21世紀(jì)之后,隨著深度學(xué)習(xí)理論的不斷完善,同時(shí),由計(jì)算機(jī)硬件性能的提升,計(jì)算機(jī)算力的不斷發(fā)展,給卷積神經(jīng)網(wǎng)絡(luò)這種算法提供了應(yīng)用的空間。著名的AlphaGo,手機(jī)上的人臉識(shí)別,大多數(shù)都是采用卷積神經(jīng)網(wǎng)絡(luò)。因此可以說(shuō),卷積神經(jīng)網(wǎng)絡(luò)在如今的深度學(xué)習(xí)領(lǐng)域,有著舉足輕重的作用。
在了解卷積神經(jīng)網(wǎng)絡(luò)之前,我們務(wù)必要知道:什么是神經(jīng)網(wǎng)絡(luò)(Neural Networks),關(guān)于這個(gè),我們已經(jīng)在深度學(xué)習(xí)簡(jiǎn)介的 第二部分有所介紹。這里就不贅述了。在了解了神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)上,我們?cè)賮?lái)探究:卷積神經(jīng)網(wǎng)絡(luò)又是什么呢?當(dāng)中的“卷積”這個(gè)詞,又意味著什么呢?
?
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ò)”?? ?已是一個(gè)相當(dāng)大的、多學(xué)科交叉的學(xué)科領(lǐng)域.各相關(guān)學(xué)科對(duì)神經(jīng)網(wǎng)絡(luò)的定義多種多樣。簡(jiǎn)單單元組成的廣泛并行互連的網(wǎng)絡(luò),它的組織能夠模擬生物神經(jīng)系統(tǒng)對(duì)真實(shí)世界物體所作出的交互反應(yīng)” 。
神經(jīng)網(wǎng)絡(luò)中最基本的成分是神經(jīng)元(neuron)模型,即上述定義中的“簡(jiǎn)單單元”,在生物神經(jīng)網(wǎng)絡(luò)中,每個(gè)神經(jīng)元與其他神經(jīng)元相連,當(dāng)它“興奮”時(shí),就會(huì)向相連的神經(jīng)元發(fā)送化學(xué)物質(zhì),從而改變這些神經(jīng)元內(nèi)的電位;如果某神經(jīng)元的電位超過(guò)了一個(gè)“閾值”(threshold),那么它就會(huì)被激活,即“興奮”起來(lái),向其他神經(jīng)元發(fā)送化學(xué)物質(zhì)。在這個(gè)模型中,神經(jīng)元接收到來(lái)自n個(gè)其他神經(jīng)元傳遞過(guò)來(lái)的輸入信號(hào),這些輸入信號(hào)通過(guò)帶權(quán)重的連接(connection)進(jìn)行傳遞,神經(jīng)元接收到的總輸入值將與神經(jīng)元的間值進(jìn)行比較,然后通過(guò)激活函數(shù)處理,產(chǎn)生神經(jīng)元輸出。
?
?1.2.2 神經(jīng)網(wǎng)絡(luò)模型
?神經(jīng)網(wǎng)絡(luò)是一種運(yùn)算模型,由大量的節(jié)點(diǎn)(或稱神經(jīng)元)之間相互聯(lián)接構(gòu)成。每個(gè)節(jié)點(diǎn)代表一種特定的輸出函數(shù),稱為激勵(lì)函數(shù)(activation function)。每?jī)蓚€(gè)節(jié)點(diǎn)間的連接都代表一個(gè)對(duì)于通過(guò)該連接信號(hào)的加權(quán)值,稱之為權(quán)重,這相當(dāng)于人工神經(jīng)網(wǎng)絡(luò)的記憶。網(wǎng)絡(luò)的輸出則依網(wǎng)絡(luò)的連接方式,權(quán)重值和激勵(lì)函數(shù)的不同而不同。而網(wǎng)絡(luò)自身通常都是對(duì)自然界某種算法或者函數(shù)的逼近,也可能是對(duì)一種邏輯策略的表達(dá)。
?
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è)由卷積層和子采樣層(池化層)構(gòu)成的特征抽取器。在卷積神經(jīng)網(wǎng)絡(luò)的卷積層中,一個(gè)神經(jīng)元只與部分鄰層神經(jīng)元連接。在CNN的一個(gè)卷積層中,通常包含若干個(gè)特征圖(featureMap),每個(gè)特征圖由一些矩形排列的的神經(jīng)元組成,同一特征圖的神經(jīng)元共享權(quán)值,這里共享的權(quán)值就是卷積核。卷積核一般以隨機(jī)小數(shù)矩陣的形式初始化,在網(wǎng)絡(luò)的訓(xùn)練過(guò)程中卷積核將學(xué)習(xí)得到合理的權(quán)值。共享權(quán)值(卷積核)帶來(lái)的直接好處是減少網(wǎng)絡(luò)各層之間的連接,同時(shí)又降低了過(guò)擬合的風(fēng)險(xiǎn)。子采樣也叫做池化(pooling),通常有均值子采樣(mean pooling)和最大值子采樣(max pooling)兩種形式。子采樣可以看作一種特殊的卷積過(guò)程。卷積和子采樣大大簡(jiǎn)化了模型復(fù)雜度,減少了模型的參數(shù)。
1.3.2 卷積的計(jì)算過(guò)程
假設(shè)我們輸入的是5*5*1的圖像,中間的那個(gè)3*3*1是我們定義的一個(gè)卷積核(簡(jiǎn)單來(lái)說(shuō)可以看做一個(gè)矩陣形式運(yùn)算器),通過(guò)原始輸入圖像和卷積核做運(yùn)算可以得到綠色部分的結(jié)果,怎么樣的運(yùn)算呢?實(shí)際很簡(jiǎn)單就是我們看左圖中深色部分,處于中間的數(shù)字是圖像的像素,處于右下角的數(shù)字是我們卷積核的數(shù)字,只要對(duì)應(yīng)相乘再相加就可以得到結(jié)果。例如圖中‘3*0+1*1+2*2+2*2+0*2+0*0+2*0+0*1+0*2=9’
計(jì)算過(guò)程如下動(dòng)圖:
圖中最左邊的三個(gè)輸入矩陣就是我們的相當(dāng)于輸入d=3時(shí)有三個(gè)通道圖,每個(gè)通道圖都有一個(gè)屬于自己通道的卷積核,我們可以看到輸出(output)的只有兩個(gè)特征圖意味著我們?cè)O(shè)置的輸出d=2,有幾個(gè)輸出通道就有幾層卷積核(比如圖中就有FilterW0和FilterW1),這意味著我們的卷積核數(shù)量就是輸入d的個(gè)數(shù)乘以輸出d的個(gè)數(shù)(圖中就是2*3=6個(gè)),其中每一層通道圖的計(jì)算與上文中提到的一層計(jì)算相同,再把每一個(gè)通道輸出的輸出再加起來(lái)就是綠色的輸出數(shù)字。
1.3.3?感受野
感受野(Receptive Field):卷積神經(jīng)網(wǎng)絡(luò)各輸出層每個(gè)像素點(diǎn)在原始圖像上的映射區(qū)域大小。
下圖為感受野示意圖:
?當(dāng)我們采用尺寸不同的卷積核時(shí),最大的區(qū)別就是感受野的大小不同,所以經(jīng)常會(huì)采用多層小卷積核來(lái)替換一層大卷積核,在保持感受野相同的情況下減少參數(shù)量和計(jì)算量。
例如十分常見的用2層3 * 3卷積核來(lái)替換1層5 * 5卷積核的方法,如下圖所示。
1.3.4?步長(zhǎng)
每次卷積核移動(dòng)的大小。
1.3.5?輸出特征尺寸計(jì)算
輸出特征尺寸計(jì)算:在了解神經(jīng)網(wǎng)絡(luò)中卷積計(jì)算的整個(gè)過(guò)程后,就可以對(duì)輸出特征圖的尺寸進(jìn)行計(jì)算。如下圖所示,5×5的圖像經(jīng)過(guò)3×3大小的卷積核做卷積計(jì)算后輸出特征尺寸為3×3
?1.3.6?全零填充
當(dāng)卷積核尺寸大于 1 時(shí),輸出特征圖的尺寸會(huì)小于輸入圖片尺寸。如果經(jīng)過(guò)多次卷積,輸出圖片尺寸會(huì)不斷減小。為了避免卷積之后圖片尺寸變小,通常會(huì)在圖片的外圍進(jìn)行填充(padding),如下圖所示
全零填充(padding):為了保持輸出圖像尺寸與輸入圖像一致,經(jīng)常會(huì)在輸入圖像周圍進(jìn)行全零填充,如下所示,在5×5的輸入圖像周圍填0,則輸出特征尺寸同為5×5。
當(dāng)padding=1和paadding=2時(shí),如下圖所示:
1.3.7 標(biāo)準(zhǔn)化
使數(shù)據(jù)符合0均值,1為標(biāo)準(zhǔn)差的分布。
批標(biāo)準(zhǔn)化(Batch Normalization):對(duì)一小批數(shù)據(jù)(batch),做標(biāo)準(zhǔn)化處理。
?Batch Normalization將神經(jīng)網(wǎng)絡(luò)每層的輸入都調(diào)整到均值為0,方差為1的標(biāo)準(zhǔn)正態(tài)分布,其目的是解決神經(jīng)網(wǎng)絡(luò)中梯度消失的問題.
BN操作的另一個(gè)重要步驟是縮放和偏移,值得注意的是,縮放因子γ以及偏移因子β都是可訓(xùn)練參數(shù)。?
1.3.7?池化層
池化(Pooling)用于減少特征數(shù)據(jù)量。
最大值池化可提取圖片紋理,均值池化可保留背景特征
?1.4 卷積神經(jīng)網(wǎng)絡(luò)的全過(guò)程
?1.5?PyTorch的卷積神經(jīng)網(wǎng)絡(luò)(cnn)手寫數(shù)字識(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))#測(cè)試模型 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)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逻辑复制mysql_物理复制 vs 逻辑
- 下一篇: 卷积神经网络实战之LeNet5股票预测代