写在前面
本系列博客记录了作者上手MXNet的全过程。作者在接触MXNet之前主要使用keras,和一点tensorflow,因此在上手MXNet之前有一点deep learning的项目基础。主要参考资料为MXNet官方教程,也阅读了一些有价值的博客。
博客结构为:先列出作者对于该阶段的期望目标,以及各目标完成过程中的笔记(仅记下个人认为重要的),再附上学习过程中自己的提问(solved & unsolved,天马行空的提问,欢迎讨论)。
本阶段目标
任务 | 预计花时间 | 完成状态 | 遇到问题 | 补充 |
了解MXNet的框架理念与特点 | 1.5hour | https://mxnet-bing.readthedocs.io/en/latest/zh/overview.html#id8 | ||
了解MXNet中数据处理格式 | 1.5hour | https://beta.mxnet.io/guide/crash-course/1-ndarray.html | ||
搭建简单模型 | 5hour | https://beta.mxnet.io/guide/crash-course/2-nn.html | ||
通过与keras等平台对比,快速加深对MXNet的印象 | 待补充 |
具体笔记
task1 MXNet的特点
- 命令式编程与声明式编程的结合
命令式编程(imperative programming),嵌入较浅,其中每个语句都按原来的意思执行,例如numpy和Torch
声明式语言(declarative programming),嵌入较深,既用户只需要声明要做什么,而具体执行则由系统完成。这类系统包括Caffe,theano和刚公布的TensorFlow
MXNet结合了"Symbol:声明式的符号表达式"和"NDArray:命令式的张量计算"
- MXNet中几个库的使用
名称 | 用途 |
Symbol | 生成计算图,符号编程 |
Gluon | |
Module | 模型类,可用于训练和测试模型 |
task2 NDArray数据
首先需要 from mxnet import nd,mxnet.ndarray与numpy.ndarray相似。
1. 初始化:
from mxnet import nd
a = nd.array([1,2,3])
b = nd.ones((2,3))
c = nd.full((2,3),7) #填充
d = nd.arange(4).reshape((2,2))
2. 运算:
from mxnet import nd
a = nd.array([[1,2,3],[1,2,3],[1,2,3]])
b = nd.ones((3,3))
c = a*b #对应位置乘法
d = nd.dot(a,b) #矩阵相乘
e = nd.maximum(a, c) #求对应位置最大
3. 形状改变
from mxnet import nd
np.concat
a.reshape
a = mx.nd.array(np.arange(6).reshape(6,1))
b = a.broadcast_to((6,4)) #复制广播
b.asnumpy()
4. 深拷贝和浅拷贝
b = a.copy() # 深
b = a # 浅。这时修改b也会动a
5. 指定变量在CPU还是GPU上计算
gpu_device=mx.gpu() # Change this to mx.cpu() in absence of GPUs.
a = mx.nd.ones((100,100), mx.cpu())
b = mx.nd.ones((100,100), gpu_device)
6. 读写数据
- pickle
import pickle as pkl
import mxnet as mx
a = mx.nd.ones((2, 3))
# pack and then dump into disk
data = pkl.dumps(a) #dumps返回一个序列化的bytes对象,不到文件中去
pkl.dump(data, open('tmp.pickle', 'wb')) #dump到文件
# load from disk and then unpack
data = pkl.load(open('tmp.pickle', 'rb')) #读取出的data是二进制格式数据
b = pkl.loads(data) #将b从二进制读取为正常格式
b.asnumpy()
- save & load (这种方法更好)
通过nd.save和nd.load,写或读二进制文件,数据可以和其他语言通用
import mxnet as mx
a = mx.nd.ones((2,3))
b = mx.nd.ones((5,6))
mx.nd.save("temp.ndarray", [a,b])
c = mx.nd.load("temp.ndarray")
task3 搭建模型
1. 生成单层
layer = nn.Dense(2)
2. 生成网络
\Checkmark
3. 使用类来搭建block(推荐)
将层结构和forward函数分开,可以构建例如dense block\ res block\ vgg block,块堆叠网络使用这种结构很方便.
以VGG网络为例:
import d2lzh as d2l
from mxnet import gluon, init, nd
from mxnet.gluon import nn
def vgg_block(num_convs, num_channels):
blk = nn.Sequential()
for _ in range(num_convs):
blk.add(nn.Conv2D(num_channels, kernel_size=3,
padding=1, activation='relu'))
blk.add(nn.MaxPool2D(pool_size=2, strides=2))
return blk
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
def vgg(conv_arch):
net = nn.Sequential()
# 卷积层部分
for (num_convs, num_channels) in conv_arch:
net.add(vgg_block(num_convs, num_channels))
# 全连接层部分
net.add(nn.Dense(4096, activation='relu'), nn.Dropout(0.5),
nn.Dense(4096, activation='relu'), nn.Dropout(0.5),
nn.Dense(10))
return net
net = vgg(conv_arch)
task4 和keras对比
问题 | keras | MXNet | 补充 |
模型结构列表打印 | model.summary() | print(net) | |
直接获取网络中间层weight值 | layer.weight.data() net.blk[1].weight.data() | ||
画模型结构图 | plot_model | ||
为数据指定是GPU还是CPU | a = mx.nd.ones((100,100), mx.cpu()) a = mx.nd.ones((100,100), mx.gpu()) | ||
学习过程问题记录
About | Question | Answer |
torch | torch和pytorch的区别? | |
和keras对比 | 有没有类似于keras中net.summary()的函数? | |
python | super(MixMLP, self).__init__(**kwargs) super函数? | |
python中类的多继承? | 一个类同时继承多个类的特征 | |
pickle | load和loads的区别、dump和dumps的区别 | |
编程方式 | 命令式编程和声明式的区别? | |
Symbol声明式和NDArray命令式? |
而
| |
MXNet | Symbol 和 Gluon的区别? | |
“Symbol API类似于caffe中的网络配置或者Theano中的符号编程。”怎么理解? | ||
官方的crash course教程里,讲模型搭建的这一节,第三种方法为什么更灵活?为什么要设置一个blk然后获取中间层?不能直接net[4].weight.data()这样获取中间层的weight吗? | 教程中更灵活的意思是在这个类里面,结构和forward函数分开,这样在resnet这种有重复性结构的网络中,容易获取中间层的输出? (再想想) | |
gluon和mxnet的关系?不用gluon的话mxnet能使用吗? | ||
Apache MXNe什么意思?加不加前缀的区别? | ||
本阶段感想
刚入门MXNet,应该先有一个清晰框架,逐步了解遮盖东西的原理、具体实施以及别的库的用法。刚看到官方教程的时候脑子有点晕,Symbol\Gluon到底是什么概念,目前还不清楚。需要结合不同资料自己来提取信息并理解。整理ing
参考资料
- dive into deep learning,基于Apache MXNet对深度学习算法进行实现,内容详实,代码实现;中文版《动手学深度学习》
- MXNet官方教程的中文翻译版本
- github资料,教程、模型以及预训练weight