MXNet学习1——数据模拟

本文记录了作者从TensorFlow转向MXNet的学习过程,并详细介绍了MXNet的基础组件及如何使用MXNet进行数据模拟。适合初学者参考。

写在前面:

最近在学习神经网络,正好赶上国内外一大批深度学习框架开源,乱花渐欲迷人眼。看了挺多对比文章再结合自身的需求,最终选择了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初始化时就已经规定好,没有道理,只是随机得到的,之后一直不变。后续的训练数据都是以此为均值的一个正太分布随机数
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值