首页 > 其他分享 >123

123

时间:2023-10-25 14:44:35浏览次数:37  
标签:loss 60000 torch 123 FashionMNIST model data


   

一个完整的模型训练过程包括数据准备、模型搭建、训练与优化等过程,每个过程又涉及若干不同的知识点,本篇中,我们通过一个示例,从整体层面介绍PyTorch的完整建模流程,通过这个例子,我们可以知道建模流程中的各个环节所要做的事情及其意义。在后续的博客中,我们将展开介绍各个过程环节涉及的相关知识内容。

   

1 数据准备

   

无论是构建何种模型,完成何种训练任务,都是建立在一定数据的基础上,所以,在建模之初,首先要做的就是准备数据。

PyTorch有两个与处理数据相关的模块:torch.utils.data.DataLoadertorch.utils.data.Dataset,其中torch.utils.data.DataLoader用于将数据集进行打包封装成一个可迭代对象,torch.utils.data.Dataset存储有一些常用的数据集示例以及相关标签。

同时PyTorch针对不同的专业领域,也提供有不同的模块,例如 TorchText(自然语言处理), TorchVision(计算机视觉), TorchAudio(音频),这些模块中也都包含一些真实数据集示例。例如TorchVision模块中提供了CIFAR, COCO, FashionMNIST 数据集。

现在,我们使用FashionMNIST数据集,以服饰分类任务介绍PyTorch的建模流程。

   

我们导入必要的模块:

  In [1]:
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda, Compose
import matplotlib.pyplot as plt
   

现在,我们下载数据,代码如下,我们通过torchvision中的datasets加载自带的FashionMNIST数据集,并通过root参数指定数据集存放在当前目录下的data目录内,因为我在此前没有下载过,所以将download参数设为True,表示需要通过代码进行自动下载,如果你的网络不好,下载一直失败,那么,你可以从这里下载数据集,解压后放到root指定的目录中。

  In [6]:
# 下载数训练据集
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)
   
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to data/FashionMNIST/raw/train-images-idx3-ubyte.gz
 
100%|██████████| 26421880/26421880 [1:19:01<00:00, 5572.61it/s]
 
Extracting data/FashionMNIST/raw/train-images-idx3-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw/train-labels-idx1-ubyte.gz
 
100%|██████████| 29515/29515 [00:00<00:00, 45160.87it/s]
 
Extracting data/FashionMNIST/raw/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz
 
100%|██████████| 4422102/4422102 [2:31:30<00:00, 486.43it/s]  
 
Extracting data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz
 
100%|██████████| 5148/5148 [00:00<00:00, 10844940.73it/s]
 
Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw

    In [7]:
# 下载测试数据集
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)
   

下载后的数据集将保存在training_data和test_data两个对象中,这两个对象都是torch.utils.data.Dataset类的实例。关于FashionMNIST、Dataset、Dataloader,在后续的博客中,我们都会一一详细介绍。

  In [8]:
isinstance(training_data, torch.utils.data.Dataset), isinstance(test_data, torch.utils.data.Dataset)
  Out[8]:
(True, True)
   

接下来,我们需要将training_data和test_data封装成DataLoader类实例,封装成DataLoader类实例后,且支持迭代、自动分割成簇、下采样、打乱、多进程加载数据等操作。

  In [11]:
batch_size = 64

# 创建数据加载器
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break
   
Shape of X [N, C, H, W]:  torch.Size([64, 1, 28, 28])
Shape of y:  torch.Size([64]) torch.int64
   

我们展示一下这些数据:

  In [12]:
from chb import show_image
   

chb是我放在pypi的一个开源库,里面是我平时会用的到一些小代码,show_image就是其中一个用于展示图片的方法。大家可以通过以下命令下载:

$ pip install chb
  In [14]:
images, labels = next(iter(train_dataloader))
show_image([(img, lab) for img, lab in zip(images[:10], labels[:10]) ])
       

到此,对数据的处理过程已然完成,可以开始定义模型。由于我们使用的是人工神经网络模型,我们可以创建一个类,去继承nn.Module,在类的构造方法中定义网络各个层。

   

2 模型搭建

  In [6]:
# 定义模型
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
   

为加速训练,我们可以使用GPU进行训练,不过有必要判断一下是否存在GPU设备,然后再将模型加载到设备中:

  In [7]:
# 判断是否存在GPU
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
model = NeuralNetwork().to(device)
print(model)
   
Using cuda device
NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=784, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=512, bias=True)
    (3): ReLU()
    (4): Linear(in_features=512, out_features=10, bias=True)
  )
)
   

3 训练与优化

   

数据集和模型都准备好之后,就可以开始训练和优化的过程。为完成模型训练,我们还需要为模型指定损失函数和优化器:

  In [8]:
# 交叉熵损失函数
loss_fn = nn.CrossEntropyLoss()
# SGD方法进行优化
optimizer = torch.optim.SGD(model.parameters(), lr=1e-3)
   

在一次单独训练过程中,模型会通过预测结果与训练集标签进行校对,根据校对准确率进行反向传播,从而达到调整模型参数的目的。训练过程代码如下:

  In [9]:
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)

        # 计算误差
        pred = model(X)
        loss = loss_fn(pred, y)

        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")
   

在训练过程中,我们常常通过测试集来验证模型的准确率:

  In [10]:
def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            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")
   

接下来,可以正式开始训练,我们先训练5轮:

  In [13]:
epochs = 5
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 1
-------------------------------
loss: 0.786908  [    0/60000]
loss: 0.856685  [ 6400/60000]
loss: 0.633258  [12800/60000]
loss: 0.849028  [19200/60000]
loss: 0.738350  [25600/60000]
loss: 0.734769  [32000/60000]
loss: 0.812572  [38400/60000]
loss: 0.795026  [44800/60000]
loss: 0.797189  [51200/60000]
loss: 0.763483  [57600/60000]
Test Error: 
 Accuracy: 72.3%, Avg loss: 0.758835 

Epoch 2
-------------------------------
loss: 0.750288  [    0/60000]
loss: 0.828323  [ 6400/60000]
loss: 0.602143  [12800/60000]
loss: 0.825365  [19200/60000]
loss: 0.716997  [25600/60000]
loss: 0.709113  [32000/60000]
loss: 0.787452  [38400/60000]
loss: 0.778843  [44800/60000]
loss: 0.775311  [51200/60000]
loss: 0.743379  [57600/60000]
Test Error: 
 Accuracy: 73.4%, Avg loss: 0.737126 

Epoch 3
-------------------------------
loss: 0.718289  [    0/60000]
loss: 0.802935  [ 6400/60000]
loss: 0.575369  [12800/60000]
loss: 0.805272  [19200/60000]
loss: 0.698708  [25600/60000]
loss: 0.687783  [32000/60000]
loss: 0.764835  [38400/60000]
loss: 0.764436  [44800/60000]
loss: 0.756569  [51200/60000]
loss: 0.725625  [57600/60000]
Test Error: 
 Accuracy: 74.4%, Avg loss: 0.717835 

Epoch 4
-------------------------------
loss: 0.689940  [    0/60000]
loss: 0.779801  [ 6400/60000]
loss: 0.551888  [12800/60000]
loss: 0.787713  [19200/60000]
loss: 0.682854  [25600/60000]
loss: 0.669718  [32000/60000]
loss: 0.744048  [38400/60000]
loss: 0.751069  [44800/60000]
loss: 0.740112  [51200/60000]
loss: 0.709649  [57600/60000]
Test Error: 
 Accuracy: 75.2%, Avg loss: 0.700398 

Epoch 5
-------------------------------
loss: 0.664450  [    0/60000]
loss: 0.758469  [ 6400/60000]
loss: 0.531073  [12800/60000]
loss: 0.772000  [19200/60000]
loss: 0.668949  [25600/60000]
loss: 0.654071  [32000/60000]
loss: 0.724732  [38400/60000]
loss: 0.738524  [44800/60000]
loss: 0.725478  [51200/60000]
loss: 0.694969  [57600/60000]
Test Error: 
 Accuracy: 75.9%, Avg loss: 0.684460 

Done!
   

5轮训练完成,从输出结果可以看出,模型装瘸率逐渐提高。当然,如果要更高的准确率,我们需要更多轮次的训练,或者优化模型。

   

4 保存模型与加载

4.1 保存模型

保存模型常用的方法就是将模型序列化到本地进行离线保存模型各个参数,后续需要再次使用模型时,就不需要重新训练,直接加载即可。

  In [14]:
torch.save(model.state_dict(), "models/fashion_mnist/model.pth")
print("Saved PyTorch Model State to model.pth")
   
Saved PyTorch Model State to model.pth
   

4.2 加载模型

   

之前保存在本地的模型可以再次加载出来,然后直接进行预测。

  In [15]:
model = NeuralNetwork()
model.load_state_dict(torch.load("models/fashion_mnist/model.pth"))
  Out[15]:
<All keys matched successfully>
   

尝试使用刚加载的模型进行识别:

  In [16]:
classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{predicted}", Actual: "{actual}"')
   
Predicted: "Ankle boot", Actual: "Ankle boot"
   

5 总结

上文中,为完成一个服饰分类任务,我们使用PyTorch构建并训练了一个网络模型。在此过程中,我们进行了数据准备、模型构建、模型训练与优化、模型保存与加载等等过程。对于初学者,这些过程中涉及的细节可能不甚了解,例如数据准备过程中为什么要使用torch.utils.data.DataLoadertorch.utils.data.Dataset、模型构建过程,我们怎么去个性化定制网络结构、训练过程,我们怎么去配置优化器,优化器又有哪一些。别急,这些内容在我们后续的文章中,都有专门的内容介绍。通过本篇,你只需要记住一个完整的建模有哪些过程,作用是什么即可。

标签:loss,60000,torch,123,FashionMNIST,model,data
From: https://www.cnblogs.com/chenhuabin/p/17787185.html

相关文章

  • 123456
    ;++++++++++++++++++++712B584835483739676B383D495647774B476942737342785158354A6544356C5132337A4F484569532F2B5542697258444133326749654A2B4A494B50592B506A774F2F566C397442644266635478484D48677652727953576A59776A4B58622B73496443666A626E2B7342722F76774530666A6......
  • 模拟输入密码只有三次机会密码为123
    #include <stdio.h>{inti=0;ints=0;for(i=0;i<3;i++) {  printf("请输入密码:\n"); scanf("%d",&s);if(s==123){printf("登录成功\n");break;}else{if(i==2){printf("已错三次登录失败\n");beeak;}printf(&q......
  • 12306
    importreimportrequestsdefkeys_values(d,value):returnlist(d.keys())[list(d.values()).index(value)]headers={"Cookie":"_uab_collina=169692832736292006740293;tk=J8HeHzkZevrt4pki7lrzlw0gWQAuAtETriqaAQ09x1x0;JSESSIONID=80DA6......
  • Acwing.第123场周赛
    Acwing.第123场周赛比赛链接回家休息了五天调整好状态继续出发!!!!A.队列一共有三个队列,当前分别已有a,b,c个人。现在有n个人尚未进队,每个人都需要被安排到一个队列当中。为了队形整齐,我们希望所有人被安排进队后,三个队列包含的人数均相等。请你判断,是否可能做到。输入格式......
  • 123木头人
    html+css入门:html入门教程_html教程-CSDN博客HTML+CSS小白入门与进阶教程-CSDN博客......
  • 1113123131
    //#include<bits/stdc++.h>//usingnamespacestd;//intmain(){// inta,b,c;// scanf("%d%d%d",&a,&b,&c);// cout<<setw(8)<<a<<""<<setw(8)<<b<<""<<setw(8)<<......
  • CF1234(Div. 3) 题解(A to E)
    AEqualizePricesAgain题解题目大意\(n\)个商品,每个商品价格为\(a_i\),求一个最小的价格\(x\),使得不亏本(即\(\sum\limits_{i=1}^n{(a_i-x)}\ge0\))。解题思路输出平均数向上取整(即\(\left\lceil(\sum\limits_{i=1}^n{a_i})\divn\right\rceil\))即可。代码#include<bit......
  • 以下是一个比较复杂的R语言代码示例: ```R # 生成随机数 set.seed(123) data <- rnorm
    以下是一个比较复杂的R语言代码示例:#生成随机数set.seed(123)data<-rnorm(1000)#数据处理和分析data_mean<-mean(data)data_sd<-sd(data)data_median<-median(data)#创建一个绘图窗口par(mfrow=c(2,2))#绘制直方图hist(data,main="HistogramofDat......
  • AtCoder Regular Contest 123 F Insert Addition
    洛谷传送门AtCoder传送门用\((x,y)\)表示\(Ax+By\),那么这个等价于SB树。那么直接在SB树上二分,遍历一遍找到\(n\)个点就好了。可以采用类似线段树查询的方式。于是现在还剩下一个子问题:给定\(a,b\),求\(ax+by\len\)且\(\gcd(x,y)=1\)的正整数\((x,y......
  • 砝码123456
    法玛三因子模型(Fama-FrenchThree-FactorModel)是一种资本资产定价模型(CapitalAssetPricingModel,CAPM)的扩展,用于解释股票回报的变异性。该模型由尤金·法玛(EugeneFama)和肯尼斯·法rench(KennethFrench)于1992年提出。该模型考虑了三个因子对股票回报的影响:市场风险因子、市值......