由于caffe依赖性太多,配置极其复杂,所以将接下来的学习转向mxnet.因此本文主要记录我的学习历程,如果描述有什么问题,欢迎大家的指正。
mxnet的优点很明显,简洁灵活效率高 ,多机多卡支持好。
mxnet的github下载链接:https://github.com/dmlc/mxnet/
mxnet的开发文档链接:http://mxnet.readthedocs.org/en/latest/build.html
开发文档清晰易读,包含安装、语法、示例等,并且还在不断丰富当中
目录
1- linux下安装mxnet和python接口配置
mxnet可以安装到Linux、OSX和windows下。由于windows下配置相对较为复杂,故这里选择安装在linux下。 具体我的linux版本为64位的ubuntu14.04LTS,之前使用ubuntu15时发现不是很稳定。还有,这里我是在笔记本上安装的,因此没有安装CUDA、CUDNN之类的GPU管理程序。
mxnet支持在线安装,在终端中单步依次执行以下代码:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
Python接口的配置:
mxnet目前主要支持python、R和Julia这3种接口。我选择了相对熟悉的python。
mxnet要求2.7及以上版本的python和numpy库,一般linux都自带python编译器,因此我们只需要再检查一下是否缺少numpy库。可以直接输入下面的numpy安装代码:
- 1
- 1
上面处理完成之后可以尝试一下能否运行官方提供的一个案例:在mnist数据集上训练一个多层感知器MLP。
- 1
- 1
如果之前配置过GPU(如何配置可以参考官方文档),可以尝试用GPU测试一下网络:
- 1
- 1
注意:上述过程完成后,直接在python中执行以下代码(如 import mxnet as mx)可能会提示“no module named ”,这可能是因为未添加路径导致的。可以通过单步依次执行下面代码解决:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
2- 如何将训练图片转换格式并送入网络
就好像在caffe中训练模型之前要现将训练图片转化为leveldb或者LMDB格式数据一样,mxnet在训练之前也要先将图片转化为REC格式的数据。
这里直接记录转换过程,后续会详细讲解REC数据格式的编码以及最终如何将REC格式数据再加载到网络当中。
linux下转换使用的工具是mxnet/bin下名为“im2rec”的可执行文件,该文件的源码可以查看mxnet/tools/im2rec.cc
首先,来说明以下im2rec这个转换工具有哪些输入参数:
首先是必须输入的3个参数,依次是
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
可选的输入参数有:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
这里举一个实际应用的例子
(1)首先是保存图片和标签信息的文本,这里我的文件是train.txt.
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
(2)为了方便运行和调整参数,这里写了一个类似于windows批处理命令一样的可执行文件,来调用im2rec。这里我的可执行文件名为convert.sh,训练图片存储于data文件夹,转换后的结果保存到当前文件夹下,命名为train.rec
- 1
- 2
- 1
- 2
(3)打开终端,cd到convert.sh所在文件夹,输入 ./convert.sh 回车。运行提示如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
迭代器-将转换后的数据送入网络:
总体来说,开始一项训练,需要3个部分:训练参数、网络模型和训练数据。在上一小节,我已经详细介绍了如何将原始图片数据转化为mxnet可以接受的REC格式数据。但是,实际训练的时候我们还需要一个工具来将REC数据送入我们的训练网络中。这个工具就是“迭代器”-iterator
mxnet为我们提供了快速构建迭代器的函数ImageRecordIter,该函数位于python/mxnet/io.py中,其返回一个迭代器对象。或者可以在python命令窗中键入以下命令来获取io函数的位置以及说明:
- 1
- 2
- 3
- 1
- 2
- 3
接下来说明ImageRecordIter的几个常用参数:(更多的参数可以通过上面的help查看)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
接下来以实例来说明怎样构建迭代器,该例子位于example/image-classification/train_imagenet.py中
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
3- 构建一个网络模型
一个网络模型是一层一层连接器来的,因此想要构建一个网络模型,首先我们得知道mxnet中都有哪些可以用的层。(以下按照使用频率来排序)
下面介绍一些比较常用的层,更多的层大家可以在python命令窗执行以下代码来查询
- 1
- 2
- 1
- 2
(1)Activation:激活函数
- 1
- 2
- 1
- 2
(2)Convolution:卷积层
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
(3)Deconvolution:反卷积层
- 1
- 1
(4)Dropout:
- 1
- 2
- 1
- 2
(5)Flatten:将N维数据变为1维
- 1
- 2
- 1
- 2
(6)FullyConnected:全连接层
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
(7)LRN:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
(8)Pooling
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
(9)SoftmaxOutput:使用logloss进行BP
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
(10)Variable:定义一个symbol型变量
- 1
- 2
- 1
- 2
mxnet/example/image-classification文件夹下以symbol开头的几个.py文件都是定义好的网络模型。我们可以任意打开一个来具体了解一下如何构建一个网络。
有一点需要注意的是:mxnet中通常要在卷积层和全连接层之间价加一个Flatten层用于衔接
4- 开始训练
首先,来总结一下我们现在都有了什么:保存网络模型的.py文件、REC格式的训练数据、将数据送入网络的迭代器。
在此基础上,我们缺少的就只剩下网络训练的一些控制参数:如学习率、训练日志、GPU选择等等。
在初期,我们往往可以先快速的拿来用,而不用在意其细节。那么,最简单的办法就是直接修改套用mxnet中的示例。示例主要集中在/example/image-classification和/tests/python当中。下面就简单的介绍如何快速开始训练:
(1)新建一个文件夹,将/example/image-classification文件夹下find_mxnet.py、symbol_alexnet.py、train_imagenet.py和train_model.py这4个文件copy进来;
(2)保持find_mxnet.py文件不变,在symbol_alexnet.py中按照里面Alexnet网络的构建方法来建立自己的网络。最后最好再把文件名改为自己的网络名,如mynet.py;
(3)将train_imagenet.py最好也修改一下名字,如改为train_xx.py.将第40行代码中的’symbol’删除,否则你的网络文件就必须以‘symbol’开始命名,如symbol_mynet.py.
- 1
- 2
- 3
- 1
- 2
- 3
剩下的就是要在parser.add_argument中修改默认值了,否则你在调用mynet.py就必须准确的指定每一个参数。
(4)写一个脚本文件,运行脚本文件就可以开始训练了。如
- 1
- 2
- 1
- 2