加载 EMNIST 字母数据集

Tis*_*box 6 python numpy scipy python-3.x mnist

我一直试图找到一种方法来加载 EMNIST-letters 数据集,但没有取得多大成功。我在结构中发现了有趣的东西,并且无法理解正在发生的事情。这就是我的意思:

我在这里下载了 .mat 格式

我可以使用加载数据

import scipy.io
mat = scipy.io.loadmat('letter_data.mat') # renamed for conveniance
Run Code Online (Sandbox Code Playgroud)

它是一个字典,键如下:

dict_keys(['__header__', '__version__', '__globals__', 'dataset'])
Run Code Online (Sandbox Code Playgroud)

唯一感兴趣的关键是数据集,我无法从中收集数据。打印它的形状给这个:

>>>print(mat['dataset'].shape)
(1, 1)
Run Code Online (Sandbox Code Playgroud)

我越挖越深,找到了一个看起来有点像真实数据集的形状,并发现了这个:

>>>print(mat['dataset'][0][0][0][0][0][0].shape)
(124800, 784)
Run Code Online (Sandbox Code Playgroud)

这正是我想要的,但我找不到标签和测试数据,我尝试了很多东西,但似乎无法理解这个数据集的结构。

如果有人能告诉我这是怎么回事,我将不胜感激

Jos*_*yne 6

由于数据集的结构方式,可以使用 访问图像数组数组,使用 访问mat['dataset'][0][0][0][0][0][0]标签数组数组mat['dataset'][0][0][0][0][0][1]。例如,print(mat['dataset'][0][0][0][0][0][0][0])将打印出第一张图像的像素值,print(mat['dataset'][0][0][0][0][0][1][0])并将打印第一张图像的标签。

对于不太复杂的数据集,我实际上建议在 Kaggle 上使用 EMNIST 数据集的 CSV 版本:https ://www.kaggle.com/crawford/emnist ,其中每一行是一个单独的图像,有 785列,其中第一列 = class_label,之后的每一列代表一个像素值(28 x 28 图像总共 784 个)。


Dan*_*l B 6

另一种解决方案是使用 EMNIST python 包。(完整详细信息请参见https://pypi.org/project/emnist/)

这使您可以pip install emnist在您的环境中导入数据集(它们将在您第一次运行程序时下载)。

来自网站的示例:

  >>> from emnist import extract_training_samples
  >>> images, labels = extract_training_samples('digits')
  >>> images.shape
  (240000, 28, 28)
  >>> labels.shape
  (240000,)
Run Code Online (Sandbox Code Playgroud)

您还可以列出数据集

 >>> from emnist import list_datasets
  >>> list_datasets()
  ['balanced', 'byclass', 'bymerge', 'digits', 'letters', 'mnist']
Run Code Online (Sandbox Code Playgroud)

并将第一个示例中的“数字”替换为您的选择。

这为您提供了 numpy 数组中的所有数据,我发现这些数据使操作变得容易。


小智 5

@Josh Payne 的回答是正确的,但我会为那些想要使用 .mat 文件并强调典型数据拆分的人扩展它。

数据本身已经被分成训练集和测试集。这是我访问数据的方式:

    from scipy import io as sio
    mat = sio.loadmat('emnist-letters.mat')
    data = mat['dataset']

    X_train = data['train'][0,0]['images'][0,0]
    y_train = data['train'][0,0]['labels'][0,0]
    X_test = data['test'][0,0]['images'][0,0]
    y_test = data['test'][0,0]['labels'][0,0]
Run Code Online (Sandbox Code Playgroud)

还有一个额外的字段“writers”(例如data['train'][0,0]['writers'][0,0])可以区分原始样本作者。最后,还有另一个 field data['mapping'],但我不确定它将数字映射到什么。

此外,在 Secion II D 中,EMNIST 论文指出“训练集的最后一部分,与测试集大小相等,留作验证集”。奇怪的是,.mat 文件训练/测试大小与表 II 中列出的数字不匹配,但确实与图 2 中的大小匹配。

    val_start = X_train.shape[0] - X_test.shape[0]
    X_val = X_train[val_start:X_train.shape[0],:]
    y_val = y_train[val_start:X_train.shape[0]]
    X_train = X_train[0:val_start,:]
    y_train = y_train[0:val_start]
Run Code Online (Sandbox Code Playgroud)

如果您不需要验证集,可以将这些样本留在训练集中。

此外,如果您想将数据重塑为 2D、28x28 大小的图像而不是 1D 784 数组,要获得正确的图像方向,您需要使用 Fortran 排序进行 numpy 重塑(Matlab 使用列优先排序,只是像 Fortran。参考)。例如——

    X_train = X_train.reshape( (X_train.shape[0], 28, 28), order='F')
Run Code Online (Sandbox Code Playgroud)