keras(tensorflow)对后端GPU的灵活使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013044310/article/details/81433231

一、指定对应的GPU(适用于tensorflow,keras)

如果你土豪到有自己的专用服务器那就完全可以忽略这一节,但是大多数时候,我们需要和实验室或者公司的其他人共用一台服务器。一般深度学习程序需要跑一天甚至几天。为了避免你们程序之间的“相爱相杀”,最终谁都跑不成的悲惨结局,那么就需要在跑程序之前先封疆而治,指定自己的势力范围。

首先,先要知道实验室(公司)的显卡有多少,再决定怎么分蛋糕。只需要打开终端,输入:nvidia-smi 一般会显示这样一张图片:

显卡型号

可以看到,这台服务器上有四块 1TB 的显卡,编号分别是:0,1,2,3。

或者为了持续观察显卡用量也可以设置动态刷新查看:

# 设置1秒钟动态刷新一次(1可以调整成别的数字)
watch -n 1 nvidia-smi

知道了显卡的数量和代号,那么,指定对应的显卡只需要在开头加入如下代码:

import os
#使用第12张显卡
os.environ["CUDA_VISIBLE_DEVICES"] = "0, 1"

指定之后,在运行该程序的时候,tensorflow只会加载代号为0,1的这两张显卡为可用状态。别的显卡会自动屏蔽。但是,这只是你占用了多个显卡,占有和使用还是两个不同的概念。就好比你占有两亩地,这两块地就是你的,但是,要想让自己的田地发挥价值,还必须在田地里耕种,否则只是白白的浪费土地资源。最典型的一种浪费是:如果不是特殊设置,很多时候tensorflow和keras一般都在单显卡上工作,这样,如果没有进行多显卡部署部署,即使你占有了两块显卡,在程序执行时也仅仅使用了一块显卡,要想让多显卡同时为你的程序服务,就需要部署多GPU并行处理。另外,在同时需要跑多个程序的情况下,也会指定每个程序对GPU的用量。

二、指定GPU用量

当然,有时候对于小型的深度学习程序,或者实验室显卡紧缺的情况下(比如三个人要在两个GPU的显卡上跑程序),也可以精确指定每块GPU的用量,来榨干GPU的劳动力(有时候也为了防止服务器卡死)。代码如下:

1、固定GPU用量
import tensorflow as tf
import keras.backend.tensorflow_backend as KTF

#进行配置,使用30%的GPU
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.3
session = tf.Session(config=config)

# 设置session
KTF.set_session(session )
2、当然,也可以对GPU用量进行动态调整:
import tensorflow as tf
import keras.backend.tensorflow_backend as KTF

config = tf.ConfigProto()  
config.gpu_options.allow_growth=True   #不全部占满显存, 按需分配
session = tf.Session(config=config)

# 设置session
KTF.set_session(sess)

三、keras下的多GPU运行

当然,有用时间换取多个程序同时运行的,也有的时候需要将一个程序部署在多个GPU上节省时间的。大多数情况下采用数据并行的方式就可以解决,具体如下:

用到的包是: multi_gpu_model

用到的函数是: keras.utils.multi_gpu_model(model, gpus)

它按照下面的方式工作:

(1)将模型的输入分为多个子batch
(2)在每个设备上调用各自的模型,对各自的数据集运行
(3)将结果连接为一个大的batch(在CPU上)

例如,你的batch_size是64而gpus=2,则输入会被分为两个大小为32的子batch,在两个GPU上分别运行,通过连接后返回大小为64的结果。 该函数线性的增加了训练速度,最高支持8卡并行。

当然,该函数只能在tf后端下使用。

参数如下:

  • model: Keras模型对象,为了避免OOM错误(内存不足),该模型应在CPU上构建。
  • gpus: 大或等于2的整数,要并行的GPU数目。该函数返回Keras模型对象,它看起来跟普通的keras模型一样,但实际上分布在多个GPU上。

官方给出的例子:

import tensorflow as tf
from keras.applications import Xception
from keras.utils import multi_gpu_model
import numpy as np

num_samples = 1000
height = 224
width = 224
num_classes = 1000

# 初始化模型
# (here, we do it on CPU, which is optional).
with tf.device('/cpu:0'):
    model = Xception(weights=None,
                     input_shape=(height, width, 3),
                     classes=num_classes)

# 在 8 个 GPU上训练模型.
# This assumes that your machine has 8 available GPUs.
parallel_model = multi_gpu_model(model, gpus=8)
parallel_model.compile(loss='categorical_crossentropy',
                       optimizer='rmsprop')

# Generate dummy data.
x = np.random.random((num_samples, height, width, 3))
y = np.random.random((num_samples, num_classes))

# 这个 `fit` 操作将会分布在 8 个 GPU上.
# 如果 batch size 为 256, 则每个 GPU 将处理 32 个样本.
parallel_model.fit(x, y, epochs=20, batch_size=256)

另外还有一个minist数据集下的例子:

'''Trains a simple deep NN on the MNIST dataset.
Gets to 98.40% test accuracy after 20 epochs
(there is *a lot* of margin for parameter tuning).
2 seconds per epoch on a K520 GPU.
'''

from __future__ import print_function

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop
from keras.utils import multi_gpu_model

batch_size = 128
num_classes = 10
epochs = 20

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')


# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)


model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))


model = multi_gpu_model(model, 2)
model.summary()


model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])


history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])

最后,附上一个linux下查看cpu信息的操作:Ubuntu – 下如何查看CPU信息, 包括位数和多核信息

展开阅读全文

没有更多推荐了,返回首页