1.1.2 定義網絡結構
1.1.2定義網絡結構
一般認為,深度學習訓練好的模型包括兩部分,一個是對網絡結構的描述,或者稱為對網絡結構的定義;另外一個是每層網絡的具體參數值,這兩部分加起來才是一個完整的深度學習模型。完成數據預處理后,就需要定義網絡結構,或者說對我們的問題進行數學建模。
假設可以通過一條直線,把黑客和正常用戶區分開,即我們認為這個二分類問題是線性問題,如圖1-1所示。設特徵向量為x,對應的標籤為y,使用一個線性函數定義整個網絡:
y=w*x+b
其中w和b就是模型的參數,訓練模型的過程就是疊代求解w和b的過程,通常x是一個多維向量,所以w和b通常也是多維向量。當完成了網絡的定義后,輸入x就可以獲得確定的y,這一過程稱為前向計算過程,或者稱為前向傳播。面對更加複雜的問題,需要使用更加複雜的層來定義網絡。定義網絡時的常用層包括:Dense層、Activation層、Dropout層、Flatten層、Reshape層和Permute層等。
圖1-1區分正常用戶和黑客的二分類問題
1.Dense層
Dense層是最常見的網絡層,用於構建一個全連接。一個典型的全連接結構由輸入、求和、激活、權重矩陣、偏置和輸出組成,如圖1-2所示,訓練的過程就是不斷獲得最優的權重矩陣和偏置(bias)的過程。
圖1-2全連接結構示意圖
了解了全連接的結構后,也不難理解創建Dense層的幾個參數了,例如:
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表示隱藏層節點數。
activation(激活函數)詳細介紹請參見Activation層的相關內容。
use_bias表示是否使用偏置。
2.Activation層
Actiration層對一個層的輸出施加激活函數,常見的激活函數包括以下幾種。
(1)relu
relu函數當輸入小於0時為0,當輸入大於0時等於輸入。使用代碼繪製relu的圖像,獲得圖像(見圖1-3)。
defrelu(x):
ifx>0:
returnx
else:
return0
deffunc4():
x=np.arange(-5.0,5.0,0.02)
y=[]
foriinx:
yi=relu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('yrelu(x)')
plt.title('relu')
plt.plot(x,y)
plt.show()
圖1-3relu函數
(2)leakyrelu
leakyrelu函數是從relu函數發展而來的,當輸入小於0時為輸入乘以一個很小的係數,比如0.1,當輸入大於0時等於輸入。使用代碼繪製leakyrelu的圖像,獲得圖像(見圖1-4)。
defleakyrelu(x):
ifx>0:
returnx
else:
returnx*0.1
deffunc5():
x=np.arange(-5.0,5.0,0.02)
y=[]
foriinx:
yi=leakyrelu(i)
y.append(yi)
plt.xlabel('x')
plt.ylabel('yleakyrelu(x)')
plt.title('leakyrelu')
plt.plot(x,y)
plt.show()
圖1-4leakyrelu圖像
(3)tanh
tanh也稱為雙切正切函數,取值範圍為[–1,1]。tanh在特徵相差明顯時的效果會很好,在循環過程中會不斷擴大特徵效果。tanh的定義如下:
使用代碼繪製tanh的圖像,獲得圖像(見圖1-5)。
x=np.arange(-5.0,5.0,0.02)
y=(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
plt.xlabel('x')
plt.ylabel('ytanh(x)')
plt.title('tanh')
plt.plot(x,y)
plt.show()
圖1-5tanh圖像
(4)sigmoid
sigmoid可以將一個實數映射到(0,1)的區間,可以用來做二分類。sigmoid的定義如下:
使用代碼繪製sigmoid的圖像,獲得圖像(見圖1-6)。
圖1-6sigmoid圖像
x=np.arange(-5.0,5.0,0.02)
y=1/(1+np.exp(-x))
plt.xlabel('x')
plt.ylabel('ysigmoid(x)')
plt.title('sigmoid')
plt.plot(x,y)
plt.show()
Activation層可以單獨使用,也可以作為其他層的參數,比如創建一個輸入大小為784,節點數為32,激活函數為relu的全連接層的代碼為:
model.add(Dense(32,input_shape=(784,)))
model.add(Activation('relu'))
等價於下列代碼:
model.add(Dense(32,activation='relu',input_shape=(784,)))
3.Dropout層
在深度學習中,動輒幾萬的參數需要訓練,非常容易造成過擬合,通常為了避免過擬合,會在每次訓練的時候隨機選擇一定的節點,使它們臨時失效,形象的比喻是,好比每次識別圖像的時候,隨機地擋住一些像素,遮擋適當比例的像素不會影響圖像的識別,但是卻可以比較有效地抑制過擬合。Dropout層的定義如下:
keras.layers.core.Dropout(rate,noise_shape=None,seed=None)
其中,常用的參數就是rate,表示臨時失效的節點的比例,經驗值為0.2~0.4比較合適。
4.Embedding層
Embedding層負責將輸入的向量按照一定的規則改變維度,有點類似於Word2Vec的處理方式,把詞可以映射到一個指定維度的向量中,其函數定義如下:
keras.layers.Embedding(input_dim,output_dim,
embeddings_initializer='uniform',embeddings_regularizer=None,
activity_regularizer=None,embeddings_constraint=None,mask_zero=False,
input_length=None)
其中比較重要的參數為:
input_dim:輸入的向量的維度。
output_dim:輸出的向量的維度。
embeddings_initializer:初始化的方式,通常使用glorot_normal或者uniform。
5.Flatten層
Flatten層用來將輸入壓平,即把多維的輸入一維化。
6.Permute層
Permute層將輸入的維度按照給定模式進行重排。一個典型場景就是在Keras處理圖像數據時,需要根據底層是TensorFlow還是Theano調整像素的順序。在TensorFlow中圖像保存的順序是(width,height,channels)而在Theano中則為(channels,width,height),比如MNIST圖像,在TensorFlow中的大小就是(28,28,1),而在Theano中是(1,28,28)。示例代碼如下:
ifK.image_dim_ordering()=='tf':
#(width,height,channels)
model.add(Permute((2,3,1),input_shape=input_shape))
elifK.image_dim_ordering()=='th':
#(channels,width,height)
model.add(Permute((1,2,3),input_shape=input_shape))
else:
raiseRuntimeError('Unknownimage_dim_ordering.')
7.Reshape層
Reshape層用於將輸入shape轉換為特定的shape。函數定義如下代碼所示:
keras.layers.core.Reshape(target_shape)
其中target_shape為希望轉換成的形狀,比如圖片的大小為(1,28,28,1),但是網絡的輸入大小為(1,784)時就需要使用Reshape層。