MNISTデータセットの詳細

10209 ワード

MNISTデータセットはすでに「噛まれた」データセットであり、多くのチュートリアルが「手をつける」ことで、ほとんど「模範」となっている.しかし、まだよく知らない人もいるかもしれませんが、紹介します.
MNISTデータセットはhttp://yann.lecun.com/exdb/mnist/4つのセクションを含む取得:
  • Training set images: train-images-idx3-ubyte.gz(9.9 MB、解凍後47 MB、60000サンプルを含む)
  • Training set labels: train-labels-idx1-ubyte.gz(29 KB、解凍後60 KB、60000個のラベルを含む)
  • Test set images: t10k-images-idx3-ubyte.gz(1.6 MB、解凍後7.8 MB、10000サンプルを含む)
  • Test set labels: t10k-labels-idx1-ubyte.gz(5 KB、解凍後10 KB、10000個のラベルを含む)
  • MNISTデータセットはアメリカ国家標準と技術研究所、National Institute of Standards and Technology(NIST)から来た.トレーニングセット(training set)は250人の異なる人から手書きの数字で構成され、そのうち50%は高校生で、50%は国勢調査局(the Census Bureau)のスタッフから構成されている.テストセット(test set)も同様の割合の手書きデジタルデータである.
    新しいフォルダ-mnistを作成して、データセットをmnistにダウンロードした後、解凍すればいいです.
    详解 MNIST 数据集_第1张图片
    画像はバイト形式で記憶されており、アルゴリズムの訓練とテストのためにNumPy arrayに読み込む必要がある.
    import os
    import struct
    import numpy as np
    
    def load_mnist(path, kind='train'):
        """Load MNIST data from `path`"""
        labels_path = os.path.join(path,
                                   '%s-labels-idx1-ubyte'
                                   % kind)
        images_path = os.path.join(path,
                                   '%s-images-idx3-ubyte'
                                   % kind)
        with open(labels_path, 'rb') as lbpath:
            magic, n = struct.unpack('>II',
                                     lbpath.read(8))
            labels = np.fromfile(lbpath,
                                 dtype=np.uint8)
    
        with open(images_path, 'rb') as imgpath:
            magic, num, rows, cols = struct.unpack('>IIII',
                                                   imgpath.read(16))
            images = np.fromfile(imgpath,
                                 dtype=np.uint8).reshape(len(labels), 784)
    
        return images, labels
    load_mnistの関数は2つの配列を返し、1つ目はn x m次元のNumPy array(images)であり、ここでnはサンプル数(行数)、mは特徴数(列数)である.トレーニングデータセットは60000個のサンプルを含む、テストデータセットは10000個のサンプルを含む.MNISTデータセットの各ピクチャは、28 x 28個の画素点で構成する、各画素点は1階調値で表される.ここで、28 x 28の画素を1次元の行ベクトルに展開する、これらの行ベクトルは、ピクチャ配列内の行(行当たり784の値、または行当たり1枚のピクチャを表す)である.load_mnistの関数が返す2番目の配列(labels)は、対応するターゲット変数、すなわち手書き数字のクラスラベル(整数0-9)を含む.
    初めて見ると、私たちが画像を読み取る方法がおかしいと思うかもしれません.
    magic, n = struct.unpack('>II', lbpath.read(8))
    labels = np.fromfile(lbpath, dtype=np.uint8)

    この2行のコードを理解するために、まずMNISTのウェブサイトでデータセットの紹介を見てみましょう.
    TRAINING SET LABEL FILE (train-labels-idx1-ubyte):
    
    [offset] [type]          [value]          [description] 
    0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
    0004     32 bit integer  60000            number of items 
    0008     unsigned byte   ??               label 
    0009     unsigned byte   ??               label 
    ........ 
    xxxx     unsigned byte   ??               label
    The labels values are 0 to 9.

    上記の2行のコードを用いることにより、まずmagic numberを読み込む.これはファイルプロトコルの記述であり、fromfileメソッドを呼び出してNumPy arrayにバイトを読み込む前にファイルバッファ内のite m数(n)である.パラメータ値としてstruct.unpackに入力される>IIには、2つの部分があります.
  • >:これは、大端(バイトがどのように格納されるかを定義するために使用される)を指す.大きな端と小さな端がまだ分からない場合は、Endiannessは非常に良い解釈です.(サイズ端については、詳細は<>)
  • I:符号のない整数を指す.

  • 次のコードを実行することで、MNISTデータセットを解凍したばかりのmnistディレクトリから60000個のトレーニングサンプルと10000個のテストサンプルをロードします.
    MNISTの画像が何に見えるかを知るために、可視化処理を行いましょう.784ピクセル値のベクトルreshapeをfeature matrixから前の28*28の形状にし、matplotlibのimshow関数で描画します.
    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(
        nrows=2,
        ncols=5,
        sharex=True,
        sharey=True, )
    
    ax = ax.flatten()
    for i in range(10):
        img = X_train[y_train == i][0].reshape(28, 28)
        ax[i].imshow(img, cmap='Greys', interpolation='nearest')
    
    ax[0].set_xticks([])
    ax[0].set_yticks([])
    plt.tight_layout()
    plt.show()

    私たちは今2*5の画像を見ることができるはずです.中にはそれぞれ0-9の単一の数字の画像があります.
    详解 MNIST 数据集_第2张图片
    また、ある数字の複数のサンプル画像を描くこともできます.これらの手書きサンプルがどれだけ異なるかを見てみましょう.
    fig, ax = plt.subplots(
        nrows=5,
        ncols=5,
        sharex=True,
        sharey=True, )
    
    ax = ax.flatten()
    for i in range(25):
        img = X_train[y_train == 7][i].reshape(28, 28)
        ax[i].imshow(img, cmap='Greys', interpolation='nearest')
    
    ax[0].set_xticks([])
    ax[0].set_yticks([])
    plt.tight_layout()
    plt.show()

    上記のコードを実行すると、数字7の25の異なる形態が表示されます.
    详解 MNIST 数据集_第3张图片
    また、MNISTのピクチャデータとラベルをCSVファイルとして保存することも可能である、特殊なバイトフォーマットをサポートしないプログラムでデータセットを開くことができる.ただし、以下に示すように、CSVのファイルフォーマットはより多くのディスク領域を占有することについて説明します.
  • train_img.csv: 109.5 MB
  • train_labels.csv: 120 KB
  • test_img.csv: 18.3 MB
  • test_labels: 20 KB

  • これらのCSVファイルを保存する場合は、MNISTデータセットをNumPy arrayにロードした後、次のコードを実行します.
    np.savetxt('train_img.csv', X_train,
               fmt='%i', delimiter=',')
    np.savetxt('train_labels.csv', y_train,
               fmt='%i', delimiter=',')
    np.savetxt('test_img.csv', X_test,
               fmt='%i', delimiter=',')
    np.savetxt('test_labels.csv', y_test,
               fmt='%i', delimiter=',')

    データセットをCSVファイルとして保存すると、NumPyのgenfromtxt関数を使用してプログラムに再ロードすることもできます.
    X_train = np.genfromtxt('train_img.csv',
                            dtype=int, delimiter=',')
    y_train = np.genfromtxt('train_labels.csv',
                            dtype=int, delimiter=',')
    X_test = np.genfromtxt('test_img.csv',
                           dtype=int, delimiter=',')
    y_test = np.genfromtxt('test_labels.csv',
                           dtype=int, delimiter=',')

    ただし、CSVファイルからのMNISTデータのロードは、より長い時間にわたって顕著に送信されるので、可能であれば、データセットの元のバイトフォーマットを維持することをお勧めします.
    参考:-Book,Python Machine Learning.