『MXNet』第十一弹_符号式编程专题

一、符号分类

符号对我们想要进行的计算进行了描述, 下图展示了符号如何对计算进行描述.

我们定义了符号变量A, 符号变量B, 生成了符号变量C, 其中, A, B为参数节点, C为内部节点! mxnet.symbol.Variable可以生成参数节点, 用于表示计算时的输入.

二、常用符号方法

一个Symbol具有的属性和方法如下图所示:

关联节点查看

list_argument()用来检查计算图的输入参数;

list_output()返回此Symbol的所有输出,输出的自动命名遵循一定的规则

input = mx.sym.Variable(‘data‘)  # 生成一个符号变量,名字是可以随便取的
fc1 = mx.sym.FullyConnected(data=input, num_hidden=128,name=‘fc1‘)  # 全连接层
act1 = mx.sym.Activation(fc1, act_type=‘relu‘)  # 激活

type(fc1)  # mxnet.symbol.Symbol, act1的类型也是这个!!!
fc1.list_outputs()  # [‘fc1_output‘],自动在输入name属性名的后面加上"_output"作为本节点名称
fc1.list_arguments()  # [‘data‘,‘fc1_weight‘,‘fc1_bias‘],自动生成fc1_weight,fc1_bias两个参数节点

act1.list_outputs()  # [‘actvation0_output‘] 这个名字就不是随便起的了!!!
act1.list_arguments()  # [‘data‘,‘fc1_weight‘,‘fc1_bias‘]

返回逻辑如下图,

数据维度推断

mxnet.symbol.Symbol.infer_shape(self, *args, **kwargs): 推测输入参数和输出参数的shape, 返回一个list of tuple;

a = mx.sym.Variable(‘A‘)
b = mx.sym.Variable(‘B‘)
c = (a + b) / 10
d = c + 1
input_shapes = {‘A‘:(10,2), ‘B‘:(10,2)}   # 定义输入的shape
d.infer_shape(**input_shapes) # ([(10L, 2L), (10L, 2L)], [(10L, 2L)], [])
arg_shapes, out_shapes, aux_shapes = d.infer_shape(**input_shapes)

In [1]: arg_shapes

Out[1]: [(10L, 2L), (10L, 2L)]

In [2]: out_shapes

Out[2]: [(10L, 2L)]

In [3]: aux_shapes

Out[3]: []

三、绑定执行

A = mx.sym.Variable(‘A‘)
B = mx.sym.Variable(‘B‘)
C = A * B
D = mx.sym.Variable(‘D‘)
E = C + D
a = mx.nd.empty(1)  # 生成一个维度为1的随机值
b = mx.nd.ones(1)    # b等于1
d = mx.nd.ones(1)
executor = E.bind(ctx=mx.cpu(), args={‘A‘:a, ‘B‘:b, ‘D‘:d})
type(executor)  # mxnet.executor.Executor
executor.arg_dict  # {‘A‘: <NDArray 1 @cpu(0)>, ‘B‘: <NDArray 1 @cpu(0)>, ‘D‘: <NDArray 1 @cpu(0)>}
executor.forward()  # [<NDArray 1 @cpu(0)>]
executor.outputs[0]  # <NDArray 1 @cpu(0)>, 值呢? 还是看不到值啊???
executor.outputs[0].asnumpy()  # array([ 1.], dtype=float32)

首先我们需要调用绑定函数(bind function:*.bind)来绑定NDArrays(下图中的a/b/d)到参数节点(argument nodes: A/B/D,不是内部节点C/E),从而获得一个执行器(Executor):

然后,调用Executor.Forward 便可以得到输出结果.

执行器属性方法如下:

绑定多个输出

我们可以使用mx.symbol.Group([])来将symbols进行分组,然后将它们进行绑定,从而得到更多的中间变量输出。

下图中,A/B/D为参数节点,C/E为内部节点,将E/C绑定为G,这样,E和C的计算结果都可以得到,但是出于优化计算图的考虑,不建议过多绑定输出节点。

梯度计算

在绑定函数中,可以指定NDArrays来保存梯度,在Executor.forward()的后面调用Executor.backward()可以得到相应的梯度值.

神经网络的简单绑定接口

反向传播时,我们需要定义很多新的grad节点并绑定给Executor,过程较为繁琐,Symbol.simple_bind()函数可以帮助我们简化这个过程,指定输入数据的大小(shape),这个函数可以定位梯度参数并将其绑定为Executor.

辅助变量

原文地址:https://www.cnblogs.com/hellcat/p/9639079.html

时间: 2024-08-02 15:42:51

『MXNet』第十一弹_符号式编程专题的相关文章

『MXNet』第七弹_分类器demo示意

解压文件命令: with zipfile.ZipFile('../data/kaggle_cifar10/' + fin, 'r') as zin: zin.extractall('../data/kaggle_cifar10/') 拷贝文件命令: shutil.copy(原文件, 目标文件) 整理数据 我们有两个文件夹'../data/kaggle_cifar10/train'和'../data/kaggle_cifar10/test',一个记录了文件名和类别的索引文件 我们的目的是在新的文件

『MXNet』第六弹_数据处理API(待续)

一.Gluon数据加载 图片数据(含标签)加载函数:gluon.data.vision.ImageFolderDataset 给出ImageFolderDataset类的描述, Init signature: mxnet.gluon.data.vision.datasets.ImageFolderDataset(root, flag=1, transform=None) Source: class ImageFolderDataset(dataset.Dataset): """

『MXNet』第八弹_物体检测之SSD

预.API介绍 mxnet.metric from mxnet import metric cls_metric = metric.Accuracy() box_metric = metric.MAE() cls_metric.update([cls_target], [class_preds.transpose((0,2,1))]) box_metric.update([box_target], [box_preds * box_mask]) cls_metric.get() box_metr

『MXNet』第五弹_多GPU并行程序设计

资料原文 一.概述思路 假设一台机器上有k个GPU.给定需要训练的模型,每个GPU将分别独立维护一份完整的模型参数. 在模型训练的任意一次迭代中,给定一个小批量,我们将该批量中的样本划分成k份并分给每个GPU一份. 然后,每个GPU将分别根据自己分到的训练数据样本和自己维护的模型参数计算模型参数的梯度. 接下来,我们把k个GPU上分别计算得到的梯度相加,从而得到当前的小批量梯度. 之后,每个GPU都使用这个小批量梯度分别更新自己维护的那一份完整的模型参数. 二.网络以及辅助函数 使用“卷积神经网

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import torch.nn as nn import torch.nn.functional as F class LeNet(nn.Module): def __init__(self): super(LeNet,self).__init__() self.conv1 = nn.Conv2d(3, 6, 5)

『PyTorch』第十弹_循环神经网络

『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 对于torch中的RNN相关类,有原始和原始Cell之分,其中RNN和RNNCell层的区别在于前者一次能够处理整个序列,而后者一次只处理序列中一个时间点的数据,前者封装更完备更易于使用,后者更具灵活性.实际上RNN层的一种后端实现方式就是调用RNNCell来实现的. 一.nn.RNN import torch as t from torch import nn from torch.autograd import Variab

『PyTorch』第三弹_自动求导

torch.autograd 包提供Tensor所有操作的自动求导方法. 数据结构介绍 autograd.Variable 这是这个包中最核心的类. 它包装了一个Tensor,并且几乎支持所有的定义在其上的操作.一旦完成了你的运算,你可以调用 .backward()来自动计算出所有的梯度,Variable有三个属性: 访问原始的tensor使用属性.data: 关于这一Variable的梯度则集中于 .grad: .creator反映了创建者,标识了是否由用户使用.Variable直接创建(No

『PyTorch』第五弹_深入理解Tensor对象_中上:索引

一.普通索引 示例 a = t.Tensor(4,5) print(a) print(a[0:1,:2]) print(a[0,:2]) # 注意和前一种索引出来的值相同,shape不同 print(a[[1,2]]) # 容器索引 3.3845e+15 0.0000e+00 3.3846e+15 0.0000e+00 3.3845e+15 0.0000e+00 3.3845e+15 0.0000e+00 3.3418e+15 0.0000e+00 3.3845e+15 0.0000e+00 3

『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较

一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view(2,3) print("a:",a) print("t.cos(a):",t.cos(a)) print("a % 3:",a % 3) # t.fmod(a, 3) print("a ** 2:",a ** 2) # t.po