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]

運行以上程序,即可預測出圖片的類別,如下:

 

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