• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

MNIST数据集

武飞扬头像
保持理智802
帮助1

一、MNIST数据集介绍

MNIST数据集是NIST(National Institute of Standards and Technology,美国国家标准与技术研究所)数据集的一个子集,MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取,主要包括四个文件:
学新通
在上述文件中,训练集train一共包含了 60000 张图像和标签,而测试集一共包含了 10000 张图像和标签。

idx3表示3维,ubyte表示是以字节的形式进行存储的,t10k表示10000张测试图片(test10000)。

每张图片是一个28*28像素点的0 ~ 9的灰质手写数字图片,黑底白字,图像像素值为0 ~ 255,越大该点越白。

二、数据下载和读取

导入PyTorch的两个核心库torch和torchvision,这两个库基本包含了PyTorch会用到的许多方法和函数,其他库为下面所需要的一些辅助库。

import gzip
import os

import torch
import torchvision
import numpy as np
from PIL import Image
from matplotlib import pyplot as plt
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, Dataset

注:

  • import datasets是为了方便自动下载数据集,可以下载多种数据集,如MNIST、ImageNet、CIFAR10等。
  • import transforms是pytorch中的图像预处理库,一般用Compose把多个步骤整合到一起。 相关详情见:transforms.Compose()函数

1、使用Pytorch自带的库函数

导入MNIST数据集代码:

train_data = datasets.MNIST(
            root="./data/",
            train=True,
            transform=transforms.ToTensor(),
            download=True)

test_data = datasets.MNIST(
            root="./data/",
            train=False,
            transform=transforms.ToTensor(),
            download=True)

其中:

  1. root 指定MNIST数据集存放的路径

  2. train 设置为True表示导入的是训练集合,否则为测试集合

  3. transform 指定导入数据集时需要进行何种变换操作

    此处ToTensor()shape(H, W, C)nump.ndarrayimg转为shape(C, H, W)tensor,其将每一个数值归一化到[0,1],其归一化方法比较简单,直接除以255即可

  4. download 设置为True表示当root参数指定的数据集存放的路径下没有数据时,则自动从网络上下载MNIST数据集,否则就不自动下载

注意: 返回值为一个二元组(data,target),一般是与torch.utils.data.DataLoader配合使用,也可自己对数据进行处理,见二、2

加载MNIST数据集代码:

train_data_loader = torch.utils.data.DataLoader(
        dataset=train_data,
        batch_size=64,
        shuffle=True,
        drop_last=True)

test_data_loader = torch.utils.data.DataLoader(
        dataset=test_data,
        batch_size=64,
        shuffle=False,
        drop_last=False)

其中:

  1. dataset 指定欲装载的MNIST数据集
  2. batch_size 设置了每批次装载的数据图片为64个(自行设置)
  3. shuffle 设置为True表示在装载数据时随机乱序,常用于进行多批次的模型训练
  4. drop_last 设置为True表示当数据集size不能整除batch_size时,则删除最后一个batch_size,否则就不删除

在加载完成后,可以选取其中一个批次的数据进行预览:

********************
images, labels = next(iter(train_data_loader))	# images:Tensor(64,1,28,28)、labels:Tensor(64,)
********************
img = torchvision.utils.make_grid(images)	# 把64张图片拼接为1张图片

# pytorch网络输入图像的格式为(C, H, W),而numpy中的图像的shape为(H,W,C)。故需要变换通道才能有效输出
img = img.numpy().transpose(1, 2, 0) 
std = [0.5, 0.5, 0.5]
mean = [0.5, 0.5, 0.5]
img = img * std   mean
print(labels)
plt.imshow(img)
plt.show()

下图展示的是一个batch数据集(64张图片)的显示:
学新通
对其中某一个图片进行像素化展示:

# images:Tensor(64,1,28,28)、labels:Tensor(64,)	
images, labels = next(iter(train_data_loader))  #(1,28,28)表示该图像的 height、width、color(颜色通道,即单通道)
images = images.reshape(64, 28, 28) 
img = images[0, :, :]	# 取batch_size中的第一张图像
np.savetxt('img.txt', img.cpu().numpy(), fmt="%f", encoding='UTF-8')	# 将像素值写入txt文件,以便查看
img = img.cpu().numpy()	#转为numpy类型,方便有效输出

fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111)
ax.imshow(img, cmap='gray')
width, height = img.shape
thresh = img.max()/2.5

for x in range(width):
    for y in range(height):
        val = round(img[x][y], 2) if img[x][y] !=0 else 0
        ax.annotate(str(val), xy=(y, x),
                    horizontalalignment='center',
                    verticalalignment='center',
                    color='white' if img[x][y] < thresh else 'black')
plt.show()
学新通

学新通

2、通过重构Dataset类读取特定的MNIST数据或者制作自己的MNIST数据集

定义一个子类,继承Dataset类, 重写 len()getitem() 方法。
getitem 是获取样本对,模型直接通过这一函数获得一对样本对{ x:y }
len 是指数据集长度

① 读取MNIST文件夹下processed文件中的training.pt、test.pt数据集

class Data_Loader(Dataset):
    def __init__(self, root, transform=None):
        self.data, self.targets = torch.load(root)	#采用torch.load进行读取,读取之后的结果为torch.Tensor形式
		self.transform = transform
		
    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)
        
        return img, target

    def __len__(self):
        return len(self.data)
学新通

接下来,调用我们自定义的Data_Loader类来读取数据集:

# root 为training.pt、test.pt文件所在的绝对路径
train_data = Data_Loader(root='./mnist/MNIST/processed/training.pt', transform= None)
test_data = Data_Loader(root='./mnist/MNIST/processed/test.pt', transform= None)

再使用torch.utils.data.DataLoadertrain_datatest_data进行加载,展示。

② 读取MNIST文件夹下raw文件中的数据集

class Data_Loader(Dataset):
    def __init__(self, folder, data_name, label_name, transform=None):
        (train_set, train_labels) = load_data(folder, data_name, label_name)
        self.train_set = train_set
        self.train_labels = train_labels
        self.transform = transform

    def __getitem__(self, index):
        img, target = self.train_set[index], int(self.train_labels[index])
        if self.transform is not None:
            img = self.transform(img)
        return img, target

    def __len__(self):
        return len(self.train_set)


def load_data(data_folder, data_name, label_name):
    with gzip.open(os.path.join(data_folder, label_name), 'rb') as lbpath:  # rb表示的是读取二进制数据
        y_train = np.frombuffer(lbpath.read(), np.uint8, offset=8)

    with gzip.open(os.path.join(data_folder, data_name), 'rb') as imgpath:
        x_train = np.frombuffer(
            imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
    return x_train, y_train
学新通

接下来,调用我们自定义的Data_Loader类来读取数据集:

#	folder:MNIST数据集中raw文件的绝对路径

# 读取MNIST数据集中的训练集
train_data = Data_Loader('./MNIST/MNIST/raw', "train-images-idx3-ubyte.gz",
                           "train-labels-idx1-ubyte.gz", transform=transforms.ToTensor())

# 读取MNIST数据集中的测试集
test_data = Data_Loader('./MNIST/MNIST/raw', "t10k-images-idx3-ubyte.gz",
                           "t10k-labels-idx1-ubyte.gz", transform=transforms.ToTensor())

再使用torch.utils.data.DataLoadertrain_datatest_data进行加载,展示。

③ 直接读取MNIST数据集

def data_loader(path):
    # Train Data
    mnist_train = torchvision.datasets.MNIST(root=path, train=True, download=False)
    train_data = mnist_train.data.view([-1, 784]).float()/255.	# mnist_train.data 获取数字
    train_labels = mnist_train.targets	# mnist_train.targets 获取标签

    # Test Data
    mnist_test = torchvision.datasets.MNIST(root=path, train=False, download=False)
    test_data = mnist_test.data.view([-1, 784]).float()/255.
    test_labels = mnist_test.targets
	
	# translate the numeric label [0-9] into a vector label[0, ..., 1, ..0, 0]
	train_labelvec = torch.zeros([10, 60000]).int()
    train_labelvec[train_labels.cpu().numpy(), np.arange(60000)] = 1

    test_labelvec = torch.zeros([10, 10000]).int()
    test_labelvec[test_labels.cpu().numpy(), np.arange(10000)] = 1
    
	return train_data, train_labelvec, test_data, test_labelvec
学新通

通过调用该函数可以获取数据:

"""
    Load data and preprocess
    DataTrain:Tensor(60000,784) LabelsTrain:Tensor(10,60000)
    DataTest:Tensor(10000,784)  LabelsTest:Tensor(10,10000)
    """
    DataTrain, LabelsTrain, DataTest, LabelsTest = data_loader(args.datapath)

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiahekg
系列文章
更多 icon
同类精品
更多 icon
继续加载