写在前面:
最近在学习神经网络,正好赶上国内外一大批深度学习框架开源,乱花渐欲迷人眼。看了挺多对比文章再结合自身的需求,最终选择了MXNet(0.9)。事实上一开始选择的是Tensorflow(r0.12),然而本身基础太差却又恰好遇到到了多GPU跑程序的需求。Tensorflow当然是支持多GPU,但是需要调整代码,这对于当前只知道看官方简单tutorial的我真是太困难了。MXNet是自动支持数据并行的,根据我当前的了解,基本不需要修改代码就能够利用多GPU跑程序。OK,既然选定了MXNet,就要沉下心了,千山万水还是要一步步,所以还是看官方的tutorial吧(好像没什么变化ㄒ_ㄒ)。本系列记录MXNet学习的历程,一般使用通俗的语言,将会不定期更新,欢迎讨论~~
安装过程就不用说了,按照官网上的说明,无论是linux,windows,无论是cpu还是gpu版,都比较简单,需要注意的是今后不需要使用gpu的代码都在windows上跑,需要使用gpu的则在centos7下跑。
按照官方的教程,需要了解ndarray,symbol,module,model等,但是官方例子大多都是片段,不太清晰,对于新手不太友好,只需要简单知道概念就好。稍微复杂的例子看起来就十分费劲,需要来回跳跃API,所以本系列主要按照github上的教学代码同时参考官网tutorial。这里吐槽一下MXNet的API,实在是太简略了,很多方法只用文字说明一下,一般都看不懂啊,希望官方尽快完善文档。
官方代码在https://github.com/dmlc/mxnet-notebooks/blob/master/python/basic/data_iter.py
数据模拟
很多的教程为了展示方法的使用会自己生成一些假数据,所以数据模拟比较基础,这里优先讲这个例子,不需要知道MXNet的知识,涉及到的主要是numpy的操作。为了说明,规定num_classes=10, num_features=128, batch_size=32
import numpy as np
import mxnet as mx
class SimpleBatch(object):
def __init__(self, data, label, pad=None):
self.data = data
self.label = label
self.pad = pad
"""
data是输入的训练数据,二维数组,32*128
label是数据对应的分类,比如手写数字对应的值是0~9,32*1
pad在这里没有用到,就不说了
"""
class SimpleIter:
def __init__(self, mu, sigma, batch_size, num_batches):
self.mu = mu
self.sigma = sigma
self.batch_size = batch_size
self.num_batches = num_batches
self.data_shape = (batch_size, mu.shape[1])
self.label_shape = (batch_size, )
self.cur_batch = 0
"""
batch_size是一次训练的参数个数,规定是32
mu是10*128的二维数组,正太分布的均值,用来生成训练数据
sigma是10*128的二维数组,正太分布的标准差,用来生成训练数据
data_shape的第一个参数是一次处理的个数,32,第二个参数是每个数据的特征数,128
"""
def __iter__(self):
return self
def reset(self):
self.cur_batch = 0
def __next__(self):
return self.next()
@property
def provide_data(self):
return [('data', self.data_shape)]
@property
def provide_label(self):
return [('softmax_label', self.label_shape)]
"""
provide_data,provide_label提供的是shape
"""
def next(self):
if self.cur_batch < self.num_batches:
self.cur_batch += 1
num_classes = self.mu.shape[0]
label = np.random.randint(0, num_classes, self.label_shape)
data = np.zeros(self.data_shape)
for i in range(num_classes):
data[label==i,:] = np.random.normal(
self.mu[i,:], self.sigma[i,:], (sum(label==i), self.data_shape[1]))
return SimpleBatch(data=[mx.nd.array(data)], label=[mx.nd.array(label)], pad=0)
else:
raise StopIteration
"""
cur_batch判断当前是第几组(总共batch_num)数据
np.random.randint产生整数随机数,第一个参数<=随机数<第二个参数,第三个参数是最后的shape
np.zeros生成全0的数组,data是输入的训练数据
np.random.normal为产生正态分布随机数,第一个参数是均值,第二个标准差,(sum(label==i), self.data_shape[1]))是表示最后数组的shape。
均值的shape==标准差的shape==self.data_shape[1].shape
label==i,生成的是bool值,其实是告诉data数组哪一行的值需要更新
sum(label==i)则表示生成的数据的行数,相对于多少组数据,比如2组,那么赋值时data一次赋值了2个
mx.nd.array是将numpy数据转换成mxnet的ndarray格式,不用管
"""
class SyntheticData:
"""Genrate synthetic data
"""
def __init__(self, num_classes, num_features):
self.num_classes = num_classes
self.num_features = num_features
self.mu = np.random.rand(num_classes, num_features)
self.sigma = np.ones((num_classes, num_features)) * 0.1
def get_iter(self, batch_size, num_batches=10):
return SimpleIter(self.mu, self.sigma, batch_size, num_batches)
"""
数据模拟的入口是SyntheticData,这意味着之后get_iter时的mu和sigma是相同的
特征与分类的对应在SyntheticData初始化时就已经规定好,没有道理,只是随机得到的,之后一直不变。后续的训练数据都是以此为均值的一个正太分布随机数
"""
本文记录了作者从TensorFlow转向MXNet的学习过程,并详细介绍了MXNet的基础组件及如何使用MXNet进行数据模拟。适合初学者参考。
556

被折叠的 条评论
为什么被折叠?



