天天看點

TensorFlow2.0 Keras介紹

Keras簡介

keras現在是一個非常流行的工具庫,包括tensorflow已經把keras合并到了自己的主代碼當中了,大家可以直接tf.keras就可以直接調用其中的工具庫了。單獨講keras的原因是因為keras有他獨特的應用場景如實驗室、資料競賽等小型環境中,使用keras,工程師們可以将更多時間花在設計網絡模型上而不是coding上,而且keras是所有工具庫當中最容易上手的工具庫之一。

Keras是一個高層神經網絡API,它本身就是一個上層封裝的工具庫,它是由純Python編寫而成并基Tensorflow、Theano、mxnet以及CNTK後端。keras非常容易上手可以說是為快速實驗而生能将你的idea迅速轉換為結果,适合于小型環境(實驗室、資料競賽),但在工業界由于分布式底層封裝不好,是以大型項目keras并不能很好的發揮其作用。但是keras也有它獨特的優點如下

1.簡易和快速的原型設計

2.支援CNN與RNN,或兩者結合

3.無縫CPU與GPU切換

TensorFlow2.0自帶有Keras,直接可以用tf.keras調用。

keras的主要子產品介紹

TensorFlow2.0 Keras介紹

我們這裡介紹幾個主要的子產品:

1. 目标函數Objectives

目标函數,或稱損失函數,是編譯一個模型必須的兩個參數之一

可以通過傳遞預定義目标函數名字指定目标函數,也可以傳遞一個Theano/TensroFlow的符号函數作為目标函數,該函數對每個資料點應該隻傳回一個标量值,并以下列兩個參數為參數:

y_true:真實的資料标簽, Theano/TensorFlow張量

y_pred:預測值,與y_true相同shape的Theano/TensorFlow張量

真實的優化目标函數是在各個資料點得到的損失函數值之和的均值

可用的目标函數

mean_squared_error或mse

mean_absolute_error或mae

mean_absolute_percentage_error或mape

mean_squared_logarithmic_error或msle

squared_hinge

hinge

binary_crossentropy(亦稱作對數損失, logloss)

categorical_crossentropy:亦稱作多類的對數損失,注意使用該目标函數時,需要将标簽轉化為形如 (nb_samples, nb_classes) 的二值序列

sparse_categorical_crossentrop:如上,但接受稀疏标簽。注意,使用該函數時仍然需要你的标簽與輸出值的次元相同,你可能需要在标簽資料上增加一個次元: np.expand_dims(y,-1)

kullback_leibler_divergence:從預測值機率分布Q到真值機率分布P的資訊增益,用以度量兩個分布的差異.

poisson:即 (predictions - targets * log(predictions)) 的均值

cosine_proximity:即預測值與真實标簽的餘弦距離平均值的相反數

2. 優化器optimizers

優化器是編譯Keras模型必要的兩個參數之一,可以在調用 model.compile() 之前初始化一個優化器對象,然後傳入該函數(如上所示),也可以在調用 model.compile() 時傳遞一個預定義優化器名。

參數 clipnorm 和 clipvalue 是所有優化器都可以使用的參數,用于對梯度進行裁剪.

2.1. SGD

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

随機梯度下降法,支援動量參數,支援學習衰減率,支援Nesterov動量

lr:大于0的浮點數,學習率

momentum:大于0的浮點數,動量參數

decay:大于0的浮點數,每次更新後的學習率衰減值

nesterov:布爾值,确定是否使用Nesterov動量

2.2. RMSprop

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)

除學習率可調整外,建議保持優化器的其他預設參數不變,該優化器通常是面對遞歸神經網絡時的一個良好選擇

lr:大于0的浮點數,學習率

rho:大于0的浮點數

epsilon:大于0的小浮點數,防止除0錯誤

2.3. Adagrad

keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)

建議保持優化器的預設參數不變

lr:大于0的浮點數,學習率

epsilon:大于0的小浮點數,防止除0錯誤

2.4. Adadelta

keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)

建議保持優化器的預設參數不變

lr:大于0的浮點數,學習率

rho:大于0的浮點數

epsilon:大于0的小浮點數,防止除0錯誤

2.5. Adam

keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

lr:大于0的浮點數,學習率

beta_1/beta_2:浮點數, 0<beta<1,通常很接近1

epsilon:大于0的小浮點數,防止除0錯誤

2.6. Adamax

keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

Adamax優化器來自于Adam的論文的Section7,該方法是基于無窮範數的Adam方法的變體。

lr:大于0的浮點數,學習率

beta_1/beta_2:浮點數, 0<beta<1,通常很接近1

epsilon:大于0的小浮點數,防止除0錯誤

2.7. Nadam

keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)

Nesterov Adam optimizer: Adam本質上像是帶有動量項的RMSprop, Nadam就是帶有Nesterov 動量的Adam RMSprop

lr:大于0的浮點數,學習率

beta_1/beta_2:浮點數, 0<beta<1,通常很接近1

epsilon:大于0的小浮點數,防止除0錯誤

3. 激活函數Activations

激活函數可以通過設定單獨的激活層實作,也可以在構造層對象時通過傳遞 activation 參數實作。

from keras.layers.core import Activation, Dense
model.add(Dense(64))
model.add(Activation('tanh'))
           

等價于

model.add(Dense(64, activation='tanh'))
           

也可以通過傳遞一個逐元素運算的Theano/TensorFlow函數來作為激活函數:

也可以通過傳遞一個逐元素運算的Theano/TensorFlow函數來作為激活函數:

from keras import backend as K
def tanh(x):
    return K.tanh(x)
model.add(Dense(64, activation=tanh))
model.add(Activation(tanh)
           

3.1. 預定義激活函數

softmax:對輸入資料的最後一維進行softmax,輸入資料應形如 (nb_samples, nb_timesteps, nb_dims) 或 (nb_samples,nb_dims)

softplus

softsign

relu

tanh

sigmoid

hard_sigmoid

linear

3.2. 進階激活函數

對于簡單的Theano/TensorFlow不能表達的複雜激活函數,如含有可學習參數的激活函數,可通過進階激活函數實作,如PReLU, LeakyReLU等

4. 回調函數Callbacks

回調函數是一組在訓練的特定階段被調用的函數集,你可以使用回調函數來觀察訓練過程中網絡内部的狀态和統計資訊。通過傳遞回調函數清單到模型的 .fit() 中,即可在給定的訓練階段調用該函數集中的函數。

雖然我們稱之為回調“函數”,但事實上Keras的回調函數是一個類,回調函數隻是習慣性稱呼

CallbackList
keras.callbacks.CallbackList(callbacks=[], queue_length=10)

Callback

keras.callbacks.Callback()
           

這是回調函數的抽象類,定義新的回調函數必須繼承自該類

4.1. BaseLogger

keras.callbacks.BaseLogger()

該回調函數用來對每個epoch累加 metrics 指定的監視名額的epoch平均值

該回調函數在每個Keras模型中都會被自動調用

4.2. ProgbarLogger

keras.callbacks.ProgbarLogger()

該回調函數用來将 metrics 指定的監視名額輸出到标準輸出上

4.3. History

keras.callbacks.History()

該回調函數在Keras模型上會被自動調用, History 對象即為 fit 方法的傳回值

4.4. ModelCheckpoint

keras.callbacks.ModelCheckpoint(filepath, monitor=‘val_loss’, verbose=0, save_best_only=False, save_weights_only=False, mode=‘auto’)

該回調函數将在每個epoch後儲存模型到 filepath,filepath 可以是格式化的字元串,裡面的占位符将會被 epoch 值和傳入 on_epoch_end 的 logs 關鍵字所填入

filename:字元串,儲存模型的路徑

monitor:需要監視的值

verbose:資訊展示模式, 0或1

save_best_only:當設定為 True 時,将隻儲存在驗證集上性能最好的模型

mode: ‘auto’, ‘min’, ‘max’之一,在 save_best_only=True 時決定性能最佳模型的評判準則,例如,當監測值為 val_acc 時,模式應為 max ,當檢測值為 val_loss 時,模式應為 min 。在 auto 模式下,評價準則由被監測值的名字自動推斷。

save_weights_only:若設定為True,則隻儲存模型權重,否則将儲存整個模型(包括模型結構,配置資訊等)

4.5. EarlyStopping

keras.callbacks.EarlyStopping(monitor=‘val_loss’, patience=0, verbose=0, mode=‘auto’)

當監測值不再改善時,該回調函數将中止訓練

monitor:需要監視的量

patience:當early stop被激活(如發現loss相比上一個epoch訓練沒有下降),則經過 patience 個epoch後停止訓練。

verbose:資訊展示模式

mode: ‘auto’, ‘min’, ‘max’之一,在 min 模式下,如果檢測值停止下降則中止訓練。在 max 模式下,當檢測值不再上升則停止訓練。

4.6. RemoteMonitor

keras.callbacks.RemoteMonitor(root='http://localhost:9000')
           

該回調函數用于向伺服器發送事件流,該回調函數需要 requests 庫

root:該參數為根url,回調函數将在每個epoch後把産生的事件流發送到該位址,事件将被發往 root + ‘/publish/epoch/end/’ 。發送方法為HTTP POST,其 data 字段的資料是按JSON格式編碼的事件字典。

4.7. LearningRateScheduler

keras.callbacks.LearningRateScheduler(schedule)
           

該回調函數是學習率排程器

schedule:函數,該函數以epoch号為參數(從0算起的整數),傳回一個新學習率(浮點數)

4.8. TensorBoard

keras.callbacks.TensorBoard(log_dir=’./logs’, histogram_freq=0)

該回調函數是一個可視化的展示器

log_dir:儲存日志檔案的位址,該檔案将被TensorBoard解析以用于可視化

histogram_freq:計算各個層激活值直方圖的頻率(每多少個epoch計算一次),如果設定為0則不計算。

4.9. 自定義回調函數

我們可以通過繼承 keras.callbacks.Callback 編寫自己的回調函數,回調函數通過類成員 self.model 通路通路,該成員是模型的一個引用。

這裡是一個簡單的儲存每個batch的loss的回調函數:

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
 
history = LossHistory()
model.fit(X_train, Y_train, batch_size=128, nb_epoch=20, verbose=0, callbacks=[history])
           

5. 性能評估Metrices

性能評估子產品提供了一系列用于模型性能評估的函數,這些函數在模型編譯時由 metrices 關鍵字設定

性能評估函數類似與目标函數, 隻不過該性能的評估結果将不會用于訓練.

可以通過字元串來使用域定義的性能評估函數,也可以自定義一個Theano/TensorFlow函數并使用之

5.1. 可用預定義

除fbeta_score額外擁有預設參數beta=1外,其他各個性能名額的參數均為y_true和y_pred

binary_accuracy: 對二分類問題,計算在所有預測值上的平均正确率

categorical_accuracy:對多分類問題,計算在所有預測值上的平均正确率

sparse_categorical_accuracy:與 categorical_accuracy 相同,在對稀疏的目标值預測時有用

top_k_categorical_accracy: 計算top-k正确率,當預測值的前k個值中存在目标類别即認為預測正确

mean_squared_error:計算預測值與真值的均方差

mean_absolute_error:計算預測值與真值的平均絕對誤差

mean_absolute_percentage_error:計算預測值與真值的平均絕對誤差率

mean_squared_logarithmic_error:計算預測值與真值的平均指數誤差

hinge:計算預測值與真值的hinge loss

squared_hinge:計算預測值與真值的平方hinge loss

categorical_crossentropy:計算預測值與真值的多類交叉熵(輸入值為二值矩陣,而不是向量)

sparse_categorical_crossentropy:與多類交叉熵相同,适用于稀疏情況

binary_crossentropy:計算預測值與真值的交叉熵

poisson:計算預測值與真值的泊松函數值

cosine_proximity:計算預測值與真值的餘弦相似性

matthews_correlation:計算預測值與真值的馬氏距離

fbeta_score:計算F值,即召回率與準确率的權重調和平均,該函數在多标簽分類(一個樣本有多個标簽)時有用,如果隻使用準确率作為度量,模型隻要把所有輸入分類為"所有類别"就可以獲得完美的準确率,為了避免這種情況,度量名額應該對錯誤的選擇進行懲罰. F-beta分值(0到1之間)通過準确率和召回率的權重調和平均來更好的度量.當beta為1時,該名額等價于F-measure,beta<1時,模型選對正确的标簽更加重要,而beta>1時,模型對選錯标簽有更大的懲罰.

5.2. 定制評估函數

定制的評估函數可以在模型編譯時傳入,該函數應該以 (y_true, y_pred) 為參數,并傳回單個張量,或從 metric_name 映射到 metric_value 的字典,下面是一個示例:

import keras.backend as K
def mean_pred(y_true, y_pred):
    return K.mean(y_pred)
def false_rates(y_true, y_pred):
    false_neg = ...
    false_pos = ...
    return {
        'false_neg': false_neg,
        'false_pos': false_pos,
    }
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy', mean_pred, false_rates])
           

6. 初始化方法Initialization

初始化方法定義了對Keras層設定初始化權重的方法,不同的層可能使用不同的關鍵字來傳遞初始化方法,一般來說指定初始化方法的關鍵字是 init

6.1. 預定義初始化方法

uniform

lecun_uniform: 即有輸入節點數之平方根放縮後的均勻分布初始化( LeCun 98) .

normal

identity:僅用于權值矩陣為方陣的2D層(shape[0]=shape[1] )

orthogonal:僅用于權值矩陣為方陣的2D層(shape[0]=shape[1] )

zero

glorot_normal:由扇入扇出放縮後的高斯初始化( Glorot 2010)

glorot_uniform

he_normal:由扇入放縮後的高斯初始化( He et al.,2014)

he_uniform

6.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))
           

7. 正則項Regularizer

正則項在優化過程中層的參數或層的激活值添加懲罰項,這些懲罰項将與損失函數一起作為網絡的最終優化目标

懲罰項基于層進行懲罰,目前懲罰項的接口與層有關,但 Dense, TimeDistributedDense, MaxoutDense, Covolution1D, Covolution2D 具有共同的接口。

這些層有三個關鍵字參數以施加正則項:

W_regularizer :施加在權重上的正則項,為 WeightRegularizer 對象

b_regularizer :施加在偏置向量上的正則項,為 WeightRegularizer 對象

activity_regularizer :施加在輸出上的正則項,為 ActivityRegularizer 對象

7.1. 預定義正則項

keras.regularizers.WeightRegularizer(l1=0., l2=0.)

keras.regularizers.ActivityRegularizer(l1=0., l2=0.)

7.2. 縮寫

keras.regularizers 支援以下縮寫:

l1(l=0.01): L1正則項,又稱LASSO

l2(l=0.01): L2正則項,又稱權重衰減或Ridge

l1l2(l1=0.01, l2=0.01): L1-L2混合正則項, 又稱ElasticNet

activity_l1(l=0.01): L1激活值正則項

activity_l2(l=0.01): L2激活值正則項

activity_l1l2(l1=0.01, l2=0.01): L1+L2激活值正則項

正則項通常用于對模型的訓練施加某種限制, L1正則項即L1範數限制,該限制會使被限制矩陣/向量更稀疏。 L2正則項即L2範數限制,該限制會使被限制的矩陣/向量更平滑,因為它對脈沖型的值有很大的懲罰。

**

8. 限制項Constraint

**

來自 constraints 子產品的函數在優化過程中為網絡的參數施加限制,懲罰項基于層進行懲罰,目前懲罰項的接口與層有關,但 Dense, TimeDistributedDense, MaxoutDense, Covolution1D, Covolution2D 具有共同的接口。

這些層通過一下關鍵字施加限制項:

W_constraint :對主權重矩陣進行限制

b_constraint :對偏置向量進行限制

8.1. 預定義限制項

maxnorm(m=2):最大模限制

nonneg():非負性限制

unitnorm():機關範數限制, 強制矩陣沿最後一個軸擁有機關範數

9. 預訓練模型Application

Kera的應用子產品Application提供了帶有預訓練權重的Keras模型,這些模型可以用來進行預測、特征提取和finetune,模型的預訓練權重将下載下傳到 ~/.keras/models/ 并在載入模型時自動載入

9.1. 可用的模型

應用于圖像分類的模型,權重訓練自ImageNet: Xception VGG16 VGG19 ResNet50 * InceptionV3

所有的這些模型(除了Xception)都相容Theano和Tensorflow,并會自動基于 ~/.keras/keras.json 的Keras的圖像次元進行自動設定。例如,如果你設定 image_dim_ordering=tf ,則加載的模型将按照TensorFlow的次元順序來構造

應用于音樂自動标簽(以Mel-spectrograms為輸入):MusicTaggerCRNN

9.2. 圖檔分類模型的示例

利用ResNet50網絡進行ImageNet分類

from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np
model = ResNet50(weights='imagenet')
img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
preds = model.predict(x)

# decode the results into a list of tuples (class, description, probability)
# (one such list for each sample in the batch)
print('Predicted:', decode_predictions(preds, top=3)[0])
# Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225), (u'n01871265', u'tusker', 0.1122357), 
#(u'n02504458', u'African_elephant', 0.061040461)]
           

利用VGG16提取特征

from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np
model = VGG16(weights='imagenet', include_top=False)
img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
features = model.predict(x)
           

10. 常用資料集Dataset

10.1. CIFAR10 小圖檔分類資料集

該資料庫具有50,000個32*32的彩色圖檔作為訓練集, 10,000個圖檔作為測試集。圖檔一共有10個類别。

使用方法:

from keras.datasets import cifar10
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
           

傳回值:兩個Tuple

X_train 和 X_test 是形如( nb_samples, 3, 32, 32)的RGB三通道圖像資料,資料類型是無符号8位整形( uint8)

Y_train 和 Y_test 是形如( nb_samples,)标簽資料,标簽的範圍是0~9

10.2. CIFAR100 小圖檔分類資料庫

該資料庫具有50,000個32*32的彩色圖檔作為訓練集, 10,000個圖檔作為測試集。圖檔一共有100個類别,每個類别有600張圖檔。這100個類别又分為20個大類。

from keras.datasets import cifar100
(X_train, y_train), (X_test, y_test) = cifar100.load_data(label_mode='fine')
           

label_mode:為‘fine’或‘coarse’之一,控制标簽的精細度, ‘fine’獲得的标簽是100個小類的标簽, ‘coarse’獲得的

标簽是大類的标簽

10.3. IMDB影評傾向分類

本資料庫含有來自IMDB的25,000條影評,被标記為正面/負面兩種評價。影評已被預處理為詞下标構成的序列。友善起見,單詞的下标基于它在資料集中出現的頻率标定,例如整數3所編碼的詞為資料集中第3常出現的詞。這樣的組織方法使得使用者可以快速完成諸如“隻考慮最常出現的10,000個詞,但不考慮最常出現的20個詞”這樣的操作

按照慣例, 0不代表任何特定的詞,而用來編碼任何未知單詞

from keras.datasets import imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(path="imdb_full.pkl",
	nb_words=None,
	skip_top=0,
	maxlen=None,
	test_split=0.1)
	seed=113,
	start_char=1,
	oov_char=2,
	index_from=3)
           

path:如果你在本機上已有此資料集(位于 ‘~/.keras/datasets/’+path ),則載入。否則資料将下載下傳到該目錄下

nb_words:整數或None,要考慮的最常見的單詞數,任何出現頻率更低的單詞将會被編碼到0的位置。

skip_top:整數,忽略最常出現的若幹單詞,這些單詞将會被編碼為0

maxlen:整數,最大序列長度,任何長度大于此值的序列将被截斷

seed:整數,用于資料重排的随機數種子

start_char:字元,序列的起始将以該字元标記,預設為1因為0通常用作padding

oov_char:字元,因 nb_words 或 skip_top 限制而cut掉的單詞将被該字元代替

index_from:整數,真實的單詞(而不是類似于 start_char 的特殊占位符)将從這個下标開始

傳回值:兩個Tuple,其中

X_train和X_test:序列的清單,每個序列都是詞下标的清單。如果指定了 nb_words ,則序列中可能的最大下标為 nb_words-1 。如果指定了 maxlen ,則序列的最大可能長度為 maxlen

y_train和y_test:為序列的标簽,是一個二值list

10.4. 路透社新聞主題分類

本資料庫包含來自路透社的11,228條新聞,分為了46個主題。與IMDB庫一樣,每條新聞被編碼為一個詞下标的序列。

from keras.datasets import reuters
(X_train, y_train), (X_test, y_test) = reuters.load_data(path="reuters.pkl",
	nb_words=None,
	skip_top=0,
	maxlen=None,
	test_split=0.2,
	seed=113,
	start_char=1,
	oov_char=2,
	index_from=3)
           

test_split:用于指定從原資料中分割出作為測試集的比例。

10.5. MNIST手寫數字識别

本資料庫有60,000個用于訓練的28*28的灰階手寫數字圖檔, 10,000個測試圖檔

from keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()

11. 可視化Visualization

11.1. 模型可視化

keras.utils.visualize_util 子產品提供了畫出Keras模型的函數(利用graphviz),該函數将畫出模型結構圖,并儲存成圖檔:

from keras.utils.visualize_util import plot

plot(model, to_file=‘model.png’)

plot 接收兩個可選參數:

show_shapes :指定是否顯示輸出資料的形狀,預設為 False

show_layer_names :指定是否顯示層名稱,預設為 True

依賴 pydot-ng 和 graphviz,指令行輸入 pip

繼續閱讀