栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

ndarray和array_numpy中的ndarray对象的zeros?

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ndarray和array_numpy中的ndarray对象的zeros?

        NDArray是从MXNet导入的一个类(from mxnet import nd),存储和变换数据的主要工具,跟Numpy的用法非常类似,语法区别不是很大,可以很快的上手,增加了对GPU计算以及可以自动求梯度等很多非常实用且方便的功能,简单来说就是NDArray变得更加适合深度学习了。

import numpy as np
from mxnet import nd
a=nd.arange(10)

[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]

返回一个NDArray实例,语法跟Numpy一样,不同的是多了一个@cpu(0),意思就是创建在CPU使用的内存上。

a.shape
(10,)
a.size
10

a.reshape((2,5))
#这里有点区别,nd里的形状变换,数量可以小于10,而np.reshape需要数量刚好相等才可以
[[0. 1. 2. 3. 4.]
 [5. 6. 7. 8. 9.]]


nd.zeros(10)
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]


nd.ones(10)
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]


nd.array([[1,2,3],[4,5,6]])
[[1. 2. 3.]
 [4. 5. 6.]]


nd.random.normal(0,1,shape=(2,3))
[[ 1.1630785   0.4838046   0.29956347]
 [ 0.15302546 -1.1688148   1.558071  ]]

normal()的均值为0,标准差为1的正态分布,参数形状shape有点区别,在np里是size
np.random.normal(0,1,size=(2,3))

数据的连接有点区别(三处不同)
np.concatenate((c,d),axis=0)
nd.concat(a,b,dim=0)
其余nd里面的+,-,*,/,exp,sum,sqrt,dot等运算和np语法一样

类型转换

转换成标量
a=nd.arange(10)
a.norm().asscalar()#16.881943,L2范数:平方和再开平方np.sqrt(np.sum(pow(c,2)))

NDArray转换成NumPy
x.asnumpy()

索引的操作和np的用法一样

x=nd.array([[1,2,3],[76,4,5],[21,23,2]])
x[1,2]=99

[[ 1.  2.  3.]
 [76.  4. 99.]
 [21. 23.  2.]]


x[1:2,:]=999
[[  1.   2.   3.]
 [999. 999. 999.]
 [ 21.  23.   2.]]

内存开销

在做运算的时候,如果不注意的话,容易出现开辟新的内存
x=nd.array([[1,2,3],[76,4,5],[21,23,2]])
y=nd.array([[1,2,3],[3,4,5],[6,7,8]])
print(id(x))#1561184090760
x=x+y
print(id(x))#1561193379528
这两个x的id不一样,说明不是在同一个内存里面,可以使用运算符全名函数中的out参数来指定,避免产生新的内存开销

z=y.zeros_like()
print(id(z))#1756866715912
nd.elemwise_add(x,y,out=z)
print(id(z))#1756866715912
这个z在x+y的前后,id是一样的,说明没有产生新的内存
当然,如果确保程序在后面不再使用到前面定义的x,可以使用x+=y或者x[:]=x+y来代替x=x+y,这样也不会产生新的内存开销

自动求梯度【这个很关键,后期使用最多】

函数y=2x²,求关于x的梯度?实际梯度是4x,我们最后也可以看到结果是对的

from mxnet import nd,autograd
x=nd.arange(5).reshape((5,1))
x.attach_grad()#申请存储梯度所需要的内存
#record函数记录与梯度有关的计算(类似前向传播)
with autograd.record():
    y=2*nd.dot(x.T,x)#[[60.]]
y.backward()#反向传播求出梯度(如果y不是标量,会先求和得到新变量,再求该变量有关x的梯度)
#assert(x.grad-4*x).norm().asscalar()==0
x.grad

[[ 0.]
 [ 4.]
 [ 8.]
 [12.]
 [16.]]

默认情况下的autograd会将运行模式从预测模式转为训练模式
print(autograd.is_training())#False预测模式
with autograd.record():
    y=2*nd.dot(x.T,x)
    print(autograd.is_training())#True训练模式

 除了对函数求梯度之外,还可以对控制流(if判断,while等循环)求梯度,这样就显得更加方便了

from mxnet import nd,autograd
def f(x):
    y=2*x
    while y.norm().asscalar()<1000:
        y=2*y
    if y.sum().asscalar()>0:
        z=y
    else:
        z=100*y
    return z
x=nd.random.normal(shape=(2,3))
x.attach_grad()
with autograd.record():
    z=f(x)
z.backward()
x.grad==z/x
print(x.grad==z/x,x.grad,z/x)

[[1. 1. 1.]
 [1. 1. 1.]]
 
[[512. 512. 512.]
 [512. 512. 512.]]
 
[[512. 512. 512.]
 [512. 512. 512.]]

这个f函数,实质是一个线性函数,梯度的值就是z/x,结果也证明了是正确的。

当然对于有些语法忘记了,这个没有关系,help进行查看,很方便,比如help(nd.concat)

最后对于想更进一步了解如何手工求解梯度的过程,可以查看以前的两篇文章: 

误差反向传播法(一)【计算图】https://blog.csdn.net/weixin_41896770/article/details/120461867

误差反向传播法(二)【神经网络以层的方式实现】https://blog.csdn.net/weixin_41896770/article/details/120487639

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/783155.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号