實踐詳細篇-Windows下使用Caffe訓練自己的Caffemodel數據集並進行圖像分類


三:使用Caffe訓練Caffemodel並進行圖像分類

上一篇記錄的是如何使用別人訓練好的MNIST數據做訓練測試。上手操作一邊后大致了解了配置文件屬性。這一篇記錄如何使用自己准備的圖片素材做圖像分類。第一篇《實踐詳細篇-Windows下使用VS2015編譯安裝Caffe環境(CPU ONLY) 》有講過使用Caffe的背景.所以這篇記錄使用的素材就是12306的驗證碼來進行圖像識別分類。

1、准備素材

由於這里抓取到的驗證碼是整合后的大圖。就是8張小圖片合成的。由於12306的驗證碼大圖並不是固定的,而是每一張驗證碼圖片都是隨機使用一些小圖組成,所以需要將大圖進行切割為八張小圖片,這樣才能准確的提高識別圖。

  大圖:

  切割后的小圖:

注意:准備的樣本圖片命名最好有一個格式,比如同一種類型用一種編號,可以是數字或者是數字+字母。比如獅子的編號以100開始,圖片編號就是100,101,102....。以此類推。

2、處理樣本並將素材轉換為leveldb或lmdb數據格式

2.1.下載樣本處理工具,解壓至Caffe根目錄。結構如下:

在mydata目錄中分別創建train文件夾和test文件夾。train文件夾用於存放訓練樣本圖片,test文件夾用於存放測試樣本圖片。

注意:

一、train圖片資源最好是比測試圖片多。

二、圖片尺寸需要保持統一並圖片名稱不能包含特殊字符 有規則的命名,這樣便於下一步創建標簽

2.2.創建標簽樣本

首先需要確定自己有幾個樣本標簽。在caffe根目錄\examples目錄下新建一個文件夾testImg(這個文件夾就是后期用到的訓練主目錄了,里面將存放均值文件+神經網絡等配置主文件。)並在testImg目錄下新建一個文本labels.txt 將樣本標簽內容填寫進去,比如我們這里測試用了8個標簽樣本,分別是:

1 獅子
2 海鷗
3 本子
4 剪紙
5 綠豆
6 啤酒
7 錦旗
8 金字塔

找到create_filelist.sh文件進行編輯

需要修改的地方:

         for i in 語句后面對應的就是需要循環的樣本編號 需要修改兩處,修改完成后直接運行腳本。

  1. FILETYPE 需要處理的圖片類型 我這邊使用的是png 如果你是jpg或者其他格式就修改為別的類型即可
#!/usr/bin/env sh
DATA=mydata
FILETYPE=png ##需要處理樣本的圖片格式
echo "Create train.txt..."
rm -rf $DATA/train.txt
for i in 1 2 3 4 5 6 7 8 ##需要處理幾個樣本標簽就填寫幾個 我這里處理8個樣本  順序最好是從0開始 我這里以1開始迭代,但是后面我又手動處理了的
do
find $DATA/train -name $i*.$FILETYPE | cut -d '/' -f2-4 | sed "s/$/ $i/">>train.txt
done
echo "Create test.txt..."
rm -rf $DATA/test.txt
for i in 1 2 3 4 5 6 7 8 ##需要處理幾個樣本標簽就填寫幾個 我這里處理8個樣本  
do
find $DATA/test -name $i*.$FILETYPE | cut -d '/' -f2-4 | sed "s/$/ $i/">>test.txt
done
echo "All done"
pause

執行腳本進行創建樣本文件

Administrator@2T93DQV8MG8N68O MINGW64 /e/shenduxuexi/caffe/create_img_db (windows)
$ sh create_filelist.sh
Create train.txt...
Create test.txt...
All done

執行完成后會在當前腳本目錄生成兩個文件,分別是train.txt和test.txt樣本文件。其中的內容就是使用腳本進行便利圖片然后根據圖片編號第一位生成了標簽編號,標簽編號就是用於分類使用的。每一行包含兩個內容,分別是圖片路徑和標簽編號。

手動處理:

去掉路徑(train/)/(test/),如果將圖片分類放置不同的文件夾的話可以不用處理。比如train/老虎/106.png。

將編號-1  也就是 全部替換 將1 改為0 ,2改為1  以此類推,因為標簽索引從0開始可以避免一個錯誤

train.txt文件內容:

train/100.png 1
train/101.png 1
train/103.png 1
train/104.png 1
train/105.png 1
train/106.png 1
train/108.png 1
train/109.png 1
train/110.png 1
train/112.png 1
train/201.png 2
train/202.png 2
train/203.png 2
train/204.png 2
train/205.png 2
train/206.png 2
train/207.png 2
train/208.png 2
........

test.txt內容:

test/100.png 1
test/101.png 1
test/103.png 1
test/104.png 1
test/105.png 1
test/106.png 1
test/108.png 1
test/124.png 1
test/125.png 1
test/200.png 2
test/201.png 2
test/202.png 2
test/203.png 2
test/204.png 2
test/205.png 2
test/206.png 2
test/207.png 2
test/208.png 2
test/209.png 2
test/300.png 3
test/301.png 3
test/302.png 3
test/303.png 3
.......

將兩個文件復制到examples/testImg目錄下。

2.3.資源轉換為數據庫文件

找到create_db.sh或create_db.bat文件 進行編輯修改。(如果准備的資源素材圖片尺寸不統一則修改resize_height和resize_width表示對圖像的尺寸統一轉換。自行根據資源決定)我准備的資源尺寸都是67的,所以我在轉換的過程就不用附帶--resize_height=227 --resize_width=227參數了

#!/usr/bin/env sh
ROOTURL=E:/shenduxuexi/caffe/create_img_db ##當前文件夾絕對路徑根目錄 根據自己的項目路徑修改
BACKEND=lmdb ##需要創建的數據集格式 leveldb或lmdb 
echo "Create test $BACKEND.."
rm -rf ./mnist_test_$BACKEND
../scripts/build/tools/Release/convert_imageset --resize_height=227 --resize_width=227 --backend=$BACKEND --shuffle $ROOTURL/mydata/test/  ./test.txt ./mnist_test_$BACKEND
echo "Create train end.."

echo "Create train $BACKEND.."
rm -rf ./mnist_train_$BACKEND
../scripts/build/tools/Release/convert_imageset --resize_height=227 --resize_width=227 --backend=$BACKEND --shuffle $ROOTURL/mydata/train/  ./train.txt ./mnist_train_$BACKEND
echo "All Done.."

修改完成保存后運行create_db.sh文件進行創建圖片數據轉換,轉換成功后會分別創建兩個文件夾 mytest_test_lmdb和mytest_train_lmdb。
     2.3.1.mytest_test_lmdb文件夾中存放的就是用於測試訓練模型的數據集
     2.3.2.mytest_train_lmdb文件夾中存放的就是用於訓練的數據模型

 

如兩個文件夾中分別包含了以上兩個文件表示轉換成功了。將轉換好的數據模型(mytest_train_lmdb文件夾)和測試數據集(mytest_test_lmdb文件夾)拷貝至examples\testImg文件夾下。

3、計算圖像的均值

圖片減去均值后再訓練會提高訓練速度和精度。

caffe程序提供了一個計算均值的工具,所以我們直接使用就可以了

在caffe根目錄下新建一個腳本,名為computeImageMean.bat。

第一個是啟動均值計算的程序路徑(scripts\build\tools\Release\compute_image_mean),

第二個是需要計算均值的數據庫文件(examples\testImg\mnist_train_lmdb)

第三個是創建均值保存的路徑(examples\testImg\train_mean.binaryproto)。

路徑根據自己的項目路徑決定

::當前caffe根目錄
SET ROOTURL=E:\shenduxuexi\caffe\
%ROOTURL%scripts\build\tools\Release\compute_image_mean %ROOTURL%examples\testImg\mnist_train_lmdb %ROOTURL%examples\testImg\train_mean.binaryproto
pause

  

創建好腳本后直接雙擊運行.

E:\shenduxuexi\caffe>E:\shenduxuexi\caffe\scripts\build\tools\Release\compute_image_mean examples\testImg\mnist_train_lmdb examples\testImg\train_mean.binaryproto
I0509 16:23:34.263166 268128 db_lmdb.cpp:40] Opened lmdb examples\testImg\mnist_train_lmdb
I0509 16:23:34.265166 268128 compute_image_mean.cpp:70] Starting iteration
I0509 16:23:34.268167 268128 compute_image_mean.cpp:101] Processed 200 files.
I0509 16:23:34.269166 268128 compute_image_mean.cpp:108] Write to examples\testImg\train_mean.binaryproto
I0509 16:23:34.269166 268128 compute_image_mean.cpp:114] Number of channels: 3
I0509 16:23:34.270167 268128 compute_image_mean.cpp:119] mean_value channel [0]: 113.79
I0509 16:23:34.270167 268128 compute_image_mean.cpp:119] mean_value channel [1]: 138.185
I0509 16:23:34.270167 268128 compute_image_mean.cpp:119] mean_value channel [2]: 160.625

如出現以上反饋即表示運行完成了,均值生成完成后進入examples\testImg文件夾會發現多出一個train_mean.binaryproto文件夾,這個就是均值文件。以上步驟都執行完成后examples\testImg文件下結構如下:

4、訓練數據模型

2.2.准備訓練神經網絡等文件夾(如果豪氣的話可以直接點我去下載配置的好的文件,以免出現自己新建文件出現編碼格式有誤。)

train_val.prototxt文件

name: "CaffeNet"
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size:227   //訓練的圖像大小 建議不要太小了 太小會出現識別不出來的,識別度很低,如果設置過高的話又非常浪費時間  我資源是67的 所以我這里修改的是67
    mean_file: "examples/testImg/train_mean.binaryproto"   //均值文件所在的路徑,改為你自己的均值文件所在的路徑
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }
  data_param {
    source: "examples/testImg/mnist_train_lmdb" //訓練樣本生成的數據庫所在的目錄,是訓練樣本 
    batch_size: 50 //每次訓練的樣本數量 由於我們的訓練樣本不多,所以我們一次讀入50張圖片就好
    backend: LMDB //數據模型的格式 lmdb或LEVELDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size:227  //訓練的圖像大小 建議不要太小了 太小會出現識別不出來的,識別度很低,如果設置過高的話又非常浪費時間  我資源是67的 所以我這里修改的是67
    mean_file: "examples/testImg/train_mean.binaryproto" //均值文件所在的路徑,改為你自己的均值文件所在的路徑
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: false
#  }
  data_param {
    source: "examples/testImg/mnist_test_lmdb" //測試樣本生成的數據庫所在的目錄,是測試樣本目錄
    batch_size: 50 //每次測試的樣本數量 
    backend: LMDB //數據模型的格式 lmdb或LEVELDB
  }
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "norm1"
  top: "conv2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 2
    kernel_size: 5
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv3"
  type: "Convolution"
  bottom: "norm2"
  top: "conv3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}
layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}
layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "fc6"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6"
  top: "fc6"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 8 //樣本標簽數量 我們這里訓練的標簽數量是8個 所以我們填寫8
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "fc8"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "fc8"
  bottom: "label"
  top: "loss"
}

solver.prototxt文件

net: "examples/testImg/train_val.prototxt" //神經網絡的配置地址
test_iter: 4 //因為我們的訓練圖片只有200張,設為4,而batch_size設為50,剛好是200張
test_interval: 50 //每迭代50次, 進行一次測試
base_lr: 0.001
momentum: 0.9
weight_decay: 0.004
lr_policy: "fixed" 
display: 1
max_iter: 2000 //最大循環迭代多少次 
snapshot: 1000 //每循環多少次生成一次數據模型文件
snapshot_format: HDF5 //輸出格式
snapshot_prefix: "examples/testImg/cifar10_quick" //輸出文件的前綴
solver_mode: CPU //訓練方式

deploy.prototxt文件

name: "CaffeNet"
layer {
  name: "data"
  type: "Input"
  top: "data"
  input_param { shape: { dim: 10 dim: 3 dim: 227 dim: 227 } }  //這里dim 227 兩個地方需要對應上你自己訓練時候的尺寸,否則會出現以下描述的異常
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  convolution_param {
    num_output: 8
    kernel_size: 11
    stride: 4
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "norm1"
  top: "conv2"
  convolution_param {
    num_output: 256
    pad: 2
    kernel_size: 5
    group: 2
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv3"
  type: "Convolution"
  bottom: "norm2"
  top: "conv3"
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}
layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    group: 2
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}
layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    group: 2
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "fc6"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6"
  inner_product_param {
    num_output: 4096
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6"
  top: "fc6"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6"
  top: "fc7"
  inner_product_param {
    num_output: 4096
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  inner_product_param {
    num_output: 8 //配置的標簽個數
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "fc8"
  top: "prob"
}

三個配置文件准備完成

在caffe根目錄下新建一個run.bat文件並填寫以下代碼

scripts/build/tools/Release/caffe.exe train --solver=examples/testImg/solver.prototxt
pause

雙擊執行腳本。

以上就是正在進行訓練的過程了,看圖片設置的大小以及訓練次數決定時間。 Iteration 6就是當前已經訓練到的次數,solver.prototxt文件中的max_iter屬性決定了最大迭代次數。所以耐心等待訓練完成吧。

經過幾個小時的等待,終於訓練完成。

訓練過程由於配置信息不同很容易造成失敗,以下就是整理了幾個異常信息。

異常1:

I0509 15:10:03.983913 158628 layer_factory.cpp:58] Creating layer data
I0509 15:10:03.984913 158628 db_lmdb.cpp:40] Opened lmdb examples/testImg/mnist_train_lmdb
I0509 15:10:03.984913 158628 net.cpp:84] Creating Layer data
I0509 15:10:03.984913 158628 net.cpp:380] data -> data
I0509 15:10:03.984913 158628 net.cpp:380] data -> label
I0509 15:10:03.984913 158628 data_transformer.cpp:25] Loading mean file from: examples/testImg/train_mean.binaryproto
I0509 15:10:03.984913 158628 common.cpp:36] System entropy source not available, using fallback algorithm to generate seed inste
F0509 15:10:03.985913 158628 data_transformer.cpp:466] Check failed: datum_height >= crop_size (32 vs. 227)
*** Check failure stack trace: ***

如執行run.bat出現以上錯誤的原因是因為train_val.prototxt文件中的 crop_size: 32大小設置的和模型圖像大小不一樣,確認是否在 2.3.資源轉換為數據庫文件這一步驟的時候設置的圖像大小和train_val.prototxt文件設置的crop_size大小是否一致 不一致的話需要修改crop_size屬性值。

異常2:

F0509 15:47:32.350512 263476 data_transformer.cpp:63] Check failed: datum_height == data_mean_.height() (67 vs. 24)
*** Check failure stack trace: ***

出現這種情況的原因是因為在生成數據模型文件(cifar10_quick_iter_2000.caffemodel.h5)的時候和數據均值文件里面的圖像高度和寬度不一致導致的。

異常3:

t_format.cc:298] Error parsing text-format caffe.NetParameter: 17:3: Unknown enu
meration value of "lmdb" for field "backend".
F0503 09:41:57.582864  7968 upgrade_proto.cpp:88] Check failed: ReadProtoFromTex
tFile(param_file, param) Failed to parse NetParameter file: examples/mnist/lenet
_train_test.prototxt
*** Check failure stack trace: ***

因為生成的數據格式和訓練格式不一致,核對下生成數據庫文件時設置的--backend數據格式是否和train_val.prototxt文件中的backend屬性配置的一致

5、進行測試圖像分類效果

 首先在caffe根目錄新建一個sh腳本,然后將以下代碼復制進去

./scripts/build/examples/cpp_classification/Release/classification.exe examples/testImg/deploy.prototxt examples/testImg/cifar10_quick_iter_1000.caffemodel.h5 examples/testImg/train_mean.binaryproto examples/testImg/labels.txt  E:/shenduxuexi/caffe/examples/images/212.jpg

 參數描述:

 ./scripts/build/examples/cpp_classification/Release/classification.exe  這個是caffe提供的一個C++圖像分類工具 

examples/testImg/deploy.prototxt   神經網絡的配置地址

examples/testImg/cifar10_quick_iter_1000.caffemodel.h5 訓練出來的數據模型地址

examples/testImg/train_mean.binaryproto 計算的均值文件地址

examples/testImg/labels.txt 標簽別名地址 對應的就是樣本標簽的順序 比如獅子原圖是100.png 編號索引就是1 那labels第一行就是寫一個別稱  獅子即可 這樣識別出來的時候就不是數字順序 

E:/shenduxuexi/caffe/examples/images/212.jpg 需要進行分類的測試圖片

以上參數需要根據自己電腦環境地址配置,配置完成雙擊運行。

效果圖如下:

測試過程可能出現的幾個異常情況,這邊也親測整理了下。

異常1:

*** Check failure stack trace: ***
F0509 10:19:03.050204 651172 classification.cpp:82] Check failed: labels_.size() == output_layer->channels() (100 vs. 1000) Number of labels is different from the output layer dimension.

生成訓練模型的時候配置文件solver.prototxt配置的num_output屬性為1000 而設置的測試lables標簽只有100,也就是訓練標簽和測試別名標簽不一致導致的

異常2:

*** Check failure stack trace: ***
F0509 19:21:29.603761 359572 hdf5.cpp:79] Check failed: blob_dims == blob->shape() Cannot load blob from h                           df5; shape mismatch. Source shape is 8 4096 (32768) target shape is 1000 4096 (4096000)

分類識別過程出現這個 是因為訓練的模型設置標簽是8個 但是識別的時候deploy.prototxt配置文件的num_output屬性是配置的1000個標簽。將num_output: 1000修改為num_output: 8即可

layer {
name: "fc8"
type: "InnerProduct"
bottom: "fc7"
top: "fc8"
inner_product_param {
num_output: 1000
}

異常3:

---------- Prediction for E:/shenduxuexi/caffe/examples/images/730 ----------
*** Check failure stack trace: ***
F0510 15:52:47.969362 721856 classification.cpp:251] Check failed: !img.empty()                          Unable to decode image E:/shenduxuexi/caffe/examples/images/730

主要原因是因為需要被識別分類的圖片路徑有問題,需要附帶圖片后綴。不知為何我跑PNG的圖片做分類也是這個錯誤,所以如果使用的是.png后綴格式圖片出現以上錯誤的話就將圖片進行格式轉換即可。點我下載批量轉換圖片工具

 總結:

歷經長久的學習和嘗試,終於完美的運行了自己想要的結果。三篇博客都是匆匆忙忙記錄的,因為我也是初學,剛接觸。在安裝caffe的過程也是踩了不少坑,做訓練自己的圖片素材也是,所以我記錄這篇博客的主要原因是為了方便自己后期的使用,那么既然自己記錄了也順便分享出來希望能幫助有需要的小伙伴。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM