《零基础实践深度学习》2.3 手写数字识别之数据处理

简介: 这篇文章详细介绍了手写数字识别任务中数据处理的优化方法,包括数据读取、划分数据集、生成批次数据、训练样本乱序和校验数据有效性等环节,并通过代码示例展示了如何使用飞桨框架对MNIST数据集进行有效处理以提升模型训练效果。

2.3 手写数字识别之数据处理

第2.2节我们使用“横纵式”教学法中的纵向极简方案快速完成手写数字识别任务的建模,但模型测试效果并未达成预期。我们换个思路,从横向展开,如图1所示,逐个环节优化,以达到最优训练效果。本节主要介绍手写数字识别模型中,数据处理的优化方法。

图1:“横纵式”教学法 — 数据处理优化

第2.2节我们通过调用飞桨提供的paddle.vision.datasets.MNISTAPI加载MNIST数据集。但实践中,我们面临的任务和数据环境千差万别,通常需要自己编写适合当前任务的数据处理程序,一般涉及如下五个环节:

  • 读入数据
  • 划分数据集
  • 生成批次数据
  • 训练样本集乱序
  • 校验数据有效性

前提条件

在数据读取与处理前,首先要加载飞桨平台和数据处理库,代码如下。

In [1]

# 数据处理部分之前的代码,加入部分数据处理的库
import paddle
from paddle.nn import Linear
import paddle.nn.functional as F
import os
import gzip
import json
import random
import numpy as np

2.3.1 读入数据并划分数据集

在实际应用中,保存到本地的数据存储格式多种多样,如MNIST数据集以json格式存储在本地,其数据存储结构如图2所示。

图2:MNIST数据集的存储结构

data包含三个元素的列表:训练集train_set、验证集val_set、测试集test_set,分别为50 000条训练样本、10 000条验证样本和10 000条测试样本。每条样本数据都包含手写数字的图像和对应的标签。

  • 训练集 :用于确定模型参数
  • 验证集 :用于调节模型超参数(如多个网络结构、正则化权重的最优选择)。
  • 测试集 :用于估计应用效果(没有在模型中应用过的数据,更贴近模型在真实场景应用的效果)。

train_set包含两个元素的列表:train_images、train_labels。

  • train_images :[50 000, 784]的二维列表,包含50 000张图片。每张图片用一个长度为784的向量表示,内容是 28 × 28 像素的灰度值(黑白图片)。
  • train_labels :[50 000, ]的列表,表示这些图片对应的分类标签,即0~9之间的一个数字。

在本地./work/目录下读取文件名称为mnist.json.gz的MNIST数据,并拆分成训练集、验证集和测试集,代码实现如下。

In [2]

# 声明数据集文件位置
datafile = './work/mnist.json.gz'
print('loading mnist dataset from {} ......'.format(datafile))
# 加载json数据文件
data = json.load(gzip.open(datafile))
print('mnist dataset load done')
# 读取到的数据区分训练集,验证集,测试集
train_set, val_set, eval_set = data
# 观察训练集数据
imgs, labels = train_set[0], train_set[1]
print("训练数据集数量: ", len(imgs))
# 观察验证集数量
imgs, labels = val_set[0], val_set[1]
print("验证数据集数量: ", len(imgs))
# 观察测试集数量
imgs, labels = val= eval_set[0], eval_set[1]
print("测试数据集数量: ", len(imgs))
print(len(imgs[0]))

loading mnist dataset from ./work/mnist.json.gz ......

mnist dataset load done

训练数据集数量: 50000

验证数据集数量: 10000

测试数据集数量: 10000

784

扩展阅读:为什么学术界的模型总在不断精进呢?

通常某组织发布一个新任务的训练集和测试集数据后,全世界的科学家都针对该数据集进行创新研究,随后大量针对该数据集的论文会陆续发表。论文1的A模型声称在测试集的准确率70%,论文2的B模型声称在测试集的准确率提高到72%,论文NN的xx模型声称在测试集的准确率提高到90% ...

然而这些论文中的模型在测试集上准确率提升真实有效么?我们不妨大胆猜测一下。假设所有论文共产生1000个模型,这些模型使用的是测试数据集来评判模型效果,并最终选出效果最优的模型。这相当于把原始的测试集当作了验证集,使得测试集失去了真实评判模型效果的能力,正如机器学习领域非常流行的一句话:“拷问数据足够久,它终究会招供”。

图3:拷问数据足够久,它总会招供

那么当我们需要将学术界研发的模型复用于工业项目时,应该如何选择呢?给读者一个小建议:当几个模型的准确率在测试集上差距不大时,尽量选择网络结构相对简单的模型。往往越精巧设计的模型和方法,越不容易在不同的数据集之间迁移。

2.3.2 训练样本乱序、生成批次数据

(1)训练样本乱序:先将样本按顺序进行编号,建立ID集合index_list****。然后将index_list乱序,最后按乱序后的顺序读取数据。


说明:

通过大量实验发现,模型对最后出现的数据印象更加深刻。训练数据导入后,越接近模型训练结束,最后几个批次数据对模型参数的影响越大。为了避免模型记忆影响训练效果,需要进行样本乱序操作。


(2)生成批次数据:先设置合理的batch size,再将数据转变成符合模型输入要求的np.array格式****返回。同时,在返回数据时将Python生成器设置为yield模式,以减少内存占用。

在执行如上两个操作之前,需要先将数据处理代码封装成load_data函数,方便后续调用。load_data有三种模型:trainvalideval,分为对应返回的数据是训练集、验证集、测试集。

In [3]

imgs, labels = train_set[0], train_set[1]
print("训练数据集数量: ", len(imgs))
# 获得数据集长度
imgs_length = len(imgs)
# 定义数据集每个数据的序号,根据序号读取数据
index_list = list(range(imgs_length))
# 读入数据时用到的批次大小
BATCHSIZE = 100
# 随机打乱训练数据的索引序号
random.shuffle(index_list)
# 定义数据生成器,返回批次数据
def data_generator():
    imgs_list = []
    labels_list = []
    for i in index_list:
        # 将数据处理成希望的类型
        img = np.array(imgs[i]).astype('float32')
        label = np.array(labels[i]).astype('float32')
        imgs_list.append(img) 
        labels_list.append(label)
        if len(imgs_list) == BATCHSIZE:
            # 获得一个batchsize的数据,并返回
            yield np.array(imgs_list), np.array(labels_list)
            # 清空数据读取列表
            imgs_list = []
            labels_list = []
    # 如果剩余数据的数目小于BATCHSIZE,
    # 则剩余数据一起构成一个大小为len(imgs_list)的mini-batch
    if len(imgs_list) > 0:
        yield np.array(imgs_list), np.array(labels_list)
    return data_generator

训练数据集数量: 50000

In [4]

# 声明数据读取函数,从训练集中读取数据
train_loader = data_generator
# 以迭代的形式读取数据
for batch_id, data in enumerate(train_loader()):
    image_data, label_data = data
    if batch_id == 0:
        # 打印数据shape和类型
        print("打印第一个batch数据的维度:")
        print("图像维度: {}, 标签维度: {}".format(image_data.shape, label_data.shape))
    break

打印第一个batch数据的维度:

图像维度: (100, 784), 标签维度: (100,)

相关文章
|
机器学习/深度学习 数据采集 算法
如何利用机器学习进行文本分类
在当今信息爆炸的时代,我们每天都要面对大量的文本数据。无论是社交媒体的评论、新闻文章还是电子邮件,都需要有效地对这些文本进行分类和理解。传统的基于规则的方法在处理这种大规模文本数据时存在一些局限性,因此机器学习成为了解决这个问题的热门技术。
145 0
|
4月前
|
数据采集 机器学习/深度学习 Python
深度学习中的高效数据预处理技巧
【7月更文第29天】在构建深度学习模型时,数据预处理是至关重要的步骤之一。高质量的数据预处理可以显著提高模型的性能并加速训练过程。本文将探讨几种有效的数据预处理技巧,包括数据清洗、特征归一化和数据增强,并通过实际的Python代码示例进行说明。
370 5
|
13天前
|
机器学习/深度学习 人工智能 自然语言处理
浅谈机器学习与深度学习的区别
浅谈机器学习与深度学习的区别
24 0
|
5月前
|
机器学习/深度学习 自然语言处理 算法
机器学习和深度学习的区别
机器学习和深度学习的区别
120 1
|
6月前
|
机器学习/深度学习 数据采集 传感器
深度学习在图像识别中的应用进展构建高效机器学习模型:从数据预处理到模型优化的洞见
【5月更文挑战第29天】 在人工智能领域,深度学习技术已经成为推动图像识别进步的核心动力。随着卷积神经网络(CNN)的不断发展和优化,以及大数据和计算能力的显著提升,图像识别的准确性和效率得到了极大增强。本文将探讨深度学习技术在图像识别领域的最新应用,分析其关键技术创新点,并讨论未来可能的发展趋势。 【5月更文挑战第29天】 在探索数据科学与机器学习的融合艺术中,本文将引导读者穿越数据处理的迷宫,解锁特征工程的秘密,并最终在模型优化的顶峰俯瞰效率与准确性的壮丽景色。我们将通过一系列经过实战验证的技术感悟,展现如何打造一个既健壮又灵敏的机器学习模型。文章不仅聚焦于技术细节,更注重于概念理解与实
|
6月前
|
机器学习/深度学习 数据采集 算法
机器学习实战第3天:手写数字识别
机器学习实战第3天:手写数字识别
|
6月前
|
机器学习/深度学习 数据可视化 Linux
深度学习模型可视化工具——Netron使用介绍
深度学习模型可视化工具——Netron使用介绍
882 2
|
机器学习/深度学习 算法 数据可视化
PyTorch深度学习实战 | 神经网络的优化难题
即使我们可以利用反向传播来进行优化,但是训练过程中仍然会出现一系列的问题,比如鞍点、病态条件、梯度消失和梯度爆炸,对此我们首先提出了小批量随机梯度下降,并且基于批量随机梯度下降的不稳定的特点,继续对其做出方向和学习率上的优化。
166 0
PyTorch深度学习实战 | 神经网络的优化难题
|
机器学习/深度学习 人工智能 算法
【深度学习】(一)机器学习基础
AI人工智能包含的内容十分广泛,对于图像处理而言,机器学习、深度学习或者计算机视觉主要关注图像识别这部分内容,所以重点学习CNN卷积神经网络。今天先从上古时期的机器学习开始。
149 0
【深度学习】(一)机器学习基础
|
机器学习/深度学习 数据采集 算法