Red Huang

Red Huang

使用多個GPU進行快速訓練的Keras

使用多个 GPU 进行高效训练的 keras#

由于实验室的电脑目前装有三张高性能的 GPU,但为了让 keras 发挥其效益,需要更改代码

当前环境为 keras 配上 tensorflow 后端,python3
三张 1080ti 显卡

我们原先的网络架构是 Sequential 架构(简单介绍)

image

所以每个批次都是通过 GPU 接收任务的方式执行

也就是平均分配给每个 GPU

但是显然所有的 GPU 无法充分利用

所以我们需要将批次切分成 GPU 的数量(有三片就切成三等份)
然后将所有批次的结果合并为一个输出,这样可以加快计算速度(当然每个 GPU 也会有输出限制)

使用下面的代码将 x 切分成(n_gpus) 等份,注意此时的 x 并不是真正的数字而是 tensor(即还没有运行出来的值)

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] 

之后将 model 传入下面的函数,就会将当前这个 model 加上(n_gpus) 个 lambda 层接在 input 上

然后将这些结果全部合并为输出(并以 batch 的 axis 合并)

def to_multi_gpu(model, n_gpus=3):
    with tf.device('/cpu:0'):
        print(model.input_shape)
        x = Input(model.input_shape[1:], name="input")

    towers = []
    for g in range(n_gpus):
        with tf.device('/gpu:' + str(g)):
            slice_g = Lambda(slice_batch, lambda shape: shape, arguments={'n_gpus': n_gpus, 'part': g})(x)
            towers.append(model(slice_g))

    with tf.device('/cpu:0'):
        merged = Concatenate(axis=0)(towers)

    return Model(inputs=[x], outputs=[merged]) 

使用完的结果会类似下面的图
image

没有使用此技巧时训练的时间为

160 个 epoch: 23 分钟

使用此技巧平均分配到三张显卡上的时间为

160 个 epoch: 9 分钟

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。