MNIST手寫數字辨識資料集
MNIST手寫數字辨識資料集,是由Yann LeCun(揚·勒丘恩)大神所蒐集,這位大神同時也是Convulution Nueral Networks(卷積神經網絡)的創始人,因此享有"卷積網絡之父"的美譽。關於這位大神的事蹟在維基百科上有詳細的介紹,再者裡就不在多做闡述。由於MNIST的資料大小適中,而且皆為單色影像(黑字白底),十分適合做為初學者第一個建立模型、訓練、與預測的資料集。
MNIST資料集是由60,000筆訓練資料、10,000筆測試資料所組成。MNIST資料集裡的每一筆資料皆由images(數字的影像)與labels(該圖片的真實數字,其實就是答案)所組成,示意圖如圖表1。
圖表1. MNIST資料集的組成 |
下載MNIST資料
Step1. 匯入Keras與其它需要使用的模組
首先先匯入Keras與其它模組,程式碼與相關註解如下:
#匯入Keras及相關模組 import numpy as np #匯入numpy模組,NumPy是Python語言的擴充程式庫。支援維度陣列與矩陣運算 import pandas as pd from keras.utils import np_utils #匯入keras.utils因為後續要將label標籤轉換為One-hotencoding np.random.seed(10) #設定seed可以讓每次需要隨機產生的資料,都有相同的輸出
Step2. 匯入Keras模組中的mnist
在Keras中已經預設提供mnist,可以直接匯入並使用資料,在這裡先將minst匯入,程式碼與相關註解如下:
from keras.datasets import mnist #匯入Keras的mnist模組
Step3. 第一次執行程式並下載mnist資料
當執行mnist.load_data()程式碼,程式會先去檢查使用者目錄下的.keras\datasets資料夾中是否存在mnist.npz這個檔案,如果回傳值為空則會自動開始下載。檔案大小為10.9MB,因此程式需要耗費一些時間去完成。程式碼與相關註解如下:
#下載minst資料集檔案 #資料集檔案位置:C:\Users\alanjian\.keras\datasets\mnist.npz (x_train_image, y_train_label),\ (x_test_image, y_test_label) = mnist.load_data()
Step4. 在Windows系統中查看mnist.npz檔案
mnist.npz檔案的路徑位置為C:\Users\alanjian\.keras\datasets\mnist.npz,因為我的使用者名稱是alanjian,因此會存放在alanjian資料夾裡的.keras目錄中。檔案位置路徑示意圖如圖表2:圖表2. mnist.npz的位置路徑 |
Step5. 查看mnist資料組成
在程式下載完mnist.npz檔案後,我們可以查看minst的資料集組成,輸出結果表示minst由60,000筆的train data(訓練資料)與10,000筆的test data(訓練資料)所組成,程式碼如下:
#查看mnist資料集筆數 print('train data=', len(x_train_image)) print('test data=', len(x_test_image))
顯示單筆mnist資料內容
Step1. 每一筆mnist資料的組成方式
每一筆mnist資料皆是由images(數字影像)與labels(數字真實值)所組成,images的部分為單色、28*28像素的影像檔案(圖片),label則是該張影像檔案的真實數值(解答),程式碼如下:
print('x_train_image :', x_train_image.shape) #x_train_image : (60000, 28, 28) print('y_train_label :', y_train_label.shape) #共60000張圖片資料,圖片像素28*28
Step2. 使用matplotlib輸出images數字影像
為了能夠顯示images數字影像,我們使用matplotlib工具將images輸出首先匯入matplotlib模組,程式碼如下:
import matplotlib.pyplot as plt #匯入matplotlib.pyplot模組
Step3.建立plot_image()函式
撰寫plot_image()函式,實作將images輸出方法,程式碼如下:
#建立plot_image函數,顯示images數字影像 def plot_image(image): #定義plot_image函數,傳入image作為參數 fig = plt.gcf() #設定顯示圖形的大小 fig.set_size_inches(2,2) plt.imshow(image, cmap='binary') #傳入參數image、28*28像素的圖形,camp="binary"表示以黑白色顯示 plt.show() #顯示圖片
Step4. 呼叫plot_image()函式顯示第1筆數字影像資料
接下來我們呼叫Step3.建立的plot_image()函式,顯示出第mnist資料及的第1筆資料,程式碼如下:
#呼叫plot_image,顯示mnist.train.images[1]的資料圖片 plot_image(x_train_image[1])
執行後的輸出結果如下圖表3:
|
圖表3. mnist資料集第1筆資料的圖形影像 |
Step5.查看第1筆的label資料內容
第1筆label資料是第1筆數字影像的真實值,所以是0,程式碼與輸出結果如圖表4:y_train_label[1]
圖表4. mnist資料集第1筆資料的真實值 |
顯示多筆mnist資料內容
Step.1 匯入matplotlib模組並建立plot_images_labels()函數
#匯入matplotlib.pyplot模組內容 import matplotlib.pylot as plt #顯示資料集內容 def plot_images_labels(images, labels, idx, num = 10): #定義plot_images_labels_prediction()函式 fig = plt.gcf() #設定顯示圖形的大小 fig.set_size_inches(12, 14) if num > 25: num = 25 #如果顯示筆數參數大於25鎖定在25,避免輸出時發生錯誤 for i in range(0, num): ax = plt.subplot(5, 5, 1+i) #建立subgraph子圖形為5行5列 ax.imshow(images[idx], cmap='binary') #劃出subgraph子圖形 title = "label=" + str(labels[idx]) #設定子圖形的title,顯示標籤欄 ax.set_title(title, fontsize = 10) #子圖形的標題tilte與大小 ax.set_xticks([]);ax.set_yticks([]) #設定不顯示刻度 idx += 1 #讀取下一筆 plt.show() #開始繪圖
Step2. 查看訓練資料集前10筆資料
執行plot_images_labels()函式,將訓練資料集的前10筆。輸入x_test_image, y_test_label,由第0筆開始顯示至第9筆,程式碼如下:
#顯示第0到第9訓練資料 plot_images_labels(x_train_image, y_train_label, idx=0)
Step3.查看測試資料集前10筆資料
同樣使用plot_images_labels()顯示第0到第9共10筆資料,程式碼如下:#顯示第0到第9筆測試資料 plot_images_labels(x_test_image, y_test_label, idx=0)
MINST資料預處理---features(數字影像的特徵值)
對features的資料預處理可以分為下列2部分:
1. 將原本28*28的2維數字影像,以reshape函式轉換為1維的向量。並且以float(浮點數)的型態儲存於向量中。
2. 將一維向量裡的數值正規化(Normalization)。
Step1. 將image以reshape()函式轉換
我們使用reshape()函式將原本28*28的二維數字影像,轉換維1維的向量,接著使用astype()函示轉換為float(浮點數)後儲存,程式碼如下:
#將image以reshape()轉換 #先將原本28*28的2維數字影像,以reshape()轉換成1維向量,再以astype()轉換為float,共784個float數字 x_Train = x_train_image.reshape(60000, 28*28).astype('float32') x_Test = x_test_image.reshape(10000, 28*28).astype('float32')
Step2. 查看轉換為1維向量的內容
我們可以使用print()函式來查看每個數字影像的內容,shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数。輸出結果如圖表5.,程式碼如下:
#查看轉換為1維向量的shape print('x_train:', x_Train.shape) print('x_train:', x_Test.shape)
圖表5. 轉換為1維向量的shape |
Step3. 查看每筆imgaes的影像內容
我們可以透過x_train_images[0]直接呼叫並查看images中第0筆的內容,程式碼如下:
#查看image第0筆的內容 #每個數字由0至255組成,代表圖形每一個點的灰階深淺 x_train_image[0]
Step4. 將images數字影像的特徵值正規化
透過正規化,可以提高後續訓練模型的準確率,因為images的數字位於0到255區間,因此最直接正規化方法就是除以255。程式碼如下:
#將數字影像image的數值正規化(normalization) x_Train_normalization = x_Train / 255 x_Test_normalization = x_Test / 255
Step5. 查看正規化後的image內容
如同Step3.,直接透過x_Train_normalize[0]可以查看正規化後的內容:
#查看標準化後的image第0筆的內容 x_Train_normalization[0]
MINST資料預處理---labels(數字影像的真實值)
label標籤欄位原本是0~9的數字,必須透過One-hot encoding模組轉換為10個0到1的組合,例如:數字5經由One-hot encoding轉換後為0000010000。10個位數正好對應到輸出層10個神經元。
Step1. 查看原本的label標籤欄位
透過y_train_label[:5]指令,可以查看訓練資料label欄位的前五筆資料,我們可以看到目前顯示的是0~9的數字。輸出如圖表6.,程式碼如下:
#查看訓練資料label標籤欄位的前五筆訓練資料 y_train_label[:5]
圖表6. One-hot encoding的轉換結果 |
Step2. 對label標籤欄位執行One-hot encoding轉換
我們使用np_utils.to_categorical分別傳入參數y_train_label(訓練資料)與y_test_label(測試資料)的label標籤欄位,並執行One-hot encoding轉換,程式碼如下:
#使用np_utils.to_categorical()分別傳入y_train_label與y_test_label的label標籤欄位,執行One-hot encoding轉換 y_TrainOneHot = np_utils.to_categorical(y_train_label) y_TestOneHot = np_utils.to_categorical(y_test_label)
Step3. 查看label 欄位經One-hot encoding轉換後的結果
執行One-hot encoding轉換之後,查看訓練資料label標籤欄位的前5筆資料。圖表7為轉換後的結果,程式碼如下:
#輸出One-hot encoding轉換結果 y_TrainOneHot[:5]
圖表7. Label經由One-hot encoding轉換後的結果 |
結論
在這篇文章中,我們介紹了如何下載Mnist資料集,接著說明Mnist資料集的內容與特色,並在最後的部分對Mnist資料集完成了資料預處理的工作。在這篇文章中所使用到的完整程式碼如下:
#匯入Keras及相關模組 import numpy as np #匯入numpy模組,NumPy是Python語言的擴充程式庫。支援維度陣列與矩陣運算 import pandas as pd from keras.utils import np_utils #匯入keras.utils因為後續要將label標籤轉換為One-hotencoding np.random.seed(10) #設定seed可以讓每次需要隨機產生的資料,都有相同的輸出 from keras.datasets import mnist #匯入Keras的mnist模組 #下載minst資料集檔案 #資料集檔案位置:C:\Users\alanjian\.keras\datasets\mnist.npz (x_train_image, y_train_label),\ (x_test_image, y_test_label) = mnist.load_data() #查看mnist資料集筆數 print('train data=', len(x_train_image)) print('test data=', len(x_test_image)) print('x_train_image :', x_train_image.shape) #x_train_image : (60000, 28, 28) print('y_train_label :', y_train_label.shape) #共60000張圖片資料,圖片像素28*28 #建立plot_image函數,顯示images數字影像 def plot_image(image): #定義plot_image函數,傳入image作為參數 fig = plt.gcf() #設定顯示圖形的大小 fig.set_size_inches(2,2) plt.imshow(image, cmap='binary') #傳入參數image、28*28像素的圖形,camp="binary"表示以黑白色顯示 plt.show() #顯示圖片 #呼叫plot_image,顯示mnist.train.images[1]的資料圖片 plot_image(x_train_image[1]) y_train_label[1] #匯入matplotlib.pyplot模組內容 import matplotlib.pylot as plt #顯示資料集內容 def plot_images_labels(images, labels, idx, num = 10): #定義plot_images_labels_prediction()函式 fig = plt.gcf() #設定顯示圖形的大小 fig.set_size_inches(12, 14) if num > 25: num = 25 #如果顯示筆數參數大於25鎖定在25,避免輸出時發生錯誤 for i in range(0, num): ax = plt.subplot(5, 5, 1+i) #建立subgraph子圖形為5行5列 ax.imshow(images[idx], cmap='binary') #劃出subgraph子圖形 title = "label=" + str(labels[idx]) #設定子圖形的title,顯示標籤欄 ax.set_title(title, fontsize = 10) #子圖形的標題tilte與大小 ax.set_xticks([]);ax.set_yticks([]) #設定不顯示刻度 idx += 1 #讀取下一筆 plt.show() #開始繪圖 #顯示第0到第9訓練資料 plot_images_labels(x_train_image, y_train_label, idx=0) #顯示第0到第9筆資料 plot_images_labels(x_test_image, y_test_label, idx=0) #將image以reshape()轉換 #先將原本28*28的2維數字影像,以reshape()轉換成1維向量,再以astype()轉換為float,共784個float數字 x_Train = x_train_image.reshape(60000, 28*28).astype('float32') x_Test = x_test_image.reshape(10000, 28*28).astype('float32') #查看轉換為1維向量的shape print('x_train:', x_Train.shape) print('x_train:', x_Test.shape) #查看image第0筆的內容 #每個數字由0至255組成,代表圖形每一個點的灰階深淺 x_train_image[0] #將數字影像image的數值正規化(normalization) x_Train_normalization = x_Train / 255 x_Test_normalization = x_Test / 255 #查看標準化後的image第0筆的內容 x_Train_normalization[0] #查看訓練資料label標籤欄位的前五筆訓練資料 y_train_label[:5] #使用np_utils.to_categorical()分別傳入y_train_label與y_test_label的label標籤欄位,執行One-hot encoding轉換 y_TrainOneHot = np_utils.to_categorical(y_train_label) y_TestOneHot = np_utils.to_categorical(y_test_label) #輸出One-hot encoding轉換結果 y_TrainOneHot[:5]
你好,我想請問一下,在"下載MNIST資料"的STEP3的部分
回覆刪除當執行mnist.load_data()程式碼時,檔案裡沒有MNIST.npz檔,它會自動下載
可是他是從哪下載這個檔案??