zoukankan      html  css  js  c++  java
  • Gluon Package

    Gluon包有以下API:只选择高频api介绍。

    1. Parameter-参数相关

    1)class mxnet.gluon.Parameter(name, grad_req='write', shape=None, dtype=<type 'numpy.float32'="">, lr_mult=1.0, wd_mult=1.0, init=None, allow_deferred_init=False, differentiable=True, stype='default', grad_stype='default'

    Parameter类包含了Blocks的参数。当指定了Parameter.initialize(...)之后,Parameter在每个context,也就是设备上都会有一份参数的copy。

    ctx = mx.gpu(0)
    x = mx.nd.zeros((16, 100), ctx=ctx)
    w = mx.gluon.Parameter('fc_weight', shape=(64, 100), init=mx.init.Xavier())
    b = mx.gluon.Parameter('fc_bias', shape=(64,), init=mx.init.Zero())
    w.initialize(ctx=ctx)
    b.initialize(ctx=ctx)
    out = mx.nd.FullyConnected(x, w.data(ctx), b.data(ctx), num_hidden=64)

    代码利用到了参数的initialize方法:

    >>> weight = mx.gluon.Parameter('weight', shape=(2, 2))
    >>> weight.initialize(ctx=mx.cpu(0))
    >>> weight.data()
    [[-0.01068833  0.01729892]
     [ 0.02042518 -0.01618656]]
    
    >>> weight.grad()
    [[ 0.  0.]
     [ 0.  0.]]
    
    >>> weight.initialize(ctx=[mx.gpu(0), mx.gpu(1)])
    >>> weight.data(mx.gpu(0))
    [[-0.00873779 -0.02834515]
     [ 0.05484822 -0.06206018]]
    
    >>> weight.data(mx.gpu(1))
    [[-0.00873779 -0.02834515]
     [ 0.05484822 -0.06206018]]

    2)class mxnet.gluon.Constant(name, value)[source]

    不可变tensor,常量。常量被autograd和Trainer忽略,因此它们的值在训练期间不会改变。但是仍然可以使用set_data方法手动更新它们的值。
    常量s可以用以下任一项创建:

    const = mx.gluon.Constant('const', [[1,2],[3,4]])
    # or:
    class Block(gluon.Block):
        def __init__(self, **kwargs):
            super(Block, self).__init__(**kwargs)
            self.const = self.params.get_constant('const', [[1,2],[3,4]])

    3)class mxnet.gluon.ParameterDict(prefix='', shared=None)

    管理参数的字典。

    2. Containers-容器


    1. class mxnet.gluon.Block(prefix=None, params=None)

    所有神经网络层和模型的基类。

    from mxnet.gluon import Block, nn
    from mxnet import ndarray as F
    
    class Model(Block):
        def __init__(self, **kwargs):
            super(Model, self).__init__(**kwargs)
            # use name_scope to give child Blocks appropriate names.
            with self.name_scope():
                self.dense0 = nn.Dense(20)
                self.dense1 = nn.Dense(20)
    
        def forward(self, x):
            x = F.relu(self.dense0(x))
            return F.relu(self.dense1(x))
    
    model = Model()
    model.initialize(ctx=mx.cpu(0))
    model(F.zeros((10, 10), ctx=mx.cpu(0)))

    Block类主要方法:

    1) collect_params(select=None)

    返回一个ParameterDict类型,包含了Block和它孩子的参数。也可以选择一部分参数返回。例如选择指定的参数:[‘conv1_weight’, ‘conv1_bias’, ‘fc_weight’, ‘fc_bias’]:

    model.collect_params('conv1_weight|conv1_bias|fc_weight|fc_bias')

    或者搜集所有名字里有‘weight’或者‘bias’的参数,可以用正则匹配:

    model.collect_params('.*weight|.*bias')
    >>>model.collect_params()
    Out[5]: 
    model1_ (
      Parameter model1_dense0_weight (shape=(20, 10), dtype=float32)
      Parameter model1_dense0_bias (shape=(20,), dtype=float32)
      Parameter model1_dense1_weight (shape=(20, 20), dtype=float32)
      Parameter model1_dense1_bias (shape=(20,), dtype=float32)
    )
    >>>model.collect_params('.*bias')
    Out[6]: 
    model1_ (
      Parameter model1_dense0_bias (shape=(20,), dtype=float32)
      Parameter model1_dense1_bias (shape=(20,), dtype=float32)
    )

    2) initialize(init=, ctx=None, verbose=False, force_reinit=False)

    初始化Block及其孩子的参数,等效于:block.collect_params().initialize(...)

    model.collect_params().initialize(ctx=mx.cpu(0))
    # or:
    model.initialize(ctx=mx.cpu(0))

     

    3)load_parameters(filename, ctx=None, allow_missing=False, ignore_extra=False, cast_dtype=False, dtype_source='current')

    save_parameters(filename

    保存和载入模型。具体操作见这里

    注意的是:利用save_parameters保存的参数只能由load_parameters载入,这个方法只是保存了参数,没有保存网络。所以你要载入就得先初始化模型。而利用HybridBlock.export()方法可以同时保存模型和参数。

     

    2. class mxnet.gluon.HybridBlock(prefix=None, params=None)[source]

     这个混合block同时支持Symbol和NDArray的前向类似于上面的Block,有点不同:

    import mxnet as mx
    from mxnet.gluon import HybridBlock, nn
    
    class Model(HybridBlock):         # 区别1
        def __init__(self, **kwargs):
            super(Model, self).__init__(**kwargs)
            # use name_scope to give child Blocks appropriate names.
            with self.name_scope():
                self.dense0 = nn.Dense(20)
                self.dense1 = nn.Dense(20)
    
        def hybrid_forward(self, F, x):        # 区别2
            x = F.relu(self.dense0(x))
            return F.relu(self.dense1(x))
    
    model = Model()
    model.initialize(ctx=mx.cpu(0))
    model.hybridize()       # 区别3
    model(mx.nd.zeros((10, 10), ctx=mx.cpu(0)))

    如上有三处区别,利用hybrid就和symbol一起工作,变成了静态图,没法像NDArray那样索引。在使用hybridize()激活之前,HybridBlock的工作方式与普通Block类似。激活后,HybridBlock将创建一个表示正向计算的符号图并将其缓存。在随后的前向过程中,将使用缓存的图而不是hybrid_forward()。说白了就是hybrid是令gluon变成Module那样可以利用Symbol的办法。这里有个ref:Hybrid - Faster training and easy deployment

    方法的话介绍一个吧:export(path, epoch=0, remove_amp_cast=True)

    主要是保存hybridblock的模型和参数,将分别保存成json和param后缀的文件。⚠️这个保存后的结果有两种载入方式:一种就是SymbolBlock.imports,,另一种是mxnet.mod.Module 或C++ interface。demo见这里。

    3. class mxnet.gluon.SymbolBlock(outputs, inputs, params=None)[source]

    根据symbol来构建block。这对于利用预训练的模型作为特征提取器时是有用的。例如,可以从alexnet的fc2层来得到输出。

    参数中的outputs就是你想要得到的哪一层的输出,inputs就是输入变量,这两都是symbol类型或者symbol的列表类型。params是ParameterDict类型,就是关于参数argumetns和辅助参数auxililary的一个字典。例子好懂:

    # To extract the feature from fc1 and fc2 layers of AlexNet:
    alexnet = gluon.model_zoo.vision.alexnet(pretrained=True, ctx=mx.cpu(),      # 搞一个预训练的gluon模型,返回的是HybridBlock类型:
    inputs = mx.sym.var('data')      # 输入变量,symbol类型
    out = alexnet(inputs)            # 上面提到了HybridBlock同时支持symbol和ndarray的前向
    internals = out.get_internals()       # 得到所有层信息
    print(internals.list_outputs())       
    outputs = [internals['model_dense0_relu_fwd_output'],internals['model_dense1_relu_fwd_output']]   # 想分别得到fc1和fc2的输出
    # Create SymbolBlock that shares parameters with alexnet
    feat_model = gluon.SymbolBlock(outputs, inputs, params=alexnet.collect_params())   # 建立这个symbolblock,把预训练参数搞进来
    x = mx.nd.random.normal(shape=(16, 3, 224, 224))
    print(feat_model(x)) 

    上面也提到了,这个SymbolBlock有个方法imports,可用来加载json类型的网络结构和参数params:

    static imports(symbol_file, input_names, param_file=None, ctx=None)[source]

    >>> net1 = gluon.model_zoo.vision.resnet18_v1(
    ...     prefix='resnet', pretrained=True)
    >>> net1.hybridize()
    >>> x = mx.nd.random.normal(shape=(1, 3, 32, 32))
    >>> out1 = net1(x)
    >>> net1.export('net1', epoch=1)       # 上面提到hybridblock保存模型的方法
    >>>
    >>> net2 = gluon.SymbolBlock.imports(      # 可用symbolblock来载入模型和参数
    ...     'net1-symbol.json', ['data'], 'net1-0001.params')
    >>> out2 = net2(x)

    4. class mxnet.gluon.nn.Sequential(prefix=None, params=None)[source]

    序列化的堆叠Blocks:

    net = nn.Sequential()
    # use net's name_scope to give child Blocks appropriate names.
    with net.name_scope():
        net.add(nn.Dense(10, activation='relu'))
        net.add(nn.Dense(20))

    5. class mxnet.gluon.nn.HybridSequential(prefix=None, params=None)[source]

    序列化堆叠HybridBlocks:

    net = nn.HybridSequential()
    # use net's name_scope to give child Blocks appropriate names.
    with net.name_scope():
        net.add(nn.Dense(10, activation='relu'))
        net.add(nn.Dense(20))
    net.hybridize()

    3. Trainer-训练器

    class mxnet.gluon.Trainer(params, optimizer, optimizer_params=None, kvstore='device', compression_params=None, update_on_kvstore=None)[source] 

    给参数施加优化器,Trainer应当与autograd一起使用。对于下面的情况,不可以把update_on_kvstore置为False:

    • dist kvstore with sparse weights or sparse gradients
    • dist async kvstore
    • optimizer.lr_scheduler is not None

    例子:

     from mxnet import autograd as ag  

    train_data, val_data = get_data_iters(dataset, batch_size, opt) net.collect_params().reset_ctx(ctx) trainer = gluon.Trainer(net.collect_params(), 'sgd', # trainer用法 optimizer_params={'learning_rate': opt.lr, 'wd': opt.wd, 'momentum': opt.momentum, 'multi_precision': True}, kvstore=kv) loss = gluon.loss.SoftmaxCrossEntropyLoss() total_time = 0 num_epochs = 0 best_acc = [0] for epoch in range(opt.start_epoch, opt.epochs): trainer = update_learning_rate(opt.lr, trainer, epoch, opt.lr_factor, lr_steps) tic = time.time() train_data.reset() metric.reset() btic = time.time() for i, batch in enumerate(train_data): data = gluon.utils.split_and_load(batch.data[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0) label = gluon.utils.split_and_load(batch.label[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0) outputs = [] Ls = [] with ag.record(): # trainer与autograd一起用 for x, y in zip(data, label): z = net(x) L = loss(z, y) # store the loss and do backward after we have done forward # on all GPUs for better speed on multiple GPUs. Ls.append(L) outputs.append(z) ag.backward(Ls) trainer.step(batch.data[0].shape[0]) # step方法在backward后更新参数,主要是在record之外 metric.update(label, outputs) if opt.log_interval and not (i+1)%opt.log_interval: name, acc = metric.get() logger.info('Epoch[%d] Batch [%d] Speed: %f samples/sec %s=%f, %s=%f'%( epoch, i, batch_size/(time.time()-btic), name[0], acc[0], name[1], acc[1]))

     

    4. Utilities-数据划分包

    1. mxnet.gluon.utils.split_data(data, num_slice, batch_axis=0, even_split=True)[source]

    针对NDArray类型数据沿着batch的维度划分,通常用在数据并行,每个设备需要一部分数据。

    num_slice:要划分的数据份数

    返回:列表,NDArray类型

    2. mxnet.gluon.utils.split_and_load(data, ctx_list, batch_axis=0, even_split=True)[source] 

    与上面唯一不同的地方是num_slice变成了ctx_list,也就是设备列表,划分数据的份数=列表长度,也就是设备数目。

            for i, batch in enumerate(train_data):
                data = gluon.utils.split_and_load(batch.data[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0)
                label = gluon.utils.split_and_load(batch.label[0].astype(opt.dtype), ctx_list=ctx, batch_axis=0)

    3. mxnet.gluon.utils.clip_global_norm(arrays, max_norm, check_isfinite=True)[source]

    缩放NDArray,使得所有元素的2范数之和小雨max_norm。

  • 相关阅读:
    kubernetes集群-04测试kubernetes集群
    kubernetes集群-03网络calico
    kubernetes集群-02部署Master Node
    kubernetes集群-01基础设置(v1.18.0)
    AWS CLI 安装
    如何理解AWS ELB
    AWS-CLI-Command
    terraform 常用命令
    terraform 初始化
    Excel设置下拉框
  • 原文地址:https://www.cnblogs.com/king-lps/p/13070598.html
Copyright © 2011-2022 走看看