1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| class Accumulator: """在n个变量上累加""" def __init__(self, n): self.data = [0.0] * n
def add(self, *args): self.data = [a + float(b) for a, b in zip(self.data, args)]
def reset(self): self.data = [0.0] * len(self.data)
def __getitem__(self, idx): return self.data[idx] def accuracy(y_hat, y): """计算预测正确的数量""" if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: y_hat = y_hat.argmax(axis=1) cmp = y_hat.type(y.dtype) == y return float(cmp.type(y.dtype).sum()) def evaluate_accuracy(net, data_iter): """计算在指定数据集上模型的精度""" if isinstance(net, torch.nn.Module): net.eval() metric = Accumulator(2) with torch.no_grad(): for X, y in data_iter: metric.add(accuracy(net(X), y), y.numel()) return metric[0] / metric[1]
def train_epoch_ch3(net, train_iter, loss, updater): """训练模型一个迭代周期(定义见第3章)""" if isinstance(net, torch.nn.Module): net.train() metric = Accumulator(3) for X, y in train_iter: y_hat = net(X) l = loss(y_hat, y) if isinstance(updater, torch.optim.Optimizer): updater.zero_grad() l.mean().backward() updater.step() else: l.sum().backward() updater(X.shape[0]) metric.add(float(l.sum()), accuracy(y_hat, y), y.numel()) return metric[0] / metric[2], metric[1] / metric[2] def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): """训练模型(定义见第3章)""" for epoch in range(num_epochs): train_metrics = train_epoch_ch3(net, train_iter, loss, updater) train_loss, train_acc = train_metrics print(f'epoch {epoch + 1}, loss {train_loss:f}, acc {train_acc:f}')
|