博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mxnet:基础知识和一个简单的示例
阅读量:7232 次
发布时间:2019-06-29

本文共 2171 字,大约阅读时间需要 7 分钟。

NDArray与NumPy的多维数组类似,但NDArray提供了更多的功能:GPU和CPU的异步计算;自动求导。这使得NDArray能更好地支持机器学习。

初始化

from mxnet import ndarray as ndnd.zeros((3,4))nd.ones((3,4))nd.array([[1,2],[3,4]])out:[[1. 2.][3. 4.]] 
nd.random_normal(0,1,shape=(3,4)) #标准正态分布# 输出信息y.shapey.size

操作符

按照相应元素运算

x+yx*ynd.exp(x)

矩阵的乘法

nd.dot(x, y.T)

广播(Beoadcasting)

当二元操作符左右两边ndarray形状不一样时,系统会尝试将它们扩充到共同的形状。

a=nd.arange(3).reshape((3,1))b=nd.arange(2),reshape((1,2))print ('a+b', a+b)out:a+b:[[ 0. 1.] [ 1. 2.] [ 2. 3.]] 

与NumPy的转换

x=np.ones((2,3))y=nd.array(x) # numpy->mxnetz=y.asnumpy() # mxnet->numpy

替换操作

如果我们写y=x+y,会开辟新的内存来存储计算结果,如:

x=nd.ones((3,4))y=nd.ones((3,4))before = id(y)y=y+xid(y)==before # False

可以通过[:]写到之间建立好的数组中

z=nd.zeros_like(y)before=id(z)z[:]=x+yid(z)==before # True

上述,系统还是为x+y创建了临时空间,再复制给了z。为了避免这个开销,可以使用操作符的全名版本并指定out参数

nd.elemwise_add(x,y,out=z)id(z)==before # True

截取(Slicing)

x=nd.arange(0,9).reshape((3,3))x[1:3]out:[[ 3. 4. 5.] [ 6. 7. 8.]] 
#改变指定位置的值x[1,2]=9.#多维截取x[1:2,1:3]#多维写入x[1:2,1:3]=9.out:[[ 0. 1. 2.] [ 3. 9. 9.] [ 6. 7. 8.]]

使用autograd自动求导

import mxnet.ndarray as ndimport mxnet.autograd as ag

为变量附上梯度

x=nd.array([[1,2],[3,4]])x.attach_grad() # ndarray的方法申请相应的空间# 定义函数f=2x*x,显式要求mxnet记录我们要求导的程序with ag.record():    y=x*2    z=y*x# 通过z.backword()来进行求导,如果z不是一个标量,z.backward()等价于nd.sum(z).backward().z.backward()print('x.grad: ',x.grad)x.grad == 4*x# outputx.grad:[[4.,  8.] [12., 16.]]
[[ 1. 1.] [ 1. 1.]]

对控制流求导

命令式的编程的一个便利之处是几乎可以对任意的可导程序进行求导,即使里面包含了 Python 的 控制流。对于计算图框架来说,这个对应于动态图,就是图的结构会根据输入数据不同而改变。

def f(a):     b=a*2    while nd.norm(b).asscalar() < 1000:         b=b*2    if nd.sum(b).asscalar() > 0:         c=b    else:        c = 100 * b     return c

使用record和backward求导

a = nd.random_normal(shape=3)a.attach_grad()with ag.record():     c = f(a)c.backward()

头梯度和链式法则

基于链式法则:

\[\frac{dz}{dx} = \frac{dz}{dy}\frac{dy}{dx}\]
\(\frac{dz}{dy}\)就是\(\frac{dy}{dx}\)的头梯度,而计算\(\frac{dz}{dy}\),头梯度则为默认值,即nd.ones_like(y)。我们也可以手动指定头梯度。

with ag.record():     y = x * 2     z = y * xhead_gradient = nd.array([[10, 1.], [.1, .01]]) z.backward(head_gradient) print(x.grad)# outx=[[1.,2.] [3.,4.]]
x.grad=[[40., 8.] [12., 0.16]]

转载地址:http://kapfm.baihongyu.com/

你可能感兴趣的文章
卖猪还钱 法院拍卖被执行人300头生猪 40.5万成交
查看>>
Python 高级编程:完全理解生成器
查看>>
当JSON.parse“遇上”非键值对
查看>>
送书拉!给开发者们的几本书籍 |福利
查看>>
深入浅出,ARCore开发原理
查看>>
玩转iOS开发:iOS 10 新特性《Siri Kit》
查看>>
从Facebook的React框架事件学习一下开源协议
查看>>
mock in iOS
查看>>
react高阶组件
查看>>
0203 - 无固化,不学习
查看>>
聊聊viewport那些事儿
查看>>
WM_QUERYENDSESSION与WM_ENDSESSION
查看>>
流式处理框架storm浅析(上篇)
查看>>
如何设计实现一个React UI组件库——Ant Design源码阅读与浅析
查看>>
Java JDK源码分析之for循环删除异常原理以及解决办法
查看>>
由迭代器到js异步操作
查看>>
双数组Trie树高效构建有向无环图
查看>>
webpack 之 loader 和 plugin 简介
查看>>
webpack打包性能优化之路
查看>>
js正则表达式
查看>>