如何在单个gpu上运行多个keras程序?

时间:2018-05-22 18:34:10

标签: python tensorflow keras

我正在开发一个python项目,我需要为每个数据集构建多个Keras模型。在这里,当我运行Keras模型时,程序正在使用我的GPU的10%(GTX 1050ti)。

我的问题是我可以100%使用我的gpu来减少时间吗?或者是否有可能在同一个GPU上运行多个程序?

我曾尝试在单个gpu上运行多个程序,但它没有并行运行,例如当我运行单个python程序时,每个时期需要5秒,而如果我为每个时期运行2个程序,则持续时间会增加到10秒,运行多个程序的最佳方法是什么。

提前致谢!!

2 个答案:

答案 0 :(得分:4)

不确定是否有正确的方法可以做到这一点,但这个“gambiarra”可能效果很好,似乎。

制作一个模型并行连接两个或多个模型。唯一的缺点是:在训练和并行预测时,您需要相同数量的输入样本。

如何将两个模型与功能API模型并行使用:

input1 = Input(inputShapeOfModel1)
input2 = Input(inputShapeOfModel2)

output1 = model1(input1)
output2 = model2(input2) #it could be model1 again, using model1 twice in parallel. 

parallelModel = Model([input1,input2], [output1,output2])

使用此模型训练和预测,传递并行输入和输出数据:

parallelModel.fit([x_train1, x_train2], [y_train1, y_train2], ...)

工作测试代码:

from keras.layers import *
from keras.models import Model, Sequential
import numpy as np

#simulating two "existing" models
model1 = Sequential()
model2 = Sequential()

#creating "existing" model 1
model1.add(Conv2D(10,3,activation='tanh', input_shape=(20,20,3)))
model1.add(Flatten())
model1.add(Dense(1,activation='sigmoid'))

#creating "existing" model 2
model2.add(Dense(20, input_shape=(2,)))
model2.add(Dense(3))


#part containing the proposed answer: joining the two models in parallel
inp1 = Input((20,20,3))
inp2 = Input((2,))

out1 = model1(inp1)
out2 = model2(inp2)

model = Model([inp1,inp2],[out1,out2])


#treat the new model as any other model
model.compile(optimizer='adam', loss='mse')

#dummy input data x and y, for models 1 and 2
x1 = np.ones((30,20,20,3))
y1 = np.ones((30,1))
x2 = np.ones((30,2))
y2 = np.ones((30,3))

#training the model and predicting
model.fit([x1,x2],[y1,y2], epochs = 50)
ypred1,ypred2 = model.predict([x1,x2])

print(ypred1.shape)
print(ypred2.shape)

高级解决方案 - 为速度分组数据并匹配样本量

还有更多优化空间,因为这种方法可以在两个模型之间同步批次。因此,如果模型比另一个模型快得多,则快速模型将根据慢模型的速度进行调整。

此外,如果您有不同数量的批次,则需要单独培训/预测一些剩余数据。

如果您对输入数据进行分组并在模型中使用一些自定义整形,您可以解决这些限制,其中Lambda图层在开始时重新整形批量维度,然后在结束时将其恢复。

例如,如果x1有300个样本且x2有600个样本,则可以重新整形输入和输出:

x2 = x2.reshape((300,2,....))
y2 = y2.reshape((300,2,....))

model2之前和之后,您使用:

#before
Lambda(lambda x: K.reshape(x,(-1,....))) #transforms in the inner's model input shape

#after
Lambda(lambda x: K.reshape(x, (-1,2,....))) #transforms in the grouped shape for output

其中....是原始输入和输出形状(不考虑batch_size)。

然后你需要思考哪个是最好的,组数据来同步数据大小或组数据以同步速度。

(优势与下一个解决方案相比:您可以轻松按任意数量进行分组,例如2,5,10,200 ......)

高级解决方案 - 与双倍速度并行使用相同模型多次

您也可以并行使用相同的模型,例如在此代码中。这可能会加倍其速度。

from keras.layers import *
from keras.models import Model, Sequential
#import keras.backend as K
import numpy as np
#import tensorflow as tf


#simulating two "existing" models
model1 = Sequential()
model2 = Sequential()

#model 1
model1.add(Conv2D(10,3,activation='tanh', input_shape=(20,20,3)))
model1.add(Flatten())
model1.add(Dense(1,activation='sigmoid'))

#model 2
model2.add(Dense(20, input_shape=(2,)))
model2.add(Dense(3))

#joining the models
inp1 = Input((20,20,3))

#two inputs for model 2 (the model we want to run twice as fast)
inp2 = Input((2,))
inp3 = Input((2,))

out1 = model1(inp1)
out2 = model2(inp2) #use model 2 once
out3 = model2(inp3) #use model 2 twice

model = Model([inp1,inp2,inp3],[out1,out2,out3])

model.compile(optimizer='adam', loss='mse')

#dummy data - remember to have two inputs for model 2, not repeated
x1 = np.ones((30,20,20,3))
y1 = np.ones((30,1))
x2 = np.ones((30,2)) #first input for model 2
y2 = np.ones((30,3)) #first output for model 2
x3 = np.zeros((30,2)) #second input for model 2
y3 = np.zeros((30,3)) #second output for model 2

model.fit([x1,x2,x3],[y1,y2,y3], epochs = 50)
ypred1,ypred2,ypred3 = model.predict([x1,x2,x3])

print(ypred1.shape)
print(ypred2.shape)
print(ypred3.shape)

与之前的解决方案相比的优势:操作数据和自定义重塑更少麻烦。

答案 1 :(得分:-2)

高级解决方案部分-以两倍的速度并行使用同一模型多次,我发现我的模型无法准确预测结果。

我想并行计算具有相同输入和输出形状但不同填充数据的多个keras模型,这些模型共享相同的结构但具有不同的权重矩阵。此外,如何为“ mse”的不同子模型设置多重损失函数。通过使用您的方法,模型内部只有一个序列层,所以我想知道out2和out3在模型中共享相同的权重矩阵吗?