pytorch实现下载加载mnist数据集

来自:网络
时间:2024-08-28
阅读:

pytorch下载加载mnist数据集

1.下载mnist

使用torchvision.datasets,其中含有一些常见的MNIST等数据集,

使用方式:

train_data=torchvision.datasets.MNIST(
    root='MNIST',
    train=True,
    transform=torchvision.transforms.ToTensor(),
    download=True
)
test_data=torchvision.datasets.MNIST(
    root='MNIST',
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True
)
  • root:表示下载位置,下载后,会在该位置中新建一个MNIST文件夹,底下还有一个raw文件夹
  • train:True下载就会是训练集,False下载就会是测试集
  • transform:表示转换方式
  • download:表示是否下载

下载完后会生成四个压缩包,分别代表着train的img和label以及test的img和label

变量train_data和test_data的类型分别为'torchvision.datasets.mnist.MNIST',如果想用到pytorch中的进行训练,就必须将变量改为torch

2.torch.utils.data.DataLoader( )

用from torch.utils.data import DataLoader进行导入,

train_load=DataLoader(dataset=train_data,batch_size=100,shuffle=True)
test_load=DataLoader(dataset=test_data,batch_size=100,shuffle=True)

随机加载批量大小为l00数据给train_load和test_load,每个变量都由两部分组成,用迭代器将两部分分开

train_x,train_y=next(iter(train_load))

其中train_x为属性值,type(train_x)=torch.Size([100, 1, 28, 28])#100个,channel为1,长宽为28*28,type(train_y)=torch.size([100])

3.opencv显示图片

import cv2

img=torchvision.utils.make_grid(train_x,nrow=10)#将train_x赋给一个宽为10的网格
#因为cv2显示的图片格式是(size,size,channel),但是img格式为(channel,size,size)
img = img.numpy().transpose(1,2,0)
cv2.imshow('img', img)
cv2.waitKey()

mnist手写数字识别实践

MNIST数据集是手写数字识别领域最常用的数据集。它包含60,000个用于训练的示例和10,000个用于测试的示例。这些手写数字图像来自美/国人口/普查局的员工和美国高中学生。MNIST数据集中的每个图像都是28x28的灰度图像,包含一个手写数字 0-9。所有的数字都以清晰的黑色位于图像的中心,背景为白色。

MNIST数据集主要用于测试各种手写数字识别算法的性能。我们可以使用这个数据集构建自己的手写数字识别模型,并在10,000个测试集图像上评估其性能。

在MNIST数据集上,一个较好的模型可以达到超过99%的识别准确率。所以,这个数据集对初学者来说比较简单,可以用来验证自己构建的模型是否工作正常。对专家来说,达到99.9%以上的识别率则需要更复杂的模型和更高级的技巧。

MNIST数据集非常适合作为手写数字识别入门数据集:

  • 它包含一个非常标准的问题定义:识别0-9之间的10个类别
  • 数据集规模适中,训练和测试都非常快速
  • 高识别准确率比较容易达到,可以快速验证自己的方法
  • 数据集简单而标准化,便于比较不同方法的性能

MNIST可以通过TensorFlow和Keras等深度学习框架非常简单地载入使用。我们只需要几行代码就可以构建一个基本的手写数字识别模型并在此数据集上训练与评估。

所以,总的来说,MNIST是一个非常典型和流行的手写数字识别入门数据集。它包含标准化的图像和问题定义,规模适中,具有较高的识别准确率,非常适合初学者练手和验证模型。这个数据集让手写数字识别变得简单可学,降低了入门难度,值得倾注时间去理解与实践。

下面使用Keras训练MNIST数据集,Keras具有简洁而快速的API,可以使用很少的代码构建强大的神经网络。它降低了深度学习的入门难度,让更多人可以轻松使用。

安装python环境,推荐使用Anaconda,Anaconda安装完毕后可以使用Jupyter编写python代码。Jupyter可以一段一段的执行代码,每写完一句python就可以立即运行并查看结果,极大提高了效率。

# 导入numpy并为计算机的伪随机数生成器设置种子开始
import numpy as np
np.random.seed(123)
'''
设置随机数种子的主要目的是确保随机结果可复现。
如果不设置随机数种子,每次运行代码时各种随机操作的结果都会略微不同,导致实验结果也不同,给实验带来不必要的变量。
设置随机数种子后,每次运行代码时各种随机操作的初始化结果都会相同,所以运行结果也相同,确保了实验的可复现性。
'''
#从Keras导入Sequential模型类型
from keras.models import Sequential
#从Keras层模块中导入Dense、Dropout、Activation和Flatten四种层。
from keras.layers import Dense, Dropout, Activation, Flatten
'''
Sequential是Keras中最简单的模型,它由多个网络层线性堆叠而成。我们只需要将各种Keras层逐个添加到该模型中,即可构建自己的网络结构。
四种Keras层的作用分别是:
- Dense:全连接层,用于连接网络层之间的节点,实现函数拟合等作用。在分类和回归任务中广泛使用。
- Dropout:随机置零层,用于在训练过程中随机舍弃一定比例的节点,用于防止过拟合。
- Activation:激活层,用于对上一层的输出施加非线性激活,如ReLU、sigmoid等。增强模型的表达能力。 
- Flatten:展平层,用于将输入“压平”,例如将多维输入压平为二维,以供全连接层使用。
所以,简而言之,这四种Keras层的主要作用是:
- Dense:实现网络连接,用于拟合和回归 
- Dropout:实现随机舍弃,用于正则化和防过拟合 
- Activation:实现非线性转换,增强表达能力 
- Flatten:实现维度压缩和reshape,以连串网络 
这些层是构建神经网络的基本模块,我们可以像搭积木一样组合这些层,构建出自己想要的复杂网络结构。
'''
#从Keras导入CNN层,这些卷积层将帮助我们有效地训练图像数据
from keras.layers import Conv2D, MaxPool2D
#导入一些实用程序
from keras.utils import np_utils
#加载keras库的MNIST数据集
from keras.datasets import mnist
#载入数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#打印数据集的形状
print(x_train.shape, y_train.shape)
#输出结果显示训练集中有60000个样本,每个图像都是28x28

#通过matplotlib绘制第一个样本
from matplotlib import pyplot as plt
plt.imshow(x_train[0])

#使用Theano后端时,必须声明输入图像的深度
#即将数据集的形状从nx高x宽转换为nx宽x高x深度
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
print(x_train.shape)

#输入数据的最后预处理步骤是将数据类型转换为float32并将我们的数据值规范化为[0, 1]
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

#看看类标签数据
print(y_train.shape)
#有十个不同的类,每个数字一个,看起来只有一个一维数组
print(y_train[:10])
#将一维类数组转换为10维类矩阵
Y_train = np_utils.to_categorical(y_train, 10)
Y_test = np_utils.to_categorical(y_test, 10)
print(Y_train.shape)

#定义一个顺序模型
model = Sequential()
#在一个模型中添加一个卷积层
'''
filters=32:使用32个卷积滤波器(卷积核)
kernel_size=(3, 3):每个滤波器的大小为3x3
activation='relu':激活函数采用ReLU
input_shape=(28, 28, 1):输入数据的shape为28x28x1,这里1表示黑白图像
'''
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
print(model.output_shape)


#再添加一个卷积层
'''
1、Conv2D层:二维卷积层,32个卷积核,核大小为3x3,激活函数为ReLU
2. MaxPool2D层:二维最大池化层,池化窗口大小为2x2
3. Dropout层:随机舍弃25%的节点
'''
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))
model.add(MaxPool2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

#添加一个全连接层,然后是输出层
'''
Flatten层:将输入“压平”,例如从三维特征图变成二维特征向量 
Dense层:全连接层,128个节点,激活函数为ReLU
Dropout层:随机舍弃50%的节点
Dense层:全连接输出层,10个节点,激活函数为softmax
'''
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

#编译模型
'''
该行代码为模型指定:
- loss:损失函数,这里为 categorical_crossentropy,用于多分类任务
- optimizer:优化器,这里为Adam算法,是一个较为常用的优化器 
- metrics:评价指标,这里为accuracy,用于评价分类准确度
所以,这个编译步骤为模型指定:
1. 损失函数:categorical_crossentropy,计算多分类任务中的交叉熵损失 
2. 优化器:Adam,用于更新网络权重,根据损失函数更新权重以最小化损失 
3. 评价指标:accuracy,用于评价模型在训练和测试期间的分类准确度
这三个specification对模型训练至关重要:
- 损失函数决定了模型在训练时要最小化的代价函数 
- 优化器决定了模型如何根据损失函数更新权重以最小化损失 
- 评价指标用于评判模型的训练效果和泛化能力
'''
model.compile(loss='categorical_crossentropy',
             optimizer='adam',
             metrics=['accuracy'])

#训练数据上拟合模型
'''
该行代码会使用X_train和Y_train的数据对模型进行训练,具体参数为:
- X_train:训练数据的特征值
- Y_train:训练数据的标签值 
- batch_size:批大小,这里为32,表示每批32个样本
- epochs:训练轮数,这里为10轮
- verbose:日志显示,这里为1,显示一个进度条
- 所以,这行代码会以以下方式训练模型:
1. X_train和Y_train作为训练集数据         
2. 以批大小32的mini-batch进行训练,每批选32个样本进行训练更新 
3. 训练10轮,用全部训练集训练10次 
4. 训练过程中显示一个进度条,日志级别为1 
'''
model.fit(X_train, Y_train, batch_size=32, epochs=10, verbose=1)

#在测试数据上评估模型
score = model.evaluate(X_test, Y_test, verbose=0)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

返回顶部
顶部