关于Pytorch的MNIST数据集的预处理详解

关于Pytorch的MNIST数据集的预处理详解

MNIST的准确率达到99.7%

用于MNIST的卷积神经网络(CNN)的实现,具有各种技术,例如数据增强,丢失,伪随机化等。

操作系统:ubuntu18.04

显卡:GTX1080ti

python版本:2.7(3.7)

网络架构

具有4层的CNN具有以下架构。

输入层:784个节点(MNIST图像大小)

第一卷积层:5x5x32

第一个最大池层

第二卷积层:5x5x64

第二个最大池层

第三个完全连接层:1024个节点

输出层:10个节点(MNIST的类数)

用于改善CNN性能的工具

采用以下技术来改善CNN的性能。

1. Data augmentation

通过以下方式将列车数据的数量增加到5倍

随机旋转:每个图像在[-15°,+ 15°]范围内随机旋转。

随机移位:每个图像在两个轴上随机移动一个范围为[-2pix,+ 2pix]的值。

零中心归一化:将像素值减去(PIXEL_DEPTH / 2)并除以PIXEL_DEPTH。

2. Parameter initializers

重量初始化器:xaiver初始化器

偏差初始值设定项:常量(零)初始值设定项

3. Batch normalization

所有卷积/完全连接的层都使用批量标准化。

4. Dropout

The third fully-connected layer employes dropout technique.

5. Exponentially decayed learning rate

A learning rate is decayed every after one-epoch.

代码部分

第一步:了解MNIST数据集

MNIST数据集是一个手写体数据集,一共60000张图片,所有的图片都是28×28的,下载数据集的地址:数据集官网。这个数据集由四部分组成,分别是:

train-images-idx3-ubyte.gz: training set images (9912422 bytes)
train-labels-idx1-ubyte.gz: training set labels (28881 bytes)
t10k-images-idx3-ubyte.gz: test set images (1648877 bytes)
t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes)

也就是一个训练图片集,一个训练标签集,一个测试图片集,一个测试标签集;我们可以看出这个其实并不是普通的文本文件

或是图片文件,而是一个压缩文件,下载并解压出来,我们看到的是二进制文件。

第二步:加载MNIST数据集

先引入一些库文件

import torchvision,torch
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
import matplotlib.pyplot as plt

加载MNIST数据集有很多方法:

方法一:在pytorch下可以直接调用torchvision.datasets里面的MNIST数据集(这是官方写好的数据集类)

train = torchvision.datasets.MNIST(root='./mnist/',train=True, transform= transforms.ToTensor())

返回值为一个元组(train_data,train_target)(这个类使用的时候也有坑,必须用train[i]索引才能使用 transform功能)

一般是与torch.utils.data.DataLoader配合使用

dataloader = DataLoader(train, batch_size=50,shuffle=True, num_workers=4)
for step, (x, y) in enumerate(dataloader):
 b_x = x.shape
 b_y = y.shape
 print 'Step: ', step, '| train_data的维度' ,b_x,'| train_target的维度',b_y

如图将60000张图片的数据分为1200份,每份包含50张图像,这样并行处理数据能有效加快计算速度

看个人喜好,本人不太喜欢这种固定的数据类,所以想要灵活多变,可以开始自己写数据集类

方法二:自己设置数据集

使用pytorch相关类,API对数据集进行封装,pytorch中数据集相关的类位于torch.utils.data package中。

本次实验,主要使用以下类:

torch.utils.data.Dataset

torch.utils.data.DataLoader

Dataset类的使用: 所有的类都应该是此类的子类(也就是说应该继承该类)。 所有的子类都要重写(override) len(), getitem() 这两个方法。

使用到的python package

python package 目的
numpy 矩阵操作,对图像进行转置
skimage 图像处理,图像I/O,图像变换
matplotlib 图像的显示,可视化
os 一些文件查找操作
torch pytorch
torvision pytorch

导入相关的包

import numpy as np
from skimage import io
from skimage import transform
import matplotlib.pyplot as plt
import os
import torch
import torchvision
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import transforms
from PIL import Image

第一步:

定义一个子类,继承Dataset类, 重写 __len()__, __getitem()__ 方法。

细节:

1.数据集一个样本的表示:采用字典的形式sample = {'img': img, 'target': target}。

图像的读取:采用torch.load进行读取,读取之后的结果为torch.Tensor形式。

图像变换:transform参数

class MY_MNIST(Dataset):
 training_file = 'training.pt'
 test_file = 'test.pt'
 def __init__(self, root, transform=None):
  self.transform = transform
  self.data, self.targets = torch.load(root)
 def __getitem__(self, index):
  img, target = self.data[index], int(self.targets[index])
  img = Image.fromarray(img.numpy(), mode='L')

  if self.transform is not None:
   img = self.transform(img)
  img =transforms.ToTensor()(img)

  sample = {'img': img, 'target': target}
  return sample
 def __len__(self):
  return len(self.data)

train = MY_MNIST(root='./mnist/MNIST/processed/training.pt', transform= None)

第二步

实例化一个对象,并读取和显示数据集

for (cnt,i) in enumerate(train):
 image = i['img']
 label = i['target']
 ax = plt.subplot(4, 4, cnt+1)
 # ax.axis('off')
 ax.imshow(image.squeeze(0))
 ax.set_title(label)
 plt.pause(0.001)
 if cnt ==15:
  break

输出如下 ,这样就表明,咱们自己写的数据集读取图像,并读取之后的结果为torch.Tensor形式成功啦!

第三步(可选 optional)

对数据集进行变换:一般收集到的图像大小尺寸,亮度等存在差异,变换的目的就是使得数据归一化。另一方面,可以通过变换进行数据增强

关于pytorch中的变换transforms,请参考该系列之前的文章

由于数据集中样本采用字典dicts形式表示。 因此不能直接调用torchvision.transofrms中的方法。

本实验进行了旋转,随机裁剪,调节图像的色彩饱和明暗等操作。

compose = transforms.Compose([
   transforms.Resize(20),
   transforms.RandomHorizontalFlip(),
   transforms.RandomCrop(20),
   transforms.ColorJitter(brightness=1, contrast=0.1, hue=0.5),
   # transforms.ToTensor(),
   # transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
   ])
train_transformed = MY_MNIST(root='./mnist/MNIST/processed/training.pt', transform= compose)

#显示变换后的图像
for (cnt,i) in enumerate(train_transformed):
 image = i['img']
 # print image[0].sum()
 # image = compose(image)
 print 'sdsdadfasfasfasf',type(image)
 label = i['target']
 ax = plt.subplot(4, 4, cnt+1)
 # ax.axis('off')
 ax.imshow(image.squeeze(0))
 ax.set_title(label)
 plt.pause(0.001)
 if cnt ==15:
  break

变换后的图像,和之前对比,你发现了什么不同吗?

第四步: 使用DataLoader进行包装

为何要使用DataLoader?

① 深度学习的输入是mini_batch形式

② 样本加载时候可能需要随机打乱顺序,shuffle操作

③ 样本加载需要采用多线程

pytorch提供的DataLoader封装了上述的功能,这样使用起来更方便。

# 使用DataLoader可以利用多线程,batch,shuffle等
trainset_dataloader = DataLoader(dataset=transformed_trainset,
         batch_size=4,
         shuffle=True,
         num_workers=4)

可视化:

dataloader = DataLoader(train, batch_size=50,shuffle=True, num_workers=4)

通过DataLoader包装之后,样本以min_batch形式输出,而且进行了随机打乱顺序。

for step, i in enumerate(dataloader):
 b_x = i['img'].shape
 b_y = i['target'].shape
 print 'Step: ', step, '| train_data的维度' ,b_x,'| train_target的维度',b_y

如图图片大小已经裁剪为20*20,而且并行处理让60000个数据在3秒内就能处理好,效率非常高

Step: 1186 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1187 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1188 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1189 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1190 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1191 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1192 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1193 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1194 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1195 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1196 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1197 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1198 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)
Step: 1199 | train_data的维度 (50, 1, 20, 20) | train_target的维度 (50,)

未完待续…

以上这篇关于Pytorch的MNIST数据集的预处理详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Pytorch 数据加载与数据预处理方式

    数据加载分为加载torchvision.datasets中的数据集以及加载自己使用的数据集两种情况. torchvision.datasets中的数据集 torchvision.datasets中自带MNIST,Imagenet-12,CIFAR等数据集,所有的数据集都是torch.utils.data.Dataset的子类,都包含 _ _ len _ (获取数据集长度)和 _ getItem _ _ (获取数据集中每一项)两个子方法. Dataset源码如上,可以看到其中包含了两个没有实现的子

  • 详解PyTorch手写数字识别(MNIST数据集)

    MNIST 手写数字识别是一个比较简单的入门项目,相当于深度学习中的 Hello World,可以让我们快速了解构建神经网络的大致过程.虽然网上的案例比较多,但还是要自己实现一遍.代码采用 PyTorch 1.0 编写并运行. 导入相关库 import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torchvision import datasets, t

  • Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式

    CGAN的全拼是Conditional Generative Adversarial Networks,条件生成对抗网络,在初始GAN的基础上增加了图片的相应信息. 这里用传统的卷积方式实现CGAN. import torch from torch.utils.data import DataLoader from torchvision.datasets import MNIST from torchvision import transforms from torch import opti

  • Pytorch使用MNIST数据集实现基础GAN和DCGAN详解

    原始生成对抗网络Generative Adversarial Networks GAN包含生成器Generator和判别器Discriminator,数据有真实数据groundtruth,还有需要网络生成的"fake"数据,目的是网络生成的fake数据可以"骗过"判别器,让判别器认不出来,就是让判别器分不清进入的数据是真实数据还是fake数据.总的来说是:判别器区分真实数据和fake数据的能力越强越好:生成器生成的数据骗过判别器的能力越强越好,这个是矛盾的,所以只能

  • pytorch实现mnist分类的示例讲解

    torchvision包 包含了目前流行的数据集,模型结构和常用的图片转换工具. torchvision.datasets中包含了以下数据集 MNIST COCO(用于图像标注和目标检测)(Captioning and Detection) LSUN Classification ImageFolder Imagenet-12 CIFAR10 and CIFAR100 STL10 torchvision.models torchvision.models模块的 子模块中包含以下模型结构. Ale

  • 关于Pytorch的MNIST数据集的预处理详解

    关于Pytorch的MNIST数据集的预处理详解 MNIST的准确率达到99.7% 用于MNIST的卷积神经网络(CNN)的实现,具有各种技术,例如数据增强,丢失,伪随机化等. 操作系统:ubuntu18.04 显卡:GTX1080ti python版本:2.7(3.7) 网络架构 具有4层的CNN具有以下架构. 输入层:784个节点(MNIST图像大小) 第一卷积层:5x5x32 第一个最大池层 第二卷积层:5x5x64 第二个最大池层 第三个完全连接层:1024个节点 输出层:10个节点(M

  • pytorch 把MNIST数据集转换成图片和txt的方法

    本文介绍了pytorch 把MNIST数据集转换成图片和txt的方法,分享给大家,具体如下: 1.下载Mnist 数据集 import os # third-party library import torch import torch.nn as nn from torch.autograd import Variable import torch.utils.data as Data import torchvision import matplotlib.pyplot as plt # t

  • pytorch实现mnist数据集的图像可视化及保存

    如何将pytorch中mnist数据集的图像可视化及保存 导出一些库 import torch import torchvision import torch.utils.data as Data import scipy.misc import os import matplotlib.pyplot as plt BATCH_SIZE = 50 DOWNLOAD_MNIST = True 数据集的准备 #训练集测试集的准备 train_data = torchvision.datasets.M

  • pytorch之Resize()函数具体使用详解

    Resize函数用于对PIL图像的预处理,它的包在: from torchvision.transforms import Compose, CenterCrop, ToTensor, Resize 使用如: def input_transform(crop_size, upscale_factor): return Compose([ CenterCrop(crop_size), Resize(crop_size // upscale_factor), ToTensor(), ]) 而Resi

  • 对pytorch中的梯度更新方法详解

    背景 使用pytorch时,有一个yolov3的bug,我认为涉及到学习率的调整.收集到tencent yolov3和mxnet开源的yolov3,两个优化器中的学习率设置不一样,而且使用GPU数目和batch的更新也不太一样.据此,我简单的了解了下pytorch的权重梯度的更新策略,看看能否一窥究竟. 对代码说明 共三个实验,分布写在代码中的(一)(二)(三)三个地方.运行实验时注释掉其他两个 实验及其结果 实验(三): 不使用zero_grad()时,grad累加在一起,官网是使用accum

  • 对pytorch网络层结构的数组化详解

    最近再写openpose,它的网络结构是多阶段的网络,所以写网络的时候很想用列表的方式,但是直接使用列表不能将网络中相应的部分放入到cuda中去. 其实这个问题很简单的,使用moduleList就好了. 1 我先是定义了一个函数,用来根据超参数,建立一个基础网络结构 stage = [[3, 3, 3, 1, 1], [7, 7, 7, 7, 7, 1, 1]] branches_cfg = [[[128, 128, 128, 512, 38], [128, 128, 128, 512, 19]

  • PyTorch中反卷积的用法详解

    pytorch中的 2D 卷积层 和 2D 反卷积层 函数分别如下: class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, groups=1, bias=True) class torch.nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride=1, padding=0, output_padding=0, b

  • Pytorch之view及view_as使用详解

    view()函数是在torch.Tensor.view()下的一个函数,可以有tensor调用,也可以有variable调用. 其作用在于返回和原tensor数据个数相同,但size不同的tensor [Numpy中的size是元素个数,但是在Pytorch中size等价为Numpy中的shape] view函数的-1参数的作用在于基于另一参数,自动计算该维度的大小 很重要的一点 view函数只能由于contiguous的张量上,具体而言,就是在内存中连续存储的张量. 具体而言,可以参看 htt

随机推荐

其他