整理:python架構(gòu)師 來源:python技術(shù)迷
我們的下一個(gè)任務(wù)是使用先前標(biāo)記的圖像來訓(xùn)練神經(jīng)網(wǎng)絡(luò),以對新的測試圖像進(jìn)行分類。因此,我們將使用nn模塊來構(gòu)建我們的神經(jīng)網(wǎng)絡(luò)。
實(shí)現(xiàn)圖像識別神經(jīng)網(wǎng)絡(luò)的步驟如下:
步驟1:
在第一步中,我們將定義一個(gè)類,該類將用于創(chuàng)建我們的神經(jīng)模型實(shí)例。這個(gè)類將繼承自nn模塊,因此我們首先需要導(dǎo)入nn包。
from torch import nn class classifier (nn.Module):我們的類后面將是一個(gè)init()方法。在init()中,第一個(gè)參數(shù)將始終是self,第二個(gè)參數(shù)將是我們將稱為輸入節(jié)點(diǎn)數(shù)的輸入層節(jié)點(diǎn)數(shù),第三個(gè)參數(shù)將是隱藏層的節(jié)點(diǎn)數(shù),第四個(gè)參數(shù)將是第二隱藏層的節(jié)點(diǎn)數(shù),最后一個(gè)參數(shù)將是輸出層的節(jié)點(diǎn)數(shù)。
def __init__(self,input_layer,hidden_layer1,hidden_layer2,output_layer):
步驟2:
在第二步中,我們調(diào)用init()方法以提供各種方法和屬性,并初始化輸入層、隱藏層和輸出層。請記住,我們將處理全連接的神經(jīng)網(wǎng)絡(luò)。
super(),__init__() self.linear1=nn.Linear(input_layer,hidden_layer1) self.linear2=nn.Linear(hidden_layer1,hidden_layer2) self.linear3=nn.Linear(hidden_layer2,output_layer) def __init__(self,input_layer,hidden_layer1,hidden_layer2,output_layer):
專屬福利
點(diǎn)擊領(lǐng)取:最全Python資料合集
步驟3:
現(xiàn)在,我們將進(jìn)行預(yù)測,但在此之前,我們將導(dǎo)入torch.nn.functional包,然后我們將使用forward()函數(shù),并將self作為第一個(gè)參數(shù),x作為我們嘗試進(jìn)行預(yù)測的任何輸入。
import torch.nn.functional as func def forward(self,x):
現(xiàn)在,傳遞給forward()函數(shù)的任何輸入將傳遞給linear1對象,我們將使用relu函數(shù)而不是sigmoid。這個(gè)輸出將作為輸入傳遞到我們的第二隱藏層,并且第二隱藏層的輸出將饋送到輸出層,并返回最終層的輸出。
注意:如果我們處理的是多類別數(shù)據(jù)集,就不會在輸出層應(yīng)用任何激活函數(shù)。
x=func.relu(self.linear1(x)) x=func.relu(self.linear2(x)) x=self.linear3(x) return x
步驟4:
在下一步中,我們將設(shè)置我們的模型構(gòu)造函數(shù)。根據(jù)我們的初始化器,我們必須設(shè)置輸入維度、隱藏層維度和輸出維度。
圖像的像素強(qiáng)度將饋送到我們的輸入層。由于每個(gè)圖像都是28*28像素,總共有784個(gè)像素,將其饋送到我們的神經(jīng)網(wǎng)絡(luò)中。因此,我們將784作為第一個(gè)參數(shù)傳遞,我們將在第一和第二隱藏層中分別取125和60個(gè)節(jié)點(diǎn),在輸出層中我們將取十個(gè)節(jié)點(diǎn)。
model=classification1(784,125,65,10)
步驟5:
現(xiàn)在,我們將定義我們的損失函數(shù)。nn.CrossEntropyLoss() 用于多類別分類。該函數(shù)是log_softmax()函數(shù)和NLLLoss()函數(shù)的組合,NLLLoss是負(fù)對數(shù)似然損失。對于具有n個(gè)類別的任何訓(xùn)練和分類問題,都使用交叉熵。因此,它使用對數(shù)概率,因此我們傳遞行輸出而不是softmax激活函數(shù)的輸出。
criteron=nn.CrossEntropyLoss()之后,我們將使用熟悉的優(yōu)化器,即Adam。
optimizer=torch.optim.Adam(model.parameters(),lr=0.001)
步驟6:
在接下來的步驟中,我們將指定epoch的數(shù)量。我們初始化epoch的數(shù)量并在每個(gè)epoch分析損失。我們將初始化兩個(gè)列表,即loss_history和correct_history。
loss_history=[] correct_history=[]
步驟7:
我們將從迭代每個(gè)epoch開始,對于每個(gè)epoch,我們必須迭代由訓(xùn)練加載器提供的每個(gè)訓(xùn)練批次。每個(gè)訓(xùn)練批次包含一百個(gè)圖像以及在train加載器中訓(xùn)練的一百個(gè)標(biāo)簽。
for e in range(epochs): for input, labels in training_loader:
步驟8:
當(dāng)我們迭代圖像的批次時(shí),我們必須將它們展平,并使用view方法進(jìn)行形狀變換。
注意:每個(gè)圖像張量的形狀是(1,28,28),這意味著總共有784個(gè)像素。
根據(jù)神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu),我們的輸入值將與連接輸入層和第一隱藏層的權(quán)重矩陣相乘。為了進(jìn)行這個(gè)乘法,我們必須使我們的圖像變?yōu)橐痪S。我們需要將每個(gè)圖像從28行2列展平為784個(gè)像素的單行。
inputs=input.view(input.shape[0],-1)現(xiàn)在,借助這些輸入,我們得到輸出。
outputs=model(inputs)
步驟9:
借助輸出,我們將計(jì)算總分類交叉熵?fù)p失,并最終將輸出與實(shí)際標(biāo)簽進(jìn)行比較。我們還將基于交叉熵標(biāo)準(zhǔn)確定錯(cuò)誤。在執(zhí)行訓(xùn)練傳遞的任何部分之前,我們必須像之前一樣設(shè)置優(yōu)化器。
loss1=criteron(outputs,labels) optimizer.zero_grad() loss1.backward() optimizer.step()
步驟10:
為了跟蹤每個(gè)epoch的損失,我們將初始化一個(gè)變量loss,即running_loss。對于計(jì)算出的每個(gè)批次的每個(gè)損失,我們必須將其添加到每個(gè)單一批次的所有批次中,然后在每個(gè)epoch計(jì)算出最終損失。
loss+=loss1.item()現(xiàn)在,我們將將這個(gè)累積的整個(gè)epoch的損失附加到我們的損失列表中。為此,在循環(huán)語句之后使用else語句。因此,一旦for循環(huán)結(jié)束,那么將調(diào)用else語句。在這個(gè)else語句中,我們將打印在特定epoch計(jì)算的整個(gè)數(shù)據(jù)集的累積損失。
epoch_loss=loss/len(training_loader) loss_history.append(epoch_loss)
步驟11:
在接下來的步驟中,我們將找到網(wǎng)絡(luò)的準(zhǔn)確性。我們將初始化正確的變量并賦值為零。我們將比較模型對每個(gè)訓(xùn)練圖像的預(yù)測與圖像的實(shí)際標(biāo)簽,以顯示在一個(gè)epoch中有多少個(gè)預(yù)測是正確的。
對于每個(gè)圖像,我們將取得最大分?jǐn)?shù)值。在這種情況下,將返回一個(gè)元組。它返回的第一個(gè)值是實(shí)際的頂值-模型為該批次內(nèi)的每個(gè)單一圖像制作的最大分?jǐn)?shù)。因此,我們對第一個(gè)元組值不感興趣,第二個(gè)將對應(yīng)于模型制作的最高預(yù)測,我們將其稱為preds。它將返回該圖像的最大值的索引。
_,preds=torch.max(outputs,1)
步驟12:
每個(gè)圖像輸出將是一個(gè)值的集合,其索引范圍從0到9,因?yàn)镸NIST數(shù)據(jù)集包含從0到9的類。因此,最大值發(fā)生的位置對應(yīng)于模型做出的預(yù)測。我們將比較模型對圖像的所有這些預(yù)測與圖像的實(shí)際標(biāo)簽,以查看它們中有多少個(gè)是正確的。
correct+=torch.sum(preds==labels.data)這將給出每個(gè)圖像批次的正確預(yù)測數(shù)量。我們將以與epoch損失和準(zhǔn)確性相同的方式定義epoch準(zhǔn)確性,并打印epoch損失和準(zhǔn)確性。
epoch_acc=correct.float()/len(training_loader) print('training_loss:{:.4f},{:.4f}'.format(epoch_loss,epoch_acc.item()))這將產(chǎn)生預(yù)期的結(jié)果,如下所示:
步驟13:
現(xiàn)在,我們將將整個(gè)epoch的準(zhǔn)確性附加到我們的correct_history列表中,并為更好的可視化,我們將繪制epoch損失和準(zhǔn)確性。
plt.plot(loss_history,label='Running Loss History') plt.plot(correct_history,label='Running correct History')Epoch Loss
Epoch accuracy
完整代碼
import torch import matplotlib.pyplot as plt import numpy as np import torch.nn.functional as func from torch import nn from torchvision import datasets, transforms transform1=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,))]) training_dataset=datasets.MNIST(root='./data',train=True,download=True,transform=transform1) training_loader=torch.utils.data.DataLoader(dataset=training_dataset,batch_size=100,shuffle=True) def im_convert(tensor): image=tensor.clone().detach().numpy() image=image.transpose(1,2,0) print(image.shape) image=image*(np.array((0.5,0.5,0.5))+np.array((0.5,0.5,0.5))) image=image.clip(0,1) return image dataiter=iter(training_loader) images,labels=dataiter.next() fig=plt.figure(figsize=(25,4)) for idx in np.arange(20): ax=fig.add_subplot(2,10,idx+1) plt.imshow(im_convert(images[idx])) ax.set_title([labels[idx].item()]) class classification1(nn.Module): def __init__(self,input_layer,hidden_layer1,hidden_layer2,output_layer): super().__init__() self.linear1=nn.Linear(input_layer,hidden_layer1) self.linear2=nn.Linear(hidden_layer1,hidden_layer2) self.linear3=nn.Linear(hidden_layer2,output_layer) def forward(self,x): x=func.relu(self.linear1(x)) x=func.relu(self.linear2(x)) x=self.linear3(x) return x model=classification1(784,125,65,10) criteron=nn.CrossEntropyLoss() optimizer=torch.optim.Adam(model.parameters(),lr=0.0001) epochs=12 loss_history=[] correct_history=[] for e in range(epochs): loss=0.0 correct=0.0 for input,labels in training_loader: inputs=input.view(input.shape[0],-1) outputs=model(inputs) loss1=criteron(outputs,labels) optimizer.zero_grad() loss1.backward() optimizer.step() _,preds=torch.max(outputs,1) loss+=loss1.item() correct+=torch.sum(preds==labels.data) else: epoch_loss=loss/len(training_loader) epoch_acc=correct.float()/len(training_loader) loss_history.append(epoch_loss) correct_history.append(epoch_acc) print('training_loss:{:.4f},{:.4f}'.format(epoch_loss,epoch_acc.item()))
審核編輯:湯梓紅
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4777瀏覽量
100952 -
圖像識別
+關(guān)注
關(guān)注
9文章
521瀏覽量
38305 -
python
+關(guān)注
關(guān)注
56文章
4801瀏覽量
84865
原文標(biāo)題:PyTorch 教程-圖像識別中神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)
文章出處:【微信號:vision263com,微信公眾號:新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論