前言:
此刻大家对“pytorch卷积神经网络mnist”可能比较关注,朋友们都想要知道一些“pytorch卷积神经网络mnist”的相关资讯。那么小编在网上网罗了一些关于“pytorch卷积神经网络mnist””的相关内容,希望我们能喜欢,兄弟们快快来了解一下吧!pytorch——人工智能的开源深度学习框架pytorch深度学习框架之tensor张量计算机视觉的基石——读懂 CNN卷积神经网络
本期文章的主要内容:
1、CNN卷积神经网络
2、torchvision.datasets
3、MINIST数据集
4、神经网络的训练
5、pytorch训练模型的保存
PyTorch 提供了许多预加载的数据集(例如 FashionMNIST),所有数据集都是torch.utils.data.Dataset 的子类,它们具有__getitem__和__len__实现的方法。因此,它们都可以传递给torch.utils.data.DataLoader 也可以使用torch.multiprocessing并行加载多个样本的数据 。例如:
以下是如何从 TorchVision加载Fashion-MNIST数据集的示例。Fashion-MNIST由 60,000 个训练示例和 10,000 个测试示例组成。每个示例都包含一个 28×28 灰度图像和来自 10 个类别之一的相关标签。
MINIST数据
MINIST的数据分为2个部分:55000份训练数据(mnist.train)和10000份测试数据(mnist.test)。这个划分有重要的象征意义,他展示了在机器学习中如何使用数据。在训练的过程中,我们必须单独保留一份没有用于机器训练的数据作为验证的数据,这才能确保训练的结果的可行性。
前面已经提到,每一份MINIST数据都由图片以及标签组成。我们将图片命名为“x”,将标记数字的标签命名为“y”。训练数据集和测试数据集都是同样的结构,例如:训练的图片名为 mnist.train.images 而训练的标签名为 mnist.train.labels。
每一个图片均为28×28像素,我们可以将其理解为一个二维数组的结构:
我们使用以下参数加载MNIST 数据集:
root ( string ) – 数据集所在MNIST/processed/training.pt 和 MNIST/processed/test.pt存在的根目录。train ( bool , optional ) – 如果为 True,则从 中创建数据集training.pt,否则从test.pt.download ( bool , optional ) – 如果为 true,则从 Internet 下载数据集并将其放在根目录中。如果数据集已经下载,则不会再次下载。transform ( callable , optional ) – 一个函数/转换,它接收一个 PIL 图像并返回一个转换后的版本。例如,transforms.RandomCroptarget_transform ( callable , optional ) – 一个接收目标并对其进行转换的函数/转换。
torchvision.datasets.MNIST( root: str , train: bool = True , transform: Optional[Callable] = None , target_transform: Optional[Callable] = None , download: bool = False )
所有数据集都有几乎相似的 API。它们都有两个共同的参数: transform和 target_transform,本期文章,我们基于MNIST数据集来写一个简单的神经网络,并进行神经网络的训练
下载数据集 torchvision.datasets
import torchimport torch.nn as nnimport torch.utils.data as Dataimport torchvision # 数据库模块import matplotlib.pyplot as plt# torch.manual_seed(1) # reproducibleEPOCH = 20 # 训练整批数据次数,训练次数越多,精度越高BATCH_SIZE = 50 # 每次训练的数据集个数LR = 0.001 # 学习效率DOWNLOAD_MNIST = False # 如果你已经下载好了mnist数据就设置 False# Mnist 手写数字 训练集train_data = torchvision.datasets.MNIST( root='./data/', # 保存或者提取位置 train=True, # this is training data transform=torchvision.transforms.ToTensor(), # 转换 PIL.Image or numpy.ndarray 成tensor # torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间 download=DOWNLOAD_MNIST, # 没下载就会自动下载数据集,当等于true)# Mnist 手写数字 测试集test_data = torchvision.datasets.MNIST( root='./mnist/', train=False, # this is training data)
通过以上代码,我们便在工程目录下的data文件夹下下载了MNIST的全部数据集,torchvision.datasets是pytorch为了方便研发者,进行了绝大部分的数据库的集合,通过torchvision.datasets可以很方便地下载使用其包含的数据集,其torchvision.datasets下面主要包含如下数据集,其他方面的数据集可以自行下载尝试
torchvision.datasetsCaltechCelebACIFARCityscapesCOCOEMNISTFakeDataFashion-MNISTFlickrHMDB51ImageNetKinetics-400KITTIKMNISTLSUNMNISTOmniglotPhotoTourPlaces365QMNISTSBDSBUSEMEIONSTL10SVHNUCF101USPSVOCWIDERFaceCNN卷积神经网络搭建
# 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)train_loader = Data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)# 每一步 loader 释放50个数据用来学习# 为了演示, 我们测试时提取2000个数据先# shape from (2000, 28, 28) to (2000, 1, 28, 28), value in range(0,1)test_x = torch.unsqueeze(test_data.data, dim=1).type(torch.FloatTensor)[:2000] / 255. test_y = test_data.targets[:2000]#test_x = test_x.cuda() # 若有cuda环境,取消注释#test_y = test_y.cuda() # 若有cuda环境,取消注释# 定义神经网络class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Sequential( # input shape (1, 28, 28) nn.Conv2d( in_channels=1, # 输入通道数 out_channels=16, # 输出通道数 kernel_size=5, # 卷积核大小 stride=1, #卷积部数 padding=2, # 如果想要 con2d 出来的图片长宽没有变化, # padding=(kernel_size-1)/2 当 stride=1 ), # output shape (16, 28, 28) nn.ReLU(), # activation nn.MaxPool2d(kernel_size=2), # 在 2x2 空间里向下采样, output shape (16, 14, 14) ) self.conv2 = nn.Sequential( # input shape (16, 14, 14) nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14) nn.ReLU(), # activation nn.MaxPool2d(2), # output shape (32, 7, 7) ) self.out = nn.Linear(32 * 7 * 7, 10) # 全连接层,0-9一共10个类# 前向反馈 def forward(self, x): x = self.conv1(x) x = self.conv2(x) x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7) output = self.out(x) return output
我们使用Data.DataLoader来加载我们下载好的MNIST数据集,并分开训练集与测试集
接下来我们建立一个CNN卷积神经网络:
第一层,我们输入minist的数据集,minist的数据图片是一维 28*28的图片,所以第一层的输入(1,28,28),高度为1,设置输出16通道,使用5*5的卷积核对图片进行卷积运算,每步移动一格,为了避免图片尺寸变化,设置pading为2,则经过第一层卷积就输出(16,28,28)数据格式
再经过relu与maxpooling (使用2*2卷积核)数据输出(16,14,14)
第二层卷积层是简化写法nn.Conv2d(16, 32, 5, 1, 2)的第一个参数为输入通道数in_channels=16,其第二个参数是输出通道数out_channels=32, # n_filters(输出通道数),第三个参数为卷积核大小,第四个参数为卷积步数,最后一个为pading,此参数为保证输入输出图片的尺寸大小一致
self.conv2 = nn.Sequential( # input shape (16, 14, 14) nn.Conv2d(16, 32, 5, 1, 2), # output shape (32, 14, 14) nn.ReLU(), # activation nn.MaxPool2d(2), # output shape (32, 7, 7) )
全连接层,最后使用nn.linear()全连接层进行数据的全连接数据结构(32*7*7,10)以上便是整个卷积神经网络的结构,
大致为:input-卷积-Relu-pooling-卷积-Relu-pooling-linear-output
卷积神经网络建完后,使用forward()前向传播神经网络进行输入图片的训练
通过以上的神经网络的搭建,我们便建立一个神经网络,此神经网络类似MINIST的双隐藏层结构
神经网络的训练
神经网络搭建完成后,我们便可以进行神经网络的训练
cnn = CNN() # 创建CNN# cnn = cnn.cuda() # 若有cuda环境,取消注释optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) loss_func = nn.CrossEntropyLoss() for epoch in range(EPOCH): for step, (b_x, b_y) in enumerate(train_loader): # 每一步 loader 释放50个数据用来学习 #b_x = b_x.cuda() # 若有cuda环境,取消注释 #b_y = b_y.cuda() # 若有cuda环境,取消注释 output = cnn(b_x) # 输入一张图片进行神经网络训练 loss = loss_func(output, b_y) # 计算神经网络的预测值与实际的误差 optimizer.zero_grad() #将所有优化的torch.Tensors的梯度设置为零 loss.backward() # 反向传播的梯度计算 optimizer.step() # 执行单个优化步骤 if step % 50 == 0: # 我们每50步来查看一下神经网络训练的结果 test_output = cnn(test_x) pred_y = torch.max(test_output, 1)[1].data.squeeze() # 若有cuda环境,使用84行,注释82行 # pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze() accuracy = float((pred_y == test_y).sum()) / float(test_y.size(0)) print('Epoch: ', epoch, '| train loss: %.4f' % loss.data, '| test accuracy: %.2f' % accuracy)
首先我们使用CNN()函数进行神经网络的初始化,并建立一个神经网络模型,并利用optim.Adam优化函数建立一个optimizer神经网络优化器,torch.optim是一个实现各种优化算法的包。大部分常用的方法都已经支持,接口也足够通用,以后也可以轻松集成更复杂的方法。
常用的优化器主要有:OptimizerGradientDescentOptimizerAdadeltaOptimizerAdagradOptimizerAdagradDAOptimizerMomentumOptimizerAdamOptimizerFtrlOptimizerProximalGradientDescentOptimizerProximalAdagradOptimizerRMSPropOptimizer
然后建立一个损失函数,我们神经网络的目的就是使用损失函数使神经网络的训练loss越来越小。然后进行神经网络的训练,我们每50步打印一下神经网络的训练效果
测试神经网络的结果与保存神经网络
# test 神经网络test_output = cnn(test_x[:10])pred_y = torch.max(test_output, 1)[1].data.squeeze()# 若有cuda环境,使用92行,注释90行#pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()print(pred_y, 'prediction number')print(test_y[:10], 'real number')# save CNN# 仅保存CNN参数,速度较快torch.save(cnn.state_dict(), './model/CNN_NO1.pk')# 保存CNN整个结构#torch.save(cnn(), './model/CNN.pkl')
我们提取前10个MNIST的数据,并进行神经网络的预测,此时我们可以打印出来神经网络的预测值与实际值,最后并保存神经网络的模型,此模型我们可以直接使用来进行手写数字的识别
从训练结果可以看出,只训练了24*50个循环,神经网络的精度已经达到0.97
Epoch: 0 | train loss: 2.3018 | test accuracy: 0.18Epoch: 0 | train loss: 0.5784 | test accuracy: 0.82Epoch: 0 | train loss: 0.3423 | test accuracy: 0.89Epoch: 0 | train loss: 0.1502 | test accuracy: 0.92Epoch: 0 | train loss: 0.2063 | test accuracy: 0.93Epoch: 0 | train loss: 0.1348 | test accuracy: 0.92Epoch: 0 | train loss: 0.1209 | test accuracy: 0.95Epoch: 0 | train loss: 0.0577 | test accuracy: 0.95Epoch: 0 | train loss: 0.1297 | test accuracy: 0.95Epoch: 0 | train loss: 0.0237 | test accuracy: 0.96Epoch: 0 | train loss: 0.1275 | test accuracy: 0.97Epoch: 0 | train loss: 0.1364 | test accuracy: 0.97Epoch: 0 | train loss: 0.0728 | test accuracy: 0.97Epoch: 0 | train loss: 0.0752 | test accuracy: 0.98Epoch: 0 | train loss: 0.1444 | test accuracy: 0.97Epoch: 0 | train loss: 0.0597 | test accuracy: 0.97Epoch: 0 | train loss: 0.1162 | test accuracy: 0.97Epoch: 0 | train loss: 0.0260 | test accuracy: 0.97Epoch: 0 | train loss: 0.0830 | test accuracy: 0.97Epoch: 0 | train loss: 0.1918 | test accuracy: 0.97Epoch: 0 | train loss: 0.2217 | test accuracy: 0.97Epoch: 0 | train loss: 0.0767 | test accuracy: 0.97Epoch: 0 | train loss: 0.2015 | test accuracy: 0.97Epoch: 0 | train loss: 0.1214 | test accuracy: 0.97tensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9]) prediction numbertensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9]) real number
最后打印出来的前10个预测模型,完全一致
ok,本期我们分享了神经网络的搭建,并利用MNIST的数据集进行了神经网络的训练,并进行了神经网络的预测,下期文章我们利用训练好的模型进行神经网络的识别。
标签: #pytorch卷积神经网络mnist