import torch
import torchvision
from torchvision import transforms
from torch.utils import data
import sys
import MyFunction as MF
from torch import nn
import numpy as np
import time
from tqdm import tqdm
#预测正确个数defaccuracy(y_hat, y):iflen(y_hat.shape)>1and y_hat.shape[1]>1:
y_hat = y_hat.argmax(axis=1)cmp= y_hat.type(y.dtype)== y
returnfloat(cmp.type(y.dtype).sum())#准确度评估函数defevaluate_accuracy_gpu_ch6(net, data_iter, device=None):"""使用GPU计算模型在数据集上的精度。"""
acc_sum, n =0.0,0ifisinstance(net, torch.nn.Module):
net.eval()# 设置为评估模式ifnot device:# 如果没指定device就使用net的device
device =next(iter(net.parameters())).device
# 正确预测的数量,总预测的数量for X, y in data_iter:ifisinstance(X,list):# BERT微调所需的(之后将介绍)
X =[x.to(device)for x in X]else:
X = X.to(device)
y = y.to(device)
acc_sum += MF.accuracy(net(X), y)
n += y.shape[0]
result = acc_sum / n
return result
训练
# 训练函数deftrain_ch6_2(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU训练模型"""definit_weights(m):iftype(m)== nn.Linear ortype(m)== nn.Conv2d:
nn.init.xavier_uniform_(m.weight)
net.apply(init_weights)print(f'training on {device}:{torch.cuda.get_device_name()}')
net.to(device)
optimizer = torch.optim.SGD(net.parameters(), lr=lr)
loss = nn.CrossEntropyLoss()
timer = MF.Timer()for epoch inrange(num_epochs):
train_l_sum, train_acc_sum, n =0.0,0.0,0
net.train()for X, y in train_iter:
timer.start()
optimizer.zero_grad()
X, y = X.to(device), y.to(device)
y_hat = net(X)
l = loss(y_hat, y)
l.backward()
optimizer.step()
train_l_sum += l.item()* X.shape[0]
train_acc_sum += MF.accuracy(y_hat,y)
n += y.shape[0]
train_l = train_l_sum / n
train_acc = train_acc_sum / n
timer.stop()#保存训练的模型参数
torch.save(net.state_dict(),"./data/%d.pth"%(epoch))
test_acc = MF.evaluate_accuracy_gpu_ch6(net, test_iter)print(f'epoch:{epoch+1},loss {train_l:.3f}, train_acc {train_acc:.3f}, test_acc {test_acc:.3f}, {timer.stop()} sec')print(f'{n* num_epochs / timer.sum():.1f} examples/sec 'f'on {str(device)}')