持续创造,加速生长!这是我参与「日新计划 10 月更文应战」的第29天,点击检查活动详情


之前咱们讲了怎样从零建立一个神经网络,可是咱们要知道,只建立是没用的,由于不经过练习的模型就像没上过学的孩子,什么常识也不知道,那就不叫人工智能了,叫人工智障。

上一节咱们搞的是一个能够用于图片分类的神经网络,在输入的当地咱们没弄数据集,常识给X随机初始化了一些数字,这次为了更直观得看一下作用,这儿咱们用Fashion-MNIST数据集做一下示范,关于怎样读取数据集我没讲过,具体的能够看另一个安安的文章:PyTorch数据集处理。


咱们的模型有不同的参数(wwbb),由于这些参数能让模型学到对应的分布,练习模型也就意味着让模型取得比较好的参数。

现在咱们已经有模型和数据集了,咱们就能够运用数据优化咱们的模型,进行练习、验证、测验咱们的模型了。

模型练习进程是一个不断迭代的进程,在每个循环(epoch)中,模型都会依据输入取得一个对应的输出,并经过loss核算这个输出和实在输出的偏差,并搜集这个偏差关于参数的导数,并运用梯度下降优化参数。

更具体的能够看这个视频:反向传达演算 – YouTube

代码

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor()
)
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor()
)
train_dataloader = DataLoader(training_data, batch_size=64)
test_dataloader = DataLoader(test_data, batch_size=64)

这一段代码便是导包,然后加载torchvision的FashionMNIST数据集,咱们能够看到同时加载了练习集和测验集,练习集用于模型的练习,测验集用于测验模型作用。

然后运用DataLoader将数据加载进来,batch size设置的是64。

数据集预备代码假如看不懂能够去看安余生的博客:PyTorch数据集处理 – ()

class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )
    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits
model = NeuralNetwork()

这儿便是建立一个神经网络,网络由一个展开层、三个线性层组成,运用的激活函数是ReLU激活函数,最终

建立网络看不懂能够看LolitaAnn的:零基础用PyTorch建立自己的神经网络 – ()

代码运行之后你能够看到嘎嘎给你把数据集安排好了。

模型建好了,可以教它学习知识了!

超参数

超参数是练习人员手动调整的参数,用于操控模型的优化进程。设置不同的超参数数值会影响模型的练习和收敛作用。

在咱们这儿比如中咱们需要界说以下几个超参数:

  1. 学习率learning_rate,每个batch、epoch模型参数的更新量。学习率假如设置的太小会导致学习速率较慢,假如设置的较大,可能会导致模型重复横跳无法优化。

  2. 一个批量的巨细batch_size,模型一次读一张图太慢了,所以咱们让模型一次取得一组图,这个参数便是每次给网络的样本数量。

  3. 迭代次数epoch,便是你要练习几个循环。

learning_rate = 1e-3
batch_size = 64
epochs = 5

咱们设置好超参数之后们就能够进行循环来练习优化咱们的模型了!每次循环称之为一个epoch

每个epoch由两部分组成:

  • 练习– 运用练习集迭代,以寻觅收敛到最佳参数。

  • 验证、测验运用测验集,检查模型的性能是否在不断提高。

丢失函数

之前讲创建神经网络的时分咱们说过,一个没有经过练习的模型,假如你给他测验集,他必定胡言乱语瞎猜答案的,由于他不知道正确答案是什么。现在咱们要练习模型了,怎样让模型知道对错,就需要运用丢失函数

丢失函数的作用是:衡量所取得的成果与目标值的类似程度

咱们在这个博客里的这个图画分类的比如,在练习进程中需要最小化的丢失函数(交叉熵丢失)。为了核算丢失,咱们运用给定数据样本的输入进行猜测,并运用丢失函数将其与实在数据标签值进行比较。

# Initialize the loss function
loss_fn = nn.CrossEntropyLoss()

优化器

模型优化进程便是在每次迭代中调整模型参数,减少模型误差。优化算法界说了整个优化进程,咱们在这儿运用随机梯度下降。所有的优化逻辑都封装在了optimizer目标中,咱们今日的比如运用的SDG优化器,Pytorch还提供了许多不同的优化器,感兴趣的能够看 torch.optim — PyTorch 1.12 documentation

optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

开端练习!

现在全部预备结束,咱们能够安排上咱们的练习和测验进程了!

def train(dataloader, model, loss_fn, optimizer):
    # size是看数据集有多大,这儿FashionMNIST数据集的测验集有60000张图。
    size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
        # 运用模型猜测成果
        pred = model(X)
        # 核算loss
        loss = loss_fn(pred, y)
        # 反向传递进程
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # 每100个batch输出一次成果
        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")

这儿再弥补一下反向传达进程的代码解析:

  • optimizer.zero_grad():咱们进行下一次batch梯度核算的时分,要清空上一个batch的梯度核算成果,因而这儿在下一次梯度更新的时分,先运用optimizer.zero_grad把梯度信息设置为0。

  • loss.backward():运用autograd沿着核算图反向传达,依据链式法则核算你所需要的梯度成果。

  • optimizer.step():用来更新参数。

def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

然后是测验部分的代码。咱们能够看到有个with torch.no_grad(),这个之前在torch.autograd原理讲过,在不需要核算梯度的时分加速运算进程。

下边这段代码是初始化丢失函数和优化器,然后咱们就能够设定epoch数量对模型进行学习进程进行盯梢了。

# 初始化丢失函数和优化器
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# 设定练习迭代的次数
epochs = 10
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")

之后你就能够看到输出长这个样子,一直到epoch 10,最终练习结束显现Done!

Epoch 1
——————————- loss: 2.298552 [ 0/60000]
loss: 2.287774 [ 6400/60000]
loss: 2.263033 [12800/60000]
loss: 2.262209 [19200/60000]
loss: 2.262916 [25600/60000]
loss: 2.220241 [32000/60000]
loss: 2.238093 [38400/60000]
loss: 2.196644 [44800/60000]
loss: 2.190552 [51200/60000]
loss: 2.169663 [57600/60000]
Test Error:
Accuracy: 32.2%, Avg loss: 2.160499
……
Done!