小言_互联网的博客

PyTorch图像分类

298人阅读  评论(0)

目录

一、torch和torchvision

1、torchvision.datasets

2、torchvision.models

3、torchvision.transforms

4、torchvision.utils

二、MNIST手写数字识别

1、获取MNIST训练集和测试集

2、数据装载

3、数据预览

4、构建卷积神经网络模型

5、对模型进行训练和参数优化

6、对训练模型进行保存和加载

7、MNIST手写数字识别完整代码

三、CIFAR10图像分类

1、CIFAR10数据集介绍

2、CIFAR10图像分类实现

3、在GPU上跑神经网络


一、torch和torchvision

PyTorch 中有两个核心的包,分别是 torch torchvision

torch.nn 包提供了很多与实现神经网络中的具体功能相关的类,torch.optim包中提供了非常多的可实现参数自动优化的类,torch.autograd实现自动梯度的功能等。

torchvision 包含了目前流行的数据集,模型结构和常用的图片转换工具,它的主要功能是实现数据的处理、导入和预览等,所以如果需要对计算机视觉的相关问题进行处理,就可以借用在torchvision包中提供的大量的类来完成相应的工作。

1、torchvision.datasets

torchvision.datasets 中包含以下数据集:MNIST,COCO,LSUN Classification,ImageFolder,Imagenet-12,CIFAR10 and CIFAR100,STL10等。

2、torchvision.models

torchvision.models 模块的子模块中包含以下模型结构:AlexNet,VGG,ResNet,SqueezeNet,DenseNet

3、torchvision.transforms

(1)torchvision.transforms.Compose(transforms)

torchvision.transforms.Compose 类看作是一种容器,它能够同时对多种数据变换进行组合。传入的参数是一个列表,列表中的元素就是对载入的数据进行的各种变换操作。


  
  1. transform = transforms.Compose([transforms.ToTensor(),
  2. transforms.Normalize(mean=[ 0.5, 0.5, 0.5],
  3. std=[ 0.5, 0.5, 0.5])])

torchvision.transforms.Compose 类中只是用了一个类型的转换变化transfroms.ToTensor和一个数据标准化变换transforms.Normalize。这里使用的是标准化变换也叫标准差变换法,这种方法需要使用原始数据的均值(Mean)和标准差(Standard Deviation)来进行数据的标准化,在经过标准化变换之后,数据全部符合均值为0,标准差为1的标准正态分布。

(2)torchvision.transforms.Resize

用于对载入的图片数据按我们需求的大小进行缩放。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h ,w )的序列,其中,h 代表高度,w 代表宽度,但是如果使用的是一个整型数据,那么表示缩放的宽度和高度都是这个整型数据的值。

(3)torchvision.transforms.Scale

用于对载入的图片数据按我们需求的大小进行缩放,用法和 torchvision.transforms.Resize 类似。

(4)torchvision.transforms.CenterCrop

用于对载入的图片以图片中心为参考点,按我们需要的大小进行裁剪。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h ,w )的元组序列。

(5)torchvision.transforms.RandomCrop

用于对载入的图片按我们需要的大小进行随机裁剪。传递给这个类的参数可以是一个整型数据,也可以是一个类似于(h ,w )的元组序列。

(6)torchvision.transforms.RandomHorizontalFlip

用于对载入的图片按随机概率进行水平翻转。我们可以通过传递给这个类的参数自定义随机概率,如果没有定义,则使用默认的概率值0.5。

(7)torchvision.transforms.RandomVerticalFlip

用于对载入的图片按随机概率进行垂直翻转。我们可以通过传递给这个类的参数自定义随机概率,如果没有定义,则使用默认的概率值0.5。

(8)torchvision.transforms.ToTensor

用于对载入的图片数据进行类型转换,将之前构成PIL图片的数据转换成Tensor数据类型的变量,即将一个取值范围是[0, 255]PIL.Imageshape(H, W, C)numpy.ndarray,转换成形状为[C, H, W],取值范围是[0, 1.0]torch.FloatTensor,让PyTorch能够对其进行计算和处理。

(9) torchvision.transforms.ToPILImage

用于将Tensor变量的数据转换成PIL图片数据,主要是为了方便图片内容的显示。

(10)torchvision.transforms.RandomSizedCrop(size, interpolation=2)

先随机切,再resize成给定size大小。

(11)torchvision.transforms.Pad(padding, fill=0)

给所有边用给定的值填充。padding:要填充多少像素。

(12)torchvision.transforms.Normalize(mean, std)

给定均值与方差,正则化,即Normalized_image=(image-mean)/std

13)通用变换:使用lambda作为转换器,transforms.Lambda(lambda)

4、torchvision.utils

(1)torchvision.utils.make_grid

utils.make_grid(tensor, nrow=8, padding=2, normalize=False, range=None, scale_each=False), 给定4D-mini-batch Tensor,形状为(B*C*H*W),或者一个a list of image,做成一个size(B / nrow, nrow)的子图集,其中参数:normalize=True, 对图像像素归一化,range=(min, max),min和max是数字,则min, max用来规范化image,scale_each=True, 每个图片独立规范化。

(2)torchvision.utils.save_image

utils.save_image(tensor, filename, nrow=8, padding=2, normalize=False, range=None, scale_each=False),将给定的Tensor保存成image文件,如果是mini-batch tensor,就用make-grid做成子图集再保存。

二、MNIST手写数字识别

1、获取MNIST训练集和测试集


  
  1. # 对数据进行载入及有相应变换,将Compose看成一种容器,他能对多种数据变换进行组合
  2. # 传入的参数是一个列表,列表中的元素就是对载入的数据进行的各种变换操作(只有一个颜色通道)
  3. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[ 0.5,],std=[ 0.5,])])
  4. # 获取MNIST训练集和测试集
  5. data_train=datasets.MNIST(root= 'data/',transform=transform,train= True,download= True)
  6. data_test=datasets.MNIST(root= 'data/',transform=transform,train= False)

其中,root 用于指定数据集在下载之后的存放路径;transform用于指定导入数据集时需要对数据进行哪种变换操作,要提前定义这些变换操作;train用于指定在数据集下载完成后需要载入哪部分数据,如果设置为True,则说明载入的是该数据集的训练集部分;如果设置为False,则说明载入的是该数据集的测试集部分。

2、数据装载

在数据下载完成并且载入后,我们还需要对数据进行装载。我们可以将数据的载入理解为对图片的处理,在处理完成后,我们就需要将这些图片打包好送给我们的模型进行训练了,而装载就是这个打包的过程。在装载时通过batch_size的值来确认每个包的大小,通过shuffle的值来确认是否在装载的过程中打乱图片的顺序。

对数据的装载使用的是torch.utils.data.DataLoader类,类中的dataset参数用于指定我们载入的数据集名称,batch_size参数设置了每个包中的图片数据个数,代码中的值是64,所以在每个包中会包含64张图片。将shuffle参数设置为True,在装载的过程会将数据随机打乱顺序并进行打包。


  
  1. # 数据装载
  2. data_loader_train=torch.utils.data.DataLoader(dataset=data_train,batch_size= 64,shuffle= True)
  3. data_loader_test = torch.utils.data.DataLoader(dataset =data_test,batch_size = 64,shuffle = True)

3、数据预览


  
  1. #数据预览和图片显示
  2. images,labels=next(iter(data_loader_train))
  3. img=torchvision.utils.make_grid(images)
  4. img=img.numpy().transpose( 1, 2, 0)
  5. std=[ 0.5, 0.5, 0.5]
  6. mean=[ 0.5, 0.5, 0.5]
  7. img=img*std+mean
  8. print([labels[i] for i in range( 16)])
  9. plt.imshow(img)
  10. plt.show()

使用 iter next 来获取一个批次的图片数据和其对应的图片标签;

使用 torchvision.utils.make_grid 类方法将一个批次的图片构造成网格模式。需要传递给它的参数就是一个批次的装载数据,每个批次的装载数据都是4维的,维度的构成从前往后分别为batch_size、channel、height和weight,分别对应一个批次中的数据个数、每张图片的色彩通道数、每张图片的高度和宽度。在通过torchvision.utils.make_grid之后,图片的维度变成了(channel,height,weight),这个批次的图片全部被整合到了一起,所以在这个维度中对应的值也和之前不一样了,但是色彩通道数保持不变。

使用 Matplotlib 将数据显示成正常的图片形式,则使用的数据首先必须是数组,其次这个数组的维度必须是 (height,weight,channel),即色彩通道数在最后面。所以我们要通过numpy和transpose完成原始数据类型的转换和数据维度的交换,这样才能够使用Matplotlib绘制出正确的图像。

打印输出了这个批次中的数据的全部标签,如下:

[tensor(5), tensor(2), tensor(1), tensor(7), tensor(8), tensor(4), tensor(2), tensor(3), tensor(3), tensor(9), tensor(2), tensor(1), tensor(6), tensor(3), tensor(2), tensor(7), tensor(8), tensor(7), tensor(4), tensor(6), tensor(7), tensor(3), tensor(6), tensor(7), tensor(4), tensor(6), tensor(4), tensor(3), tensor(8), tensor(7), tensor(2), tensor(4), tensor(3), tensor(7), tensor(0), tensor(2), tensor(1), tensor(4), tensor(1), tensor(0), tensor(5), tensor(0), tensor(6), tensor(3), tensor(5), tensor(9), tensor(8), tensor(0), tensor(9), tensor(0), tensor(8), tensor(3), tensor(8), tensor(2), tensor(0), tensor(5), tensor(7), tensor(6), tensor(9), tensor(1), tensor(6), tensor(0), tensor(2), tensor(9)]

对这个批次中的所有图片数据进行显示,如下:

4、构建卷积神经网络模型

CNN一般结构如下:

  • 输入层:用于数据输入
  • 卷积层:使用卷积核进行特征提取和特征映射
  • 激励层:由于卷积也是一种线性运算,因此需要增加非线性映射
  • 池化层:进行下采样,对特征图稀疏处理,减少特征信息的损失
  • 输出层:用于输出结果
  • CNN模型具体结构:卷积层,正则化层,激励层,最大池化层,全连接层

  
  1. # 构建卷积神经网络模型
  2. class CNN_Model(torch.nn.Module):
  3. def __init__(self):
  4. super(CNN_Model, self).__init__()
  5. self.conv1 = torch.nn.Sequential(
  6. torch.nn.Conv2d( 1, 64, kernel_size= 3, stride= 1, padding= 1),
  7. torch.nn.BatchNorm2d( 64),
  8. torch.nn.ReLU(),
  9. torch.nn.MaxPool2d(stride= 2,kernel_size= 2))
  10. self.conv2=torch.nn.Sequential(
  11. torch.nn.Conv2d( 64, 128, kernel_size= 3, stride= 1, padding= 1),
  12. torch.nn.BatchNorm2d( 128),
  13. torch.nn.ReLU(),
  14. torch.nn.MaxPool2d(stride= 2, kernel_size= 2))
  15. self.dense = torch.nn.Sequential(
  16. torch.nn.Linear( 7 * 7 * 128, 1024),
  17. torch.nn.ReLU(),
  18. torch.nn.Dropout(p= 0.5),
  19. torch.nn.Linear( 1024, 10))
  20. # 前向传播
  21. def forward(self, x):
  22. x1 = self.conv1(x)
  23. x2 = self.conv2(x1)
  24. x = x2.view( -1, 7 * 7 * 128)
  25. x = self.dense(x)
  26. return x

torch.nn.Conv2d:用于搭建卷积神经网络的卷积层,主要的输入参数有输入通道数、输出通道数、卷积核大小、卷积核移动步长和Paddingde值。其中,输入通道数的数据类型是整型,用于确定输入数据的层数;输出通道数的数据类型也是整型,用于确定输出数据的层数;卷积核大小的数据类型是整型,用于确定卷积核的大小;卷积核移动步长的数据类型是整型,用于确定卷积核每次滑动的步长;Paddingde 的数据类型是整型,值为0时表示不进行边界像素的填充,如果值大于0,那么增加数字所对应的边界像素层数。

torch.nn.MaxPool2d:用于实现卷积神经网络中的最大池化层,主要的输入参数是池化窗口大小、池化窗口移动步长和Padding的值。同样,池化窗口大小的数据类型是整型,用于确定池化窗口的大小。池化窗口步长的数据类型也是整型,用于确定池化窗口每次移动的步长。Padding的值和在torch.nn.Conv2d中定义的Paddingde值的用法和意义是一样的。

torch.nn.Dropout:用于防止卷积神经网络在训练的过程中发生过拟合,其工作原理简单来说就是在模型训练的过程中,以一定的随机概率将卷积神经网络模型的部分参数归零,以达到减少相邻两层神经连接的目的。可以对随机概率值的大小进行设置,如果不足任何设置,我们就使用默认的概率值0.5。

x=x2.view(-1,7 * 7 * 128):对参数实现扁平化,因为之后紧接着的就是全连接层,所以如果不进行扁平化,则全连接层的实际输出的参数维度和其定义输入的维度将不匹配,程序将会报错。

5、对模型进行训练和参数优化


  
  1. # 对模型进行训练和参数优化
  2. cnn_model = CNN_Model()
  3. loss_func = torch.nn.CrossEntropyLoss()
  4. optimizer = torch.optim.Adam(cnn_model.parameters(),lr=learning_rate)
  5. n_epochs = 5
  6. for epoch in range(n_epochs):
  7. running_loss = 0.0
  8. running_correct = 0.0
  9. print( "Epoch {}/{}".format(epoch, n_epochs))
  10. for data in data_loader_train:
  11. X_train, y_train = data
  12. X_train, y_train = Variable(X_train), Variable(y_train)
  13. outputs = cnn_model(X_train)
  14. _, pred = torch.max(outputs.data, 1)
  15. optimizer.zero_grad()
  16. loss = loss_func(outputs, y_train)
  17. loss.backward()
  18. optimizer.step()
  19. running_loss += loss.item()
  20. running_correct += torch.sum(pred == y_train.data)
  21. testing_correct = 0.0
  22. for data in data_loader_test:
  23. X_test, y_test = data
  24. X_test, y_test = Variable(X_test), Variable(y_test)
  25. outputs = cnn_model(X_test)
  26. _, pred = torch.max(outputs, 1) #返回每一行中最大值的那个元素,且返回其索引
  27. testing_correct += torch.sum(pred == y_test.data)
  28. # print(testing_correct)
  29. print( "Loss is :{:.4f},Train Accuracy is:{:.4f}%,Test Accuracy is:{:.4f}%".format(
  30. running_loss / len(data_train), 100 * running_correct / len(data_train),
  31. 100 * testing_correct / len(data_test)))

6、对训练模型进行保存和加载


  
  1. # 保存模型
  2. torch.save(cnn_model, 'data/cnn_model.pt')
  3. # 加载模型
  4. cnn_model=torch.load( 'data/cnn_model.pt')
  5. cnn_model.eval()

7、MNIST手写数字识别完整代码


  
  1. import torch
  2. import torchvision
  3. import matplotlib.pyplot as plt
  4. from torchvision import datasets
  5. from torchvision import transforms
  6. from torch.autograd import Variable
  7. # 参数设置
  8. num_epochs = 10
  9. batch_size = 64
  10. learning_rate = 0.001
  11. # 将数据处理成Variable, 如果有GPU, 可以转成cuda形式
  12. def get_variable(x):
  13. x = Variable(x)
  14. return x.cuda() if torch.cuda.is_available() else x
  15. # 对数据进行载入及有相应变换,将Compose看成一种容器,他能对多种数据变换进行组合
  16. # 传入的参数是一个列表,列表中的元素就是对载入的数据进行的各种变换操作(只有一个颜色通道)
  17. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(mean=[ 0.5,],std=[ 0.5,])])
  18. # 获取MNIST训练集和测试集
  19. data_train=datasets.MNIST(root= 'data/',transform=transform,train= True,download= True)
  20. data_test=datasets.MNIST(root= 'data/',transform=transform,train= False)
  21. # 数据装载
  22. data_loader_train=torch.utils.data.DataLoader(dataset=data_train,batch_size=batch_size,shuffle= True)
  23. data_loader_test = torch.utils.data.DataLoader(dataset =data_test,batch_size = batch_size,shuffle = True)
  24. #数据预览和图片显示
  25. images,labels=next(iter(data_loader_train))
  26. img=torchvision.utils.make_grid(images)
  27. img=img.numpy().transpose( 1, 2, 0)
  28. std=[ 0.5, 0.5, 0.5]
  29. mean=[ 0.5, 0.5, 0.5]
  30. img=img*std+mean
  31. print([labels[i] for i in range( 64)])
  32. plt.imshow(img)
  33. plt.show()
  34. # 构建卷积神经网络模型
  35. class CNN_Model(torch.nn.Module):
  36. def __init__(self):
  37. super(CNN_Model, self).__init__()
  38. self.conv1 = torch.nn.Sequential(
  39. torch.nn.Conv2d( 1, 64, kernel_size= 3, stride= 1, padding= 1),
  40. torch.nn.BatchNorm2d( 64),
  41. torch.nn.ReLU(),
  42. torch.nn.MaxPool2d(stride= 2,kernel_size= 2))
  43. self.conv2=torch.nn.Sequential(
  44. torch.nn.Conv2d( 64, 128, kernel_size= 3, stride= 1, padding= 1),
  45. torch.nn.BatchNorm2d( 128),
  46. torch.nn.ReLU(),
  47. torch.nn.MaxPool2d(stride= 2, kernel_size= 2))
  48. self.dense = torch.nn.Sequential(
  49. torch.nn.Linear( 7 * 7 * 128, 1024),
  50. torch.nn.ReLU(),
  51. torch.nn.Dropout(p= 0.5),
  52. torch.nn.Linear( 1024, 10))
  53. # 前向传播
  54. def forward(self, x):
  55. x1 = self.conv1(x)
  56. x2 = self.conv2(x1)
  57. x = x2.view( -1, 7 * 7 * 128)
  58. x = self.dense(x)
  59. return x
  60. # 对模型进行训练和参数优化
  61. cnn_model = CNN_Model()
  62. # 将所有的模型参数移动到GPU上
  63. if torch.cuda.is_available():
  64. cnn_model = cnn_model.cuda()
  65. loss_func = torch.nn.CrossEntropyLoss()
  66. optimizer = torch.optim.Adam(cnn_model.parameters(),lr=learning_rate)
  67. for epoch in range(num_epochs):
  68. running_loss = 0.0
  69. running_correct = 0.0
  70. print( "Epoch {}/{}".format(epoch, num_epochs))
  71. for data in data_loader_train:
  72. X_train, y_train = data
  73. X_train, y_train = get_variable(X_train),get_variable(y_train)
  74. outputs = cnn_model(X_train)
  75. _, pred = torch.max(outputs.data, 1)
  76. optimizer.zero_grad()
  77. loss = loss_func(outputs, y_train)
  78. loss.backward()
  79. optimizer.step()
  80. running_loss += loss.item()
  81. running_correct += torch.sum(pred == y_train.data)
  82. testing_correct = 0.0
  83. for data in data_loader_test:
  84. X_test, y_test = data
  85. X_test, y_test = get_variable(X_test),get_variable(y_test)
  86. outputs = cnn_model(X_test)
  87. _, pred = torch.max(outputs, 1) #返回每一行中最大值的那个元素,且返回其索引
  88. testing_correct += torch.sum(pred == y_test.data)
  89. # print(testing_correct)
  90. print( "Loss is :{:.4f},Train Accuracy is:{:.4f}%,Test Accuracy is:{:.4f}%".format(
  91. running_loss / len(data_train), 100 * running_correct / len(data_train),
  92. 100 * testing_correct / len(data_test)))
  93. # 保存模型
  94. torch.save(cnn_model, 'data/cnn_model.pt')
  95. # 加载模型
  96. cnn_model=torch.load( 'data/cnn_model.pt')
  97. cnn_model.eval()

运行结果如下:

三、CIFAR10图像分类

1、CIFAR10数据集介绍

CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集。一共包含 10 个类别的 RGB 彩色图片:飞机( airplane )、汽车( automobile )、鸟类( bird )、猫( cat )、鹿( deer )、狗( dog )、蛙类( frog )、马( horse )、船( ship )和卡车( truck )。图片的尺寸为 32×32 ,数据集中一共有 50000 张训练图片和 10000 张测试图片。与 MNIST 数据集相比, CIFAR-10 具有以下不同点:

  • CIFAR-10 是 3 通道的彩色 RGB 图像,而 MNIST 是灰度图像。

  • CIFAR-10 的图片尺寸为 32×32, 而 MNIST 的图片尺寸为 28×28,比 MNIST 稍大。

  • 相比于手写字符, CIFAR-10 含有的是现实世界中真实的物体,不仅噪声很大,而且物体的比例、 特征都不尽相同,这为识别带来很大困难。

2、CIFAR10图像分类实现


  
  1. import torch
  2. import torchvision
  3. import torchvision.transforms as transforms
  4. import matplotlib.pyplot as plt
  5. import numpy as np
  6. import torch.nn as nn
  7. import torch.nn.functional as F
  8. import torch.optim as optim
  9. #参数设置
  10. num_epochs = 15
  11. batch_size = 64
  12. learning_rate = 0.001
  13. # 构建CNN模型
  14. class CNNNet(nn.Module):
  15. def __init__(self):
  16. super(CNNNet, self).__init__()
  17. self.conv1 = nn.Conv2d( 3, 64, 5)
  18. self.pool = nn.MaxPool2d( 2, 2)
  19. self.conv2 = nn.Conv2d( 64, 128, 5)
  20. self.fc1 = nn.Linear( 128* 5 * 5, 1024)
  21. self.fc2 = nn.Linear( 1024, 84)
  22. self.fc3 = nn.Linear( 84, 10)
  23. def forward(self, x):
  24. x = self.pool(F.relu(self.conv1(x)))
  25. x = self.pool(F.relu(self.conv2(x)))
  26. x = x.view( -1, 128 * 5 * 5)
  27. x = F.relu(self.fc1(x))
  28. x = F.relu(self.fc2(x))
  29. x = self.fc3(x)
  30. return x
  31. # 图片显示
  32. def imshow(img):
  33. img = img / 2 + 0.5 # unnormalize
  34. npimg = img.numpy()
  35. plt.imshow(np.transpose(npimg, ( 1, 2, 0)))
  36. plt.show()
  37. # torchvision 数据集的输出是范围在[0,1]之间的 PILImage,我们将他们转换成归一化范围为[-1,1]之间的张量Tensors
  38. transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize(( 0.5, 0.5, 0.5), ( 0.5, 0.5, 0.5))])
  39. # 获取CIFAR10训练集和测试集
  40. trainset=torchvision.datasets.CIFAR10(root= 'data/',train= True,download= True,transform=transform)
  41. testset=torchvision.datasets.CIFAR10(root= 'data/',train= False,download= True,transform=transform)
  42. # CIFAR10训练集和测试集装载
  43. trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,shuffle= True, num_workers= 0)
  44. testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,shuffle= False, num_workers= 0)
  45. # 图片类别
  46. classes = ( 'plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
  47. # 图片显示
  48. images,labels=next(iter(trainloader))
  49. imshow(torchvision.utils.make_grid(images))
  50. # 定义损失函数和优化器
  51. cnn_model=CNNNet()
  52. criterion=nn.CrossEntropyLoss()
  53. optimizer=optim.SGD(cnn_model.parameters(),lr=learning_rate,momentum= 0.9)
  54. # 训练模型
  55. for epoch in range(num_epochs):
  56. running_loss= 0.00
  57. running_correct= 0.0
  58. print( "Epoch {}/{}".format(epoch, num_epochs))
  59. for i,data in enumerate(trainloader, 0):
  60. inputs,labels=data
  61. optimizer.zero_grad()
  62. outputs=cnn_model(inputs)
  63. loss=criterion(outputs,labels)
  64. loss.backward()
  65. optimizer.step()
  66. running_loss+=loss.item()
  67. _, pred = torch.max(outputs.data, 1)
  68. running_correct += torch.sum(pred == labels.data)
  69. print( "Loss is :{:.4f},Train Accuracy is:{:.4f}%".format(running_loss / len(trainset), 100 * running_correct / len(trainset)))
  70. # 保存训练好的模型
  71. torch.save(cnn_model, 'data/cnn_model.pt')
  72. # 加载训练好的模型
  73. cnn_model=torch.load( 'data/cnn_model.pt')
  74. cnn_model.eval()
  75. #使用测试集对模型进行评估
  76. correct= 0.0
  77. total= 0.0
  78. with torch.no_grad(): # 为了使下面的计算图不占用内存
  79. for data in testloader:
  80. images, labels = data
  81. outputs = cnn_model(images)
  82. _, predicted = torch.max(outputs.data, 1)
  83. total += labels.size( 0)
  84. correct += (predicted == labels).sum().item()
  85. print( "Test Average accuracy is:{:.4f}%".format( 100 * correct / total))
  86. # 求出每个类别的准确率
  87. class_correct=list( 0. for i in range( 10))
  88. class_total=list( 0. for i in range( 10))
  89. with torch.no_grad():
  90. for data in testloader:
  91. images,labels=data
  92. outputs=cnn_model(images)
  93. _,predicted=torch.max(outputs, 1)
  94. c=(predicted==labels).squeeze()
  95. try:
  96. for i in range(batch_size):
  97. label = labels[i]
  98. class_correct[label] += c[i].item()
  99. class_total[label] += 1
  100. except IndexError:
  101. continue
  102. for i in range( 10):
  103. print( 'Accuracy of %5s : %4f %%' % (classes[i], 100 * class_correct[i] / class_total[i]))

图片显示结果:

模型训练结果:

测试集平均准确率和每个类别的准确率:

3、在GPU上跑神经网络


  
  1. device=torch.device( 'cuda:0' if torch.cuda.is_available() else 'cpu')
  2. print(device)
  3. # 递归地遍历所有模块,并将它们的参数和缓冲器转换为CUDA张量
  4. cnn_model.to(device)
  5. # 必须在每一个步骤向GPU发送输入和目标
  6. inputs,labels=inputs.to(device),labels.to(device)

 


转载:https://blog.csdn.net/asialee_bird/article/details/103978166
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场