【Keras入門日誌(2】 Keras裡的模組介紹
【時間】2018.10.30
【Keras入門日誌(2】 Keras裡的模組介紹
目錄
概述
本文內容主要來自文章 https://blog.csdn.net/u012162613/article/details/45397033,在文章基礎上進行補充說明,主要介紹了Keras中的模組,以對Keras有一個整體的認識。並在後面給出了一個使用Keras的具體程式碼例子,以加深對各個模組的理解。
一、Keras中的模組
keras模組思維導圖
1.1 Optimizers
顧名思義,Optimizers包含了一些優化的方法,比如最基本的隨機梯度下降SGD,另外還有Adagrad、Adadelta、RMSprop、Adam,一些新的方法以後也會被不斷新增進來。
keras.optimizers.SGD(lr=0.01, momentum=0.9, decay=0.9, nesterov=False)
上面的程式碼是SGD的使用方法,lr表示學習速率,momentum表示動量項,decay是學習速率的衰減係數(每個epoch衰減一次),Nesterov的值是False或者True,表示使不使用Nesterov momentum。其他的請參考文件。
1.2 Objectives
這是目標函式模組,keras提供了mean_squared_error,mean_absolute_error,squared_hinge,hinge,binary_crossentropy,categorical_crossentropy這幾種目標函式。這裡binary_crossentropy 和 categorical_crossentropy也就是常說的logloss.
1.3 Activations
這是啟用函式模組,keras提供了linear、sigmoid、hard_sigmoid、tanh、softplus、relu、softplus,另外softmax也放在Activations模組裡(我覺得放在layers模組裡更合理些)。此外,像LeakyReLU和PReLU這種比較新的啟用函式,keras在keras.layers.advanced_activations模組裡提供。
1.4 Initializations
這是引數初始化模組,在新增layer的時候呼叫init進行初始化。keras提供了uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal這幾種。
這個模組有兩種初始化方法
1.4.1 通過制定初始化方法的名稱:
示例程式碼:
model.add(Dense(64, init='uniform'))
可以選擇的初始化方法有:
uniform、lecun_uniform、normal、orthogonal、zero、glorot_normal、he_normal等
1.4.2 通過呼叫物件:
該物件必須包含兩個引數:shape(待初始化的變數的shape)和name(該變數的名字),該可呼叫物件必須返回一個(Keras)變數,例如K.variable()返回的就是這種變數,示例程式碼:
from keras import backend as K
import numpy as np
def my_init(shape, name=None):
value = np.random.random(shape)
return K.variable(value, name=name)
model.add(Dense(64, init=my_init))
或者
from keras import initializations
def my_init(shape, name=None):
return initializations.normal(shape, scale=0.01, name=name)
model.add(Dense(64, init=my_init))
所以說可以通過庫中的方法設定每一層的初始化權重,
也可以自己初始化權重,自己設定的話可以精確到每個節點的權重,
1.5. layers
layers模組包含了core(常用層)、convolutional、recurrent(遞迴層)、advanced_activations(高階啟用層)、normalization(規範層)、embeddings(嵌入層)這幾種layer,當然也可以編寫自己的層。
其中core裡面包含了flatten(CNN的全連線層之前需要把二維特徵圖flatten成為一維的)、reshape(CNN輸入時將一維的向量弄成二維的)、dense(就是隱藏層,dense是稠密的意思),還有其他的就不介紹了。convolutional層基本就是Theano的Convolution2D的封裝。還包括Dropout、Activation等。
1.5.1對於層的操作
layer.get_weights() #返回該層的權重
layer.set_weights(weights)#將權重載入到該層
config = layer.get_config()#儲存該層的配置
layer = layer_from_config(config)#載入一個配置到該層
#該層有一個節點時,獲得輸入張量、輸出張量、及各自的形狀:
layer.input
layer.output
layer.input_shape
layer.output_shape
#該層有多個節點時(node_index為節點序號):
layer.get_input_at(node_index)
layer.get_output_at(node_index)
layer.get_input_shape_at(node_index)
layer.get_output_shape_at(node_index)
1.5.2 Dense層(全連線層)
keras.layers.core.Dense(output_dim, init='glorot_uniform', activation='linear', weights=None, W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None, bias=True, input_dim=None)
output_dim:輸出資料的維度
init:初始化該層權重的方法
activation:該層的啟用函式
weights:numpy array的list。該list應含有一個形如(input_dim,output_dim)的權重矩陣和一個形如(output_dim,)的偏置向量
regularizer:正則項,w為權重的、b為偏執的,activity為輸出的
constraints:約束項
bias:是否包含偏執向量,是布林值
input_dim:輸入資料的維度
1.5.3 dropout層
keras.layers.core.Dropout(p)
為輸入資料施加Dropout。Dropout將在訓練過程中每次更新引數時隨機斷開一定百分比(p)的輸入神經元連線,Dropout層用於防止過擬合。
1.5.4 遞迴層(Recurrent)
遞迴層包含三種模型:LSTM、GRU和SimpleRNN
1)抽象層,不能直接使用
keras.layers.recurrent.Recurrent(weights=None, return_sequences=False, go_backwards=False, stateful=False, unroll=False, consume_less='cpu', input_dim=None, input_length=None)
return_sequences:True返回整個序列,false返回輸出序列的最後一個輸出
go_backwards:True,逆向處理輸入序列,預設為False
stateful:布林值,預設為False,若為True,則一個batch中下標為i的樣本的最終狀態將會用作下一個batch同樣下標的樣本的初始狀態
2) 全連線RNN網路--SimpleRNN
keras.layers.recurrent.SimpleRNN(output_dim, init='glorot_uniform', inner_init='orthogonal', activation='tanh', W_regularizer=None, U_regularizer=None, b_regularizer=None, dropout_W=0.0, dropout_U=0.0)
inner_init:內部單元的初始化方法
dropout_W:0~1之間的浮點數,控制輸入單元到輸入門的連線斷開比例
dropout_U:0~1之間的浮點數,控制輸入單元到遞迴連線的斷開比例
3) LSTM層
keras.layers.recurrent.LSTM(output_dim, init='glorot_uniform', inner_init='orthogonal', forget_bias_init='one', activation='tanh', inner_activation='hard_sigmoid', W_regularizer=None, U_regularizer=None, b_regularizer=None, dropout_W=0.0, dropout_U=0.0)
forget_bias_init:遺忘門偏置的初始化函式,Jozefowicz et al.建議初始化為全1元素
inner_activation:內部單元啟用函式
1.6 Embedding層
keras.layers.embeddings.Embedding(input_dim, output_dim, init='uniform', input_length=None, W_regularizer=None, activity_regularizer=None, W_constraint=None, mask_zero=False, weights=None, dropout=0.0)
只能作為模型第一層
mask_zero:布林值,確定是否將輸入中的‘0’看作是應該被忽略的‘填充’(padding)值,該引數在使用遞迴層處理變長輸入時有用。設定為True的話,模型中後續的層必須都支援masking,否則會丟擲異常
1.7 Preprocessing
這是預處理模組,包括序列資料的處理,文字資料的處理,影象資料的處理。重點看一下影象資料的處理,keras提供了ImageDataGenerator函式,實現data augmentation,資料集擴增,對影象做一些彈性變換,比如水平翻轉,垂直翻轉,旋轉等。
1.8 utils
此模組提供了一系列的功能集,比如:
提供了一個神經網路視覺化的函式plot,並可以將視覺化結果儲存在本地。plot使用方法如下:
from keras.utils import plot_model
plot_model(model,to_file='model.png')
1.9 Models
這是最主要的模組,模型。上面定義了各種基本元件,model是將它們組合起來.
model的方法:
model.summary() : 打印出模型概況
model.get_config() :返回包含模型配置資訊的Python字典
model.get_weights():返回模型權重張量的列表,型別為numpy array
model.set_weights():從numpy array裡將權過載入給模型
model.to_json:返回代表模型的JSON字串,僅包含網路結構,不包含權值。可以從JSON字串中重構原模型
model_from_json:從代表模型的JSON字串載入模型的網路結構:
from models import model_from_json
json_string = model.to_json()
model = model_from_json(json_string)
model.to_yaml:與model.to_json類似,同樣可以從產生的YAML字串中重構模型:
from models import model_from_yaml
yaml_string = model.to_yaml()
model = model_from_yaml(yaml_string)
model.save_weights(filepath):將模型權重儲存到指定路徑,檔案型別是HDF5(字尾是.h5)
model.load_weights(filepath, by_name=False):從HDF5檔案中載入權重到當前模型中, 預設情況下模型的結構將保持不變。如果想將權過載入不同的模型(有些層相同)中,則設定by_name=True,只有名字匹配的層才會載入權重
keras有兩種model,分別是Sequential序貫模型和函式式模型
1.9.1 Sequential模型
Sequential是多個網路層的線性堆疊
可以通過向Sequential模型傳遞一個layer的list來構造該模型:
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential([Dense(32,input_dim=784),Activation('relu'),Dense(10),Activation('softmax'),])
也可以通過.add()方法一個個的將layer加入模型中:
model = Sequential()
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))
還可以通過merge將兩個Sequential模型通過某種方式合併
Sequential模型的方法:
compile(self, optimizer, loss, metrics=[], sample_weight_mode=None)
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)
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
#按batch獲得輸入資料對應的輸出,函式的返回值是預測值的numpy array
predict(self, x, batch_size=32, verbose=0)
#按batch產生輸入資料的類別預測結果,函式的返回值是類別預測結果的numpy array或numpy
predict_classes(self, x, batch_size=32, verbose=1)
#本函式按batch產生輸入資料屬於各個類別的概率,函式的返回值是類別概率的numpy array
predict_proba(self, x, batch_size=32, verbose=1)
train_on_batch(self, x, y, class_weight=None, sample_weight=None)
test_on_batch(self, x, y, sample_weight=None)
predict_on_batch(self, x)
fit_generator(self, generator, samples_per_epoch, nb_epoch, verbose=1, callbacks=[], validation_data=None, nb_val_samples=None, class_weight=None, max_q_size=10)
evaluate_generator(self, generator, val_samples, max_q_size=10)
1.9.2 泛型模型
Keras泛型模型介面是:
使用者定義多輸出模型、非迴圈有向模型或具有共享層的模型等複雜模型的途徑
適用於實現:全連線網路和多輸入多輸出模型
多輸入多輸出,官方例子給出:預測一條新聞的點贊轉發數,主要輸入是新聞本身,還可以加入額外輸入,比如新聞釋出日期,新聞作者等,具體的實現還是看官網文件吧:
http://keras-cn.readthedocs.io/en/latest/getting_started/functional_API/
泛型模型model的屬性:
model.layers:組成模型圖的各個層
model.inputs:模型的輸入張量列表
model.outputs:模型的輸出張量列表
方法:類似序列模型的方法
補充get_layer
get_layer(self, name=None, index=None)
本函式依據模型中層的下標或名字獲得層物件,泛型模型中層的下標依據自底向上,水平遍歷的順序。
name:字串,層的名字
index: 整數,層的下標
函式的返回值是層物件
二、一個例項:用CNN分類Mnist
2.1. 資料下載
Mnist資料在其官網上有提供,但是不是影象格式的,因為我們通常都是直接處理影象,為了以後程式能複用,我把它弄成影象格式的,這裡可以下載:http://pan.baidu.com/s/1qCdS6,共有42000張圖片。
2.2 讀取圖片資料
keras要求輸入的資料格式是numpy.array型別(numpy是一個python的數值計算的庫),所以需要寫一個指令碼來讀入mnist影象,儲存為一個四維的data,還有一個一維的label,程式碼:
#coding:utf-8
"""
Author:wepon
Source:https://github.com/wepe
file:data.py
"""
import os
from PIL import Image
import numpy as np
#讀取資料夾mnist下的42000張圖片,圖片為灰度圖,所以為1通道,
#如果是將彩色圖作為輸入,則將1替換為3,並且data[i,:,:,:] = arr改為data[i,:,:,:] = [arr[:,:,0],arr[:,:,1],arr[:,:,2]]
def load_data():
data = np.empty((42000,1,28,28),dtype="float32")
label = np.empty((42000,),dtype="uint8")
imgs = os.listdir("./mnist")
num = len(imgs)
for i in range(num):
img = Image.open("./mnist/"+imgs[i])
arr = np.asarray(img,dtype="float32")
data[i,:,:,:] = arr
label[i] = int(imgs[i].split('.')[0])
return data,label
2.3.構建CNN,訓練
短短二十多行程式碼,構建一個三個卷積層的CNN,直接讀下面的程式碼吧,有註釋,很容易讀懂:
#匯入各種用到的模組元件
from __future__ import absolute_import
from __future__ import print_function
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.advanced_activations import PReLU
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD, Adadelta, Adagrad
from keras.utils import np_utils, generic_utils
from six.moves import range
from data import load_data
#載入資料
data, label = load_data()
print(data.shape[0], ' samples')
#label為0~9共10個類別,keras要求格式為binary class matrices,轉化一下,直接呼叫keras提供的這個函式
label = np_utils.to_categorical(label, 10)
###############
#開始建立CNN模型
###############
#生成一個model
model = Sequential()
#第一個卷積層,4個卷積核,每個卷積核大小5*5。1表示輸入的圖片的通道,灰度圖為1通道。
#border_mode可以是valid或者full,具體看這裡說明:http://deeplearning.net/software/theano/library/tensor/nnet/conv.html#theano.tensor.nnet.conv.conv2d
#啟用函式用tanh
#你還可以在model.add(Activation('tanh'))後加上dropout的技巧: model.add(Dropout(0.5))
model.add(Convolution2D(4, 1, 5, 5, border_mode='valid'))
model.add(Activation('tanh'))
#第二個卷積層,8個卷積核,每個卷積核大小3*3。4表示輸入的特徵圖個數,等於上一層的卷積核個數
#啟用函式用tanh
#採用maxpooling,poolsize為(2,2)
model.add(Convolution2D(8,4, 3, 3, border_mode='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(poolsize=(2, 2)))
#第三個卷積層,16個卷積核,每個卷積核大小3*3
#啟用函式用tanh
#採用maxpooling,poolsize為(2,2)
model.add(Convolution2D(16, 8, 3, 3, border_mode='valid'))
model.add(Activation('tanh'))
model.add(MaxPooling2D(poolsize=(2, 2)))
#全連線層,先將前一層輸出的二維特徵圖flatten為一維的。
#Dense就是隱藏層。16就是上一層輸出的特徵圖個數。4是根據每個卷積層計算出來的:(28-5+1)得到24,(24-3+1)/2得到11,(11-3+1)/2得到4
#全連線有128個神經元節點,初始化方式為normal
model.add(Flatten())
model.add(Dense(16*4*4, 128, init='normal'))
model.add(Activation('tanh'))
#Softmax分類,輸出是10類別
model.add(Dense(128, 10, init='normal'))
model.add(Activation('softmax'))
#############
#開始訓練模型
##############
#使用SGD + momentum
#model.compile裡的引數loss就是損失函式(目標函式)
sgd = SGD(l2=0.0,lr=0.05, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd,class_mode="categorical")
#呼叫fit方法,就是一個訓練過程. 訓練的epoch數設為10,batch_size為100.
#資料經過隨機打亂shuffle=True。verbose=1,訓練過程中輸出的資訊,0、1、2三種方式都可以,無關緊要。show_accuracy=True,訓練時每一個epoch都輸出accuracy。
#validation_split=0.2,將20%的資料作為驗證集。
model.fit(data, label, batch_size=100,nb_epoch=10,shuffle=True,verbose=1,show_accuracy=True,validation_split=0.2)
2.4.程式碼使用與結果
程式碼放在github的機器學習倉庫裡:https://github.com/wepe/MachineLearning,非github使用者直接點右下的DownloadZip。
在/DeepLearning Tutorials/keras_usage目錄下包括data.py,cnn.py兩份程式碼,下載Mnist資料後解壓到該目錄下,執行cnn.py這份檔案即可。
結果如下所示,在Epoch 9達到了0.98的訓練集識別率和0.97的驗證集識別率:
參考文章:https://blog.csdn.net/lk7688535/article/details/52862377