1 問題 訓(xùn)練集訓(xùn)練次數(shù)對(duì)測(cè)試效果的有多大效果,訓(xùn)練次數(shù)是否成正相關(guān),是否存在最優(yōu)訓(xùn)練次數(shù),它的關(guān)系圖像是怎樣的?怎樣獲得它的關(guān)系圖像? 2 方法 在這里我們通過torch,數(shù)據(jù)來自datasets,數(shù)據(jù)處理使用的是dataloader的分段功能,返回的值通過 correct = (pred.argmax(1)==y).type(torch.int).sum().item() 實(shí)現(xiàn)每一組正確的數(shù)量,我們?cè)谌∷麄兊钠骄?,在不同?xùn)練次數(shù)下 得到的平均值不同,我們可以使用兩層循~環(huán),第一層對(duì)不同次數(shù)的訓(xùn)練之后得到i個(gè)平均值進(jìn)行列表展示,第二層對(duì)訓(xùn)練集訓(xùn)練進(jìn)行循環(huán)使其進(jìn)行i次循環(huán), 即 循環(huán)多少次返回列表就有多少元素。最后我們進(jìn)行返回值的可視化。 完整代碼即注釋展示: import torch from torch import nn from torchvision import datasets from torch.utils.data import DataLoader from torchvision.transforms import ToTensor import matplotlib.pyplot as plt import numpy as np plt.rcParams["axes.unicode_minus"] = False # 防止負(fù)號(hào)顯示出錯(cuò) plt.rcParams['font.family'] = 'SimHei' # (1) 訓(xùn)練集: 訓(xùn)練模型 train_ds = datasets.MNIST( root='data', # 說明數(shù)據(jù)集下載的路徑 download=True, train=True, # 區(qū)分訓(xùn)練集還是測(cè)試集 transform=ToTensor(), # 尤其需要注意(),將原始數(shù)據(jù)格式轉(zhuǎn)換為Tensor格式 ) # (2) 測(cè)試集: 評(píng)估模型的性能/效果 test_ds = datasets.MNIST( root='data', download=True, train=False, transform=ToTensor(), ) # (3) train_loader = DataLoader( dataset=train_ds, batch_size=128, # 每一段的大小是128 shuffle=True, # 1--60000 打亂數(shù)據(jù)的次序, 一般用于訓(xùn)練 ) # (4) test_loader = DataLoader( dataset=test_ds, batch_size=128 # 測(cè)試集不需要shuffle ) # (5) 定義三層全連接網(wǎng)絡(luò) # (5.1) 創(chuàng)建一個(gè)新的類繼承nn.Module class MyNet(nn.Module): # (5.2) 定義網(wǎng)絡(luò)有哪些層,這些層都作為成員變量 def __init__(self) -> None: super().__init__() self.flatten = nn.Flatten() # 將28x28的圖像拉伸為784維向量 # 第1個(gè)全連接層Full Connection(FC) # in_features表示該層的前面一層神經(jīng)元個(gè)數(shù) # out_features標(biāo)識(shí)當(dāng)前這一層神經(jīng)元個(gè)數(shù) # 對(duì)應(yīng)圖里面Layer2 self.fc1 = nn.Linear(in_features=784, out_features=512) # 對(duì)應(yīng)Layer3 也是就輸出層 self.fc2 = nn.Linear(in_features=512, out_features=10) # (5.3) 定義數(shù)據(jù)在網(wǎng)絡(luò)中的流動(dòng) # x - 28x28 def forward(self, x): x = self.flatten(x) # 輸出: 784, 對(duì)應(yīng)圖Layer 1 x = self.fc1(x) # 輸出: 512, 對(duì)應(yīng)Layer 2 out = self.fc2(x) # 輸出: 10, 對(duì)應(yīng)Layer 3 return out # (6)網(wǎng)絡(luò)的輸入、輸出以及測(cè)試網(wǎng)絡(luò)的性能(不經(jīng)過任何訓(xùn)練的網(wǎng)絡(luò)) net = MyNet() #網(wǎng)絡(luò)訓(xùn)練過程 #x,真實(shí)標(biāo)簽y ,網(wǎng)絡(luò)預(yù)測(cè)標(biāo)簽y_hat #目標(biāo):y_hat越來越接近y #算法:mini-batch 梯度下降 #優(yōu)化器 #具體實(shí)現(xiàn)梯度下降法的傳播 optimizer=torch.optim.SGD(net.parameters(),lr=1e-3) #損失函數(shù) #衡量y與y_hat之間的差異 loss_fn=nn.CrossEntropyLoss() #訓(xùn)練網(wǎng)絡(luò) def train(dataloader,net, loss_fn , optimizer): net.train() #一個(gè)batch一個(gè)batch的訓(xùn)練網(wǎng)絡(luò) for x,y in dataloader: pred=net(x) #衡量y與y_hat之間的loss #y:128,predicate:128x10 crossentropyloss loss=loss_fn(pred,y) #基于loss信息利用優(yōu)化器從后向前更新網(wǎng)絡(luò)全部參數(shù)<--- optimizer.zero_grad() loss.backward() optimizer.step() #訓(xùn)練一下 list = [] for i in range(20): for j in range(i): train(train_loader,net,loss_fn, optimizer) #todo 簡單訓(xùn)練一下后,網(wǎng)絡(luò)的性能 #網(wǎng)絡(luò)評(píng)估 def test(dataloader ,net ,loss_fn): net.eval() with torch.no_grad(): a = 0 for x,y in dataloader: pred = net(x)#128*10 #當(dāng)前batch的正確數(shù)量 correct = (pred.argmax(1)==y).type(torch.int).sum().item() a = a+int(correct) a = (a//79) return a list.append(test(test_loader, net, loss_fn)) print(list) x=np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,8,19]) y = np.array(list) plt.scatter(x,y) plt.title('訓(xùn)練次數(shù)對(duì)正確率的關(guān)系折線圖',fontsize = 18) plt.xlabel('訓(xùn)練次數(shù)',fontsize = 14) plt.ylabel('正確次數(shù)',fontsize = 14) plt.show() |
結(jié)果圖展示: 3 結(jié)語 關(guān)于訓(xùn)練次數(shù)對(duì)測(cè)試的正確率是否有關(guān)這一問題,通過本次實(shí)驗(yàn)只能得出訓(xùn)練比起沒有進(jìn)行訓(xùn)練,正確率有非常明顯的提高,對(duì)于訓(xùn)練次數(shù),訓(xùn)練次數(shù)越多正確的越好,同時(shí)存在訓(xùn)練效果達(dá)到飽和,存在最優(yōu)訓(xùn)練次數(shù)。
|