Keras 2.X版本后可以很方便的支持使用多GPU進行訓(xùn)練了,使用多GPU可以提高我們的訓(xùn)練過程,比如加速和解決內(nèi)存不足問題稚照。
多GPU其實分為兩種使用情況:數(shù)據(jù)并行和設(shè)備并行策精。
數(shù)據(jù)并行將目標模型在多個設(shè)備上各復(fù)制一份,并使用每個設(shè)備上的復(fù)制品處理整個數(shù)據(jù)集的不同部分數(shù)據(jù)莱革。Keras在 keras.utils.multi_gpu_model 中提供有內(nèi)置函數(shù)峻堰,該函數(shù)可以產(chǎn)生任意模型的數(shù)據(jù)并行版本讹开,最高支持在8片GPU上并行。
數(shù)據(jù)并行是指將我們的模型放到多個GPU上去跑茧妒,來處理數(shù)據(jù)集的不同部分萧吠,Keras的keras.utils.multi_gpu_model支持任意模型的數(shù)據(jù)并行,最多支持8個GPU桐筏。我們大多數(shù)時候要用到的都是數(shù)據(jù)并行纸型,其他需求可以參考這篇博客:Keras多GPU及分布式。
這里就給出數(shù)據(jù)并行的多GPU訓(xùn)練示例:
from keras.utils.training_utils import multi_gpu_model #導(dǎo)入keras多GPU函數(shù)
model = get_model()
parallel_model = multi_gpu_model(model, gpus=2) # 設(shè)置使用2個gpu梅忌,該句放在模型compile之前
parallel_model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
hist = parallel_model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs_num, validation_data=(x_test, y_test), verbose=1, callbacks=callbacks)
你還可以指定要哪幾個GPU來跑:
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "3,5"
使用命令“nvidia-smi”可以查看各GPU的使用情況和序號狰腌,上面代碼就是指定用序號為3和5的兩個GPU來跑訓(xùn)練。
其實這樣就可以了牧氮,就是這么簡單琼腔。
但是實際運行中,我還是遇到了一些報錯踱葛。
報錯1:
ValueError: Variable batch_normalization_1/moving_mean/biased already exists, disallowed. Did you mean to set reuse=True in VarScope? Originally defined at:
我使用單GPU訓(xùn)練的時候沒有問題丹莲,改成多GPU后出現(xiàn)這個問題。這個問題好解決尸诽,將Tensorflow升級到1.4即可甥材。
報錯2:
TypeError: can't pickle ...(different text at different situation) objects
查找資料后,發(fā)現(xiàn)可能源于callbacks.ModelCheckpoint() 并進行多 gpu 并行計算時性含,使用姿勢不對導(dǎo)致callbacks 函數(shù)報錯洲赵。
我在代碼中為了保存最優(yōu)的訓(xùn)練模型,加了這個callback:
checkpoint = ModelCheckpoint(filepath='./cifar10_resnet_ckpt.h5', monitor='val_acc', verbose=1,save_best_only=True)
而在改為多GPU訓(xùn)練后商蕴,每次回調(diào)存儲的模型變成了parallel_model叠萍,這會導(dǎo)致報錯,只需要改成依然保存原本的model即可绪商,所以我們需要改一下:
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(model, filepath='./cifar10_resnet_ckpt.h5', monitor='val_acc', verbose=1, save_best_only=True) # 解決多GPU運行下保存模型報錯的問題
其余的不變苛谷,也就是改為依然存儲原本的model即可。還有其他的改法可以參考這篇博客:[Keras] 使用多 gpu 并行訓(xùn)練并使用 ModelCheckpoint() 可能遇到的問題格郁,思路都是一樣的腹殿,只是改法不同。
這樣就能夠成功使用多GPU訓(xùn)練啦理张。