Caffe学习(四):Windows使用Cifar10训练及测试Caffe版DenseNet

论文名称:Densely Connected Convolutional Networks(CVPR 2017, Best Paper Award)
论文链接:https://arxiv.org/pdf/1608.06993.pdf
源码链接:https://github.com/liuzhuang13/DenseNet
caffe版源码: https://github.com/liuzhuang13/DenseNetCaffe
 

1. 下载Caffe版DenseNet源码

源码中包含以下6个文件:

make_densenet.py:用于生成train_densenet.prototxt文件、test_densenet.prototxt文件以及solver.prototxt文件

train_densenet.protoxt: 训练时用到的模型网络文件

test_denset.prototxt:训练过程中验证部分用到的网络文件

solover.prototxt:caffe用到的solover文件

train.sh:ubuntu环境下的训练文件

 

train_densenet.prototxt与test_densenet.prototxt文件指定了需要用到cifar10数据集及其均值,如图。

因此我们需要先准备cifar10数据集。

2. 创建cifar10数据集

2. 1 下载cifar10数据集

官网下载bin格式的cifar10  : http://www.cs.toronto.edu/~kriz/cifar.html

CIFAR-10 binary version (suitable for C programs)格式版本,解压存放在 :caffe-master\examples\cifar10\input_folder当中(input_folder文件夹需要自己创建),

如图:

2. 2 转换为lmdb格式

首先在VS中编译出Caffe的convert_cifar_data.exe工具,在caffe-master\Build\x64\Release\目录下。

在caffe-master\examples\cifar10 下创建一个bat文件(convert_cifar10_lmdb.bat),输入以下:

..\..\Build\x64\Release\convert_cifar_data.exe  input_folder output_folders lmdb
pause

然后双击运行,可以看到在 caffe-master\examples\cifar10下会生成output_folders文件夹,里面存放的就是转换好lmdb格式数据,如图:

如果需要leveldb格式,则将bat文件中的lmdb改为lveldb,再运行即可。

2.3 生成mean.binaryproto均值文件

首先在VS中编译出Caffe的compute_image_mean.exe工具,在caffe-master\Build\x64\Release\目录下。

在caffe-master\examples\cifar10 下创建一个bat文件(get_mean_binaryproto_lmdb.bat),输入以下:

..\..\Build\x64\Release\compute_image_mean.exe -backend=lmdb ../../examples\cifar10\output_folders\cifar10_train_lmdb mean.binaryproto
Pause

双击运行后,即在affe-master\examples\cifar10下生成lmdb格式的mean.binaryproto文件,如图:

同理如果需要leveldb格式,修改bat文件中的lmdb为leveldb即可。

 

3. 训练Cifar10

3.1 更改模型文件数据集路径

在DenseNetCaffe根目录下创建data文件夹,将cifar10_train_lmdb与cifar10_test_lmdb两个文件夹以及mean.binaryproto文件到拷到data下,如图:

更改train_densenet.prototxt与test_densenet.prototxt文件中的数据集路径即均值文件路径

也可以更改make_densenet.py文件中的路径来生成3个prototxt文件,如图:

3.2 训练模型

在DenseNetCaffe根目录下创建一个train.bat文件,编辑以下代码:

SET GLOG_logtostderr=1
C:\zhh\caffe-master\Build\x64\Release\caffe.exe train --solver C:\zhh\DenseNetCaffe\solver.prototxt 
pause

另外,需要注意的是,原模型训练需要较大的显存,我本机显存为8GB,运行train.bat文件加载模型开始训练后会报out of memory错误,即显存不足。可通过降低train_densenet.prototxt文件中的batch_size来降低所需要的显存,这里我将batch_size修改为32,运行train.bat,即开始训练,如图:

迭代次数达到设定的最高值23万时,模型训练停止,模型训练的准确率已接近1,损失值接近0

在DensetNet根目录下生成了权重文件,如下:

4. 测试模型

4.1 对测试集图像数据进行测试

在DensetNet根目录下创建test.bat,如下:

SET GLOG_logtostderr=1
C:\zhh\caffe-master\Build\x64\Release\caffe.exe test -model=C:\zhh\DenseNetCaffe\test_densenet.prototxt -weights=C:\zhh\DenseNetCaffe\_iter_230000.caffemodel -iterations=100
pause

双击运行,得到对100个批次测试集数据的测试,如下:

I0708 13:51:39.630722 14688 caffe.cpp:286] Running for 100 iterations.
I0708 13:51:43.784732 14688 caffe.cpp:309] Batch 0, Accuracy1 = 0.96
I0708 13:51:44.222826 14688 caffe.cpp:309] Batch 0, SoftmaxWithLoss1 = 0.0977751
I0708 13:51:47.511251 14688 caffe.cpp:309] Batch 1, Accuracy1 = 0.92
I0708 13:51:47.512169 14688 caffe.cpp:309] Batch 1, SoftmaxWithLoss1 = 0.485769
I0708 13:51:50.807596 14688 caffe.cpp:309] Batch 2, Accuracy1 = 0.9
I0708 13:51:50.807596 14688 caffe.cpp:309] Batch 2, SoftmaxWithLoss1 = 0.317953
I0708 13:51:54.090023 14688 caffe.cpp:309] Batch 3, Accuracy1 = 0.94
I0708 13:51:54.090023 14688 caffe.cpp:309] Batch 3, SoftmaxWithLoss1 = 0.216393
I0708 13:51:57.379446 14688 caffe.cpp:309] Batch 4, Accuracy1 = 0.94
I0708 13:51:57.379446 14688 caffe.cpp:309] Batch 4, SoftmaxWithLoss1 = 0.395111
I0708 13:52:00.693857 14688 caffe.cpp:309] Batch 5, Accuracy1 = 0.92
I0708 13:52:00.693857 14688 caffe.cpp:309] Batch 5, SoftmaxWithLoss1 = 0.424328
……………
I0708 14:00:43.962534 14688 caffe.cpp:309] Batch 95, Accuracy1 = 0.84
I0708 14:00:43.962534 14688 caffe.cpp:309] Batch 95, SoftmaxWithLoss1 = 0.692951
I0708 14:00:47.326921 14688 caffe.cpp:309] Batch 96, Accuracy1 = 1
I0708 14:00:47.327920 14688 caffe.cpp:309] Batch 96, SoftmaxWithLoss1 = 0.00866098
I0708 14:00:50.655325 14688 caffe.cpp:309] Batch 97, Accuracy1 = 1
I0708 14:00:50.656323 14688 caffe.cpp:309] Batch 97, SoftmaxWithLoss1 = 0.021941
I0708 14:00:54.095676 14688 caffe.cpp:309] Batch 98, Accuracy1 = 0.88
I0708 14:00:54.095676 14688 caffe.cpp:309] Batch 98, SoftmaxWithLoss1 = 0.576406
I0708 14:00:57.427078 14688 caffe.cpp:309] Batch 99, Accuracy1 = 0.9
I0708 14:00:57.427078 14688 caffe.cpp:309] Batch 99, SoftmaxWithLoss1 = 0.586738
I0708 14:00:57.428077 14688 caffe.cpp:314] Loss: 0.312385
I0708 14:00:57.429077 14688 caffe.cpp:326] Accuracy1 = 0.9232
I0708 14:00:57.429077 14688 caffe.cpp:326] SoftmaxWithLoss1 = 0.312385 (* 1 = 0.312385 loss)

4.2 测试其他图片

这里我们编写Python文件调用Caffe对我们自己的图片文件进行测试。

(1)准备测试图片

在densenet根目录下创建images文件夹,存放要测试的图片,如下,图像为RGB格式,32x32大小

(2)生成densenet.prototxt文件

4.1中使用的prototxt文件为test_densenet.prototxt,为训练时用到的网络文件,实际在测试及部署需要deploy prototxt文件,可在test_densenet.prototxt上改写,如下步骤:

  • 拷贝test_densenet.prototxt文件,并重命名为densent.prototxt
  • 在densent.prototxt中,删除第1层,即name为Data1的层,并添加如下层:
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 1 dim: 3 dim: 32 dim: 32 } }
}
  • 将第2层(即nama为Convolution1的层)中的bottom: "Data1"改为bottom: "data"
  • 删除最后一层,即name为Accuracy1的层
  • 对最后name为SoftmaxWithLoss1的层改写,如下:

改写前:

layer {
  name: "SoftmaxWithLoss1"
  type: "SoftmaxWithLoss"
  bottom: "InnerProduct1"
  bottom: "Data2"
  top: "SoftmaxWithLoss1"
}

改写后:

layer {
  name: "prob"
  type: "Softmax"
  bottom: "InnerProduct1"
  top: "softmax"
}

(3)生成mean.npy文件

Caffe中需要的是mean.binaryproto二进制文件,但Caffe的Python接口需要npy格式的文件,因此需要将mena.binaryproto转为mean.npy格式。在mean.binaryproto的目录下(DenseNetCaffe\data)创建make_meannpy.py文件,代码如下:

import numpy as np
import caffe

MEAN_PROTO_PATH = 'mean.binaryproto'
MEAN_NPY_PATH = 'mean.npy'

blob = caffe.proto.caffe_pb2.BlobProto()
data = open(MEAN_PROTO_PATH, 'rb').read()
blob.ParseFromString(data)

array = np.array(caffe.io.blobproto_to_array(blob))
mean_npy = array[0]
np.save(MEAN_NPY_PATH, mean_npy)

运行,即在data目录下生成mean.npy文件

(4) 编写test_densenet.py文件

在densenet根目录下创建test_densenet.py文件,编写代码如下:

import os.path as osp
import numpy as np
import caffe

this_dir = osp.dirname(__file__)
net_file = osp.join(this_dir, 'densenet.prototxt')
pretrained_file = osp.join(this_dir, '_iter_230000.caffemodel')
image_file = osp.join(this_dir, 'images/05_32x32.png')
mean_file = osp.join(this_dir, 'data/mean.npy')

classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']

input_image = caffe.io.load_image(image_file, color=True) #load_image读进来的图像数据为RGB格式,范围为0~1

mean_npy = np.load(mean_file)
mean = mean_npy.mean(1).mean(1)

caffe.set_mode_gpu()
net = caffe.Classifier(net_file,
                       pretrained_file,
                       mean=mean,
                       raw_scale=255,  #数据范围调整为0~255
                       channel_swap=(2,1,0)) #转换为BGR格式
prediction = net.predict([input_image], oversample=True)

idx = prediction[0].argmax()
print image_file + ' predicted_class:', classes[idx]

运行以上程序,即可预测出图片的类别,如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章