저는 8 gpu에 대해 교육을받은 Keras 모델을 보유하고 있습니다. 즉, 모델에 with tf.device('gpu:0')
과 같은 블록이 있음을 의미합니다. 이제 4GPus가있는 다른 PC로 전송 학습을 적용하고 싶습니다. 그러나이 모델은 더 많은 gpus (error: could not set cudnn tensor descriptor: CUDNN_STATUS_BAD_PARAM
)에서 교육을 받았기 때문에 오류가 발생합니다. 오류 로그에서 tensorflow가 장치 GPU 0-7에서 그라디언트를 함께 배치하려고한다는 경고를 볼 수도 있습니다. Keras로 구성된 훈련 된 모델에서 장치를 적용하거나 지울 수있는 방법이 있습니까?훈련되고 다시로드 된 Keras 모델에서 장치 할당 변경
는 참고 : 모델이 또한 tensorflow 보호기 기능을 Keras로하지
현재 시도
내가 시도를 저장 한 때문에, 메타 그래프 파일이없는 레이어 속성을 변경하지만 작동하지는 못했습니다.
track = 0
for i in range(len(model.layers)):
if model.layers[i].name[:6] == 'lambda':
model.layers[i].arguments['n_gpus'] = n_gpus
if model.layers[i].arguments['part'] > n_gpus-1:
model.layers[i].arguments['part'] = np.arange(n_gpus)[track]
track += 1
if track > n_gpus-1:
track = 0
import os
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1,2,3"
스크립트가 8 개 GPU를
"""
to_multi_gpu & slice_batch by: https://github.com/fchollet/keras/issues/2436
baseline_model by: http://machinelearningmastery.com/
"""
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Dense, Input, Lambda, merge
import tensorflow as tf
def slice_batch(x, n_gpus, part):
"""
Divide the input batch into [n_gpus] slices, and obtain slice no. [part]
i.e. if len(x)=10, then slice_batch(x, 2, 1) will return x[5:].
x: input batch (input shape of model)
n_gpus: number of gpus
part: id of current gpu
return: sliced model per gpu
"""
sh = K.shape(x)
L = sh[0] // n_gpus
if part == n_gpus - 1:
return x[part*L:]
return x[part*L:(part+1)*L]
def to_multi_gpu(model, n_gpus):
"""
Given a keras [model], return an equivalent model which parallelizes
the computation over [n_gpus] GPUs.
Each GPU gets a slice of the input batch, applies the model on that slice
and later the outputs of the models are concatenated to a single
tensor, hence the user sees a model that behaves the same as the original.
model: sequential model created with the Keras library
n_gpus: number of gpus
return: model divided over n_gpus
"""
# Only divide model over multiple gpus if there is more than one
if n_gpus > 1:
with tf.device('/cpu:0'):
x = Input(model.input_shape[1:])#, name=model.input_names[0]
towers = []
# Divide model over gpus
for g in range(n_gpus):
# Work on GPU number g.
with tf.device('/gpu:' + str(g)):
# Obtain the g-th slice of the batch.
slice_g = Lambda(slice_batch, lambda shape: shape,
arguments={'n_gpus':n_gpus, 'part':g})(x)
# Apply model on the batch slice.
towers.append(model(slice_g))
# Merge multi-gpu outputs with cpu
with tf.device('/cpu:0'):
merged = merge(towers, mode='concat', concat_axis=0)
return Model(input=[x], output=merged)
else:
return model
def baseline_model(num_pixels, num_classes, n_gpus):
# create model
model = Sequential()
model.add(Dense(num_pixels, input_dim=num_pixels, init='normal', activation='relu'))
model.add(Dense(num_classes, init='normal', activation='softmax'))
model = to_multi_gpu(model, n_gpus)
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
if __name__ == '__main__':
model = baseline_model(784, 9, 8)