在MXNet中,NDArray是一个类,也是存储和变换数据的主要工具。
MXNet中的NDArray和Numpy中的多维数据非常类似,只是MXNet中的NDArray提供了GPU计算和自动求梯度等更多功能。
1.创建NDArray:
# 从mxnet中导入ndarray模块
from mxnet import nd
# 使用arange函数创建一个行向量
x = nd.arange(12)
x
[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.]
<NDArray 12 @cpu(0)>
可以通过size和shape属性获取NDArray的元素总数及形状。
x.size , x.shape
(12, (12,))
使用reshape方法改变NDArray的形状。
X = x.reshape((3,4))
X
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
<NDArray 3x4 @cpu(0)>
使用zeros和zeros方法创建元素均为0或1的张量。
nd.zeros((2,3)) , nd.zeros((2,3))
(
[[0. 0. 0.]
[0. 0. 0.]]
<NDArray 2x3 @cpu(0)>,
[[1. 1. 1.]
[1. 1. 1.]]
<NDArray 2x3 @cpu(0)>)
也可以通过list创建NDArray。
X = nd.array([[1,3,5],[2,4,6]])
X
[[1. 3. 5.]
[2. 4. 6.]]
<NDArray 2x3 @cpu(0)>
随机生成一个均值为0,标准差为1的正态分布的多维数组。
nd.random.normal(0,1,shape=(2,3))
[[ 1.1630785 0.4838046 0.29956347]
[ 0.15302546 -1.1688148 1.5580711 ]]
<NDArray 2x3 @cpu(0)>
2.NDArray的运算:
NDArray支持大量的运算符。
X = nd.array([[1,2,3],[4,5,6]])
Y = nd.array([[1,3,5],[2,4,6]])
加减乘除运算
X + Y , X * Y
(
[[ 2. 5. 8.]
[ 6. 9. 12.]]
<NDArray 2x3 @cpu(0)>,
[[ 1. 6. 15.]
[ 8. 20. 36.]]
<NDArray 2x3 @cpu(0)>)
指数运算。
X.exp() , nd.exp(X)
(
[[ 2.7182817 7.389056 20.085537 ]
[ 54.59815 148.41316 403.4288 ]]
<NDArray 2x3 @cpu(0)>,
[[ 2.7182817 7.389056 20.085537 ]
[ 54.59815 148.41316 403.4288 ]]
<NDArray 2x3 @cpu(0)>)
矩阵乘法
nd.dot(X,Y.T)
[[22. 28.]
[49. 64.]]
<NDArray 2x2 @cpu(0)>
条件判断式。
X == Y , X < Y
(
[[1. 0.]
[0. 0.]
[0. 0.]
[0. 0.]]
<NDArray 4x2 @cpu(0)>,
[[0. 1.]
[1. 1.]
[1. 1.]
[1. 1.]]
<NDArray 4x2 @cpu(0)>)
求和
X.sum() , nd.sum(X)
(
[21.]
<NDArray 1 @cpu(0)>,
[21.]
<NDArray 1 @cpu(0)>)
L2范数
X.norm() , nd.norm(X)
(
[9.5393915]
<NDArray 1 @cpu(0)>,
[9.5393915]
<NDArray 1 @cpu(0)>)
转换成标量
X.norm().asscalar()
9.5393915
多个NDArray的连结操作
nd.concat(X,Y,dim=0) , nd.concat(X,Y,dim=1)
(
[[1. 2. 3.]
[4. 5. 6.]
[1. 3. 5.]
[2. 4. 6.]]
<NDArray 4x3 @cpu(0)>,
[[1. 2. 3. 1. 3. 5.]
[4. 5. 6. 2. 4. 6.]]
<NDArray 2x6 @cpu(0)>)
3.广播机制:
X = nd.arange(8).reshape((4,2))
Y = nd.arange(4).reshape((4,1))
X +Y
[[0. 2.]
[2. 4.]
[4. 6.]
[6. 8.]]
<NDArray 4x2 @cpu(0)>
4.索引操作:
X = nd.arange(12).reshape((4,3))
X
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]
[ 9. 10. 11.]]
<NDArray 4x3 @cpu(0)>
X[1:3]
[[ 0. 1. 2.]
[ 3. 4. 5.]
[ 6. 7. 8.]
[ 9. 10. 11.]]
<NDArray 4x3 @cpu(0)>
X[1,2]
[5.]
<NDArray 1 @cpu(0)>
X[1:3 , 1:3]
[[4. 5.]
[7. 8.]]
<NDArray 2x2 @cpu(0)>
可以通过索引操作为多个元素重新赋值
X[1:3 , 1:3] = 10
X
[[ 0. 1. 2.]
[ 3. 10. 10.]
[ 6. 10. 10.]
[ 9. 10. 11.]]
<NDArray 4x3 @cpu(0)>
5.运算的内存开销:
X = nd.arange(8).reshape((4,2))
Y = nd.arange(4).reshape((4,1))
之前的这些运算都会新开内存用来存储运算结果
before = id(Y)
Y = X + Y
after = id(Y)
before , after , before ==after
(2046882946632, 2046882966552, False)
如果需要指定结果到特定的内存,可以使用索引方法进行替换操作,不过此方法还是为X + Y开了新的内存,然后在复制到Z对应的内存。
Z = Y.zeros_like()
before = id(Z)
Z[:] = X + Y
after = id(Z)
before , after , before ==after
(2046882966832, 2046882966832, True)
如果避免临时内存的开销,可以使用运算符全名函数中的out参数。
Z = Y.zeros_like()
before = id(Z)
nd.elemwise_add(X,Y,out=Z)
after = id(Z)
before, after , before ==after
(2046882959544, 2046882959544, True)
6.NDArray与Numpy的相互转换:
import numpy as np
#使用array和asnumpy函数可以实现NDArray与Numpy之间的相互转换
P = np.ones((2,3))
D = nd.array(P)
D
[[1. 1. 1.]
[1. 1. 1.]]
<NDArray 2x3 @cpu(0)>
D.asnumpy()
array([[1., 1., 1.],
[1., 1., 1.]], dtype=float32)
Reference:
《动手学深度学习》