MXNet GPU 设置和解耦

2,084 阅读2分钟

本文涉及如何运行MXNet的GPU环境,以及一些技巧,其中,包括环境解耦和环境设置。

环境解耦

MXNet的运行环境context,可分为CPU和GPU,一般本地电脑是CPU,远程服务器是GPU,那么如何兼容两类环境呢?即在不修改源码的前提下,解耦运行环境。

Config是一种可选方案。在工程中,添加config文件,如configs.conf,配置GPU和batch_size等信息。在本地电脑中,is_gpu是False,batch_size较小是8;在远程服务器中,is_gpu是True,batch_size较大是64。同时,在.gitignore中,忽略配置文件,避免干扰。

例如,本地电脑的配置,如下:

[net]
is_gpu = False
batch_size = 8

自动选择环境的逻辑,其中,需要使用configparser库,将配置转换为字典:

from configparser import ConfigParser

def get_configs():
    cf = ConfigParser()
    cf.read(os.path.join(ROOT_DIR, 'configs.conf'))
    is_gpu = cf.getboolean("net", "is_gpu")
    batch_size = cf.getint("net", "batch_size")
    return {'is_gpu': is_gpu, 'batch_size': batch_size}

configs = get_configs()
is_gpu = configs['is_gpu']
batch_size = configs['batch_size']

接着,根据is_gpu参数,将ctx设置为GPU,即mx.gpu(0),或CPU,即mx.cpu()。

ctx = get_context(is_gpu)

def get_context(is_gpu):
    ctx = mx.gpu(0) if is_gpu > 0 else mx.cpu()
    return ctx

这样,在服务器端,只需要重新设置一份配置环境,即可,如:

[net]
is_gpu = True
batch_size = 64

这样,就完成了MXNet在不同配置的机器中的环境解耦。

环境设置

运行环境CPU或GPU,在网络初始化时,需要设置ctx参数,如在迁移学习中,对于预训练模型的环境设置:

  • 层初始化initialize(),支持设置ctx;
  • 网络参数调用reset_ctx(),重置ctx;

如下:

def get_base_net(ctx):
    base_net = get_model('mobilenet1.0', pretrained=True)
    with base_net.name_scope():
        base_net.output = Dense(units=27)  # 全连接层
    base_net.output.initialize(Xavier(), ctx=ctx)  # 初始化
    base_net.collect_params().reset_ctx(ctx)  # 重置ctx
    base_net.hybridize()
    return base_net

数据与模型需要环境匹配,通过as_in_context(),修改数据的context。

data = data.as_in_context(context=ctx)
labels = labels.as_in_context(context=ctx)

base_net = get_base_net(ctx=ctx)
outputs = base_net(data)

注意:as_in_context只支持单GPU环境,即mx.gpu(0),不支持GPU数组,如[mx.gpu(0), mx.gpu(1), mx.gpu(2)],参考GitHub Issue

同时,数据之间,也需要context匹配,如data和label,不匹配则会报错。

loss_func = SigmoidBinaryCrossEntropyLoss()
loss = loss_func(outputs, labels)

最后推荐一篇文档:Training on multiple GPUs with gluon

That's all! Enjoy it!

更多算法技巧,关注微信公众号:深度算法(ID: DeepAlgorithm)