1. 程式人生 > >【Keras入門日誌(2】 Keras裡的模組介紹

【Keras入門日誌(2】 Keras裡的模組介紹

【時間】2018.10.30

【Keras入門日誌(2】 Keras裡的模組介紹

目錄

概述

一、Keras中的模組

 keras模組思維導圖

1.1 Optimizers

1.2 Objectives

1.3 Activations

1.4 Initializations

1.5. layers

1.6 Embedding層

1.7  Preprocessing

1.8 utils

1.9 Models

二、一個例項:用CNN分類Mnist

2.1. 資料下載

2.2 讀取圖片資料

2.3.構建CNN,訓練

2.4.程式碼使用與結果


概述

本文內容主要來自文章 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