《动手学习深度学习》 2 预备知识
本章地址:http://zh.diveintodeeplearning.org/chapter_prerequisite/index.html
2.2 数据操作
在MXNet中,NDArray是存储和变换数据的主要工具,它提供了GPU计算和自动求梯度的更多功能。
操作
from mxnet import nd x = nd.arange(12) x = nd.zeros((2,3,4)) x = nd.ones((3,4)) x = nd.array([[2,1], [3,9], [8,7]]) x = nd.random.normal(0, 1, shape=(3,4)) //它的每个元素都随机采样于均值为0 标准差为1 的正态分布。 x.shape x.size x.reshape
运算
X+Y X*Y X/Y X==Y X.sum() 或者 nd.sum(X) Y.exp() 或者 nd.exp(X) X.norm().asscalar() //asscalar 函数将结果变换为Python 中的标量 nd.dot(X, Y.T) nd.contact(X, Y, dim=0) //维度0代表行 nd.contact(X, Y, dim=1) //维度1代表列
2.2.4 索引
X[1:3] #赋值 X[1, 2] = 9 X[1:2, :] = 12
2.2.5运算的内存开销
像Y = X + Y 这样的运
算,我们也会新创建内存,然后将Y 指向新内存。为了演⽰这⼀点,我们可以使⽤Python ⾃带的id 函数:如果两个实例的ID ⼀致,那么它们所对应的内存地址相同;反之则不同。
before = id(Y) Y = Y + X id(Y) == before #指定结果到特定内存 Z = Y.zeros_like() before = id(Z) Z[:] = X + Y id(Z) == before #避免这个临时内存开销 nd.elemwise_add(X, Y, out=Z) id(Z) == before #减小开销 X[:] = X + Y 或者 X += Y
2.2.6 NDArray 和NumPy 相互变换
通过array 和asnumpy 函数令数据在NDArray 和NumPy 格式之间相互变换。
import numpy as np #将NumPy 实例变换成NDArray 实例 P = np.ones((2, 3)) D = nd.array(P) #将NDArray 实例变换成NumPy 实例 D.asnumpy()
2.3 ⾃动求梯度
#使⽤MXNet 提供的autograd 包来⾃动求梯度 from mxnet import autograd, nd #创建变量x x = nd.arange(4).reshape((4, 1)) #调⽤attach_grad 函数来申请存储梯度所需要的内存 x.attach_grad() #调⽤record 函数来要求MXNet记录与求梯度有关的计算,记录并计算梯度 with autograd.record(): y = 2 * nd.dot(x.T, x) #如果y 不是⼀个标量,MXNet 将默认先对y中元素求和得到新的变量,再求该变量有关x的梯度。 y.backward()
函数y = 2x⊤x 关于x 的梯度应为4x,验证
assert (x.grad - 4 * x).norm().asscalar() == 0 x.grad
2.3.2 训练模式和预测模式
调⽤record 函数后,MXNet 会记录并计算梯度。
默认下autograd还会将运⾏模式从预测模式转为训练模式。这可以通过调⽤is_training 函数来查看。
print(autograd.is_training()) with autograd.record(): print(autograd.is_training())
2.3.3 对Python 控制流求梯度
使⽤MXNet 的⼀个便利之处是,即使函数的计算图包含了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
使⽤record 函数记录计算,并调⽤backward 函数求梯度
a = nd.random.normal(shape=1) a.attach_grad() with autograd.record(): c = f(a) c.backward()
2.4.1 查找模块⾥的所有函数和类
使⽤dir函数查阅模块(module)⾥⾯提供了哪些可以调⽤的函数和类
from mxnet import nd print(dir(nd.random))
通常我们可以忽略掉由__开头和结尾的函数(Python 的特别对象)或者由单_开头的函数(⼀般为内部函数)。
2.4.2 查找特定函数和类的使⽤
使⽤help函数
help(nd.ones_like)