天天看點

Keras架構簡介和使用流程一、 Keras架構簡介二、使用流程三、Keras 源碼分析四、keras中model.evaluate , model.predict和model.predict_classes的差別五、部分層的使用

目錄

一、 Keras架構簡介

1. Models包:keras.models

2. Layers包:keras.layers

3. Initializations包:keras.initializations

4. Activations包:keras.activations、keras.layers.advanced_activations(新激活函數)

5. Objectives包:keras.objectives

6. Optimizers包:keras.optimizers

7. Preprocessing包:keras.preprocessing

8. metrics包:keras.metrics

二、使用流程

1、構造資料

2、構造模型

3、編譯模型

4、訓練模型

5、測試資料

6、儲存與讀取模型

7、儲存與加載權重資料

三、Keras 源碼分析

四、keras中model.evaluate , model.predict和model.predict_classes的差別

五、部分層的使用

一、 Keras架構簡介

Keras是基于Theano的一個深度學習架構,它的設計參考了Torch,用Python語言編寫,是一個高度子產品化的神經網絡庫,支援GPU和CPU。使用文檔在這:http://keras.io/,中文文檔在這:http://keras-cn.readthedocs.io/en/latest/ ,這個架構是2015年流行起來的,使用中遇到的困惑或者問題可以送出到github:https://github.com/fchollet/keras。

Keras架構簡介和使用流程一、 Keras架構簡介二、使用流程三、Keras 源碼分析四、keras中model.evaluate , model.predict和model.predict_classes的差別五、部分層的使用

Keras主要包括14個子產品包,可參見文檔https://keras.io/layers/ ,下面主要對Models、Layers、Initializations、Activations、Objectives、Optimizers、Preprocessing、metrics八個子產品包展開介紹。

1. Models包:keras.models

這是Keras中最主要的一個子產品,用于對各個元件進行組裝。

詳細說明:http://keras.io/models/

from keras.models import Sequential

model = Sequential()  # 初始化模型

model.add(...)  # 可使用add方法組裝元件

2. Layers包:keras.layers

該子產品主要用于生成神經網絡層,包含多種類型,如Core layers、Convolutional layers、recurrent layers、advanced_activations layers、normalization layers、embeddings layers等。

其中Core layers裡面包含了flatten(CNN的全連接配接層之前需要把二維特征圖flatten成為一維的)、reshape(CNN輸入時将一維的向量弄成二維的)、dense(隐藏層)。

Convolutional layers層包含Theano的Convolution2D的封裝等。

詳細說明:http://keras.io/layers/

from keras.layers import Dense  # Dense表示BP層

model.add(Dense(input_dim=3,output_dim=5))  # 加入隐含層

3. Initializations包:keras.initializations

該子產品主要負責對模型參數(權重)進行初始化,初始化方法包括:uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal等。

詳細說明:http://keras.io/initializations/

model.add(Dense(input_dim=3,output_dim=5,init='uniform')) #加入帶初始化(uniform)的隐含層

4. Activations包:keras.activations、keras.layers.advanced_activations(新激活函數)

該子產品主要負責為神經層附加激活函數,如linear、sigmoid、hard_sigmoid、tanh、softplus、softmax、relu以及LeakyReLU、PReLU等比較新的激活函數。

詳細說明:http://keras.io/activations/

model.add(Dense(input_dim=3, output_dim=5, activation='sigmoid'))  # 加入帶激活函數(sigmoid)的隐含層

等價于:

model.add(Dense(input_dim=3, output_dim=5))

model.add(Activation('sigmoid'))

5. Objectives包:keras.objectives

該子產品主要負責為神經網絡附加損失函數,即目标函數。如mean_squared_error,mean_absolute_error ,squared_hinge,hinge,binary_crossentropy,categorical_crossentropy等,其中binary_crossentropy,categorical_crossentropy是指logloss。

注:目标函數的設定是在模型編譯階段。

詳細說明:http://keras.io/objectives/

model.compile(loss='binary_crossentropy', optimizer='sgd') #loss是指目标函數

6. Optimizers包:keras.optimizers

該子產品主要負責設定神經網絡的優化方法,如最基本的随機梯度下降SGD,另外還有Adagrad、Adadelta、RMSprop、Adam,一些新的方法以後也會被不斷添加進來。

詳細說明:http://keras.io/optimizers/

keras.optimizers.SGD(lr=0.01, momentum=0.9, decay=0.9, nesterov=False)

上面的代碼是SGD的使用方法,lr表示學習速率,momentum表示動量項,decay是學習速率的衰減系數(每個epoch衰減一次),Nesterov的值是False或者True,表示使不使用Nesterov momentum。

model = Sequential()

model.add(Dense(64, init='uniform', input_dim=10))

model.add(Activation('tanh'))

model.add(Activation('softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(loss='mean_squared_error', optimizer=sgd)  #指優化方法sgd

model.compile(loss='binary_crossentropy', optimizer='sgd')

7. Preprocessing包:keras.preprocessing

資料預處理子產品,包括序列資料的處理、文本資料的處理和圖像資料的處理等。對于圖像資料的處理,keras提供了ImageDataGenerator函數,實作資料集擴增,對圖像做一些彈性變換,比如水準翻轉,垂直翻轉,旋轉等。

8. metrics包:keras.metrics

與sklearn中metrics包基本相同,主要包含一些如binary_accuracy、mae、mse等的評價方法。

predict = model.predict_classes(test_x)       #輸出預測結果

keras.metrics.binary_accuracy(test_y, predict)  #計算預測精度

二、使用流程

1、構造資料

第一步,我們需要根據模型fit(訓練)時需要的資料格式來構造資料的shape,用numpy構造兩個矩陣:

一個是資料矩陣,一個是标簽矩陣,我們舉個例子

data=np.random.random((1000,784))
labels=np.random.randint(2,size=(1000,1))
           

通過numpy的random生成随機矩陣,資料矩陣是1000行784列的矩陣,标簽矩陣是1000行1列的句子,是以資料矩陣的一行就是一個樣本,這個樣本是784維的

2、構造模型

第二步,我們來構造一個神經網絡模型

用泛型模型舉例:

兩種構造model的方法

model = Sequential([ Dense(32, input_dim=784), Activation('relu'), Dense(10), Activation('softmax'), ])
           

model = Sequential() 
model.add(Dense(32, input_dim=784)) model.add(Activation('relu'))
           

在這一步中可以add多個層,也可以merge合并兩個模型

3、編譯模型

第三步,我們編譯上一步構造好的模型,并指定一些模型的參數,比如目标函數、優化器等

model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
           
  • compile方法的三個參數:

optimizer(優化器),loss(目标函數或損失函數),metrics(評估模型的名額) 

具體見上一篇文章

4、訓練模型

第四步,傳入要訓練的資料和标簽,并指定訓練的一些參數,然後進行模型訓練

fit(self, x, y, batch_size=32, nb_epoch=10, verbose=1, callbacks=[], validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None)
           

fit方法參數解析:

verbose:訓練時顯示實時資訊,0表示不顯示資料,1表示顯示進度條,2表示用隻顯示一個資料

validation_split:0.2表示20%作為資料的驗證集

validation_data:形式為(X,y)的tuple,是指定的驗證集。此參數将覆寫validation_spilt。

class_weight:字典,将不同的類别映射為不同的權值,該參數用來在訓練過程中調整損失函數(隻能用于訓練)

sample_weight:權值的numpy array,用于在訓練時調整損失函數(僅用于訓練)。可以傳遞一個1D的與樣本等長的向量用于對樣本進行1對1的權重,或者在面對時序資料時,傳遞一個的形式為(samples,sequence_length)的矩陣來為每個時間步上的樣本賦不同的權。這種情況下請确定在編譯模型時添加了sample_weight_mode=’temporal’。

(以上兩個參資料說分别為類别權重和樣本權重,類别權重沒太了解,樣本權重貌似就是比如這個樣本對分類貢獻大,就增加他的權重,有點像TF-IDF,是否是一種注意力機制呢?)

x:輸入資料。如果模型隻有一個輸入,那麼x的類型是numpy array,如果模型有多個輸入,那麼x的類型應當為list,list的元素是對應于各個輸入的numpy array

y:标簽,numpy array

batch_size:整數,指定進行梯度下降時每個batch包含的樣本數。訓練時一個batch的樣本會被計算一次梯度下降,使目标函數優化一步。

nb_epoch:整數,訓練的輪數,訓練資料将會被周遊nb_epoch次。Keras中nb開頭的變量均為”number of”的意思

5、測試資料

第五步,用測試資料測試已經訓練好的模型,并可以獲得測試結果,進而對模型進行評估。

  • evaluate:
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
           

本函數傳回一個測試誤差的标量值(如果模型沒有其他評價名額),或一個标量的list(如果模型還有其他的評價名額)

  • predict
predict(self, x, batch_size=32, verbose=0)
           

函數的傳回值是預測值的numpy array

  • predict_classes
predict_classes(self, x, batch_size=32, verbose=1)
           

本函數按batch産生輸入資料的類别預測結果

函數的傳回值是類别預測結果的numpy array或numpy

還有其他評估名額,具體見: 

http://keras-cn.readthedocs.io/en/latest/models/sequential/

以上就是keras程式設計常用的五個步驟

6、儲存與讀取模型

将模型儲存為json
json_string = model.to_json()  
将模型儲存為yaml
yaml_string = model.to_yaml()  
從儲存的json中加載模型  
from keras.modelsimport model_from_json  
model = model_from_json(json_string)  
從儲存的yaml中加載模型  
model =model_from_yaml(yaml_string)  
           

7、儲存與加載權重資料

model.save_weights('my_model_weights.h5')  
model.load_weights('my_model_weights.h5')  
           

以上是根據keras中文文檔進行總結與修改的,主要參考 http://keras-cn.readthedocs.io/en/latest

三、Keras 源碼分析

https://www.jianshu.com/p/8dcddbc1c6d4

四、keras中model.evaluate , model.predict和model.predict_classes的差別

model.evaluate函數預測給定輸入的輸出,然後計算model.compile中指定的metrics函數,并基于y_true和y_pred,并傳回計算的路徑成本作為輸出。model.evaluate 用于評估您訓練的模型。它的輸出是準确度或損失,而不是對輸入資料的預測。

model.predict隻傳回y_pred,model.predict 實際預測,其輸出是目标值,根據輸入資料預測。

在keras中做深度網絡預測時,有這兩個預測函數model.predict_classes(test) 和model.predict(test)。

本例中是多分類,标簽經過了one-hot編碼,如[1,2,3,4,5]是标簽類别,經編碼後為[1 0 0 0 0],[0 1 0 0 0]...[0 0 0 0 1]

model.predict_classes(test)預測的是類别,列印出來的值就是類别号,同時隻能用于序列模型來預測,不能用于函數式模型

predict_test = model.predict_classes(X_test).astype('int')

  inverted = encoder.inverse_transform([predict_test])

  print(predict_test)

  print(inverted[0])

   [1 0 0 ... 1 0 0]

   [2. 1. 1. ... 2. 1. 1.]
           

model.predict(test)預測的是數值,而且輸出的還是5個編碼值,不過是實數,預測後要經過argmax(predict_test,axis=1)

predict_test = model.predict(X_test)

  predict = argmax(predict_test,axis=1)  #axis = 1是取行的最大值的索引,0是列的最大值的索引

  inverted = encoder.inverse_transform([predict])

  print(predict_test[0:3])

  print(argmax(predict_test,axis=1))

  print(inverted)

    [[9.9992561e-01 6.9890179e-05 2.3676146e-06 1.9608513e-06 2.5582506e-07]

     [9.9975246e-01 2.3708738e-04 4.9365349e-06 5.2166861e-06 3.3735736e-07]

     [9.9942291e-01 5.5233808e-04 8.9857504e-06 1.5617061e-05 2.4388814e-07]]

    [0 0 0 ... 0 0 0]

    [[1. 1. 1. ... 1. 1. 1.]]
           

相關參考:https://www.quora.com/What-is-the-difference-between-keras-evaluate-and-keras-predict

五、部分層的使用

     5.1  實作兩個層layer1和layer2的權重融合

      weight_1 = Lambda(lambda x:x*0.8)
      weight_2 = Lambda(lambda x:x*0.2)
      weight_layer1 = weight_1(layer1)
      weight_layer2 = weight_2(layer2)
      last = Add()([weight_layer1,weight_layer2])