學習人工智慧少不了需要一些資料集,例如進行鑑黃的人工智慧少不了一些類似的圖片。進行語音辨識的人工智慧,語料庫是少不了的。對於初學人工智慧的同學常常會為資料集而煩惱。今天我們就介紹一個很簡單,但很有用的資料集,這就是MNIST。這個資料集非常適合我們進行人工智慧相關演算法的學習和練習。
MNIST 資料集是美國國家標準與技術研究所(National Institute of Standards and Technology,簡稱NIST)製作的一個非常簡單的資料集。那麼該資料集是什麼內容呢?其實就是一些手寫的阿拉伯數字(0到9十個數字)。
NIST在製作資料集的時候還是很認真的。資料集中的訓練集 (training set) 由來自 250 個不同人手寫的數字構成,其中 50%是高中學生,50% 來自人口普查局 (the Census Bureau) 的工作人員。測試集(test set) 也是同樣比例的手寫數字資料。
MNIST資料集可從其官網(http://yann.lecun.com/exdb/mnist/ )下載,由於是國外網站,下載可能比較慢。它包含了四個部分:
上述包含兩種類型的內容,一種是圖片,另一種是標籤,圖片與標籤一一對應。但這裡的圖片並非是我們平常看到的圖片文件,而是一個二進位的文件。該資料集以一個二進制的形式對6萬個圖片進行了儲存。標籤則是圖片對應的真是數字。
如下圖所示,本文將資料集下載到本機,並且解壓縮後的結果。為了方便對比,這裡麵包含原始的壓縮包和解壓後的檔案。
大家已經發現,壓縮包解壓縮後並非一個個的圖片,而是每個壓縮包對應著一個獨立的問題。而在這個文件中儲存著上萬個圖片或是標籤的資訊。那麼這些資訊是如何儲存在這個檔案當中的呢?
其實MNIST的官網給了詳細的描述。以訓練集的圖片檔為例,官網給出的文件格式描述如下:
#從上圖可以看出,前4個32位數是該訓練集的描述資訊。其中第一個是魔數,為固定值0x0803;第二個是圖片的數量,0xea60,也就是60000;第三個和第四個是圖片的大小,也就是圖片是28*28像素。下面則是以一個位元組來描述每個像素。由於該檔案中以一個位元組來描述一個像素,可以知道像素的值可以是從0到255。其中0表示白色,而255表示黑色。
標籤檔案的格式與圖片檔案的類似。前面有兩個32位數,其中第一個是魔數,固定值0x0801;第二個用來描述標籤的數量。接下來的資料是每個標籤的值,用一個位元組表示。這裡表示值的範圍是
對應實際訓練集的標籤檔案的資料如下所示。可以看出與上述格式的描述是一致的。另外,我們可以看出,對應該標籤集,前面幾張圖片表示的數字分別應該是5,0,4,1等等。這裡大家記一下,後面會用到。
關於資料集的文件格式我們了解了,下面我們實際操作一下。
知道上述資料的儲存格式後,我們就可以對資料進行解析了。例如下面本文實作了一個小程序,用於解析該圖片集合中的某個圖片,並得到視覺化結果。當然,其實我們可以根據標籤集合的值知道圖片是什麼,這裡只是一個實驗。最終結果是以一個文字檔案儲存的,用字元「Y」表示筆跡,字元「0」表示背景色。具體程式碼很簡單,本文不再贅述。
# -*- coding: UTF-8 -*- def trans_to_txt(train_file, txt_file, index): with open(train_file, 'rb') as sf: with open(txt_file, "w") as wf: offset = 16 + (28*28*index) cur_pos = offset count = 28*28 strlen = 1 out_count = 1 while cur_pos < offset+count: sf.seek(cur_pos) data = sf.read(strlen) res = int(data[0]) #虽然在数据集中像素是1-255表示颜色,这里简化为Y if res > 0 : wf.write(" Y ") else: wf.write(" 0 ") #由于图片是28列,因此在此进行换行 if out_count % 28 == 0 : wf.write("n") cur_pos += strlen out_count += 1 trans_to_txt("../data/train-images.idx3-ubyte", "image.txt", 0)
我們執行上述程式碼,可以得到一個名為image.txt的檔案。可以看到該文件的內容如下。其中紅色筆記是後面添加了,主要是為看的清楚一些。從圖中內容可以看出,這個其實就是手寫的「5」。
前面我們透過原生的Python介面對資料集進行了視覺化的解析。 Python有許多已經實現好的函式庫函數,因此我們可以透過一個函式庫函數簡化上述功能。
採用原生的Python介面實作起來略顯複雜。我們知道Python有很多第三方函式庫,因此我們可以藉助第三方函式庫來實現資料集的解析和展示,具體程式碼如下。
# -*- coding: utf-8 -*- import os import struct import numpy as np # 读取数据集,以二维数组的方式返回图片信息和标签信息 def load_mnist(path, kind='train'): # 从指定目录加载数据集 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: #解析图片信息,存储在images中 magic, num, rows, cols = struct.unpack('>IIII', imgpath.read(16)) images = np.fromfile(imgpath, dtype=np.uint8).reshape(len(labels), 784) return images, labels # 在终端打印某个图片的数据信息 def print_image(data, index): idx = 0; count = 0; for item in data[index]: if count % 28 == 0: print("") if item > 0: print("33[7;31mY 33[0m", end="") else: print("0 ", end="") count += 1 def main(): cur_path = os.getcwd() cur_path = os.path.join(cur_path, "..data") imgs, labels = load_mnist(cur_path) print_image(imgs, 0) if __name__ == "__main__": main()
上述程式碼中分為兩步,第一步是將資料集解析到數組中,第二步是對數組中的某個圖片進行顯示。這裡顯示也是透過文字的方式程序,只不過不是儲存在文件中,而是列印在終端。例如我們依然列印第一張圖片,效果如下:
上述結果的呈現只是透過字元來模擬圖片。其實我們可以藉助第三方函式庫實現更完美的圖片呈現。接下來我們介紹如何透過matplotlib函式庫來呈現圖片。這個庫非常有用,後續還會接觸到這個庫。
我們實作一個
def show_image(data, index): fig, ax = plt.subplots(nrows=1, ncols=1, sharex=True, sharey=True, ) img = data[0].reshape(28, 28) ax.imshow(img, cmap='Greys', interpolation='nearest') ax.set_xticks([]) ax.set_yticks([]) plt.tight_layout() plt.show()
此時可以看到
#實作上述功能的時候可能會缺少一些第三方函式庫,例如matplotlib等。此時需要我們手動進行安裝,具體方法如下:
pip install matplotlib -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
MNIST是如此出名,以至於TensorFlow已經對其進行了支援。因此,我們可以透過TensorFlow對其進行載入和解析。下面我們給出用TensorFlow實作的程式碼。
# -*- coding: utf-8 -*- from tensorflow.examples.tutorials.mnist import input_data import pylab def show_mnist(): # 通过TensorFlow库解析数据 mnist = input_data.read_data_sets("../data", one_hot=True) im = mnist.train.images[0] im = im.reshape(28 ,28) # 进行绘图 pylab.imshow(im, cmap='Greys', interpolation='nearest') pylab.show() if __name__ == "__main__": show_mnist()
該程式碼實現的最終效果與上一個實例一致,這裡不再贅述。
以上是想學習人工智慧,這個的資料集必須掌握,MNIST入門與實戰的詳細內容。更多資訊請關注PHP中文網其他相關文章!