用caffe訓練並測試自己收集的數據,踩了一堆坑


先上一張圖,聊做安慰。 (雖然事實上,哈哈。。。。。。。)




1.數據準備:

數據是自己收集的數據,兩個人,一隻貓,總共有三個分類,每個分類有5000張左右的圖片。(事實上,我手動採集不了這麼多圖片,所以,每個分類採集了50張,然後就在自己的分類中不斷複製,粘貼。就粘貼了5000張,所以其實每一個圖片都有100張或200張一模一樣的圖片。)


data文件夾裏有三個文件夾,分別是

d(存放男士A的所有照片)

g(存放女士B的所有照片)

c(存放貓咪c的所有照片)

先用new_name.py 統一下命名d_1.jpg    ..................   d_5000.jpg 和 g_1.jpg    ..................   g_5000.jpg  和 

c_1.jpg    ..................   c_5000.jpg    


配置和執行文件:

new_name.py  是自己寫的

import os


a='miao'
path='/home/thm/caffe-master/face16/data/%s'%a
names = os.listdir(path)
os.chdir(path)
i=0
#for name in names:
 #   print(name)
    
for num in range(len(names)):
    print(names[num])
    os.rename(names[num],'%s'%a+'_'+str(num)+'.jpg')

gettxt.py 是在網上找別人的,

gettxt.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os


root = os.getcwd() 
data = '/data'  
path = os.listdir(root+'/'+ data) 
path.sort()
vp = 0.1 
ftr = open('train.txt','w')
fva = open('val.txt','w')
i = 0


for line in path:
    subdir = root+'/'+ data +'/'+line
    childpath = os.listdir(subdir)
    mid = int(vp*len(childpath))
    for child in childpath[:mid]:
        subpath = data+'/'+line+'/'+child;
        d = ' %s' %(i)
        t = subpath + d
        fva.write(t +'\n')
    for child in childpath[mid:]:
        subpath = data+'/'+line+'/'+child;
        d = ' %s' %(i)
        t = subpath + d
        ftr.write(t +'\n')
    i=i+1
ftr.close()  
fva.close() 


自己使用的時候簡單改了一下。(感謝分享)


create_imagenet.sh    和    make_imagenet_mean.sh  都是從caffe-master/examples/imagenet  裏複製出來的

train_caffenet.sh  和  solver.prototxt  和   train_val.prototxt 是從 caffe-master/models/bvlc_reference_caffenet/ 裏複製出來的


2.測試開始

(1)、用gettxt.py生成用於訓練和測試的名字序列:


就是用“1”,生成“2. 3”


(2)、用create_imagenet.sh1生成用於訓練和測試的兩個lmdb 2,3文件。需要修改文件

(如需要,還可以用make_imagenet_mean.sh 生成均值文件。需要修改文件


[踩坑,因爲前期生成的名字序列是這樣的:./data/d/d_10.jpg。然而訓練的時候是在caffe的根目錄進行的,所以導致讀圖片是少了一個文件夾face16的過渡,就“ 暗暗的 沒有生成lmdb”,導致訓練出現有路徑問題,圖片尺寸問題。~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~然後爲解決所謂的{路徑、尺寸} 問題,我還百度了一堆東西,然並卵,根據方法修改之後並沒有用]


[再踩坑,訓練時出現的問題還有net .原因是路徑,之後把一切路徑都設成絕對路徑,然後只要在solver 和 train_val 中出現路徑,就再三覈對需不需要改路徑。謹慎一點總不會錯]


(3)、修改配置和執行文件


train_caffenet.sh 文件可以不需要 

solver.prototxt 是執行的配置文件,可以在其中根據自己的需要修改執行和訓練的參數。

train_val.prototxt是具體的layer層的配置文件,包括每一層用什麼算法,算法參數的大小等。


上一張別人的“solver.prototxt”配置,作者寫的是每一個分類是5000張,因爲我和其數據大小類似,就裁取了類似的大小配置。這裏放這張圖是爲了備註下注釋。

圖的來源:http://www.cnblogs.com/alexcai/p/5469436.html


train_val.prototxt裏重點需要改的是mean_file,(均值文件路徑)   source, (lmdb 的文件路徑)   batch_size, (設爲50,不然出現cudunsuccess)   num_output(這個是改爲自己的分類個數,我寫的是3)  

哈哈哈,顏色真好玩

train_caffenet.sh 文件需要修改的是solver 的路徑


(真誠的提醒自己,不用硬性的仿照別人的東西改自己的文件,一定要理解清楚自己改的文件所涉及的關係)


(4)、執行

改完配置的文件就該執行了,不出錯是最好的,出錯了也可以讓自己多瞭解下其中的運行規則和細節。

對於執行結果,需要關注的是兩個 accuracy, loss  。前者正常情況下,總體訓練迭代的越多,最後的值對比於最初的值減小的就越多。而loss不能一直變大,否則就是發散,需要調整參數。

我將solver.prototxt 改成這樣:


訓練產生的accuracy 和loss,就從0.35,1.02 變成了0.966,0.175.。哈哈,實測參數設置一定要合適。


這些是建立在我剛接觸caffe 的客觀基礎上的,所以對caffe的體會可能有些偏頗甚至是錯誤,期待批評指正。

越接觸算法,越覺得算法有趣,尤其是對開源的人萌發出崇高的敬意。


這是畫的loss 和accuracy 的圖。參數設置是重新進行修改過的,和上述的不一樣

 


代碼在這裏: (是將別人的稍加修改  這是它人的原博客:http://www.cnblogs.com/denny402/p/5686067.html)

# -*- coding: utf-8 -*-


import matplotlib.pyplot as plt
import math  
import caffe
from numpy import *  
caffe.set_device(0)  
caffe.set_mode_gpu()   


solver = caffe.SGDSolver('/home/thm/caffe-master/face16/solver.prototxt')  
  
  
niter = 5000 
  
display= 100  
  


test_iter = 100  
 
test_interval =500  
  
 
train_loss = zeros(math.ceil(niter * 1.0 / display))   
test_loss = zeros(math.ceil(niter * 1.0 / test_interval))  
test_acc = zeros(math.ceil(niter * 1.0 / test_interval))  
  
  
solver.step(1)  
  
  
_train_loss = 0; _test_loss = 0; _accuracy = 0  
 
for it in range(niter):  
      
    solver.step(1)  
     
    _train_loss += solver.net.blobs['loss'].data  
    if it % display == 0:  
          
        train_loss[it // display] = _train_loss / display  
        _train_loss = 0  
  
    if it % test_interval == 0:  
        for test_it in range(test_iter):  
              
            solver.test_nets[0].forward()  
              
            _test_loss += solver.test_nets[0].blobs['loss'].data  
              
            _accuracy += solver.test_nets[0].blobs['accuracy'].data  
          
        test_loss[int(it/test_interval)] = _test_loss / test_iter  
          
        test_acc[int(it / test_interval)] = _accuracy / test_iter  
        _test_loss = 0  
        _accuracy = 0  
  
 
print ('\nplot the train loss and test accuracy\n')  
_, ax1 = plt.subplots()  
ax2 = ax1.twinx()  
  
  
ax1.plot(display * arange(len(train_loss)), train_loss, 'g')  
  
ax1.plot(test_interval * arange(len(test_loss)), test_loss, 'y')  
 
ax2.plot(test_interval * arange(len(test_acc)), test_acc, 'r')  
  
ax1.set_xlabel('iteration')  
ax1.set_ylabel('loss')  
ax2.set_ylabel('accuracy')  
plt.show() 

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