keras 多gpu并行運行案例
一、多張gpu的卡上使用keras
有多張gpu卡時,推薦使用tensorflow 作為后端。使用多張gpu運行model,可以分為兩種情況,一是數(shù)據(jù)并行,二是設(shè)備并行。
二、數(shù)據(jù)并行
數(shù)據(jù)并行將目標模型在多個設(shè)備上各復(fù)制一份,并使用每個設(shè)備上的復(fù)制品處理整個數(shù)據(jù)集的不同部分數(shù)據(jù)。
利用multi_gpu_model實現(xiàn)
keras.utils.multi_gpu_model(model, gpus=None, cpu_merge=True, cpu_relocation=False)
具體來說,該功能實現(xiàn)了單機多 GPU 數(shù)據(jù)并行性。 它的工作原理如下:
將模型的輸入分成多個子批次。
在每個子批次上應(yīng)用模型副本。 每個模型副本都在專用 GPU 上執(zhí)行。
將結(jié)果(在 CPU 上)連接成一個大批量。
例如, 如果你的 batch_size 是 64,且你使用 gpus=2, 那么我們將把輸入分為兩個 32 個樣本的子批次, 在 1 個 GPU 上處理 1 個子批次,然后返回完整批次的 64 個處理過的樣本。
參數(shù)
model: 一個 Keras 模型實例。為了避免OOM錯誤,該模型可以建立在 CPU 上, 詳見下面的使用樣例。
gpus: 整數(shù) >= 2 或整數(shù)列表,創(chuàng)建模型副本的 GPU 數(shù)量, 或 GPU ID 的列表。
cpu_merge: 一個布爾值,用于標識是否強制合并 CPU 范圍內(nèi)的模型權(quán)重。
cpu_relocation: 一個布爾值,用來確定是否在 CPU 的范圍內(nèi)創(chuàng)建模型的權(quán)重。如果模型沒有在任何一個設(shè)備范圍內(nèi)定義,您仍然可以通過激活這個選項來拯救它。
返回
一個 Keras Model 實例,它可以像初始 model 參數(shù)一樣使用,但它將工作負載分布在多個 GPU 上。
例子
import tensorflow as tf
from keras.applications import Xception
from keras.utils import multi_gpu_model
import numpy as np
num_samples = 1000
height = 224
width = 224
num_classes = 1000
# 實例化基礎(chǔ)模型(或者「模版」模型)。
# 我們推薦在 CPU 設(shè)備范圍內(nèi)做此操作,
# 這樣模型的權(quán)重就會存儲在 CPU 內(nèi)存中。
# 否則它們會存儲在 GPU 上,而完全被共享。
with tf.device('/cpu:0'):
model = Xception(weights=None,
input_shape=(height, width, 3),
classes=num_classes)
# 復(fù)制模型到 8 個 GPU 上。
# 這假設(shè)你的機器有 8 個可用 GPU。
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
optimizer='rmsprop')
# 生成虛擬數(shù)據(jù)
x = np.random.random((num_samples, height, width, 3))
y = np.random.random((num_samples, num_classes))
# 這個 `fit` 調(diào)用將分布在 8 個 GPU 上。
# 由于 batch size 是 256, 每個 GPU 將處理 32 個樣本。
parallel_model.fit(x, y, epochs=20, batch_size=256)
# 通過模版模型存儲模型(共享相同權(quán)重):
model.save('my_model.h5')
注意:
要保存多 GPU 模型,請通過模板模型(傳遞給 multi_gpu_model 的參數(shù))調(diào)用 .save(fname) 或 .save_weights(fname) 以進行存儲,而不是通過 multi_gpu_model 返回的模型。
即要用model來保存,而不是parallel_model來保存。
使用ModelCheckpoint() 遇到的問題
使用ModelCheckpoint()會遇到下面的問題:
TypeError: can't pickle ...(different text at different situation) objects
這個問題和保存問題類似,ModelCheckpoint() 會自動調(diào)用parallel_model.save()來保存,而不是model.save(),因此我們要自己寫一個召回函數(shù),使得ModelCheckpoint()用model.save()。
修改方法:
class ParallelModelCheckpoint(ModelCheckpoint): def __init__(self,model,filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1): self.single_model = model super(ParallelModelCheckpoint,self).__init__(filepath, monitor, verbose,save_best_only, save_weights_only,mode, period) def set_model(self, model): super(ParallelModelCheckpoint,self).set_model(self.single_model) checkpoint = ParallelModelCheckpoint(original_model)
ParallelModelCheckpoint調(diào)用的時候,model應(yīng)該為原來的model而不是parallel_model。
EarlyStopping 沒有此類問題
二、設(shè)備并行
設(shè)備并行適用于多分支結(jié)構(gòu),一個分支用一個gpu。
這種并行方法可以通過使用TensorFlow device scopes實現(xiàn),下面是一個例子:
# Model where a shared LSTM is used to encode two different sequences in parallel
input_a = keras.Input(shape=(140, 256))
input_b = keras.Input(shape=(140, 256))
shared_lstm = keras.layers.LSTM(64)
# Process the first sequence on one GPU
with tf.device_scope('/gpu:0'):
encoded_a = shared_lstm(tweet_a)
# Process the next sequence on another GPU
with tf.device_scope('/gpu:1'):
encoded_b = shared_lstm(tweet_b)
# Concatenate results on CPU
with tf.device_scope('/cpu:0'):
merged_vector = keras.layers.concatenate([encoded_a, encoded_b],
axis=-1)
三、分布式運行
keras的分布式是利用TensorFlow實現(xiàn)的,要想完成分布式的訓(xùn)練,你需要將Keras注冊在連接一個集群的TensorFlow會話上:
server = tf.train.Server.create_local_server() sess = tf.Session(server.target) from keras import backend as K K.set_session(sess)
以上這篇keras 多gpu并行運行案例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Pycharm創(chuàng)建項目時如何自動添加頭部信息
這篇文章主要介紹了Pycharm創(chuàng)建項目時 自動添加頭部信息,需要的朋友可以參考下2019-11-11
正則化DropPath/drop_path用法示例(Python實現(xiàn))
DropPath 類似于Dropout,不同的是 Drop將深度學(xué)習(xí)模型中的多分支結(jié)構(gòu)隨機"失效",而Dropout是對神經(jīng)元隨機"失效"這篇文章主要給大家介紹了關(guān)于正則化DropPath/drop_path用法的相關(guān)資料,需要的朋友可以參考下2022-04-04
Python中的xml與dict的轉(zhuǎn)換方法詳解
Python的Flask框架中實現(xiàn)簡單的登錄功能的教程

