mxnet java 例子_mxnet:基础知识和一个简单的示例

  • Post author:
  • Post category:java


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

初始化

from mxnet import ndarray as nd

nd.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.shape

y.size

操作符

按照相应元素运算

x+y

x*y

nd.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->mxnet

z=y.asnumpy() # mxnet->numpy

替换操作

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

x=nd.ones((3,4))

y=nd.ones((3,4))

before = id(y)

y=y+x

id(y)==before # False

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

z=nd.zeros_like(y)

before=id(z)

z[:]=x+y

id(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 nd

import 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

# output

x.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 * x

head_gradient = nd.array([[10, 1.], [.1, .01]])

z.backward(head_gradient)

print(x.grad)

# out

x=

[[1.,2.]

[3.,4.]]

x.grad=

[[40., 8.]

[12., 0.16]]



版权声明:本文为weixin_33551941原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。