1. 程式人生 > >caffe訓練自己的資料集

caffe訓練自己的資料集

https://www.cnblogs.com/wktwj/p/6715110.html

預設caffe已經編譯好了,並且編譯好了pycaffe

1 資料準備

首先準備訓練和測試資料集,這裡準備兩類資料,分別放在資料夾0和資料夾1中(之所以使用0和1命名資料類別,是因為方便標註資料類別,直接用資料夾的名字即可)。即訓練資料集:/data/train/0、/data/train/1  訓練資料集:/data/val/0、/data/val/1。

資料準備好之後,建立記錄資料檔案和對應標籤的txt檔案

(1)建立訓練資料集的train.txt

複製程式碼
 1 import os
 2 f =open(r'train.txt',"w")
 3 path = os.getcwd()+'/data/train/'
 4 for filename in os.listdir(path) :
 5     count = 0
 6     for file in os.listdir(path+filename) :
 7         count = count + 1
 8         ff='/'+filename+"/"+file+" "+filename+"\n"
 9         f.write(ff)
10     print '{} class: {}'.format(filename,count)
11 f.close()
複製程式碼

(2)建立測試資料集val.txt

複製程式碼
 1 import os
 2 f =open(r'val.txt',"w")
 3 path = os.getcwd()+'/data/val/'
 4 for filename in os.listdir(path) :
 5     count = 0
 6     for file in os.listdir(path+filename) :
 7         count = count + 1
 8         ff='/'+filename+"/"+file+" "+filename+"\n"
 9         f.write(ff)
10     print '{} class: {}'.format(filename,count)
11 f.close()
複製程式碼

注意,txt中檔案的路徑為: /類別資料夾名/檔名(空格,不能是製表符)類別

2 建立LMDB資料檔案

建立createlmdb.sh使用caffe自帶的(bulid/tools下的)convert_imageset建立LMDB資料檔案,主要是注意資料檔案以及上一步生成的txt檔案的位置,注意資料檔案的RESIZE,後邊在進行訓練和測試的時候還要用到,其餘就是檔案的路徑的問題了。

複製程式碼
 1 #!/usr/bin/env sh
 2 
 3 CAFFE_ROOT=/home/caf/object/caffe
 4 TOOLS=$CAFFE_ROOT/build/tools
 5 TRAIN_DATA_ROOT=/home/caf/wk/learn/data/train
 6 VAL_DATA_ROOT=/home/caf/wk/learn/data/val
 7 DATA=/home/caf/wk/learn/data
 8 EXAMPLE=/home/caf/wk/learn/data/lmdb
 9 # Set RESIZE=true to resize the images to 60 x 60. Leave as false if images have
10 # already been resized using another tool.
11 RESIZE=true
12 if $RESIZE; then
13   RESIZE_HEIGHT=227
14   RESIZE_WIDTH=227
15 else
16   RESIZE_HEIGHT=0
17   RESIZE_WIDTH=0
18 fi
19 
20 if [ ! -d "$TRAIN_DATA_ROOT" ]; then
21   echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
22   echo "Set the TRAIN_DATA_ROOT variable in create_face_48.sh to the path" \
23        "where the face_48 training data is stored."
24   exit 1
25 fi
26 
27 if [ ! -d "$VAL_DATA_ROOT" ]; then
28   echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
29   echo "Set the VAL_DATA_ROOT variable in create_face_48.sh to the path" \
30        "where the face_48 validation data is stored."
31   exit 1
32 fi
33 
34 echo "Creating train lmdb..."
35 
36 GLOG_logtostderr=1 $TOOLS/convert_imageset \
37     --resize_height=$RESIZE_HEIGHT \
38     --resize_width=$RESIZE_WIDTH \
39     --shuffle \
40     $TRAIN_DATA_ROOT \
41     $DATA/train.txt \
42     $EXAMPLE/face_train_lmdb
43 
44 echo "Creating val lmdb..."
45 
46 GLOG_logtostderr=1 $TOOLS/convert_imageset \
47     --resize_height=$RESIZE_HEIGHT \
48     --resize_width=$RESIZE_WIDTH \
49     --shuffle \
50     $VAL_DATA_ROOT \
51     $DATA/val.txt \
52     $EXAMPLE/face_val_lmdb
53 
54 echo "Done."
複製程式碼

 

3 定義網路

caffe接受的網路模型是prototxt檔案,對於caffe網路的定義語法有詳細的解釋,本次實驗用的是AlexNet,儲存在train_val.prototxt

  View Code

 

建立超引數檔案slover.prototxt,主要定義訓練的引數,包括迭代次數,每迭代多少次儲存模型檔案,學習率等等,net就是剛才定義的訓練網路,這裡訓練和測試使用同一個網路。

複製程式碼
 1 net: "train_val.prototxt"
 2 test_iter: 2
 3 test_interval: 10
 4 base_lr: 0.001
 5 lr_policy: "step"
 6 gamma: 0.1
 7 stepsize: 100
 8 display: 20
 9 max_iter: 100
10 momentum: 0.9
11 weight_decay: 0.005
12 solver_mode: GPU
13 snapshot: 20
14 snapshot_prefix: "model/"
複製程式碼

 

4 訓練模型

建立train.sh使用GPU進行訓練,否則太慢!!!

1 #!/usr/bin/env sh
2 CAFFE_ROOT=/home/caf/object/caffe
3 SLOVER_ROOT=/home/caf/wk/learn
4 $CAFFE_ROOT/build/tools/caffe train --solver=$SLOVER_ROOT/slover.prototxt --gpu=0

 在model資料夾下會生成caffemodel檔案,使用這些檔案用於影象的分類等操作。

4 測試

建立deploy.prototxt進行測試,和訓練網路一樣,只不過用於實際分類的網路並不需要訓練網路那些引數了,因此需要重新定義一個模型檔案,測試的圖片在該模型中進行。

deploy.prototxt檔案和train_val.prototxt檔案不同的地方在於:

(1)輸入的資料不再是LMDB,也不分為測試集和訓練集,輸入的型別為Input,定義的維度,和訓練集的資料維度保持一致,227*227,否則會報錯;

(2)去掉weight_filler和bias_filler,這些引數已經存在於caffemodel中了,由caffemodel進行初始化。

(3)去掉最後的Accuracy層和loss層,換位Softmax層,表示分為某一類的概率。

  View Code

用於訓練的python程式碼,使用caffe中python的介面,主要定義好自己訓練好的引數檔案,模型檔案的位置,以及均值檔案的位置。

複製程式碼
 1 import numpy as np
 2 import matplotlib.pyplot as plt
 3 
 4 import sys
 5 caffe_root="/home/caf/object/caffe/"
 6 sys.path.insert(0,caffe_root+'python')
 7 import caffe
 8 caffe.set_device(0)
 9 caffe.set_mode_gpu()
10 model_def = 'deploy.prototxt'
11 model_weights = 'model/_iter_100.caffemodel'
12 net = caffe.Net(model_def,
13                 model_weights,  
14                 caffe.TEST)     
15 mu = np.load(caffe_root + 'python/caffe/imagenet/ilsvrc_2012_mean.npy')
16 mu = mu.mean(1).mean(1)
17 #print 'mean-subtracted values:', zip('BGR', mu)
18 transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
19 transformer.set_transpose('data', (2,0,1))
20 transformer.set_mean('data', mu)
21 transformer.set_raw_scale('data', 255)    
22 transformer.set_channel_swap('data', (2,1,0))
23 net.blobs['data'].reshape(3,227, 227)
24 image = caffe.io.load_image('test.jpg')
25 transformed_image = transformer.preprocess('data', image)
26 #plt.imshow(image)
27 #plt.show()
28 net.blobs['data'].data[...] = transformed_image
29 output = net.forward()  
30 output_prob = output['prob']
31 print output_prob
32 print 'predicted class is:', output_prob.argmax()
複製程式碼

遇到的問題

(1)標籤檔案不能用製表符,必須是空格,否則會找不到資料檔案

(2)CUDA問題,報一個類似叫CUDASuccess的錯誤,說明GPU空間不夠,需要釋放空間,使用  nvidia-smi  命令檢視那個程式佔用GPU過高,使用   kill -9 PID結束掉即可

(3)由於caffe版本的問題,層的定義 有layer和layers,使用layer定義,type需要加雙引號,是字元格式;使用layers定義,type不用加雙引號,變為全大寫字母