先上一張圖,聊做安慰。 (雖然事實上,哈哈。。。。。。。)
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()