如何在Keras中使用multigpu与共享权重应用mod

2024-03-28 23:32:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在多gpu中使用keras和应用程序(比如VGG16)。但是有一些错误。在

我试着用单一的GPU这是正确的。但是多gpu是错误的。 代码如下:

import keras
    with tf.device('/cpu:0'):
        input1 = keras.layers.Input(config.input_shape)
        input2 = keras.layers.Input(config.input_shape)
        sub_model = keras.applications.VGG16(include_top=False, weights=config.VGG_MODEL_PATH,
                                             input_shape=config.input_shape)
        output1 = sub_model(input1)
        output2 = sub_model(input1)
        model = keras.Model(inputs=[input1, input2], outputs=[output1, output2])
    parallel_model = keras.utils.multi_gpu_model(model, gpus=3)
    parallel_model.compile('sgd', loss=['mse', 'mse'])
    parallel_model.fit((np.random.random([10, 128, 128, 3]), np.random.random([10, 128, 128, 3])),
                       (np.random.random([10, 4, 4, 512]), np.random.random([10, 4, 4, 512])))

错误消息是

^{pr2}$

Tags: configinputmodelgpuparallellayers错误np
2条回答

我发现有一个不明智的解决办法。 有解决方案代码:

import tensorflow as tf
from tensorflow.keras import backend as K


def slice_batch(x, n_gpus, part):
    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 multi_gpu_wrapper(single_model, num_gpu):
    inputs = single_model.inputs
    towers = []
    splited_layer = tf.keras.layers.Lambda(lambda x: slice_batch(x, num_gpu, gpu_id))
    concate_layer = tf.keras.layers.Concatenate(axis=0)
    with tf.device('/cpu:0'):
        for gpu_id in range(num_gpu):
            cur_inputs = []
            for input in inputs:
                cur_inputs.append(
                    splited_layer(input)
                )
            towers.append(single_model(cur_inputs))
            print towers[-1]
    outputs = []
    num_output = len(towers[-1])
    with tf.device('/cpu:0'):
        for i in range(num_output):
            tmp_outputs = []
            for j in range(num_gpu):
                tmp_outputs.append(towers[j][i])
            outputs.append(concate_layer(tmp_outputs))
    multi_gpu_model = tf.keras.models.Model(inputs=inputs, outputs=outputs)
    return multi_gpu_model


if __name__ == '__main__':
    import config
    import os
    import numpy as np
    gpu_ids = "0,1,3"
    os.environ["CUDA_VISIBLE_DEVICES"] = gpu_ids
    with tf.device('/cpu:0'):
        input1 = tf.keras.layers.Input(config.input_shape)
        input2 = tf.keras.layers.Input(config.input_shape)
        sub_model = tf.keras.applications.VGG16(include_top=False, weights=config.VGG_MODEL_PATH,
                                                input_shape=config.input_shape)
        output1 = sub_model(input1)
        output2 = sub_model(input2)
        model = tf.keras.Model(inputs=[input1, input2], outputs=[output1, output2])
    multi_gpu_model = multi_gpu_wrapper(model, 3)
    multi_gpu_model.compile('sgd', loss=['mse', 'mse'])
    multi_gpu_model.fit([np.random.random([1000, 128, 128, 3]), np.random.random([1000, 128, 128, 3])],
                        [np.random.random([1000, 4, 4, 512]), np.random.random([1000, 4, 4, 512])], batch_size=128)

但是,我发现这个解决方案中GPU的使用率很低。在

我只是猜测,但它在你的错误日志中说“名称”vgg16“在模型中使用了2次”。在

我想如果你创建output1和output2

    output1 = sub_model(input1)

    output2 = sub_model(input1)

并将其添加到模型中,创建VGG16模型的重复层名称。 也许你可以使用另一个输入(input2)?在

也可以尝试重命名模型:

^{pr2}$

如果您能提供更多代码,我可能会测试您的代码并尝试解决问题:)

This似乎也是一个类似的问题。在

希望这有帮助。在

相关问题 更多 >