当前位置:   article > 正文

Pytorch-以数字识别更好地入门深度学习_pytorch深度学习绘制可视化数字2

pytorch深度学习绘制可视化数字2

目录

一、数据介绍

二、下载数据 

三、可视化数据

四、模型构建

五、模型训练

六、模型预测


一、数据介绍

MNIST数据集是深度学习入门的经典案例,因为它具有以下优点:

1. 数据量小,计算速度快。MNIST数据集包含60000个训练样本和10000个测试样本,每张图像的大小为28x28像素,这样的数据量非常适合在GPU上进行并行计算。

2. 标签简单,易于理解。MNIST数据集的标签只有0-9这10个数字,相比其他图像分类数据集如CIFAR-10等更加简单易懂。

3. 数据集已标准化。MNIST数据集中的图像已经被归一化到0-1之间,这使得模型可以更快地收敛并提高准确率。

4. 适合初学者练习。MNIST数据集是深度学习入门的最佳选择之一,因为它既不需要复杂的数据预处理,也不需要大量的计算资源,可以帮助初学者快速上手深度学习。

综上所述,MNIST数据集是深度学习入门的经典案例,它具有数据量小、计算速度快、标签简单、数据集已标准化、适合初学者练习等优点,因此被广泛应用于深度学习的教学和实践中。

手写数字识别技术的应用非常广泛,例如在金融、保险、医疗、教育等领域中,都有很多应用场景。手写数字识别技术可以帮助人们更方便地进行数字化处理,提高工作效率和准确性。此外,手写数字识别技术还可以用于机器人控制、智能家居等方面  。

使用torch.datasets.MNIST下载到指定目录下:./data,当download=True时,如果已经下载了不会再重复下载,同train选择下载训练数据还是测试数据

官方提供的类:

  1. class MNIST(
  2. root: str,
  3. train: bool = True,
  4. transform: ((...) -> Any) | None = None,
  5. target_transform: ((...) -> Any) | None = None,
  6. download: bool = False
  7. )
  8. Args:
  9. root (string): Root directory of dataset where MNIST/raw/train-images-idx3-ubyte
  10. and MNIST/raw/t10k-images-idx3-ubyte exist.
  11. train (bool, optional): If True, creates dataset from train-images-idx3-ubyte,
  12. otherwise from t10k-images-idx3-ubyte.
  13. download (bool, optional): If True, downloads the dataset from the internet and
  14. puts it in root directory. If dataset is already downloaded, it is not downloaded again.
  15. transform (callable, optional): A function/transform that takes in an PIL image
  16. and returns a transformed version. E.g, transforms.RandomCrop
  17. target_transform (callable, optional): A function/transform that takes in the
  18. target and transforms it.

二、下载数据 

  1. # 导入数据集
  2. # 训练集
  3. import torch
  4. from torchvision import datasets,transforms
  5. from torch.utils.data import Dataset
  6. train_loader = torch.utils.data.DataLoader(
  7. datasets.MNIST(root="./data",
  8. train=True,
  9. download=True,
  10. transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))])),
  11. batch_size=64,
  12. shuffle=True)
  13. # 测试集
  14. test_loader = torch.utils.data.DataLoader(
  15. datasets.MNIST("./data",train=False,transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,),(0.3081,))])),
  16. batch_size=64,shuffle=True
  17. )

pytorch也提供了自定义数据的方法,根据自己数据进行处理

使用PyTorch提供的Dataset和DataLoader类来定制自己的数据集。如果想个性化自己的数据集或者数据传递方式,也可以自己重写子类。

以下是一个简单的例子,展示如何创建一个自定义的数据集并将其传递给模型进行训练:

  1. import torch
  2. from torch.utils.data import Dataset, DataLoader
  3. class MyDataset(Dataset):
  4. def __init__(self, data, labels):
  5. self.data = data
  6. self.labels = labels
  7. def __len__(self):
  8. return len(self.data)
  9. def __getitem__(self, index):
  10. x = self.data[index]
  11. y = self.labels[index]
  12. return x, y
  13. data = torch.randn(100, 3, 32, 32)
  14. labels = torch.randint(0, 10, (100,))
  15. my_dataset = MyDataset(data, labels)
  16. my_dataloader = DataLoader(my_dataset, batch_size=4, shuffle=True)

详细完整流程可参考: Pytorch快速搭建并训练CNN模型?

三、可视化数据

  1. mport matplotlib.pyplot as plt
  2. import numpy as np
  3. import torchvision
  4. def imshow(img):
  5. img = img / 2 + 0.5 # 逆归一化
  6. npimg = img.numpy()
  7. plt.imshow(np.transpose(npimg,(1,2,0)))
  8. plt.title("Label")
  9. plt.show()
  10. # 得到batch中的数据
  11. dataiter = iter(train_loader)
  12. images,labels = next(dataiter)
  13. # 展示图片
  14. imshow(torchvision.utils.make_grid(images))

四、模型构建

定义模型类并继承nn.Module基类

  1. # 构建模型
  2. import torch.nn as nn
  3. import torch
  4. import torch.nn.functional as F
  5. class MyNet(nn.Module):
  6. def __init__(self):
  7. super(MyNet,self).__init__()
  8. # 输入图像为单通道,输出为六通道,卷积核大小为5×5
  9. self.conv1 = nn.Conv2d(1,6,5)
  10. self.conv2 = nn.Conv2d(6,16,5)
  11. # 将16×4×4的Tensor转换为一个120维的Tensor,因为后面需要通过全连接层
  12. self.fc1 = nn.Linear(16*4*4,120)
  13. self.fc2 = nn.Linear(120,84)
  14. self.fc3 = nn.Linear(84,10)
  15. def forward(self,x):
  16. # 在(2,2)的窗口上进行池化
  17. x = F.max_pool2d(F.relu(self.conv1(x)),2)
  18. x = F.max_pool2d(F.relu(self.conv2(x)),2)
  19. # 将维度转换成以batch为第一维,剩余维数相乘为第二维
  20. x = x.view(-1,self.num_flat_features(x))
  21. x = F.relu(self.fc1(x))
  22. x = F.relu(self.fc2(x))
  23. x = self.fc3(x)
  24. return x
  25. def num_flat_features(self,x):
  26. size = x.size()[1:]
  27. num_features = 1
  28. for s in size:
  29. num_features *= s
  30. return num_features
  31. net = MyNet()
  32. print(net)

输出: 

  1. MyNet(
  2. (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
  3. (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  4. (fc1): Linear(in_features=256, out_features=120, bias=True)
  5. (fc2): Linear(in_features=120, out_features=84, bias=True)
  6. (fc3): Linear(in_features=84, out_features=10, bias=True)
  7. )

简单的前向传播

  1. # 前向传播
  2. print(len(images))
  3. image = images[:2]
  4. label = labels[:2]
  5. print(image.shape)
  6. print(image.size())
  7. print(label)
  8. out = net(image)
  9. print(out)

输出: 

  1. 16
  2. torch.Size([2, 1, 28, 28])
  3. torch.Size([2, 1, 28, 28])
  4. tensor([6, 0])
  5. tensor([[ 1.5441e+00, -1.2524e+00, 5.7165e-01, -3.6299e+00, 3.4144e+00,
  6. 2.7756e+00, 1.1974e+01, -6.6951e+00, -1.2850e+00, -3.5383e+00],
  7. [ 6.7947e+00, -7.1824e+00, 8.8787e-01, -5.2218e-01, -4.1045e+00,
  8. 4.6080e-01, -1.9258e+00, 1.8958e-01, -7.7214e-01, -6.3265e-03]],
  9. grad_fn=<AddmmBackward0>)

计算损失:

  1. # 计算损失
  2. # 因为是多分类,所有采用CrossEntropyLoss函数,二分类用BCELoss
  3. image = images[:2]
  4. label = labels[:2]
  5. out = net(image)
  6. criterion = nn.CrossEntropyLoss()
  7. loss = criterion(out,label)
  8. print(loss)

输出:

tensor(2.2938, grad_fn=<NllLossBackward0>)

五、模型训练

  1. # 开始训练
  2. model = MyNet()
  3. # device = torch.device("cuda:0")
  4. # model = model.to(device)
  5. import torch.optim as optim
  6. optimizer = optim.SGD(model.parameters(),lr=0.01) # lr表示学习率
  7. criterion = nn.CrossEntropyLoss()
  8. def train(epoch):
  9. # 设置为训练模式:某些层的行为会发生变化(dropout和batchnorm:会根据当前批次的数据计算均值和方差,加速模型的泛化能力)
  10. model.train()
  11. running_loss = 0.0
  12. for i,data in enumerate(train_loader):
  13. # 得到输入和标签
  14. inputs,labels = data
  15. # 消除梯度
  16. optimizer.zero_grad()
  17. # 前向传播、计算损失、反向传播、更新参数
  18. outputs = model(inputs)
  19. loss = criterion(outputs,labels)
  20. loss.backward()
  21. optimizer.step()
  22. # 打印日志
  23. running_loss += loss.item()
  24. if i % 100 == 0:
  25. print("[%d,%5d] loss: %.3f"%(epoch+1,i+1,running_loss/100))
  26. running_loss = 0
  27. train(10)

输出:

  1. [11, 1] loss: 0.023
  2. [11, 101] loss: 2.302
  3. [11, 201] loss: 2.294
  4. [11, 301] loss: 2.278
  5. [11, 401] loss: 2.231
  6. [11, 501] loss: 1.931
  7. [11, 601] loss: 0.947
  8. [11, 701] loss: 0.601
  9. [11, 801] loss: 0.466
  10. [11, 901] loss: 0.399

六、模型预测

  1. # 模型预测结果
  2. correct = 0
  3. total = 0
  4. with torch.no_grad():
  5. for data in test_loader:
  6. images,labels = data
  7. outputs = model(images)
  8. # 最大的数值及最大值对应的索引
  9. value,predicted = torch.max(outputs.data,1)
  10. total += labels.size(0)
  11. # 对bool型的张量进行求和操作,得到所有预测正确的样本数,采用item将整数类型的张量转换为python中的整型对象
  12. correct += (predicted == labels).sum().item()
  13. print("predicted:{}".format(predicted[:10].tolist()))
  14. print("label:{}".format(labels[:10].tolist()))
  15. print("Accuracy of the network on the 10 test images: %d %%"% (100*correct/total))
  16. imshow(torchvision.utils.make_grid(images[:10],nrow=len(images[:10])))

输出:

  1. predicted:[1, 0, 7, 6, 5, 2, 4, 3, 2, 6]
  2. label:[1, 0, 7, 6, 5, 2, 4, 8, 2, 6]
  3. Accuracy of the network on the 10 test images: 91 %

对应类别的准确率:

  1. class_correct = list(0. for i in range(10))
  2. class_total = list(0. for i in range(10))
  3. classes = [i for i in range(10)]
  4. with torch.no_grad():# model.eval()
  5. for data in test_loader:
  6. images,labels = data
  7. outputs = model(images)
  8. value,predicted = torch.max(outputs,1)
  9. c = (predicted == labels).squeeze()
  10. # 对所有labels逐个进行判断
  11. for i in range(len(labels)):
  12. label = labels[i]
  13. class_correct[label] += c[i].item()
  14. class_total[label] += 1
  15. print("class_correct:{}".format(class_correct))
  16. print("class_total:{}".format(class_total))
  17. # 每个类别的指标
  18. for i in range(10):
  19. print('Accuracy of -> class %d : %2d %%'%(classes[i],100*class_correct[i]/class_total[i]))

输出:

  1. class_correct:[958.0, 1119.0, 948.0, 938.0, 901.0, 682.0, 913.0, 918.0, 748.0, 902.0]
  2. class_total:[980.0, 1135.0, 1032.0, 1010.0, 982.0, 892.0, 958.0, 1028.0, 974.0, 1009.0]
  3. Accuracy of -> class 0 : 97 %
  4. Accuracy of -> class 1 : 98 %
  5. Accuracy of -> class 2 : 91 %
  6. Accuracy of -> class 3 : 92 %
  7. Accuracy of -> class 4 : 91 %
  8. Accuracy of -> class 5 : 76 %
  9. Accuracy of -> class 6 : 95 %
  10. Accuracy of -> class 7 : 89 %
  11. Accuracy of -> class 8 : 76 %
  12. Accuracy of -> class 9 : 89 %
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/690405
推荐阅读
相关标签
  

闽ICP备14008679号