1.数据操作

在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:
《动手学深度学习》

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments