wordpress 性能分析凱里seo排名優(yōu)化
一:卷積神經(jīng)網(wǎng)絡(luò)(CNN)和手寫數(shù)字識別MNIST數(shù)據(jù)集的介紹
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks,簡稱CNN)是一種深度學(xué)習(xí)模型,它在圖像和視頻識別、分類和分割任務(wù)中表現(xiàn)出色。CNN通過模仿人類視覺系統(tǒng)的工作原理來處理數(shù)據(jù),能夠從圖像中自動學(xué)習(xí)和提取特征。以下是CNN的一些關(guān)鍵特點(diǎn)和組成部分:
卷積層(Convolutional Layer):
卷積層是CNN的核心,它使用濾波器(或稱為卷積核)在輸入圖像上滑動,以提取圖像的局部特征。
每個濾波器負(fù)責(zé)檢測圖像中的特定特征,如邊緣、角點(diǎn)或紋理等。
卷積操作會產(chǎn)生一個特征圖(feature map),它表示輸入圖像在濾波器下的特征響應(yīng)。
激活函數(shù):
通常在卷積層之后使用非線性激活函數(shù),如ReLU(Rectified Linear Unit),以增加網(wǎng)絡(luò)的非線性表達(dá)能力。
激活函數(shù)幫助網(wǎng)絡(luò)處理復(fù)雜的模式,并使網(wǎng)絡(luò)能夠?qū)W習(xí)更復(fù)雜的特征組合。
池化層(Pooling Layer):
池化層用于降低特征圖的空間尺寸,減少參數(shù)數(shù)量和計(jì)算量,同時使特征檢測更加魯棒。
最常見的池化操作是最大池化(max pooling)和平均池化(average pooling)。
全連接層(Fully Connected Layer):
在多個卷積和池化層之后,CNN通常包含一個或多個全連接層,這些層將學(xué)習(xí)到的特征映射到最終的輸出類別上。
全連接層中的每個神經(jīng)元都與前一層的所有激活值相連。
softmax層:
在網(wǎng)絡(luò)的最后一層,通常使用softmax層將輸出轉(zhuǎn)換為概率分布,用于多分類任務(wù)中。
softmax函數(shù)確保輸出層的輸出值在0到1之間,并且所有輸出值的總和為1。
卷積神經(jīng)網(wǎng)絡(luò)的訓(xùn)練:
CNN通過反向傳播算法和梯度下降法進(jìn)行訓(xùn)練,以最小化損失函數(shù)(如交叉熵?fù)p失)。
在訓(xùn)練過程中,網(wǎng)絡(luò)的權(quán)重通過大量圖像數(shù)據(jù)進(jìn)行調(diào)整,以提高分類或識別的準(zhǔn)確性。
數(shù)據(jù)增強(qiáng)(Data Augmentation):
為了提高CNN的泛化能力,經(jīng)常使用數(shù)據(jù)增強(qiáng)技術(shù),如旋轉(zhuǎn)、縮放、裁剪和翻轉(zhuǎn)圖像,以創(chuàng)建更多的訓(xùn)練樣本。
遷移學(xué)習(xí)(Transfer Learning):
遷移學(xué)習(xí)是一種技術(shù),它允許CNN利用在一個大型數(shù)據(jù)集(如ImageNet)上預(yù)訓(xùn)練的網(wǎng)絡(luò)權(quán)重,來提高在小型或特定任務(wù)上的性能。
CNN在計(jì)算機(jī)視覺領(lǐng)域的應(yīng)用非常廣泛,包括但不限于圖像分類、目標(biāo)檢測、語義分割、物體跟蹤和面部識別等任務(wù)。由于其強(qiáng)大的特征提取能力,CNN已成為這些任務(wù)的主流方法之一。
MNIST數(shù)據(jù)集是一個廣泛使用的手寫數(shù)字識別數(shù)據(jù)集,可以通過TensorFlow庫或Pytorch庫來獲取, 也可以從官方網(wǎng)站下載:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges
MNIST數(shù)據(jù)集它包含四個部分:訓(xùn)練數(shù)據(jù)集、訓(xùn)練數(shù)據(jù)集標(biāo)簽、測試數(shù)據(jù)集和測試數(shù)據(jù)集標(biāo)簽。這些文件是IDX格式的二進(jìn)制文件,需要特定的程序來讀取。這個數(shù)據(jù)集包含了60,000張訓(xùn)練集圖像和10,000張測試集圖像,每張圖像都是28x28像素的手寫數(shù)字,范圍從0到9。這些圖像被處理為灰度值,其中黑色背景用0表示,手寫數(shù)字用0到1之間的灰度值表示,數(shù)值越接近1,顏色越白。
MNIST數(shù)據(jù)集的圖像通常被拉直為一個一維數(shù)組,每個數(shù)組包含784個元素(28x28像素)。數(shù)據(jù)集中的每個圖像都有一個對應(yīng)的標(biāo)簽,標(biāo)簽以one-hot編碼的形式給出,例如數(shù)字5的標(biāo)簽表示為[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]。
在機(jī)器學(xué)習(xí)模型中,MNIST數(shù)據(jù)集常用于訓(xùn)練分類器,以識別和預(yù)測手寫數(shù)字。例如,在深度學(xué)習(xí)中,可以使用卷積神經(jīng)網(wǎng)絡(luò)(CNN)來處理這些圖像,學(xué)習(xí)從圖像像素到數(shù)字標(biāo)簽的映射。
二:通過Pytorch庫建立CNN模型訓(xùn)練MNIST數(shù)據(jù)集
使用Python的Pytorch庫來完成一個卷積神經(jīng)網(wǎng)絡(luò)(CNN)來訓(xùn)練MNIST數(shù)據(jù)集,需要遵循以下步驟:
- 導(dǎo)入必要的庫:我們需要導(dǎo)入Pytorch以及其它可能需要的庫,如torchvision用于數(shù)據(jù)加載和變換。
- 加載MNIST數(shù)據(jù)集:使用torchvision庫中的datasets和DataLoader來加載和預(yù)處理MNIST數(shù)據(jù)集。
- 定義卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu):設(shè)計(jì)一個簡單的CNN結(jié)構(gòu),包括卷積層、池化層和全連接層。
- 定義損失函數(shù)和優(yōu)化器:選擇一個合適的損失函數(shù),如交叉熵?fù)p失,以及一個優(yōu)化器,如Adam或SGD。
- 訓(xùn)練模型:在訓(xùn)練集上訓(xùn)練模型,并保存訓(xùn)練過程中的損失和準(zhǔn)確率。
- 測試模型:在測試集上評估模型的性能。
接下來,我們將按照這些步驟使用Python代碼來完成這個任務(wù)。
Step1:導(dǎo)入必要的庫
# 導(dǎo)入必要的庫
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
import torch
: 導(dǎo)入了PyTorch的主庫,這是進(jìn)行深度學(xué)習(xí)任務(wù)的基礎(chǔ)。import torch.nn as nn
: 導(dǎo)入了PyTorch的神經(jīng)網(wǎng)絡(luò)模塊,它包含了構(gòu)建神經(jīng)網(wǎng)絡(luò)所需的許多類和函數(shù)。import torch.nn.functional as F
: 導(dǎo)入了PyTorch的功能性API,它提供了不需要維護(hù)狀態(tài)的神經(jīng)網(wǎng)絡(luò)操作,例如激活函數(shù)、池化等。import torchvision
: 導(dǎo)入了PyTorch的視覺庫,它提供了許多視覺任務(wù)所需的工具和數(shù)據(jù)集。import torchvision.transforms as transforms
: 導(dǎo)入了對數(shù)據(jù)進(jìn)行預(yù)處理的工具。from torch.utils.data import DataLoader
: 導(dǎo)入了PyTorch的數(shù)據(jù)加載器,它可以方便地迭代數(shù)據(jù)集。
Step2:加載MNIST數(shù)據(jù)集
# 加載MNIST數(shù)據(jù)集
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
transform = transforms.Compose(...)
: 創(chuàng)建了一個轉(zhuǎn)換管道,用于對數(shù)據(jù)進(jìn)行預(yù)處理。Compose
是一個函數(shù),它將多個轉(zhuǎn)換步驟組合成一個轉(zhuǎn)換。transforms.ToTensor()
: 將圖像數(shù)據(jù)從PIL Image或NumPy ndarray格式轉(zhuǎn)換為浮點(diǎn)張量,并且將像素值縮放到[0,1]范圍內(nèi)。transforms.Normalize((0.5,), (0.5,))
: 對圖像進(jìn)行歸一化處理。給定均值(mean)和標(biāo)準(zhǔn)差(std),這個轉(zhuǎn)換將張量的每個通道都減去均值并除以標(biāo)準(zhǔn)差。在這里,它將每個像素值從[0,1]范圍轉(zhuǎn)換為[-1,1]范圍。
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
- 這兩行代碼分別加載了MNIST數(shù)據(jù)集的訓(xùn)練集和測試集。
root='./data'
: 指定數(shù)據(jù)集下載和存儲的根目錄。train=True
: 對于trainset
,表示加載數(shù)據(jù)集的訓(xùn)練部分。train=False
: 對于testset
,表示加載數(shù)據(jù)集的測試部分。download=True
: 表示如果數(shù)據(jù)集不在指定的root
目錄下,則從互聯(lián)網(wǎng)上下載。transform=transform
: 應(yīng)用之前定義的轉(zhuǎn)換。
trainloader = DataLoader(trainset, batch_size=64, shuffle=True)
testloader = DataLoader(testset, batch_size=64, shuffle=False)
- 這兩行代碼創(chuàng)建了兩個
DataLoader
對象,用于在訓(xùn)練和測試時迭代數(shù)據(jù)集。 batch_size=64
: 指定每個批次的樣本數(shù)量。shuffle=True
: 對于trainloader
,在每次迭代時打亂數(shù)據(jù),這對于訓(xùn)練是有益的,因?yàn)樗梢詼p少模型學(xué)習(xí)數(shù)據(jù)的順序性。shuffle=False
: 對于testloader
,不打亂數(shù)據(jù),因?yàn)闇y試時不需要隨機(jī)性。
得到了一個名為data的文件夾:
Step3:定義卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
# 定義卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(1, 32, 3, padding=1)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(32, 64, 3, padding=1)self.fc1 = nn.Linear(64 * 7 * 7, 1024)self.fc2 = nn.Linear(1024, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 64 * 7 * 7)x = F.relu(self.fc1(x))x = self.fc2(x)return x
- 這段代碼定義了一個名為
CNN
的卷積神經(jīng)網(wǎng)絡(luò)類,它繼承自nn.Module
。 __init__
方法初始化了網(wǎng)絡(luò)的結(jié)構(gòu):self.conv1
是一個2D卷積層,輸入通道為1(MNIST圖像為單通道),輸出通道為32,卷積核大小為3x3,并帶有1像素的填充。self.pool
是一個2x2的最大池化層,用于減小數(shù)據(jù)的維度。self.conv2
是第二個2D卷積層,輸入通道為32,輸出通道為64,卷積核大小為3x3,并帶有1像素的填充。self.fc1
是一個全連接層,它將64個通道的7x7圖像映射到1024個特征。self.fc2
是另一個全連接層,它將1024個特征映射到10個輸出,對應(yīng)于MNIST數(shù)據(jù)集的10個類別。
forward
方法定義了數(shù)據(jù)通過網(wǎng)絡(luò)的前向傳播路徑:x
首先通過conv1
卷積層,然后應(yīng)用ReLU激活函數(shù),并使用pool
進(jìn)行池化。- 接著,
x
通過conv2
卷積層,再次應(yīng)用ReLU激活函數(shù)和池化。 x.view(-1, 64 * 7 * 7)
將數(shù)據(jù)扁平化,為全連接層準(zhǔn)備。x
通過fc1
全連接層,并應(yīng)用ReLU激活函數(shù)。- 最后,
x
通過fc2
全連接層,輸出結(jié)果。
# 實(shí)例化網(wǎng)絡(luò)
net = CNN()
- 創(chuàng)建了一個
CNN
類的實(shí)例,名為net
。
Step4:定義損失函數(shù)和優(yōu)化器
# 定義損失函數(shù)和優(yōu)化器
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.001)
criterion
是交叉熵?fù)p失函數(shù),常用于多分類問題。optimizer
是Adam優(yōu)化器,用于更新網(wǎng)絡(luò)的權(quán)重。
Step5:訓(xùn)練模型
# 訓(xùn)練模型
epochs = 5
for epoch in range(epochs):running_loss = 0.0for i, data in enumerate(trainloader, 0):inputs, labels = dataoptimizer.zero_grad()outputs = net(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()print(f"Epoch {epoch+1}, Loss: {running_loss/(i+1)}")
下面是這段代碼的逐行解釋:
epochs
是一個變量,表示訓(xùn)練過程中模型將遍歷整個訓(xùn)練數(shù)據(jù)集的次數(shù)。這里設(shè)置為5,意味著整個訓(xùn)練數(shù)據(jù)集將被遍歷5次。- 外層for循環(huán),它將執(zhí)行
epochs
次。在每次迭代中,epoch
變量將代表當(dāng)前的迭代次數(shù),從0開始到epochs-1
結(jié)束。 - 在每次epoch開始時,
running_loss
被重置為0.0。這個變量用于累加每個epoch中的所有批次損失,以便計(jì)算平均損失。 - 這是一個嵌套的for循環(huán),它遍歷
trainloader
返回的批次數(shù)據(jù)。enumerate
函數(shù)用于遍歷可迭代對象,同時跟蹤當(dāng)前的索引(這里是i
)。 trainloader
是之前定義的數(shù)據(jù)加載器,它負(fù)責(zé)分批加載數(shù)據(jù),以便于訓(xùn)練。- 參數(shù)
0
指定了索引的起始值。 - 然后解包了
data
元組,其中包含輸入(圖像)和標(biāo)簽(目標(biāo)值)。inputs
是模型的輸入數(shù)據(jù),labels
是這些輸入數(shù)據(jù)的正確類別標(biāo)簽。 - 在每次迭代開始時,調(diào)用
optimizer.zero_grad()
來清除之前梯度計(jì)算的結(jié)果。這是必要的,因?yàn)镻yTorch的梯度是累加的。 - 輸入
inputs
傳遞給神經(jīng)網(wǎng)絡(luò)net
,并得到輸出outputs
。這是模型的前向傳播步驟。 - 計(jì)算了模型輸出的損失。
criterion
是之前定義的交叉熵?fù)p失函數(shù),它比較outputs
(模型的預(yù)測)和labels
(實(shí)際類別標(biāo)簽)來計(jì)算損失。 - 執(zhí)行了反向傳播。它計(jì)算了損失相對于模型參數(shù)的梯度。
- 更新了模型的權(quán)重。
optimizer
使用計(jì)算出的梯度來調(diào)整網(wǎng)絡(luò)參數(shù),以減少下一次迭代的損失。 - 將當(dāng)前的批次損失累加到
running_loss
變量中,用于后續(xù)計(jì)算平均損失。 - 在每個epoch結(jié)束時,打印出當(dāng)前epoch的編號和平均損失。
epoch+1
是為了從1開始計(jì)數(shù)epoch,而不是從0開始。running_loss/(i+1)
計(jì)算了當(dāng)前epoch的平均損失,其中i+1
是當(dāng)前epoch中批次的數(shù)量。
最終得到每個epoch的平均損失如下:
Step6:測試模型
# 測試模型
correct = 0
total = 0
with torch.no_grad():for data in testloader:images, labels = dataoutputs = net(images)_, predicted = torch.max(outputs.data, 1)total += labels.size(0)correct += (predicted == labels).sum().item()print(f"Accuracy of the network on the 10000 test images: {100 * correct / total}%")
correct
和total
是兩個變量,分別用于跟蹤模型在測試數(shù)據(jù)集上正確預(yù)測的樣本數(shù)量和總的樣本數(shù)量。with torch.no_grad()
是一個上下文管理器,用于在測試階段禁用梯度計(jì)算。因?yàn)闇y試階段不需要計(jì)算梯度,這樣可以節(jié)省內(nèi)存并加快計(jì)算速度。- for循環(huán),遍歷
testloader
返回的測試數(shù)據(jù)集的批次數(shù)據(jù)。 - 這行代碼解包了
data
元組,其中包含測試圖像images
和它們對應(yīng)的真實(shí)標(biāo)簽labels
。 - 這行代碼將測試圖像
images
輸入到訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)net
中,并得到輸出outputs
。 torch.max(outputs.data, 1)
返回兩個值:第一個是每個批次中最大值的元素,第二個是這些最大值的索引。在這里,最大值代表模型對每個圖像的預(yù)測類別,而索引則代表預(yù)測的類別標(biāo)簽。predicted
是模型預(yù)測的類別標(biāo)簽的向量。- 這行代碼累加測試集中總的樣本數(shù)量。
labels.size(0)
給出了當(dāng)前批次中樣本的數(shù)量。 (predicted == labels)
是一個布爾表達(dá)式,它比較模型的預(yù)測predicted
和真實(shí)標(biāo)簽labels
,并返回一個布爾張量,其中正確預(yù)測的位置為True,否則為False。.sum()
計(jì)算布爾張量中True的數(shù)量,即正確預(yù)測的樣本數(shù)量。.item()
將計(jì)算得到的張量(只有一個元素)轉(zhuǎn)換為Python的標(biāo)量值。- 這行代碼計(jì)算并打印出模型在測試數(shù)據(jù)集上的準(zhǔn)確率。準(zhǔn)確率是通過將正確預(yù)測的樣本數(shù)量
correct
除以總樣本數(shù)量total
,然后乘以100來得到的百分比。這里假設(shè)測試數(shù)據(jù)集包含10000個樣本。
得到準(zhǔn)確率如下:
使用這個建立好的卷積神經(jīng)網(wǎng)絡(luò)(CNN)模型,主要用于訓(xùn)練分類器。具體來說,這個模型能夠識別手寫數(shù)字圖像,并將它們分類為0到9中的一個類別。它適用于MNIST數(shù)據(jù)集。這個示例能夠幫助更好的了解卷積神經(jīng)網(wǎng)絡(luò)(CNN)的原理。
?
想要探索更多元化的數(shù)據(jù)分析視角,可以關(guān)注之前發(fā)布的相關(guān)內(nèi)容。