Keras是一套基於Tensorflow、Theano及CNTK後端的高層神經網絡API,能夠很是友好地支持快速實驗,本文從零開始介紹瞭如何使用Keras搭建MLP並給出兩個示例。linux
具體安裝過程在官方中英文文檔中有詳細說明
中文 https://keras-cn.readthedocs.io/en/latest/for_beginners/keras_linux/
英文 https://keras.io/#installationshell
能夠認爲Keras中的所謂模型(models)就是某個具體的網絡結構,如MLP、CNN、LSTM等,在Keras中它們被分爲兩種:序貫模型(Sequential)和函數式模型(Model)。ubuntu
Sequential模型就是一個直接由若干網絡層線性堆疊起來的網絡,使用以下代碼建立一個Sequential對象:後端
from keras.models import Sequential model = Sequential()
Sequential的構造函數能夠接收一個由layer組成的list,用以初始化該model網絡
model = Sequential([ Dense(32, input_shape=(784,)),#一個Dense層 Activation('relu'),#爲上一個Dense層附加激活函數 Dense(10),#再添加一個Dense層 Activation('softmax'),#爲上一個Dense層附加激活函數 ])
也可使用.add()方法對該model初始化:dom
model.add(Dense(32, input_shape=(784,))) model.add(Activation('relu'))
Dense layer即全鏈接層,構造方法以下:函數
keras.layers.core.Dense( units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
units:大於0的整數,表示該層輸出維度。
activation:激活函數。
use_bias:是否使用偏置。
kernel_initializer:權值矩陣初始化方法。
bias_initializer:偏置的初始化方法。
regularizer與constraint:正則項與約束項。學習
咱們可使用前文提到的.add()方法爲model添加全鏈接層,只有輸入層須要指定輸入數據維度,以後的層不需再指定前一層的維度。測試
model的結構設置好以後使用compile方法編譯:優化
model.compile( self, optimizer, loss, metrics=None, sample_weight_mode=None)
optimizer:預約義的優化器名稱或自定義的優化器對象。
loss:預約義的損失函數名稱或自定義的目標函數。
編譯後使用fit方法訓練模型:
model.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)
x:做爲輸入數據的numpy array。
y:做爲標籤的numpy array。
batch_size:梯度降低時每一個batch包含的樣本數。
epochs:訓練總輪數。
verbose:日誌顯示,0爲不在標準輸出流輸出日誌信息,1爲輸出進度條記錄,2爲每一個epoch輸出一行記錄。
一個線性迴歸模型能夠被認爲是一個MLP的特例,即一個輸入與輸出只有1維且沒有激活函數(或激活函數爲線性函數a(x)=x)的MLP,咱們首先生成一些離散的點,使這些點大體成線性關係,再構建一個Sequential model,最後在這些點上訓練該model以獲得它們的線性關係。
import numpy as np from keras.models import Sequential from keras.layers import Dense from keras import optimizers data_size = 50 # 生成的數據集大小 batch_size = 40 learning_rate = 0.01 epochs = 300 # 在正負1之間均勻產生data_size個點 x_train = np.linspace(-1, 1, data_size) # 使得數據點呈y=3x+5的關係,添加小範圍正態隨機數以得到數據的隨機波動效果 y_train = 3 * x_train + 5 + np.random.rand(*x_train.shape)*0.3 # 建立一個Sequential模型 model = Sequential() # 添加一個全鏈接層,輸入數據維度爲1,含一個輸出單元,RandomUniform表示權值在正負0.05間均勻隨機初始化 model.add(Dense(units=1, input_dim=1, kernel_initializer='RandomUniform')) # 打印查看當前的權重 print(model.layers[0].get_weights()) # 建立一個SGD對象以調整學習速率 sgd = optimizers.SGD(lr=learning_rate) # 編譯model,優化器使用剛建立的SGD對象,損失函數使用最小均方差mse model.compile(optimizer=sgd, loss='mse') # 使用以前生成的數據訓練 history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1) # 再次打印權重,能夠看到其值在3與5附近 print(model.layers[0].get_weights())
結果:
... Epoch 298/300 50/50 [==============================] - 0s 36us/step - loss: 0.0325 Epoch 299/300 50/50 [==============================] - 0s 45us/step - loss: 0.0264 Epoch 300/300 50/50 [==============================] - 0s 56us/step - loss: 0.0260 [array([[2.9937706]], dtype=float32), array([5.0084023], dtype=float32)]
有趣的是,當咱們調整數據點的範圍,將
x_train = np.linspace(-1, 1, data_size)
改成
x_train = np.linspace(-25, 25, data_size)
保持其餘部分不變,再次運行程序訓練,loss會振盪到無窮到致使訓練失敗,這是學習率過大形成的,將learning_rate由0.01改成0.003,再次訓練,便可獲得正確結果。
咱們還能夠加入一個隱層,調整學習率與epochs後也能夠獲得很好的訓練結果:
import numpy as np from keras.models import Sequential from keras.layers import Dense from keras import optimizers data_size = 50 batch_size = 40 learning_rate = 0.0003 epochs = 500 x_train = np.linspace(-25, 25, data_size) y_train = 3 * x_train + 5 + np.random.rand(*x_train.shape)*0.3 model = Sequential() #這裏的units爲4,即隱層單元個數爲4 model.add(Dense(units=4, input_dim=1, kernel_initializer='RandomUniform')) #再添加輸出層,維度爲1 model.add(Dense(units=1, kernel_initializer='RandomUniform')) print(model.layers[0].get_weights()) print(model.layers[1].get_weights()) sgd = optimizers.SGD(lr=learning_rate) model.compile(optimizer=sgd, loss='mse') history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1) print(model.layers[0].get_weights()) print(model.layers[1].get_weights())
結果:
Epoch 498/500 50/50 [==============================] - 0s 119us/step - loss: 0.0169 Epoch 499/500 50/50 [==============================] - 0s 156us/step - loss: 0.0168 Epoch 500/500 50/50 [==============================] - 0s 85us/step - loss: 0.0182 [array([[ 0.8122992 , -0.08030439, -0.05526135, -1.0514123 ]], dtype=float32), array([ 1.110988 , -0.11047827, -0.07585457, -1.4386528 ], dtype=float32)] [array([[ 1.3721825 ], [-0.13642032], [-0.09367472], [-1.7768502 ]], dtype=float32), array([0.968823], dtype=float32)]
結果中兩個list中的第一個array是權值,第二個array是偏置。
在Keras安裝路徑下的examples文件夾中能夠找到mnist_mlp.py:
from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import RMSprop batch_size = 128 num_classes = 10 epochs = 20 #讀取mnist的訓練與測試數據 (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train = x_train.reshape(60000, 784) x_test = x_test.reshape(10000, 784) #整型轉爲浮點型 x_train = x_train.astype('float32') x_test = x_test.astype('float32') #歸一到(0,1)區間內 x_train /= 255 x_test /= 255 print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convert class vectors to binary class matrices y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) #使用了兩個隱層,每一個隱層512個單元,激活函數選用relu,添加了Dropout防止過擬合,最後經過softmax輸出 model = Sequential() model.add(Dense(512, activation='relu', input_shape=(784,))) model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) model.add(Dense(num_classes, activation='softmax')) model.summary() #損失函數選用多分類對數損失函數,優化器選用RMSprop model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy']) history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
結果:
... 59392/60000 [============================>.] - ETA: 0s - loss: 0.0183 - acc: 0.99 59776/60000 [============================>.] - ETA: 0s - loss: 0.0182 - acc: 0.99 60000/60000 [==============================] - 15s 253us/step - loss: 0.0182 - acc: 0.9953 - val_loss: 0.1072 - val_acc: 0.9842 Test loss: 0.10721807914278024 Test accuracy: 0.9842