M本篇博客主要讲讲MXNet如何加载数据的,因为它自己实现了一个方便的数据加载的方法。当然最全面的还是去看MXNet的官方文档了,这里主要是简单介绍一下,外加一些自己实验的结果。
MXNet主要使用迭代器(Iterator)来为神经网络提供数据,当然迭代器还会对数据进行一些预处理和生成批数据。
并且,MXNet的Iterator还有两点特殊的:
Iterator需要五类参数:
其中,dataset,batch param是必须的,其他视情况而定。每种参数具体效用,大家可以去看看文档,这里就不赘言了。
好了。BB完了,下面开始我们的干货。
等一下,这儿还得在B一句,不过这一句很重要。简述一下MXNet加载数据的整个流程:
MXNet的这个方法之所以与众不同,在于神经网络或者说Iterator并不是直接处理原生数据比如图片之类的,而是处理的自定义的一种文件格式rec。而rec格式的文件由依赖于一个描述原生数据的列表文件格式lst。最后lst才是依赖于原生数据的。所以流程看起来就是:
raw data –> .lst –> .rec –> iterator
这个图像文件列表的格式如下:
integer_image_index \t label_index \t path_to_image
例子如下:
integet_image_index | label_index | path_to_image |
---|---|---|
895099 | 464 | n04467665_17283.JPEG |
10025081 | 412 | ILSVRC2010_val_00025082.JPEG |
74181 | 789 | n01915811_2739.JPEG |
10035553 | 859 | ILSVRC2010_val_00035554.JPEG |
10048727 | 929 | ILSVRC2010_val_00048728.JPEG |
94028 | 924 | n01980166_4956.JPEG |
1080682 | 650 | n11807979_571.JPEG |
972457 | 633 | n07723039_1627.JPEG |
7534 | 11 | n01630670_4486.JPEG |
1191261 | 249 | n12407079_5106.JPEG |
但是,如果我有上亿的图片那我什么都不用干了。所以大家肯定想到了编程实现自动化。不过人家MXNet想得周到啊,给我们已经写好了。
在mxnet/tools/下有个:(MXNet具体安装教程可参照此处)
make_list.py
没错,就是它。是它,是它,就是它。
具体如何使用其实可以直接查看它的源码,看看参数就OK啦。
不过我这儿还是简单举个栗子:
我在~/data/路径下有六张图片:
现在我直接在mxnet/tools/路径下运行make_list.py
sudo python make_list.py ~/data/ ~/data/test
第一个参数是图片所在的根目录,data后面的/可不能省哦
第二个参数是生成lst文件的前缀,这里我们可以把路径加进去从而保证test.lst是生成在~/data/下的。
它还有很多附加的参数,大家可以看看源码一一尝试。
这一步里也需要依赖于MXNet给的工具,真是想得周到啊。
这里有两个方法:
在路径mxnet/bin/下有个文件:
im2rec
直接在命令行使用这个文件就行。具体使用方法可以查看源码,这里我只举个最简单的栗子:
sudo ./im2rec ~/data/test.lst ~/data/ ~/data/test.rec
第一个参数指明lst文件
第二个参数指明图片根目录,这样才能找到图片
第三个参数指明生成的rec文件
当然,为了方便可以把im2rec加入系统路径,这样使用起来更方便一些。
相信心细的同学已经发现在tools文件夹下有一个im2rec.py文件。
没错,我们可以使用这个文件生成rec文件。
sudo python im2rec.py ~/data/test ~/data/
第一个参数是lst文件的前缀,以及生成的rec文件的前缀和所在路径
第二个参数是图片文件的根目录
还是那句话,其他参数大家直接看源码就OK啦~
在执行这个文件的时候可能会遇到一个问题:
No module named cv, cv2
这是因为python下没有opencv模块所致,直接运行:
sudo apt-get install python-opencv
搞定~
前面的步骤都是使用的人家现成的工具搞定的,还挺爽~
现在我们得撸起袖管自己干了。
data iterator的创建很简单,但是iterator的类别以及它的参数都是挺多了。所以还是那句话,找找文档源码例程看看。源码之前,已无秘密。
不过,我这儿举个小小的栗子:
dataiter = mx.io.ImageRecordIter(
#rec文件的路径
path_imgrec="~/data/test.rec",
#iterator生成的每一个实例的shape
data_shape=(3, 28, 28),
#batch的大小
batch_size=2,
#是否随机从原图中切取出一个data_shape大小
rand_crop=True,
#是否随机水平反射
rand_mirror=True)
其中,path_imgrec, data_shape, batch_size是必须的。
OK.打完收工~
[1]MXNet文档