写在前面
本系列博客记录了作者上手MXNet的全过程。作者在接触MXNet之前主要使用keras,和一点tensorflow,因此在上手MXNet之前有一点deep learning的项目基础。主要参考资料为MXNet官方教程,也阅读了一些有价值的博客。
博客结构为:先列出作者对于该阶段的期望目标,以及各目标完成过程中的笔记(仅记下个人认为重要的),再附上学习过程中自己的提问(solved & unsolved,天马行空的提问,欢迎讨论)。
Table of Contents
本阶段目标
任务 | 优先级 | 预计花时间 | 完成状态 | 遇到问题 | 补充 |
学习Symbol | P0 | 1.5hour | |||
具体笔记
Symbol API概念
符号式编程。我们首先定义一个计算图,而不是一步步的执行计算。计算图中包含了用于代表输入输出数据的占位符。然后通过编译计算图,生成一个函数,和NDArray
绑定后即可运行。MXNet的Symbol API和Caffe使用的网络配置以及Theano中的符号式编程很相似。
Symbol创建基础占位符
a = mx.sym.Variable('a')
Symbol创建基础神经网络
net = mx.sym.FullyConnected(data=net, name='fc1', num_hidden=128)
模块化构建深层网络
def块,将块堆叠
def ConvFactory(data, num_filter, kernel, stride=(1,1), pad=(0, 0), name=None, suffix=''):
# 常见的结构中,每一个卷积模块都是由卷积,BN和激活组成
conv = mx.sym.Convolution(data=data, num_filter=num_filter, kernel=kernel,
stride=stride, pad=pad, name='conv_%s%s' %(name, suffix))
bn = mx.sym.BatchNorm(data=conv, name='bn_%s%s' %(name, suffix))
act = mx.sym.Activation(data=bn, act_type='relu', name='relu_%s%s'
%(name, suffix))
return act
def InceptionFactoryA(data, num_1x1, num_3x3red, num_3x3, num_d3x3red, num_d3x3,
pool, proj, name):
'''
通过将基本模块组合成结构部件进行进一步的调用。
其中pool指定了池化层的类型,一般选用最大池化
'''
# 1x1卷积
c1x1 = ConvFactory(data=data, num_filter=num_1x1, kernel=(1, 1), name=('%s_1x1' % name))
# 1x1通道缩减 + 3x3卷积
c3x3r = ConvFactory(data=data, num_filter=num_3x3red, kernel=(1, 1), name=('%s_3x3' % name), suffix='_reduce')
c3x3 = ConvFactory(data=c3x3r, num_filter=num_3x3, kernel=(3, 3), pad=(1, 1), name=('%s_3x3' % name))
# 1x1通道缩减+ 3x3卷积×2(但是在原生结构中此处应为5×5卷积)
cd3x3r = ConvFactory(data=data, num_filter=num_d3x3red, kernel=(1, 1), name=('%s_double_3x3' % name), suffix='_reduce')
cd3x3 = ConvFactory(data=cd3x3r, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), name=('%s_double_3x3_0' % name))
cd3x3 = ConvFactory(data=cd3x3, num_filter=num_d3x3, kernel=(3, 3), pad=(1, 1), name=('%s_double_3x3_1' % name))
# 3×3池化 + 1×1卷积
pooling = mx.sym.Pooling(data=data, kernel=(3, 3), stride=(1, 1), pad=(1, 1), pool_type=pool, name=('%s_pool_%s_pool' % (pool, name)))
cproj = ConvFactory(data=pooling, num_filter=proj, kernel=(1, 1), name=('%s_proj' % name))
# concat
concat = mx.sym.Concat(*[c1x1, c3x3, cd3x3, cproj], name='ch_concat_%s_chconcat' % name)
return concat
prev = mx.sym.Variable(name="Previous Output")
in3a = InceptionFactoryA(prev, 64, 64, 64, 64, 96, "avg", 32, name="in3a")
mx.viz.plot_network(symbol=in3a, shape=shape)
prev = mx.sym.Variable(name="Previous Output")
conv_comp = ConvFactory(data=prev, num_filter=64, kernel=(7,7), stride=(2, 2))
shape = {"Previous Output" : (128, 3, 28, 28)}
mx.viz.plot_network(symbol=conv_comp, shape=shape)
构建多符号组
使用Group将不同输出结合在一起
group = mx.sym.Group([out1, out2]) # 这个和concat有什么区别?
模型结构可视化
不显示shape:
import matplotlib.pyplot as plt
import mxnet as mx
batch_size = 100
data_shape = (batch_size, 784)
mx.viz.plot_network(softmax).view()
效果如左图
显示shape:
import matplotlib.pyplot as plt
import mxnet as mx
batch_size = 100
data_shape = (batch_size, 3, 224, 224)
mx.viz.plot_network(softmax, shape={"data":data_shape}, node_attrs={"shape":'oval',"fixedsize":'false'}).view()
问题记录
About | Question | Answer |
MXNet | 可视化怎么显示? | 之后就好了 |
本阶段总结
Symbol API中包含了很多有用操作,实践用到某些功能的时候还需要再来查,目前学习只是过一遍功能脑子里有个印象。后续Gluon、Module等模块也是类似。