如何用卷積神經網路CNN識別手寫數字集BaseLine版本 超級小白註釋
阿新 • • 發佈:2018-12-12
如何用卷積神經網路CNN識別手寫數字集?
由於剛剛開始學習機器學習方面的知識,網上很多基礎的教程真的看不懂,所以只能自己一點點摸索,一篇很簡單的程式碼,可能我也要看很久QAQ,原博主的程式碼對於我來說可能還是很懵逼,因此自己加了很多註釋,希望可以幫到和我一樣的初學者。
# coding:utf-8
# Baseline MLP for MNIST dataset
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
seed = 7
numpy.random.seed(seed)
# 如果在seed()中傳入的數字相同,那麼接下來使用random()
# 或者rand()方法所生成的隨機數序列都是相同的(僅限使用一次random()或者rand()方法,
# 第二次以及更多次仍然是隨機的數字),知道改變傳入seed()的值,以後再改回來,
# random()生成的隨機數序列仍然與之前所產生的序列相同(好像沒用)
# 載入資料
(X_train, y_train), (X_test, y_test) = mnist.load_data()
# y_train和y_test分別對應著矩陣對應的標籤0-9,X_train和X_test對應著數字灰度值矩陣28*28
num_pixels = X_train.shape[1] * X_train.shape[2] # shape是:(60000, 28, 28),則shape[1]和shape[2]是28,28,即28*28解析度
X_train = X_train.reshape(X_train.shape[0], num_pixels).astype('float32') # (60000, 28, 28)->(60000, 784) 二維圖片灰度值換成一維
X_test = X_test.reshape(X_test.shape[0], num_pixels).astype('float32')
X_train = X_train / 255
X_test = X_test / 255
# 對輸出進行one hot編碼
y_train = np_utils.to_categorical(y_train)
# 會把y_train中的矩陣數字換為另一種表示方式:如0->[1,0,0,0,0,0,0,0,0,0]
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1] # 轉換後的one-hot數字種類的個數即10
# MLP模型
def baseline_model():
model = Sequential()
'''
傳遞一個input_shape的關鍵字引數給第一層,input_shape是一個tuple型別的資料,其中也可以填入None,
如果填入None則表示此位置可能是任何正整數。資料的batch大小不應包含在其中。
有些2D層,如Dense,支援通過指定其輸入維度input_dim來隱含的指定輸入資料shape,是一個Int型別的資料。
一些3D的時域層支援通過引數input_dim和input_length來指定輸入shape。
如果你需要為輸入指定一個固定大小的batch_size(常用於stateful RNN網路),可以傳遞batch_size引數到一個層中,
例如你想指定輸入張量的batch大小是32,資料shape是(6,8),則你需要傳遞batch_size=32和input_shape=(6,8)。
'''
model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu'))
model.add(Dense(num_classes, init='normal', activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
'''在訓練模型之前,我們需要通過compile來對學習過程進行配置。compile接收三個引數:
優化器optimizer:該引數可指定為已預定義的優化器名,如rmsprop、adagrad,或一個Optimizer類的物件,詳情見optimizers
損失函式loss:該引數為模型試圖最小化的目標函式,它可為預定義的損失函式名,如categorical_crossentropy、mse,也可以為一個損失函式。詳情見losses
指標列表metrics:對分類問題,我們一般將該列表設定為metrics=['accuracy']。指標可以是一個預定義指標的名字,也可以是一個使用者定製的函式.
指標函式應該返回單個張量,或一個完成metric_name - > metric_value對映的字典.請參考性能評估
metrics:列表,包含評估模型在訓練和測試時的網路效能的指標,典型用法是metrics=['accuracy']
'''
return model
# 建立模型
model = baseline_model()
# Fit
model.fit(X_train, y_train, validation_data=(X_test, y_test), nb_epoch=10, batch_size=200, verbose=2)
'''
fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0,
validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
本函式將模型訓練nb_epoch輪,其引數有:
x:輸入資料。如果模型只有一個輸入,那麼x的型別是numpy array,如果模型有多個輸入,那麼x的型別應當為list,list的元素是對應於各個輸入的numpy array
y:標籤,numpy array
batch_size:整數,指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降,使目標函式優化一步。
epochs:整數,訓練終止時的epoch值,訓練將在達到該epoch值時停止,當沒有設定initial_epoch時,它就是訓練的總輪數,否則訓練的總輪數為epochs - inital_epoch
verbose:日誌顯示,0為不在標準輸出流輸出日誌資訊,1為輸出進度條記錄,2為每個epoch輸出一行記錄
callbacks:list,其中的元素是keras.callbacks.Callback的物件。這個list中的回撥函式將會在訓練過程中的適當時機被呼叫,參考回撥函式
validation_split:0~1之間的浮點數,用來指定訓練集的一定比例資料作為驗證集。驗證集將不參與訓練,並在每個epoch結束後測試的模型的指標,如損失函式、精確度等。注意,validation_split的劃分在shuffle之前,因此如果你的資料本身是有序的,需要先手工打亂再指定validation_split,否則可能會出現驗證集樣本不均勻。
validation_data:形式為(X,y)的tuple,是指定的驗證集。此引數將覆蓋validation_spilt。
shuffle:布林值或字串,一般為布林值,表示是否在訓練過程中隨機打亂輸入樣本的順序。若為字串“batch”,則是用來處理HDF5資料的特殊情況,它將在batch內部將資料打亂。
class_weight:字典,將不同的類別對映為不同的權值,該引數用來在訓練過程中調整損失函式(只能用於訓練)
sample_weight:權值的numpy array,用於在訓練時調整損失函式(僅用於訓練)。可以傳遞一個1D的與樣本等長的向量用於對樣本進行1對1的加權,或者在面對時序資料時,傳遞一個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請確定在編譯模型時添加了sample_weight_mode='temporal'。
initial_epoch: 從該引數指定的epoch開始訓練,在繼續之前的訓練時有用。
'''
# Evaluation
scores = model.evaluate(X_test, y_test, verbose=0)
'''
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
本函式按batch計算在某些輸入資料上模型的誤差,其引數有:
x:輸入資料,與fit一樣,是numpy array或numpy array的list
y:標籤,numpy array
batch_size:整數,含義同fit的同名引數
verbose:含義同fit的同名引數,但只能取0或1
sample_weight:numpy array,含義同fit的同名引數
本函式返回一個測試誤差的標量值(如果模型沒有其他評價指標),或一個標量的list(如果模型還有其他的評價指標)。model.metrics_names將給出list中各個值的含義。
如果沒有特殊說明,以下函式的引數均保持與fit的同名引數相同的含義
如果沒有特殊說明,以下函式的verbose引數(如果有)均只能取0或1'''
print("Baseline Error: %.2f%%" % (100 - scores[1] * 100)) # 輸出錯誤率