http://caffe.berkeleyvision.org/gathered/examples/imagenet.html
Brewing ImageNet
本指南旨在根据自己准备好的数据来训练自己的模型。 如果你只是想要一个训练好的ImageNet网络模型,(Note that since training takes a lot of energy and we hate global warming)我们在model zoo中提供训练好的CaffeNet模型。Data Preparation
本指南指定所有的路径并且所有的命令,均在caff根目录下执行(~/caff)。
本文档中的“ImageNet”,是指 ILSVRC12 Challenge,但是也可以方便的在整个ImageNet上进行训练,但需更多的磁盘空间和更长的训练时间。
假定已经下载好了ImageNet的训练数据集和验证数据集,并且以如下所示的方式存放在磁盘上:
/path/to/imagenet/train/n01440764/n01440764_10026.JPEG
/path/to/imagenet/val/ILSVRC2012_val_00000001.JPEG
需要一些辅助数据(auxiliary data)用于训练。数据可以通过在文件夹中执行shell命令下载获取:
./data/ilsvrc12/get_ilsvrc_aux.sh
训练和验证输入在train.txt和val.txt中进行了描述,两个文件列出了所有文件及其对应的标签。 请注意,我们对标签使用的索引不同于ILSVRC devkit:我们按照它们的ASCII顺序对synset名称进行排序,然后将它们标记为0到999。有关synset/name映射的信息,请参阅synset_words.txt。你可能需要提前将图像大小调整为256*256。 默认情况下,我们没有明确地这样做,因为在集群环境中,可以使用mapreduce以并行方式调整图像大小,从而获益。 例如,Yang qing 使用了他的轻量级mincepie 包( lightweight mincepie package)。 如果你更喜欢简单的东西,你也可以使用shell命令,例如:
for name in /path/to/imagenet/val/*.JPEG; do
convert -resize 256x256\! $name $name
done
看下 examples/imagenet/create_imagenet.sh 路径。根据需要设置训练集文件目录和验证集文件目录的路径。如果没有事先调整好图像的大小,需要设置“RESIZE=true”,将所有的图像大小调整为256*256。
现在需要执行shell命令
examples/imagenet/create_imagenet.sh 来创建 leveldbs。注意:在执行上述shell命令之前
examples/imagenet/ilsvrc12_train_leveldb
和 examples/imagenet/ilsvrc12_val_leveldb 文件夹是不存在。它将由脚本创建。 GLOG_logtostderr = 1只需转储更多信息供检查,可以放心地忽略它。
Compute Image Mean
该模型要求每个图像需要减去图像平均值,因此必须计算图像的平均值。tools/compute_image_mean.cpp实现了这一点---这也是一个很好的例子,可以帮助熟悉如何处理多个组件,例如协议缓冲区,leveldbs和日志记录,如果您不熟悉这些组件。也可以通过执行如下shell命令计算平均值:
./examples/imagenet/make_imagenet_mean.sh
这将创建 data/ilsvrc12/imagenet_mean.binaryproto
Model Definition
我们将描述Krizhevsky,Sutskever和Hinton在他们的NIPS 2012论文中首次提出的方法的参考实现。
网络定义(models/bvlc_reference_caffenet/train_val.prototxt)遵循Krizhevsky等人的定义。请注意,如果偏离本指南中建议的文件路径,则需要调整 .prototxt 文件中的相关路径。
如果仔细查看models/bvlc_reference_caffenet/train_val.prototxt,你会注意到几个包含部分,指定为:phase: TRAIN或phase:TEST。这些部分允许我们在一个文件中定义两个紧密相关的网络:用于训练的网络和用于测试的网络。这两个网络几乎完全相同,共享除标记为include {phase:TRAIN}或include{phase:TEST}的所有层。在这种phase不同的情况下,只有输入层和输出层是不同的。
输入层差异(Input layer differences):训练网络的数据输入层从examples/imagenet/ilsvrc12_train_leveldb中获取数据,并随机镜像输入图像。测试网络的数据层从example/imagenet/ilsvrc12_val_leveldb获取数据,不执行随机镜像。
输出层差异(Output layer differences:):两个网络均输出softmax_loss层,该层在训练过程中用于计算损失函数并初始化反向传播,而在验证中,这种损失只是简单计算出来(并不用于反向传播优化网络)。测试网络还具有第二输出层,准确度,用于报告测试集的准确度。在训练过程中,测试网络偶尔会在测试集上进行实例化和测试,产生如测试分数#0:xxx和测试分数#1:xxx的数据输出行。在这种情况下,分数0是准确性(对于未经训练的网络将以1/1000 = 0.001开始),分数1是损失(对于未经训练的网络将大约以7开始)。
我们还将为运行solver布置一个协议缓冲区。让我们制定一些计划:
a.我们将分批运行256次,共运行450,000次迭代(约90个时期)。
b.对于每1000次迭代,我们在验证数据上测试学习到的网络。
c.我们将初始学习率设置为0.01,并且在每100,000次迭代(约20个时期)减少它。
d.每20次迭代后将信息显示一次。
e.该网络将以0.9动力momentum和0.0005权重衰减进行训练。
f.对于每10,000次迭代,保存一下当前状态的信息。
这在models/bvlc_reference_caffenet/solver.prototxt中实现。
Training ImageNet
开始训练:
./build/tools/caffe train --solver=models/bvlc_reference_caffenet/solver.prototxt
在K40机器上,每20次迭代运行大约耗时26.5秒(而在K20上这需要36秒),因此对于完全前向传播-反向传播过程,每个图像有效耗时大约5.2ms。大约2ms是前向的,其余的是反向的。如果你有兴趣剖析计算时间,你可以运行:
./build/tools/caffe time --model=models/bvlc_reference_caffenet/train_val.prototxt
Resume Training?
当遇到断电或不能继续训练的情况,因为我们间隔一段时间就保存一次当前训练状态信息(就是训练的中间结果),所以我们可以从这些保存的信息开始恢复训练。具体操作如下:
./build/tools/caffe train --solver=models/bvlc_reference_caffenet/solver.prototxt --
snapshot=models/bvlc_reference_caffenet/caffenet_train_iter_10000.solverstate
其中在脚本中caffenet_train_iter_10000.solverstate是solver状态信息,其存储用于恢复solver状态(包括参数,动量历史等)的所有必要信息。
Parting Words
希望你喜欢这个方法!自ILSVRC2012 challenge以来,许多研究人员已经走得更远,改变了网络架构或微调网络中的各种参数,以满足新的数据和任务。 通过简单地编写不同的prototxt文件,Caffe让你更容易探索不同的网络 - 那不是很令人兴奋吗?
现在你有一个训练好的网络模型,看看如何使用它和Python接口用于classifying ImageNet.。