深度学习高能干货:手把手教你搭建MXNet框架

640?wx_fmt=gif

导读:相信很多程序员在学习一门新的编程语言或者框架时,都会先了解下该语言或者该框架涉及的数据结构,毕竟当你清晰地了解了数据结构之后才能更加优雅地编写代码,MXNet同样也是如此。


在MXNet框架中你至少需要了解这三驾马车:NDArraySymbolModule。这三者将会是你今后在使用MXNet框架时经常用到的接口。那么在搭建或者训练一个深度学习算法时,这三者到底扮演了一个什么样的角色呢?


这里可以做一个简单的比喻,假如将从搭建到训练一个算法的过程比作是一栋房子从建造到装修的过程,那么NDArray就相当于是钢筋水泥这样的零部件,Symbol就相当于是房子每一层的设计,Module就相当于是房子整体框架的搭建。


在本文中你将实际感受命令式编程(imperative programming)和符号式编程(symbolic programming)的区别,因为NDArray接口采用的是命令式编程的方式,而Symbol接口采用的是符号式编程的方式。

 
 


作者:迈克尔·贝耶勒(Michael Beyeler)

如需转载请联系大数据(ID:hzdashuju)


640?wx_fmt=jpeg



01 NDArray


NDArray是MXNet框架中数据流的基础结构,NDArray的官方文档地址是:


https://mxnet.apache.org/api/python/ndarray/ndarray.html


与NDArray相关的接口都可以在该文档中查询到。在了解NDArray之前,希望你先了解下Python中的NumPy库:


http://www.numpy.org/


因为一方面在大部分深度学习框架的Python接口中,NumPy库的使用频率都非常高;另一方面大部分深度学习框架的基础数据结构设计都借鉴了NumPy。


在NumPy库中,一个最基本的数据结构是array,array表示多维数组,NDArray与NumPy库中的array数据结构的用法非常相似,可以简单地认为NDArray是可以运行在GPU上的NumPy array。


接下来,我会介绍在NDArray中的一些常用操作,并提供其与NumPy array的对比,方便读者了解二者之间的关系。


首先,导入MXNet和NumPy,然后通过NDArray初始化一个二维矩阵,代码如下:


import mxnet as mximport numpy as npa = mx.nd.array([[1,2],[3,4]])print(a)as mx
import numpy as np
a = mx.nd.array([[1,2],[3,4]])
print(a)


输出结果如下:


 
 
[[1. 2.] [3. 4.]]<NDArray 2x2 @cpu(0)>2.]
 [3. 4.]]
<NDArray 2x2 @cpu(0)>


接着,通过NumPy array初始化一个相同的二维矩阵,代码如下:


 
 
b = np.array([[1,2],[3,4]])print(b)2],[3,4]])
print(b)


输出结果如下:


 
 
[[1 2] [3 4]]2]
 [3 4]]


实际使用中常用缩写mx代替mxnet,mx.nd代替mxnet.ndarray,np代替numpy,本书后续篇章所涉及的代码默认都采取这样的缩写。


再来看看NumPy array和NDArray常用的几个方法对比,比如打印NDArray的维度信息:


 
 
print(a.shape)


输出结果如下:


 
 
(2, 2)2)


打印NumPy array的维度信息:


 
 
print(b.shape)


输出结果如下:


 
 
(2, 2)2)


打印NDArray的数值类型:


 
 
print(a.dtype)


输出结果如下:


 
 
<class 'numpy.float32'>


打印Numpy array的数值类型:


 
 
print(b.dtype)


输出结果如下:


 
 
int64


在使用大部分深度学习框架训练模型时默认采用的都是float32数值类型,因此初始化一个NDArray对象时默认的数值类型是float32。


如果你想要初始化指定数值类型的NDArray,那么可以通过dtype参数来指定,代码如下:


 
 
c=mx.nd.array([[1,2],[3,4]], dtype=np.int8)print(c.dtype)2],[3,4]], dtype=np.int8)
print(c.dtype)


输出结果如下:


 
 
<class 'numpy.int8'>


如果你想要初始化指定数值类型的NumPy array,则可以像如下这样输入代码:


 
 
d = np.array([[1,2],[3,4]], dtype=np.int8)print(d.dtype)2],[3,4]], dtype=np.int8)
print(d.dtype)


输出结果如下:


 
 
int8


在NumPy的array结构中有一个非常常用的操作是切片(slice),这种操作在NDArray中同样也可以实现,具体代码如下:


 
 
c = mx.nd.array([[1,2,3,4],[5,6,7,8]])print(c[0,1:3])2,3,4],[5,6,7,8]])
print(c[0,1:3])


输出结果如下:


 
 
[2. 3.]<NDArray 2 @cpu(0)>3.]
<NDArray 2 @cpu(0)>


在NumPy array中可以这样实现:


 
 
d = np.array([[1,2,3,4],[5,6,7,8]])print(d[0,1:3])2,3,4],[5,6,7,8]])
print(d[0,1:3])


输出结果如下:


 
 
[2 3]3]


在对已有的NumPy array或NDArray进行复制并修改时,为了避免影响到原有的数组,可以采用copy()方法进行数组复制,而不是直接复制,这一点非常重要。下面以NDArray为例来看看采用copy()方法进行数组复制的情况,首先打印出c的内容:


 
 
print(c)


输出结果如下:


 
 
[[1. 2. 3. 4.] [5. 6. 7. 8.]]<NDArray 2x4 @cpu(0)>2. 3. 4.]
 [5. 6. 7. 8.]]
<NDArray 2x4 @cpu(0)>


然后调用c的copy()方法将c的内容复制到f,并打印f的内容:


 
 
f = c.copy()print(f)


输出结果如下:


 
 
[[1. 2. 3. 4.] [5. 6. 7. 8.]]<NDArray 2x4 @cpu(0)>2. 3. 4.]
 [5. 6. 7. 8.]]
<NDArray 2x4 @cpu(0)>


修改f中的一个值,并打印f的内容:


 
 
f[0,0] = -1print(f)0] = -1
print(f)


输出结果如下,可以看到此时对应位置的值已经被修改了:


 
 
[[-1. 2. 3. 4.] [ 5. 6. 7. 8.]]<NDArray 2x4 @cpu(0)>2. 3. 4.]
 [ 5. 6. 7. 8.]]
<NDArray 2x4 @cpu(0)>


那么c中对应位置的值有没有被修改呢?可以打印此时c的内容:


 
 
print(c)


输出结果如下,可以看到此时c中对应位置的值并没有被修改:


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值