詳解 MNIST 數(shù)據(jù)集

MNIST 數(shù)據(jù)集已經(jīng)是一個(gè)被"嚼爛"了的數(shù)據(jù)集, 很多教程都會(huì)對(duì)它"下手", 幾乎成為一個(gè) "典范". 不過(guò)有些人可能對(duì)它還不是很了解, 下面來(lái)介紹一下.

MNIST 數(shù)據(jù)集可在 http://yann.lecun.com/exdb/mnist/ 獲取, 它包含了四個(gè)部分:

  • Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解壓后 47 MB, 包含 60,000 個(gè)樣本)
  • Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解壓后 60 KB, 包含 60,000 個(gè)標(biāo)簽)
  • Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解壓后 7.8 MB, 包含 10,000 個(gè)樣本)
  • Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解壓后 10 KB, 包含 10,000 個(gè)標(biāo)簽)

MNIST 數(shù)據(jù)集來(lái)自美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究所, National Institute of Standards and Technology (NIST). 訓(xùn)練集 (training set) 由來(lái)自 250 個(gè)不同人手寫(xiě)的數(shù)字構(gòu)成, 其中 50% 是高中學(xué)生, 50% 來(lái)自人口普查局 (the Census Bureau) 的工作人員. 測(cè)試集(test set) 也是同樣比例的手寫(xiě)數(shù)字?jǐn)?shù)據(jù).

不妨新建一個(gè)文件夾 -- mnist, 將數(shù)據(jù)集下載到 mnist 以后, 解壓即可:

dataset

圖片是以字節(jié)的形式進(jìn)行存儲(chǔ), 我們需要把它們讀取到 NumPy array 中, 以便訓(xùn)練和測(cè)試算法.

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 函數(shù)返回兩個(gè)數(shù)組, 第一個(gè)是一個(gè) n x m 維的 NumPy array(images), 這里的 n 是樣本數(shù)(行數(shù)), m 是特征數(shù)(列數(shù)). 訓(xùn)練數(shù)據(jù)集包含 60,000 個(gè)樣本, 測(cè)試數(shù)據(jù)集包含 10,000 樣本. 在 MNIST 數(shù)據(jù)集中的每張圖片由 28 x 28 個(gè)像素點(diǎn)構(gòu)成, 每個(gè)像素點(diǎn)用一個(gè)灰度值表示. 在這里, 我們將 28 x 28 的像素展開(kāi)為一個(gè)一維的行向量, 這些行向量就是圖片數(shù)組里的行(每行 784 個(gè)值, 或者說(shuō)每行就是代表了一張圖片). load_mnist 函數(shù)返回的第二個(gè)數(shù)組(labels) 包含了相應(yīng)的目標(biāo)變量, 也就是手寫(xiě)數(shù)字的類標(biāo)簽(整數(shù) 0-9).

第一次見(jiàn)的話, 可能會(huì)覺(jué)得我們讀取圖片的方式有點(diǎn)奇怪:

magic, n = struct.unpack('>II', lbpath.read(8))
labels = np.fromfile(lbpath, dtype=np.uint8)

為了理解這兩行代碼, 我們先來(lái)看一下 MNIST 網(wǎng)站上對(duì)數(shù)據(jù)集的介紹:

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.

通過(guò)使用上面兩行代碼, 我們首先讀入 magic number, 它是一個(gè)文件協(xié)議的描述, 也是在我們調(diào)用 fromfile 方法將字節(jié)讀入 NumPy array 之前在文件緩沖中的 item 數(shù)(n). 作為參數(shù)值傳入 struct.unpack>II 有兩個(gè)部分:

  • >: 這是指大端(用來(lái)定義字節(jié)是如何存儲(chǔ)的); 如果你還不知道什么是大端和小端, Endianness 是一個(gè)非常好的解釋. (關(guān)于大小端, 更多內(nèi)容可見(jiàn)<<深入理解計(jì)算機(jī)系統(tǒng) -- 2.1 節(jié)信息存儲(chǔ)>>)
  • I: 這是指一個(gè)無(wú)符號(hào)整數(shù).

通過(guò)執(zhí)行下面的代碼, 我們將會(huì)從剛剛解壓 MNIST 數(shù)據(jù)集后的 mnist 目錄下加載 60,000 個(gè)訓(xùn)練樣本和 10,000 個(gè)測(cè)試樣本.

為了了解 MNIST 中的圖片看起來(lái)到底是個(gè)啥, 讓我們來(lái)對(duì)它們進(jìn)行可視化處理. 從 feature matrix 中將 784-像素值 的向量 reshape 為之前的 28*28 的形狀, 然后通過(guò) matplotlib 的 imshow 函數(shù)進(jìn)行繪制:

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()

我們現(xiàn)在應(yīng)該可以看到一個(gè) 2*5 的圖片, 里面分別是 0-9 單個(gè)數(shù)字的圖片.

0-9

此外, 我們還可以繪制某一數(shù)字的多個(gè)樣本圖片, 來(lái)看一下這些手寫(xiě)樣本到底有多不同:

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()

執(zhí)行上面的代碼后, 我們應(yīng)該看到數(shù)字 7 的 25 個(gè)不同形態(tài):

7

另外, 我們也可以選擇將 MNIST 圖片數(shù)據(jù)和標(biāo)簽保存為 CSV 文件, 這樣就可以在不支持特殊的字節(jié)格式的程序中打開(kāi)數(shù)據(jù)集. 但是, 有一點(diǎn)要說(shuō)明, CSV 的文件格式將會(huì)占用更多的磁盤(pán)空間, 如下所示:

  • train_img.csv: 109.5 MB
  • train_labels.csv: 120 KB
  • test_img.csv: 18.3 MB
  • test_labels: 20 KB

如果我們打算保存這些 CSV 文件, 在將 MNIST 數(shù)據(jù)集加載入 NumPy array 以后, 我們應(yīng)該執(zhí)行下列代碼:

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=',')

一旦將數(shù)據(jù)集保存為 CSV 文件, 我們也可以用 NumPy 的 genfromtxt 函數(shù)重新將它們加載入程序中:

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=',')

不過(guò), 從 CSV 文件中加載 MNIST 數(shù)據(jù)將會(huì)顯著發(fā)給更長(zhǎng)的時(shí)間, 因此如果可能的話, 還是建議你維持?jǐn)?shù)據(jù)集原有的字節(jié)格式.

參考:

  • Book , Python Machine Learning.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末到推,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖揭绑,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帜乞,死亡現(xiàn)場(chǎng)離奇詭異搀玖,居然都是意外死亡莉炉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)陕悬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)题暖,“玉大人,你說(shuō)我怎么就攤上這事捉超‰事保” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵拼岳,是天一觀的道長(zhǎng)枝誊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)惜纸,這世上最難降的妖魔是什么叶撒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任绝骚,我火速辦了婚禮,結(jié)果婚禮上痊乾,老公的妹妹穿的比我還像新娘。我一直安慰自己椭更,他們只是感情好哪审,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著虑瀑,像睡著了一般湿滓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上舌狗,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天叽奥,我揣著相機(jī)與錄音,去河邊找鬼痛侍。 笑死朝氓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的主届。 我是一名探鬼主播赵哲,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼君丁!你這毒婦竟也來(lái)了枫夺?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绘闷,失蹤者是張志新(化名)和其女友劉穎橡庞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體印蔗,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扒最,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了华嘹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扼倘。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖除呵,靈堂內(nèi)的尸體忽然破棺而出再菊,到底是詐尸還是另有隱情,我是刑警寧澤颜曾,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布纠拔,位于F島的核電站,受9級(jí)特大地震影響泛豪,放射性物質(zhì)發(fā)生泄漏稠诲。R本人自食惡果不足惜侦鹏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臀叙。 院中可真熱鬧略水,春花似錦、人聲如沸劝萤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)床嫌。三九已至跨释,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厌处,已是汗流浹背鳖谈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阔涉,地道東北人缆娃。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瑰排,于是被迫代替她去往敵國(guó)和親龄恋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 今天看了用主成分分析簡(jiǎn)化數(shù)據(jù)凶伙,就順便用MNIST數(shù)據(jù)集做了下實(shí)驗(yàn)郭毕,想直觀地看一下效果,并通過(guò)完成這個(gè)小demo深入...
    劉開(kāi)心_8a6c閱讀 14,595評(píng)論 10 22
  • 讀取mnist數(shù)據(jù) TRAINING SET IMAGE FILE (train-images-idx3-ubyt...
    大魔王是本人閱讀 430評(píng)論 0 0
  • 我叫陳醉函荣,今年37歲显押,是一間文玩店的老板,生活在中國(guó)最休閑的城市傻挂,閑都乘碑。 我的店開(kāi)在老城區(qū),一個(gè)叫做海椒市的地方金拒。...
    乖乖Alisa閱讀 520評(píng)論 0 1
  • 1兽肤、每天一秒鐘 講師:Cesar Kuriyama 授課語(yǔ)言:英文 類型:藝術(shù) TED 課程簡(jiǎn)介:你的生命中曾經(jīng)有...
    妖精sama閱讀 797評(píng)論 0 2