1. 程式人生 > >【Keras】MLP多層感知機

【Keras】MLP多層感知機

在進行神經網路模型的構建時,有優化模型訓練速度的技巧,以下從兩個方面進行分析。並在接下來實現MLP的模型中應用。

1、優化梯度下降

之前使用的梯度下降訓練模型,優化模型的引數,但是每次更新梯度時需要把資料集中的每個樣本都重新計算一邊,在海量計算的深度學習中,這個計算量非常的大。

因此引入隨機梯度的思想,隨機抽取一批資料進行計算(資料量引數是:batch_size),這樣計算量會大大減少,但是並不能保證計算出來的梯度方向正確。對於彎路問題,可以增加迭代次數補償(iteration),因為只要迭代次數足夠多,那麼梯度下降最終也會朝著正確的方向優化引數。這種方法就是SGD演算法(隨機梯度下降)。

在SGD的基礎上,梯度下降的過程中還有兩個地方可以優化:
a>通過動量(引數:momentum),優化“彎路”軌跡。比如快取一個之前的梯度的平均值,每次梯度更新時都和之前的平均梯度想加。
b>優化梯度下降時每一步的步長,或者受學習速率(learning rate,引數lr),一種思路是將lr**指數衰減,內在思想是當引數越接近理想點時學習的過程應該越謹慎。還有一個思路就是將學習速率的大小和損失函式輸出值掛鉤。大體上所有的學習速率優化的方式都是學習速率隨著學習的過程不斷減小**。

隨機批量資料(batch)、梯度動量(momentum)和學習速率引數(learning rate)是優化梯度下降的三個重要部分。

,常見的RMSprop、Adagrad都是在這三個地方對原始的梯度下降演算法動手術,區別只是具體的實現方式不同。

梯度下降的內容總結:
a.梯度下降需要輸入在同一尺度上可比較。處理手段:對資料集去均值和歸一化,使其滿足0均值,等方差
b.隨機初始化引數權重,初始化的數值滿足0均值,等方差
c.批量訓練資料(batch)
d.動量(momentum)
e.學習速率(learning rate)

2、處理過度擬合(Dropout)

在淺層模型中,處理過擬合的常用手段是減少特徵、增加資料集或者調整模型的L2正則化引數。在深層模型中,可以繼續調節L2正則化引數或者採用(Dropout)。

Dropout的引數設定為0.25,在啟用層之後,Dropout層會隨機抽出1/4的資料集的啟用值更改為0,同時將剩餘神經元的**輸出值等比放大**4/3,使得輸出整體維持量級恆定。相當於使剩餘的神經元負責被扔掉部分神經元的工作,學習了冗餘的表示式。

3、MLP模型實踐

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#from _future_ import print_function
import numpy as np
#from keras.dataseets import mnist
from keras.models import Sequential
from keras.layers.core import Dense,Activation,Dropout
from keras.optimizers import SGD,Adam,RMSprop
from keras.utils import np_utils

'''
一次epoch是指訓練集整體被遍歷一次,根據batch_sized大小決定包含多少個iteration;一次iteration對應的是一個batch資料,這時梯度引數更新一次。也就是說,使用SGD訓練深度學習模型時,訓練集可以被訓練很多次。
'''
batch_size = 128 #梯度下降一個批(batch)的資料量,訓練時拿一個batch的樣本計算一次梯度下降,更新一次梯度。
nb_classes =10 #類別
nb_epoch =10 #梯度下降epoch迴圈訓練次數,每次迴圈包含全部的樣本,也就是模型的訓練資料集全部被訓練的次數
image_size = 28*28 #輸入圖片的大小,由於是灰度圖片,因此只有一個顏色通道
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
#載入資料
x_train,y_train= mnist.train.images, mnist.train.labels
print(y_train)
#print(x_train.shape,y_train.shape) #(55000, 784) (55000, 10)
x_test,y_test= mnist.test.images, mnist.test.labels
#print(x_test.shape,y_test.shape) #(10000, 784) (10000, 10)
#建立模型,邏輯分類相當於一層全連結的神經網路(Dense是Keras中定義的DNN模型)
#model = Sequential([Dense(10,input_shape=(image_size,),activation= 'softmax')])
#建立模型,增加一層包含128個神經網路的隱層,Dense預設activation為linear線性
model = Sequential([Dense(512,input_shape=(image_size,)),
                    Activation('relu'),
                    Dropout(0.2),
                    Dense(512,input_shape = (512,)),
                    Activation('relu'),
                    Dropout(0.2),
                    Dense(10,input_shape = (512,),activation = 'softmax')])

"""編譯的選項引數中,“優化器”是指訓練模型時使用哪種方式優化模型引數,這些優化演算法基本
上都是各種變種的梯度下降演算法,這裡選擇SGD(隨機梯度下降)。“loss”是指選擇那種損失函式,這裡選擇多類別交叉熵。"""
model.compile(optimizer = 'rmsprop',loss = 'categorical_crossentropy',metrics= ['accuracy'])
#模型的訓練函式:fit函式通過sample_per_epoch 和 nb_epoch 兩個引數來確定什麼時候訓練終止,這兩個引數指定了每個epoch包含多少個樣本以及要訓練多少個epoch。
model.fit(x_train,y_train,batch_size = batch_size,nb_epoch = nb_epoch,verbose = 1,validation_data = (x_test,y_test))
#模型評估
score = model.evaluate(x_test,y_test,verbose = 0)
#score分數包含兩部分,一部分是val_loss,一部分是val_acc。取score[1]來進行模型的得分評價
print('Accuracy:{}'.format(score[1]))