1. 程式人生 > >Caffe:使用 Caffe 訓練自己的 Alexnet

Caffe:使用 Caffe 訓練自己的 Alexnet

使用 Caffe 訓練自己的 Alexnet


參考:

  1. caffe:用自己的影象資料訓練模型(圖片分類)
  2. Brewing ImageNet

1. 資料準備

caffe_master/data 中新建資料夾 myalex,在 myalex/train

檔案裡存放訓練的圖片 85 張,在 myalex/val 檔案裡存放驗證集的圖片 36 張,在 myalex/test 檔案裡面放測試的照片

根據訓練和測試的圖片生成 train.txt 檔案、 val.txt 檔案和 test.txt 檔案,此檔案裡包含檔名和分類標籤。標籤為 1 或 -1。

可在 train 資料夾路徑下,使用 find -name *.jpeg |cut -d ‘/’ -f2-3 >train.txt 指令碼命令來生成 train.txt 檔案。val.txt 的生成方法類似。

train.txt 如圖所示:

把圖片變成 256×256 大小,使用 shell 命令:

for name in /path/to/imagenet/val/*.JPEG; do
    convert -resize 256x256\! $name $name
done

或者在下一步建立 leveldb 資料時,將 examples/imagenet/create_imagenet.sh 的 RESIZE 設定為 true 來更改大小。

生成 leveldb 格式資料:在 caffe-master/examples 裡建立資料夾 myalex,將 imagenet 資料夾裡的 create_imagenet.sh 複製到該資料夾下進行修改,主要修改訓練和測試路徑的位置,然後在命令列的 caffe-master 路徑下,執行 ./examples/myalex/create_imagenet.sh

。執行完畢,將在 myalex 裡生成 myalex_train_leveldb 和 myalex_val_leveldb。

修改如下:

#!/usr/bin/env sh
# Create the imagenet lmdb inputs
# N.B. set the path to the imagenet train + val data dirs
set -e

# 改為自己的 train 和 val 路徑
EXAMPLE=examples/myalex
DATA=data/myalex
TOOLS=build/tools

TRAIN_DATA_ROOT=data/myalex/train/
VAL_DATA_ROOT=data/myalex/val/

# Set RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
# 使用 Alexnet 輸入是 277x277 而不是 256x256
RESIZE=true
if $RESIZE; then
  RESIZE_HEIGHT=227
  RESIZE_WIDTH=227
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi

if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet training data is stored."
  exit 1
fi

if [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet validation data is stored."
  exit 1
fi

echo "Creating train lmdb..."

# 同樣改為自己的命名
GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $TRAIN_DATA_ROOT \
    $DATA/train.list \
    $EXAMPLE/myalex_train_lmdb

echo "Creating val lmdb..."

GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $VAL_DATA_ROOT \
    $DATA/val.list \
    $EXAMPLE/myalex_val_lmdb

echo "Done."

我們得到了這兩個東西:

2. 計算影象均值

模型需要從每張圖片裡減去均值,所以我們必須提前獲得影象的均值,用 tools/compute_image_mean.cpp 實現,這個 cpp 是一個很好的例子去熟悉如何操作多個元件,例如協議緩衝區,leveldb,登入等。我們直接複製 Imagenet 的 make_imagenet_mean,並修改路徑即可。然後在命令列的 caffe-master 路徑下,執行 ./examples/myalex/make_imagenet_mean.sh,執行結束後,將會在 caffe-master/data/myalex 裡生成 myalex_mean.binaryproto。

#!/usr/bin/env sh
# Compute the mean image from the imagenet training lmdb
# N.B. this is available in data/ilsvrc12

EXAMPLE=examples/myalex
DATA=data/myalex
TOOLS=build/tools

$TOOLS/compute_image_mean $EXAMPLE/myalex_train_lmdb \
  $DATA/myalex_mean.binaryproto

echo "Done."

3. 定義網路

我們使用 Alexnet,拷貝 caffe/models/bvlc_alexnetcaffe/examples/myalex/

要修改 solver.prototxttrain_val.prototxt

3.1 修改 solver.prototxt

net: "examples/myalex/bvlc_alexnet/train_val.prototxt"
test_iter: 50 //測試迭代次數
test_interval: 100 //多少次迭代測試一次
base_lr: 0.01 //基礎學習率
lr_policy: "step"
gamma: 0.1
stepsize: 100000
display: 20 //多少次迭代顯示一次
max_iter: 700 //多少次迭代顯示一次
momentum: 0.9
weight_decay: 0.0005
snapshot: 700 //多少次迭代儲存一次模型快照
snapshot_prefix: "examples/myalex/bvlc_alexnet/caffe_alexnet_train" //快照儲存位置
solver_mode: GPU

3.2 修改 train_val.prototxt

//記得兩個引數不止一個!全部修改了!別隻修改一個

mean_file : "examples/myalex/imagenet_mean.binaryproto"
//這個是上面生成的均值檔案位置

source : "examples/myalex/myalex_train_lmdb"
//這個是上面生成的 lmdb 檔案位置

//然後如果你自己要定義類別個數(嫌麻煩就別改這裡了!不會影響!),請在最後一層裡面
name : "fc8" //這個名字的代表 alexnet 的最後一層,其他的網路自己找
num_output: 2 //alexnet 預設 1000 個 改成你自己的個數,我改成: num_output: 2 //也可以不改,訓練不影響

4. 訓練網路

到根目錄,執行命令:

./build/tools/caffe train --solver=examples/myalex/bvlc_alexnet/solver.prototxt