环境搭建
采用Apache MXNet上手,环境搭建部分看zh.d2l.ai,这里略过不表。
优点是多语言支持,多GPU支持(表示看到1024块GPU的时候还吓了一下)。
数据操作
NDArray是MXNet提供存储和变换数据的主要工具。
from mxnet import nd
与numpy的操作基本类似。
创建
arange shape size reshape zeros ones array
# 对均值为0、标准差为1的正态分布随机采样
nd.random.normal(0, 1, shape=(3, 4))
运算
- *(元素乘法) /(按元素除法) exp()(按元素指数运算)
# 矩阵乘法
nd.dot(X, X.T)
连结 在行(维度1)上、列(维度2)上…等
nd.concat(X, Y, dim=0), nd.concat(X, Y, dim=1)
==(按元素判等) 会得到元素为1或0的新NDArray
sum()(求和) 得到只有一个元素的NDArray
asscalar()(转化为标量)
X.norm().asscalar()
广播机制
与numpy基本类似,不同形状的NDArray也会适当复制来确保按元素运算进行。
索引
从0开始,左闭右开,和numpy都是相同的,不知道支不支持花式索引。
运算的内存开销
总会开辟临时内存,除非使用运算符全名函数中的out参数指定。
nd.elemwise_add(X, Y, out=Z)
id(Z) == before # True
或原地运算,如X[:] = X + Y, X += Y等操作。
与numpy互转
P = np.ones((2, 3))
D = nd.array(P)
D.asnumpy()
自动求梯度
对函数求梯度
利用autograd模块。
from mxnet import autograd, nd
简单例子
为了减少计算和内存开销,默认情况下MXNet不会记录用于求梯度的计算。
# 首先申请梯度所需要的内存
x.attach_grad()
# 再调用record()函数来要求MXNet记录
with autograd.record():
y = 2 * nd.dot(x.T, x)
接下来就可以调用backward()函数来自动求梯度。
另,如果y不是一个标量,MXNet默认先对y中元素求和得到新的变量,再求该变量有关x的梯度。
训练模式与预测模式
调用record()函数后,MXNet会记录并计算梯度,此外还会将运行模式由预测模式改为训练模式,可以通过调用is_training()函数来验证。
需要注意的是,有些情况下,同一个模型在训练模式和预测模式下的行为并不相同。
对Python控制流求梯度
即使函数的计算图包含了Python的控制流,我们也有可能对变量求梯度。
def f(a):
b = a * 2
while b.norm().asscalar() < 1000:
b = b * 2
if b.sum().asscalar() > 0:
c = b
else:
c = 100 * b
return c
a = nd.random.normal(shape=1)
a.attach_grad()
with autograd.record():
c = f(a)
c.backward()
查阅文档
查找模块里的所有函数和类
dir()
查找特定函数和类的使用
help()
在notebook中,可以使用函数加?的方式在另一窗口显示文档,加??会额外显示该函数实现的代码。
在MXNet网站上查余额
找对应语言的API