python - 如何在单个 gpu 上运行多个 keras 程序?
问题描述
我正在开发一个 python 项目,我需要为每个数据集构建多个 Keras 模型。在这里,当我运行构建程序的 Keras 模型时,我使用了 10% 的 GPU(GTX 1050ti)。
我的问题是我可以使用我的 gpu 100% 来减少时间吗?还是有可能在同一个 gpu 上运行多个程序?
我试图在单个 gpu 上运行多个程序,但它没有并行运行,例如,当我运行单个 python 程序时,每个 epoch 需要 5 秒,而如果我为每个 epoch 运行 2 个程序,则持续时间增加到 10 秒,运行多个程序的最佳方法是什么。
提前致谢!!
解决方案
不确定是否有正确的方法可以做到这一点,但这个“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)
与以前的解决方案相比的优势:操作数据和自定义重塑的麻烦更少。
推荐阅读
- c# - IMongoCollection Substitute 上的模拟数据
- c# - 具有动态策略提供程序授权的 .NET Core 多重身份验证
- ruby-on-rails - Ruby:如何记录对象并将其重用于测试?
- angular - 使用实体适配器 ngrx 创建子减速器
- python-3.x - 在 psycopg2 中使用循环查询和数据元组的更新语句失败
- mysql - 所以我试图了解 sql 中的 Exists 条件。我知道如果存在一个或多个元组,它会返回 True
- python - 使用现有函数,如何定义具有不同默认可选参数的新函数?
- python - 根据 output2 值从 output1 打印行
- typo3 - TYPO3 - 如何通过前端用户登录限制所有页面,但登录页面本身
- r - 隐藏复选框组选项之一,但仍保持其功能处于激活状态