keras 多gpu並行執行案例
一、多張gpu的卡上使用keras
有多張gpu卡時,推薦使用tensorflow 作為後端。使用多張gpu執行model,可以分為兩種情況,一是資料並行,二是裝置並行。
二、資料並行
資料並行將目標模型在多個裝置上各複製一份,並使用每個裝置上的複製品處理整個資料集的不同部分資料。
利用multi_gpu_model實現
keras.utils.multi_gpu_model(model,gpus=None,cpu_merge=True,cpu_relocation=False)
具體來說,該功能實現了單機多 GPU 資料並行性。 它的工作原理如下:
將模型的輸入分成多個子批次。
在每個子批次上應用模型副本。 每個模型副本都在專用 GPU 上執行。
將結果(在 CPU 上)連線成一個大批量。
例如, 如果你的 batch_size 是 64,且你使用 gpus=2, 那麼我們將把輸入分為兩個 32 個樣本的子批次, 在 1 個 GPU 上處理 1 個子批次,然後返回完整批次的 64 個處理過的樣本。
引數
model: 一個 Keras 模型例項。為了避免OOM錯誤,該模型可以建立在 CPU 上, 詳見下面的使用樣例。
gpus: 整數 >= 2 或整數列表,建立模型副本的 GPU 數量, 或 GPU ID 的列表。
cpu_merge: 一個布林值,用於標識是否強制合併 CPU 範圍內的模型權重。
cpu_relocation: 一個布林值,用來確定是否在 CPU 的範圍內建立模型的權重。如果模型沒有在任何一個裝置範圍內定義,您仍然可以通過啟用這個選項來拯救它。
返回
一個 Keras Model 例項,它可以像初始 model 引數一樣使用,但它將工作負載分佈在多個 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 # 例項化基礎模型(或者「模版」模型)。 # 我們推薦在 CPU 裝置範圍內做此操作, # 這樣模型的權重就會儲存在 CPU 記憶體中。 # 否則它們會儲存在 GPU 上,而完全被共享。 with tf.device('/cpu:0'): model = Xception(weights=None,input_shape=(height,width,3),classes=num_classes) # 複製模型到 8 個 GPU 上。 # 這假設你的機器有 8 個可用 GPU。 parallel_model = multi_gpu_model(model,gpus=8) parallel_model.compile(loss='categorical_crossentropy',optimizer='rmsprop') # 生成虛擬資料 x = np.random.random((num_samples,height,3)) y = np.random.random((num_samples,num_classes)) # 這個 `fit` 呼叫將分佈在 8 個 GPU 上。 # 由於 batch size 是 256,每個 GPU 將處理 32 個樣本。 parallel_model.fit(x,y,epochs=20,batch_size=256) # 通過模版模型儲存模型(共享相同權重): model.save('my_model.h5')
注意:
要儲存多 GPU 模型,請通過模板模型(傳遞給 multi_gpu_model 的引數)呼叫 .save(fname) 或 .save_weights(fname) 以進行儲存,而不是通過 multi_gpu_model 返回的模型。
即要用model來儲存,而不是parallel_model來儲存。
使用ModelCheckpoint() 遇到的問題
使用ModelCheckpoint()會遇到下面的問題:
TypeError: can't pickle ...(different text at different situation) objects
這個問題和儲存問題類似,ModelCheckpoint() 會自動呼叫parallel_model.save()來儲存,而不是model.save(),因此我們要自己寫一個召回函式,使得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呼叫的時候,model應該為原來的model而不是parallel_model。
EarlyStopping 沒有此類問題
二、裝置並行
裝置並行適用於多分支結構,一個分支用一個gpu。
這種並行方法可以通過使用TensorFlow device scopes實現,下面是一個例子:
# 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實現的,要想完成分散式的訓練,你需要將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並行執行案例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。