深度学习Imagenet caffe AlexNet 实验步骤


1       论文:

ImageNet Classification with Deep Convolutional NeuralNetworks

2       环境需求

Linux操作系统(如ubuntu14.04)

caffe

matlab(windows或linux版都可以)

3       数据集:

3.1   数据集的准备

3.1.1  下载训练和验证图片

由于ILSVRC2012没有提供测试数据集的ground truth,所以本报告拟在训练数据集上进行训练,然后给出验证数据集的top-1和top-5的错误率。

首先到ImageNet官网下载ILSVRC2012的训练数据集和验证数据集。除数据集外,ImageNet还提供了一个开发工具包ILSVRC2012_devkit_t12.tar.gz,是对ILSVRC2012数据集的详细讲解,提交比赛结果的要求,和对结果评价的代码。可以下载下来看一下里面的内容。ImageNet官网地址:http://www.image-net.org/signup.php?next=download-images。注意下载前需用邮箱注册,而且邮箱不能是地址以.com结尾的邮箱。

训练数据集和验证数据集分别是两个tar文件ILSVRC2012_img_train.tar和ILSVRC2012_img_val.tar。将这两个文件拷贝至服务器合适的地址中(如/dataset/imagenet),对着两个文件分别解压到当前目录下。解压命令为:

tar –xvf  ILSVRC2012_img_train.tar./train

tar –xvf ILSVRC2012_img_val.tar ./val

ILSVRC2012_img_train.tar解压后是1000个tar文件,每个tar文件表示1000个分类中的一个类。需要对这1000个tar文件再次解压。在train目录下执行unzip.sh文件,最后得到1000个文件夹。每个文件夹中是该类的图片。ILSVRC2012_img_val.tar解压后的文件夹包含了所有的验证集图片。

unzip.sh

dir=./

for x in `ls *.tar`

do

filename=`basename $x .tar`

mkdir $filename

tar -xvf $x -C ./$filename

done

3.1.2  下载其他需要的文件

在caffe目录下执行命令 ./data/ilsvrc12/get_ilsvrc_aux.sh,下载一些训练需要的附加文件。其中train.txt是训练数据集的ground truth文件,val.txt是验证数据集的ground truth文件。需要这两个文件在生成lmdb数据库时提供label信息。

3.1.3  图片预处理:

(1)大小归一化:所有的图片都归一化为256*256的大小,对于一个长方形图片,首先将短边变成256的长度,然后剪裁图片中心的256*256部分。

将examples/imagenet/create_imagenet.sh文件中,将为RESIZE=false更改为RESIZE=true,将所有图片归一化为256*256的大小。注意需将文件中的训练数据集和测试数据集的地址更改为服务器中实际存放的地址,即文件中设置

TRAIN_DATA_ROOT=/dataset/ imagenet/train/

VAL_DATA_ROOT=/dataset/imagenet/val/

执行该文件后生成训练数据和验证数据的lmdb数据库:ilsvrc12_train_lmdb 、ilsvrc12_val_lmdb。

(2)减去像素平均值:所有图片的每个像素都减去所有训练集图片的平均值。

 训练集图片的平均值存储于data/ilsvrc12/imagenet_mean.binaryproto。如果没有该文件,执行

./examples/imagenet/make_imagenet_mean.sh可以生成该文件。

3.2   ImageNet数据集的详细内容

ImageNet Large-Scale Visual Recognition Challenge(ILSVRC)是Pascal Visual Object Challenge的子部分。ImageNet是一个数据库,有超过22000个种类,超过1500万张图片。

ILSVRC使用1000个类,每个类中有1000个图片。这1000个类一一对应于WorldNet的1000个同义子集。这1000个同义子集互相不重叠,对于同义子集,不是的祖先。这样的子集称为低层子集。这1000个子集是ImageNet层次结构的一部分。可以认为这个子集包含了1000个低层子集和他们所有的祖先。共有860个这样的祖先,被称为高层子集。在层次结构中,所有的低层特征称为叶节点,高层子集称为中间节点。尽管在ImageNet中低层子集会有子类,但ILSVRC2012并不考虑这些子类,ILSVRC2012的层次结构可以看作是对完整ImageNet结构的剪裁。ILSVRC竞赛中,所有的标记都是针对低层子集,参赛者必须预测这1000个低层子集标记之一,不考虑预测高层子集的结果,而且也没有高层子集的训练图片。

在ILSVRC中,子集信息可参见ILSVRC2012_devkit_t12中的data/meta.mat文件中的矩阵。

矩阵中的每一个行对应于一个子集,每一项中包含如下域值:

ILSVRC2012_ID是为每一子集分配的一个整数ID值,所有低层子集的ID值都在1到1000之间,所有高层子集的ID值都大于1000。所有的子集都是一句其ID值进行排序。提交预测结果时,ILSVRC2012_ID也作为相应子集的标记。

WNID是子集在WordNet中的ID。用于在ImageNet或WorldNet中唯一标记一个子集。包含训练图片的tar文件就是用WNID命名的。同样每一个训练图片也是用WNID命名的。

num_children是子集在剪裁后的结构中子孙的数目。对于低层子集其值为0,对于高层子集的值不为0。

children是子孙子集的ILSVRC2012_ID的向量。

wordnet_height是完整的ImageNet/WorldNet层次结构中到叶节点的最长路径的值。(完整的ImageNet/WorldNet层次结构中叶节点的wordnet_height值为0)

注意caffe使用的labelILSVRC2012_devkit是不一致的。ILSVRC2012_IDILSVRC2012_devkit的提供的编号。而caffe中图片的label是以图片所属子集的名字的ASC II的顺序排列,并依次从0999编号。本文提供的所有程序都是依据caffe的编号编写的。在caffe目录下的data/ilsvrc12/synset_words.txt文件查看子集/编号的对应。

训练图片

对于每一个子集都有一个tar文件,用其WNID命名。图片文件,命名为x_y.JPEG。其中x是子集的WNID,y是整数(不是固定长度,而且不一定连续),所有的图片都是JPEG格式。

共有1281167张训练图片。其中每个子集的训练图片数目在732 至1300之间。

验证图片

共有50000张验证图片,分别被命名为:

      ILSVRC2012_val_00000001.JPEG

      ILSVRC2012_val_00000002.JPEG

      ...

      ILSVRC2012_val_00049999.JPEG

      ILSVRC2012_val_00050000.JPEG

对于每一个子集分别有50张验证图片。

验证图片的groundtruth在data/ILSVRC2012_validation_ground_truth.txt,文件中每一行包含一个图片对应的ILSVRC2012_ID,并以图片名称的升序排列。

测试图片

共有100000张测试图片,测试图片的命名如下:

ILSVRC2012_test_00000001.JPEG

      ILSVRC2012_test_00000002.JPEG

      ...

      ILSVRC2012_test_00099999.JPEG

      ILSVRC2012_test_00100000.JPEG

对于每一个子集分别有100张测试图片。

4      AlexNet结构的创新点

4.1   ReLU

加快训练速度,使大规模神经网络能够成功训练。

4.2   多GPU训练

单GPU的存储空间过小,用120万张图片训练的网络规模超出了单个GPU的存储能力。因此使用2块GPU,在每个GPU上存储一半的kenels,这2块GPU只在特定的层上通信。比起在在一个GPU上训练的每个卷积层只有一半kernels的方案,top1和top5的错误率分别降低了1.7%和1.2%。

4.3   局部响应归一化

局部相应归一化有助于模型的泛化,将模型top1和top5的错误率分别降低了1.4%和1.2%。

4.4   重叠池化

将模型top1和top5的错误率分别降低了0.4%和0.3%。

4.5   整体结构

AlexNet共8层,包括5个卷积层和3个全连接层。第2、4、5层的kernels仅与上一层在同一块GPU上的kernel maps连接,第3层kernels与第2层所有的kernel maps连接。第1、2层卷积后进行局部相应归一化。第1、2、5层有重叠池化。卷积层和全连接层的每层输出都有ReLU。

5      AlexNet避免过拟合的策略

5.1   数据增多

(1)在256*256的图像中选取224*224的patches以及这些patches的水平镜像作为网络的输入、将训练数据增加了2048倍。

(2)在训练集的RGB像素值的集合上运用主成分分析。这个策略捕获到了自然图像的一个重要特征:物体的类别不随着光线的亮度和颜色变化。这个策略将top1的错误率降低了1%。

5.2   Dropout

Dropout是一种组合多种模型的方式。在前两个全连接层运用dropout。如果不使用dropout,模型会出现明显的过拟合。但dropout会导致模型收敛需要的迭代次数翻倍。

6      模型训练

AlexNet模型定义于文件:models/bvlc_alexnet/train_val.prototxt,注意需将文件中的训练数据集和测试数据集的地址更改为服务器中实际存放的地址。

训练参数定义于文件:models/bvlc_alexnet/solver.prototxt

在caffe目录下执行命令:

./build/tools/caffe train --solver=models/bvlc_alexnet/solver.prototxt

由于训练时间过程,可以令训练过程不挂断在后台运行,命令为

nohup ./build/tools/caffe train--solver=models/bvlc_alexnet/solver.prototxt &

该命令的输出会重定向到nohup.out文件中,可以查看该文件查看模型的训练情况。

查看GPU是否被占用以及被占用的内存大小命令:

nvidia-smi

模型训练参数:

默认batch大小256(我们的服务器GPU内存不够,需要调整到128),迭代450000次,约90个epoch

learning rate初始化为0.01,采用step的算法,每100000次(约20个epoch)迭代衰减一次。

momentum值为0.9,weight decay为0.0005

每10000个迭代输出一个snapshot

caffe的AlexNet模型定义与论文不同之处:

1、caffe中的AlexNet模型没有进行数据增多的操作。

2、用于训练的图片大小不一样,论文中实际用于训练的图片大小为224*224,caffe的大小是227*227。而且对训练图片进行了随机镜像。

3、non-zero biases被初始化为0.1而不是1

训练过程可以暂停,并从之前训练生成的一个snapshort中开始恢复训练。如从第10000轮迭代结果开始继续训练:

./build/tools/caffe train --solver=models/bvlc_alexnet/solver.prototxt–

snapshot=models/bvlc_alexnet/caffenet_train_iter_10000.solverstate

如果最多迭代450000次,最后训练的模型为caffenet_train_iter_450000.caffemodel。大概需要2-3天。

7      模型验证

利用已经训练好的模型对验证数据集的数据生成一个结果,该结果为一个文本文件,文件中的每一行对应一张图片,以图片名称的升序排列,如从ILSVRC2012_val_00000001.JPEG 到 ILSVRC2012_val_00050000.JPEG。每一行包含对图片预测的结果标记,即预测图片所属类别的值(0至999的整数),并以confidence值的降序排列。每一行的标记数目可以变化,但不能超过5。验证数据预测结果的示例文件可见ILSVRC2012_devkit中的/evaluation/demo.val.pred.txt

在caffe/examples目录下执行alexneteval.py文件。执行命令:

python alexneteval.py (需要将modelname改为自己训练的模型名字)

生成结果文件alexnetpred.txt

alexneteval.py

import numpy as np

caffe_root = '../' # this file is expected to be in {caffe_root}/examples

val_dir = '/dataset/imagenet/val'

model_name ='caffenet_train_iter_450000.caffemodel'

import sys

sys.path.insert(0, caffe_root + 'python')

import caffe

import os

caffe.set_mode_cpu()

net = caffe.Net(caffe_root +'models/bvlc_reference_caffenet/deploy.prototxt',

               caffe_root + 'models/bvlc_reference_caffenet/'+model_name,

               caffe.TEST)

transformer = caffe.io.Transformer({'data':net.blobs['data'].data.shape})

transformer.set_transpose('data', (2,0,1))

transformer.set_mean('data', np.load(caffe_root +'python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1))

transformer.set_raw_scale('data', 255)  # the reference model operates on images in [0,255]range instead of [0,1]

transformer.set_channel_swap('data', (2,1,0))  # the reference model has channels in BGRorder instead of RGB  

net.blobs['data'].reshape(50,3,227,227)

fh = open('alexnetpred.txt','w')

batchsize = net.blobs['data'].shape[0]

for dirpath,dirnames,filenames inos.walk(val_dir):

   sortedfiles = sorted(filenames)

n=len(sortedfiles)

nbatch = (n+ batchsize - 1) // batchsize

for i inrange(nbatch):

   idx = np.arange(i*batchsize,min(n,(i+1)*batchsize))

   for tdx in idx:

              filename = sortedfiles[tdx]

                  indexofdata= tdx%batchsize

                  net.blobs['data'].data[indexofdata]= transformer.preprocess('data', caffe.io.load_image(os.path.join(dirpath,filename)))

       out =net.forward()

   for j in range(batchsize)

         output_pred=out['prob'][j].argsort()[-1:-6:-1]

         outlist=output_pred.tolist()

         templist=[str(i) for i in outlist]

         fh.write(' '.join(templist))

         fh.write('\n')

fh.close()

8      结果评价

基于matlab的评价程序参见ILSVRC2012_devkit_t12中demo_eval.m和eval_flat.m,其中demo_eval调用了eval_flat函数,这个函数需要输入3个参数:

predict_file,预测结果文件,每一行是对一张图片的预测labels,必须为正整数,以空格分隔,以confidence的降序排列,每一行的labels可以改变,但是不能超过max_num_pred_per_image。我们的预测结果文件就是alexnetpred.txt。

gtruth_file,与predict_file的格式一致,每一行是相应图片的ground truth labels。在ILSVRC2012中,gtruth_file每行只有一个值。可以将caffe/data/ilsvrc12目录下的val.txt文件作为gtruth_file。但需要将文件的第一列删除。

max_num_pred_per_image,在计算top-1和top-5错误率的值分别为1和5。

在demo_eval.m中设置

pred_file='alexnetpred.txt'

ground_truth_file='val.txt';

在matlab中运行demo_eval输出top-1和top-5的错误率。注意需要demo_eval.m和eval_flat.m文件放置到matlab的当前工作路径中。

参考资料

[1]     KrizhevskyA, Sutskever I, Hinton G E. Imagenet classification with deep convolutionalneural networks[C]//Advances in neural information processing systems. 2012:1097-1105.

[2]     http://caffe.berkeleyvision.org/gathered/examples/imagenet.html

[3]     http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb

[4]     ~/caffee/models/bvlc_alexnet/readme.md

[5]     ~/caffee/models /examples/imagenet/readme.md

[6]     ILSVRC2012_devkit_t12

没有更多推荐了,返回首页