今天使用的toolkit是Keras,使用的資料集是MNIST的data,而Keras提供了自動下載MNIST data的function。
今天要實作一個最基本的Fully connected feedforward Network,做的是手寫數字辨識,用這個範例來當作我們深度學習的"Hello world"。
舉例來說,我們要建一個Network的Structure,它的輸入是一張解析度是28x28的圖片,而我們把它拉直變成一個28x28維的向量,中間有兩個hidden layer,然後每一個layer都有500個Neuron,最後輸出是10維的向量,分別對應0~9的數字。
首先要先宣告一個model。
model = sequential()
接著要把第一個hidden layer加進去,就使用"add"指令,而後面加了一個"Dense"的意思是你加的是一個Fully connected的layer,"input_dim"就是要設定輸入的維度是多少,"units"是代表你的Neuron有幾個,最後是"activation",就是你要使用什麼Activation function。
model.add(Dense(input_dim=28 * 28, units=500, activation='relu'))
再加入第二個layer,這時候就不用再宣告輸入的維度了,因為第二個layer的輸入維度就是前一個layer的unit,不需要再定義一次,所以你只需要再宣告第二個layer會有多少個unit。
model.add(Dense(units=500, activation='relu'))
而最後一個layer,因為輸出要是10個數字,所以最後一個layer的輸出一定要是10維,所以unit就設10,然後Activation function我們通常會用softmax,使用softmax意味著輸出的每一個維度的值都會介於0~1之間且總和是1,就可以當作是機率來看待。
model.add(Dense(units=10, activation='softmax'))
接下來我們要評估一個function的好壞。
使用"compile",定義你的Loss function。
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
在訓練之前你要先給一些Configuration告訴它你訓練的時候要怎麼做,所以你第一個要給的東西是optimizer,也就是說,你要找最好的function的時候,你要用什麼樣的方式來找到最好的function。雖然這邊optimizer的後面可以接不同的方式,但是這些方式其實都是基於Gradient Descent的方法,只是有一些方法是機器會自動決定Learning rate的值。
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
接著你就可以開始訓練你的Network,使用"fit",就可以用Gradient Descent來訓練你的Network,其中要給它你的訓練資料的輸入還有Label,"x_train"代表圖片,"y_train"代表Label,然後再設定Batch size以及Epochs的大小。
model.fit(x_train, y_train, batch_size=100, epochs=20)
訓練好之後,你要拿這個model來做評估,意思就是說你實際上有測試資料的label,你只是想要知道你model在測試資料的表現如何,那就使用"evaluation",只要把測試資料的圖片跟Label給它,它就會幫你計算你的model的正確率。而它會輸出一個二維的向量,第一個維度會是在測試資料上的Loss,第二個維度是在測試資料上的Accuracy。
result_train = model.evaluate(x_train, y_train)
result_test = model.evaluate(x_test, y_test)
print('Train Acc:', result_train[1])
print('Test Acc:', result_test[1])
那有可能你是要做預測,意思是說你沒有正確答案,你要去預測它的結果是多少,所以就使用"predict"並給它測試的圖片。
result = model.predict(x_test)
import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
from keras.datasets import mnist
def load_data(): # categorical_crossentropy
(x_train, y_train), (x_test, y_test) = mnist.load_data()
number = 10000
x_train = x_train[0:number]
y_train = y_train[0:number]
x_train = x_train.reshape(number, 28 * 28)
x_test = x_test.reshape(x_test.shape[0], 28 * 28)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)
x_train = x_train
x_test = x_test
# x_test = np.random.normal(x_test)
x_train = x_train / 255
x_test = x_test / 255
return (x_train, y_train), (x_test, y_test)
if __name__ == '__main__':
# load training data and testing data
(x_train, y_train), (x_test, y_test) = load_data()
# define network structure
model = Sequential()
model.add(Dense(input_dim=28 * 28, units=500, activation='relu'))
# model.add(Dropout(0.5))
model.add(Dense(units=500, activation='relu'))
# model.add(Dropout(0.5))
model.add(Dense(units=10, activation='softmax'))
# set configurations
model.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
# train model
model.fit(x_train, y_train, batch_size=100, epochs=20)
# evaluate the model and output the accuracy
result_train = model.evaluate(x_train, y_train)
result_test = model.evaluate(x_test, y_test)
print('Train Acc:', result_train[1])
print('Test Acc:', result_test[1])
李宏毅老師 - ML Lecture 8-1
李宏毅老師 - ML Lecture 8-2
李宏毅老師 - ML Lecture 8-3