keras學(xué)習(xí)筆記

  • 參考keras 中文文檔

1.在多張GPU卡上使用Keras

以TnesorFlow后端,可以使用數(shù)據(jù)并行的方式。數(shù)據(jù)并行將目標(biāo)模型在多個(gè)設(shè)備上各復(fù)制一份,并使用每個(gè)設(shè)備上的復(fù)制品處理整個(gè)數(shù)據(jù)集的不同部分?jǐn)?shù)據(jù)。
from keras.utils import multi_gpu_model

# Replicates `model` on 8 GPUs.
# This assumes that your machine has 8 available GPUs.
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
                       optimizer='rmsprop')

# This `fit` call will be distributed on 8 GPUs.
# Since the batch size is 256, each GPU will process 32 samples.
parallel_model.fit(x, y, epochs=20, batch_size=256)

2. "batch", "epoch"和"sample"的含義

Sample:樣本,數(shù)據(jù)集中的一條數(shù)據(jù)。例如圖片數(shù)據(jù)集中的一張圖片
Batch:中文為批,一個(gè)batch由若干條數(shù)據(jù)構(gòu)成。batch是進(jìn)行網(wǎng)絡(luò)優(yōu)化的基本單位,網(wǎng)絡(luò)參數(shù)的每一輪優(yōu)化需要使用一個(gè)batch。batch越大則對(duì)輸入數(shù)據(jù)分布模擬的越好,反應(yīng)在網(wǎng)絡(luò)訓(xùn)練上,則體現(xiàn)為能讓網(wǎng)絡(luò)訓(xùn)練的方向“更加正確”。但另一方面,一個(gè)batch也只能讓網(wǎng)絡(luò)的參數(shù)更新一次,因此網(wǎng)絡(luò)參數(shù)的迭代會(huì)較慢。在測(cè)試網(wǎng)絡(luò)的時(shí)候,應(yīng)該在條件的允許的范圍內(nèi)盡量使用更大的batch,這樣計(jì)算效率會(huì)更高。
Epoch,epoch可譯為“輪次”。如果說(shuō)每個(gè)batch對(duì)應(yīng)網(wǎng)絡(luò)的一次更新的話(huà),一個(gè)epoch對(duì)應(yīng)的就是網(wǎng)絡(luò)的一輪更新。每一輪更新中網(wǎng)絡(luò)更新的次數(shù)可以隨意,但通常會(huì)設(shè)置為遍歷一遍數(shù)據(jù)集。因此一個(gè)epoch的含義是模型完整的看了一遍數(shù)據(jù)集。

3. 保存Keras模型

可以使用model.save(filepath)將Keras模型和權(quán)重保存在一個(gè)HDF5文件中,該文件將包含:

  • 模型的結(jié)構(gòu),以便重構(gòu)該模型
  • 模型的權(quán)重
  • 訓(xùn)練配置(損失函數(shù),優(yōu)化器等)
  • 優(yōu)化器的狀態(tài),以便于從上次訓(xùn)練中斷的地方開(kāi)始
    使用keras.models.load_model(filepath)來(lái)重新實(shí)例化你的模型
from keras.models import load_model
model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
del model  # deletes the existing model
# returns a compiled model
# identical to the previous one
model = load_model('my_model.h5')

如果需要保存模型的權(quán)重,可通過(guò)下面的代碼利用HDF5進(jìn)行保存。注意,在使用前需要確保你已安裝了HDF5和其Python庫(kù)h5py

model.save_weights('my_model_weights.h5')

如果你需要在代碼中初始化一個(gè)完全相同的模型,請(qǐng)使用:

model.load_weights('my_model_weights.h5')

如果你需要加載權(quán)重到不同的網(wǎng)絡(luò)結(jié)構(gòu)(有些層一樣)中,例如fine-tune或transfer-learning,你可以通過(guò)層名字來(lái)加載模型:

model.load_weights('my_model_weights.h5', by_name=True)

例如:僅加載層名字相同的參數(shù)。

"""
假如原模型為:
    model = Sequential()
    model.add(Dense(2, input_dim=3, name="dense_1"))
    model.add(Dense(3, name="dense_2"))
    ...
    model.save_weights(fname)
"""
# new model
model = Sequential()
model.add(Dense(2, input_dim=3, name="dense_1"))  # will be loaded
model.add(Dense(10, name="new_dense"))  # will not be loaded

# load weights from first model; will only affect the first layer, dense_1.
model.load_weights(fname, by_name=True)

獲取中間層的輸出

可以建立一個(gè)Keras的函數(shù)來(lái)達(dá)到這一目的:

from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
                                  [model.layers[3].output])
layer_output = get_3rd_layer_output([X])[0]

注意,如果你的模型在訓(xùn)練和測(cè)試兩種模式下不完全一致,例如你的模型中含有Dropout層,批規(guī)范化(BatchNormalization)層等組件,你需要在函數(shù)中傳遞一個(gè)learning_phase的標(biāo)記,像這樣:

get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()],
                                  [model.layers[3].output])
# output in test mode = 0
layer_output = get_3rd_layer_output([X, 0])[0]
# output in train mode = 1
layer_output = get_3rd_layer_output([X, 1])[0]

數(shù)據(jù)集分割與洗亂

如果在model.fit中設(shè)置validation_spilt的值,則可將數(shù)據(jù)分為訓(xùn)練集和驗(yàn)證集,原數(shù)據(jù)在進(jìn)行驗(yàn)證集分割前并沒(méi)有被shuffle,所以這里的驗(yàn)證集嚴(yán)格的就是你輸入數(shù)據(jù)最末的x%。
如果model.fit的shuffle參數(shù)為真,訓(xùn)練的數(shù)據(jù)就會(huì)被隨機(jī)洗亂。不設(shè)置時(shí)默認(rèn)為真。訓(xùn)練數(shù)據(jù)會(huì)在每個(gè)epoch的訓(xùn)練中都重新洗亂一次。驗(yàn)證集的數(shù)據(jù)不會(huì)被洗亂

在每個(gè)epoch后記錄訓(xùn)練/測(cè)試的loss和正確率

model.fit在運(yùn)行結(jié)束后返回一個(gè)History對(duì)象,其中含有的history屬性包含了訓(xùn)練過(guò)程中損失函數(shù)的值以及其他度量指標(biāo)。

hist = model.fit(X, y, validation_split=0.2)
print(hist.history)

“凍結(jié)”網(wǎng)絡(luò)的層

“凍結(jié)”一個(gè)層指的是該層將不參加網(wǎng)絡(luò)訓(xùn)練,即該層的權(quán)重永不會(huì)更新。在進(jìn)行fine-tune時(shí)我們經(jīng)常會(huì)需要這項(xiàng)操作。
可以通過(guò)向?qū)拥臉?gòu)造函數(shù)傳遞trainable參數(shù)來(lái)指定一個(gè)層是不是可訓(xùn)練的,如:

frozen_layer = Dense(32,trainable=False)

此外,也可以通過(guò)將層對(duì)象的trainable屬性設(shè)為T(mén)rue或False來(lái)為已經(jīng)搭建好的模型設(shè)置要凍結(jié)的層。 在設(shè)置完后,需要運(yùn)行compile來(lái)使設(shè)置生效,例如:

x = Input(shape=(32,))
layer = Dense(32)
layer.trainable = False
y = layer(x)

frozen_model = Model(x, y)
# in the model below, the weights of `layer` will not be updated during training
frozen_model.compile(optimizer='rmsprop', loss='mse')

layer.trainable = True
trainable_model = Model(x, y)
# with this model the weights of the layer will be updated during training
# (which will also affect the above model since it uses the same layer instance)
trainable_model.compile(optimizer='rmsprop', loss='mse')

frozen_model.fit(data, labels)  # this does NOT update the weights of `layer`
trainable_model.fit(data, labels)  # this updates the weights of `layer`

從Sequential模型中去除一個(gè)層

通過(guò)調(diào)用.pop()來(lái)去除模型的最后一個(gè)層,反復(fù)調(diào)用n次即可去除模型后面的n個(gè)層

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

print(len(model.layers))  # "2"

model.pop()
print(len(model.layers))  # "1"

在Keras中使用預(yù)訓(xùn)練的模型

通過(guò)keras.applications載入這些模型:

from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
from keras.applications.resnet50 import ResNet50
from keras.applications.inception_v3 import InceptionV3

model = VGG16(weights='imagenet', include_top=True)

序列模型

model = Sequential()
#定義各層
model.add()
#編譯
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
#訓(xùn)練
model.fit()
  • 常用Sequential屬性

  • model.layers是添加到模型上的層的list

函數(shù)式(Functional)模型

只要你的模型不是類(lèi)似VGG一樣一條路走到黑的模型,或者你的模型需要多于一個(gè)的輸出,那么你總應(yīng)該選擇函數(shù)式模型。函數(shù)式模型是最廣泛的一類(lèi)模型,序貫?zāi)P停⊿equential)只是它的一種特殊情況。函數(shù)式模型稱(chēng)作Functional,但它的類(lèi)名是Model

使用函數(shù)式模型的一個(gè)典型場(chǎng)景是搭建多輸入、多輸出的模型


keras 常用層

Dense層是全連接層

所實(shí)現(xiàn)的運(yùn)算是output = activation(dot(input, kernel)+bias)也就是激活函數(shù)(wx+b)
第一個(gè)參數(shù)是指輸出的維度。

卷積層

Conv2D層

keras.layers.convolutional.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), 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)

二維卷積層,即對(duì)圖像的空域卷積。該層對(duì)二維輸入進(jìn)行滑動(dòng)窗卷積

  • filters:卷積核的數(shù)目(即輸出的維度)
  • kernel_size:卷積核
  • strides:步長(zhǎng),任何不為1的strides均與任何不為1的dilation_rate均不兼容。
  • padding:補(bǔ)0策略,“valid”代表只進(jìn)行有效的卷積,即對(duì)邊界數(shù)據(jù)不處理。“same”代表保留邊界處的卷積結(jié)果,通常會(huì)導(dǎo)致輸出shape與輸入shape相同。
  • activation:激活函數(shù),如果不指定該參數(shù),將不會(huì)使用任何激活函數(shù),極線(xiàn)性激活函數(shù)。
  • dilation_rate: 指定dilated convolution中的膨脹比例。任何不為1的dilation_rate均與任何不為1的strides均不兼容。(沒(méi)明白)
  • use_bias:布爾值,是否使用偏置項(xiàng)
  • data_format:字符串,“channels_first”或“channels_last”之一,代表圖像的通道維的位置。tensorflow對(duì)應(yīng)“channels_last”,thoneo對(duì)應(yīng)“channels_first”。以128x128的RGB圖像為例,“channels_first”應(yīng)將數(shù)據(jù)組織為(3,128,128),而“channels_last”應(yīng)將數(shù)據(jù)組織為(128,128,3)。不指定時(shí),默認(rèn)為channels_last,也就是把維數(shù)放在后面。

Conv2DTranspose層

該層是轉(zhuǎn)置的卷積操作(反卷積)

Conv3D層

三維卷積對(duì)三維的輸入進(jìn)行滑動(dòng)窗卷積,也就是視頻。

Cropping2D層

對(duì)2D輸入(圖像)進(jìn)行裁剪,將在空域維度,即寬和高的方向上裁剪。

ZeroPadding2D層

對(duì)2D輸入(如圖片)的邊界填充0,以控制卷積以后特征圖的大小


池化層

MaxPooling2D層

為空域信號(hào)施加最大值池化

keras.layers.pooling.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)

pool_size:整數(shù)或長(zhǎng)為2的整數(shù)tuple,代表在兩個(gè)方向(豎直,水平)上的下采樣因子,如?。?,2)將使圖片在兩個(gè)維度上均變?yōu)樵L(zhǎng)的一半。為整數(shù)意為各個(gè)維度值相同且為該數(shù)字。

AveragePooling2D層

為空域信號(hào)施加平均值池化

GlobalMaxPooling2D層

為空域信號(hào)施加全局最大值池化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容