深度学习(二):训练过程

一、加载数据集

        在开始训练之前,首先需要下载数据集并对其进行预处理。我们以Fashion-MNIST数据集为例,这是一个包含10种时尚物品的数据集。

import torch
from torchvision import datasets, transforms

def load_dataset():
    # 数据预处理流程 将数据转化为张量并对其进行归一化
    data_transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])
    # 下载训练数据并创建训练数据加载器
    train_set = datasets.FashionMNIST("dataset/", download=True, train=True, transform=data_transform)
    trainloader = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)
    # 下载测试数据并创建测试数据加载器
    test_set = datasets.FashionMNIST("dataset/", download=True, train=False, transform=data_transform)
    testloader = torch.utils.data.DataLoader(test_set, batch_size=64, shuffle=True)
    # 返回训练数据和测试数据加载器
    return trainloader, testloader

二、搭建模型

        我们简要搭建一个由全连接层构成的神经网络结构,如下图所示。

from torch import nn
import torch.nn.functional as F

class Classifier(nn.Module):
    def __init__(self):
        super().__init__()
        # 模型神经网络结构
        self.fc1 = nn.Linear(784, 256)
        self.fc2 = nn.Linear(256, 128)
        self.fc3 = nn.Linear(128, 64)
        self.fc4 = nn.Linear(64, 10)

        # 随机掐死一部分神经元
        self.dropout = nn.Dropout(p=0.2)

    def forward(self, x):
        x = x.view(x.shape[0], -1)

        # 模型前向传播过程
        x = self.dropout(F.relu(self.fc1(x)))
        x = self.dropout(F.relu(self.fc2(x)))
        x = self.dropout(F.relu(self.fc3(x)))
        x = F.log_softmax(self.fc4(x), dim=1)

        return x

三、训练过程

        在加载数据集并搭建好模型后,就可以开始训练了。首先,我们定义一个用于训练的类。然后,我们在开始训练前,先设定好一些基本的参数,例如损失函数,优化器,epoch等。

import torch
from models import Classifier
from torch import nn, optim
import matplotlib.pyplot as plt
from datasets import load_dataset

class training():
    def __init__(self):
        self.epoch = 15

    def training(self):
        # best_model用于保存测试效果最好的模型参数,best_loss用于保存效果最好的模型测试loss
        best_model = {}
        best_loss = 1
        # 初始化模型
        model = Classifier()
        # 创建训练数据和测试数据加载器
        trainloader, testloader = load_dataset()
        # 定义loss
        loss_function = nn.NLLLoss()
        # 定义优化器
        optimizer = optim.Adam(model.parameters(), lr=0.003)
        # train_losses和test_losses分别用于记录训练过程中每个epoch的loss
        train_losses, test_losses = [], []
        print("------------开始训练------------")
        # 开始训练
        for i in range(self.epoch):
            running_loss = 0
            # 导入一个批次的数据
            for images, labels in trainloader:
                # 梯度清零
                optimizer.zero_grad()
                # 推理
                predicts = model(images)
                # 计算loss
                loss = loss_function(predicts, labels)
                # 反向传播
                loss.backward()
                # 优化参数
                optimizer.step()
                # 将张量转化为标量 方便累加
                running_loss += loss.item()

            else:
                test_loss = 0
                # 准确度
                accuracy = 0
                with torch.no_grad():
                    # 使模型进入评估模式,例如取消dropout
                    model.eval()

                    for images, labels in testloader:
                        # 推理
                        predicts = model(images)
                        test_loss += loss_function(predicts, labels)
                        # 计算每种类别的概率 最大值为1
                        pr = torch.exp(predicts)
                        # 取最大的概率和类别
                        top_p, top_class = pr.topk(1, dim=1)
                        # 转化为0,1,方便计算准确度
                        res = top_class == labels.view(*top_class.shape)

                        # 计算准确度
                        accuracy += torch.mean(res.type(torch.FloatTensor))
                    # 使模型进入训练模式
                    model.train()
                    # 计算当前epoch的loss
                    epoch_train_loss = running_loss/len(trainloader)
                    epoch_test_loss = test_loss/len(testloader)
                    epoch_accuracy = accuracy/len(testloader)
                    # 记录所有epoch的loss
                    train_losses.append(epoch_train_loss)
                    test_losses.append(epoch_test_loss)
                    # 保存最佳模型
                    if epoch_test_loss < best_loss:
                        best_model = model.state_dict()
                        best_loss = epoch_test_loss
                    print("epoch:{}/{}..".format(i+1, self.epoch),
                          "epoch_train_loss:{}..".format(epoch_train_loss),
                          "epoch_test_loss:{}..".format(epoch_test_loss),
                          "epoch_accuracy:{}".format(epoch_accuracy))
        torch.save(best_model, "saved_models/best_model.pth")
        plt.plot(train_losses, label="train_losses")
        plt.plot(test_losses, label="test_losses")
        plt.legend()
        plt.show()

训练结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值