1.数据操作
首先,先了解下数据操作相关线性代数知识
(1)向量:一个n维的x向量表达式为:x=[x1,x2,x3,x4,,,,,,xn],x内元素均为实数。
(2)矩阵:一个2x3(两行三列)的矩阵可以写成: X= [[x11,x12,x13],[x21,x22,x23],[x31,x32,x33]]
矩阵X的逆矩阵记为XT,为原矩阵的行列对换
(3)范数:n维向量x中的元素为x1,x2,x3,,,,xn。向量x的Lp范数为:
=
x的L1范数:
x的L2范数:
NDArry基本功能:
NDArry为MXnet中储存和变换数据的主要工具
导入NDArry,nd为NDarry的缩写
from mxnet import nd
创建向量
x = nd.arange(12)
获取x的形状(维度信息)
x.shape
x.size
改变x的形状
s=x.reshape((-1,4))
s
创建全0的三维数组
nd.zeros((2,3,4))
创建全1的二维数组
nd.ones((2,3))
X=nd.random.normal(0,1,shape=(3,4))
Y=nd.random.normal(0,1,shape=(3,4))
X+Y
X*Y
X.exp()#指数运算
nd.dot(X,Y.T)#矩阵相乘运算
nd.concat(X,Y,dim=0),nd.concat(X,Y,dim=1)#NDArry连结,相连两个矩阵,dim为维度位置,01234维
X==Y#条件判断,返回0或1
Y.sum()#求和
Y.norm().asscalar()#Y的L2范数的标量
Y[0:2]#索引行,0到2行之间
Y[0:2,:]=7#截取部分元素并重新赋值
内存开销
#当前为消耗内存状态
before = id(Y)#获取当前实例ID
Y=Y+X
id(Y) == before
#开辟临时内存
Z=Y.zeros_like()#创建与Y形状相同且为零的NDArry,开辟临时内存
before = id(Z)
Z[:] = Y+Z
id(Z) == before
#不消耗内存
nd.elemwise_add(X,Y,out=Z)#运算符全名函数,out输出z,避免临时内存开销
id(Z) == before
######################
before = id(Y)
Y += X #如果Y在之后的程序之中不会复用,则可以使用此方法避免内存的开销
id(Y)== before
· NDArray和Numpy相互转换
import numpy as np
P = np.ones((2,3))
D = nd.array(P) #Numpy—>NDArray
D
D.asnumpy()#NDArray->Numpy
2. 自动求梯度(gradient)
梯度:
from mxnet import autograd, nd
x = nd.arange(4).reshape(4,1)
x.attach_grad()#申请储存梯度所需内存
with autograd.record():
y = 2 * nd.dot(x.T,x)#y=2*2*x=4x
y.backward()#自动求梯度
assert(x.grad-4*x).norm().asscalar()==0
x.grad
[[ 0.] [ 4.] [ 8.] [12.]] <NDArray 4x1 @cpu(0)>
#训练模式和预测模式
print(autograd.is_training())
with autograd.record():#调用record函数后会Mxnet会记录并计算梯度,autograd将运行模式从预测模式转成训练模式
print(autograd.is_training())
#对python控制流求梯度
def f(a):
b = a * 2
while b.norm().asscalar() < 1000:#求b向量的L2范数的标量,norm即L2范数,asscalar即将向量转换成标量
b = b*2
if b.sum().asscalar() > 0:
c=b
else:
c = 100*b
return c
a= nd.random.normal(shape=1)#生成随机一维向量,满足正态分布
print(a)
a.attach_grad()
with autograd.record():
c=f(a)
c.backward()
a.grad == c / a
[1.] <NDArray 1 @cpu(0)>