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不用加雙引號,變為全大寫字母