本文假設你已經完成了安裝,並可以運行demo.py
不會安裝且用PASCAL VOC數據集的請看另來兩篇博客。
caffe學習一:ubuntu16.04下跑Faster R-CNN demo (基於caffe). (親測有效,記錄經歷兩天的吐血經歷)
https://www.cnblogs.com/elitphil/p/11527732.html
caffe學習二:py-faster-rcnn配置運行faster_rcnn_end2end-VGG_CNN_M_1024 (Ubuntu16.04)
https://www.cnblogs.com/elitphil/p/11547429.html
一般上面兩個操作你實現了,使用Faster RCNN訓練自己的數據就順手好多。
第一步:准備自己的數據集
(1). 首先,自己的數據集(或自己拍攝或網上下載)分辨率可能太大,不利於訓練,通過一頓操作把他們縮小到跟VOC里的圖片差不多大小。
在/py-faster-rcnn/data/VOCdevkit2007/VOC2007 (找到你自己文件相對應的目錄),新建一個python文件(如命名為trans2voc_format.py)
把以下內容粘貼復制進去,然后執行該python文件即可對你的圖片進行裁剪縮放等操作:
#coding=utf-8
import os #打開文件時需要
from PIL import Image
import re
Start_path='./JPEGImages/' # 唯一一處需要修改的地方。把對應的圖片目錄換成你的圖片目錄。
iphone5_width=333 # 圖片最大寬度
iphone5_depth=500 # 圖片最大高度
list=os.listdir(Start_path)
#print list
count=0
for pic in list:
path=Start_path+pic
print path
im=Image.open(path)
w,h=im.size
#print w,h
#iphone 5的分辨率為1136*640,如果圖片分辨率超過這個值,進行圖片的等比例壓縮
if w>iphone5_width:
print pic
print "圖片名稱為"+pic+"圖片被修改"
h_new=iphone5_width*h/w
w_new=iphone5_width
count=count+1
out = im.resize((w_new,h_new),Image.ANTIALIAS)
new_pic=re.sub(pic[:-4],pic[:-4]+'_new',pic)
#print new_pic
new_path=Start_path+new_pic
out.save(new_path)
if h>iphone5_depth:
print pic
print "圖片名稱為"+pic+"圖片被修改"
w=iphone5_depth*w/h
h=iphone5_depth
count=count+1
out = im.resize((w_new,h_new),Image.ANTIALIAS)
new_pic=re.sub(pic[:-4],pic[:-4]+'_new',pic)
#print new_pic
new_path=Start_path+new_pic
out.save(new_path)
print 'END'
count=str(count)
print "共有"+count+"張圖片尺寸被修改"
(2).圖片有了,然后我們需要對圖片進行重命名(理論上來說你不重命名來說也沒影響)。
同樣在/py-faster-rcnn/data/VOCdevkit2007/VOC2007 (找到你自己文件相對應的目錄),新建一個python文件(如命名為pic_rename.py)
把以下內容粘貼復制進去,然后執行該文件,就可以把圖片重命名(如你有一百張圖片,則會重命名為:000001~0001000):
# coding=utf-8
import os # 打開文件時需要
from PIL import Image
import re
class BatchRename():
def __init__(self):
self.path = './JPEGImages' # 同樣(也是),把圖片路徑換成你的圖片路徑
def rename(self):
filelist = os.listdir(self.path)
total_num = len(filelist)
i = 000001 # 還有這里需要注意下,圖片編號從多少開始,不要跟VOC原本的編號重復了。
n = 6
for item in filelist:
if item.endswith('.jpg'):
n = 6 - len(str(i))
src = os.path.join(os.path.abspath(self.path), item)
dst = os.path.join(os.path.abspath(self.path), str(0) * n + str(i) + '.jpg')
try:
os.rename(src, dst)
print 'converting %s to %s ...' % (src, dst)
i = i + 1
except:
continue
print 'total %d to rename & converted %d jpgs' % (total_num, i)
if __name__ == '__main__':
demo = BatchRename()
demo.rename()
(3). 然后需要對圖片進行手動標注,建議使用labelImg工具,簡單方便。
下載地址:https://github.com/tzutalin/labelImg
使用方法特別簡單,設定xml文件保存的位置,打開你的圖片目錄,然后一幅一幅的標注就可以了
(借用參考鏈接第二條的一張圖)
把所有圖片文件標准完畢,並且生成了相對應的.xml文件。
接下來,來到voc207這里,把原來的圖片和xml刪掉(或備份),位置分別是:
-
/home/py-faster-rcnn/data/VOCdevkit2007/VOC2007/JPEGImages
-
/home/py-faster-rcnn/data/VOCdevkit2007/VOC2007/Annotations
刪掉是因為我們不需要別的數據集,只想訓練自己的數據集,這樣能快一點
(4)數據和圖片就位以后,接下來生成訓練和測試用需要的txt文件索引,程序是根據這個索引來獲取圖像的。
在/py-faster-rcnn/data/VOCdevkit2007/VOC2007 (找到你自己文件相對應的目錄),新建一個python文件(如命名為xml2txt.py)
把以下內容粘貼復制進去,然后執行該python文件即可生成索引文件:
# !/usr/bin/python
# -*- coding: utf-8 -*-
import os
import random
trainval_percent = 0.8 #trainval占比例多少
train_percent = 0.7 #test數據集占比例多少
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main' # 生成的索引文集所在路徑
total_xml = os.listdir(xmlfilepath)
num=len(total_xml)
list=range(num)
tv=int(num*trainval_percent)
tr=int(tv*train_percent)
trainval= random.sample(list,tv)
train=random.sample(trainval,tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name=total_xml[i][:-4]+'\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftrain.write(name)
else:
fval.write(name)
else:
ftest.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
生成的索引文件在這
以上,數據准備完畢。
第二步,修改源代碼:
(1). 修改prototxt配置文件
這些配置文件都在models下的pascal_voc下。里面有三種網絡結構:ZF、VGG16、VGG_CNN_M_1024,本文選擇的是
VGG_CNN_M_1024。每個網絡結構中都有三個文件夾,分別是faster_rcnn_end2end、faster_rcnn_alt_opt、faster_rcnn。
使用近似聯合訓練,比交替優化快1.5倍,並且准確率相近,所以推薦使用這種方法。更改faster_rcnn_end2end文件夾下的
的train.protxt和test.prototxt。其中train.prototxt文件共有四處需要修改(有些文章寫的是只有三處需要修改,但是通過我的試驗
和百度,最終發現有四處需要修改)
第一處是input-data層,將原先的21改成:你的實際類別+1(背景),我的目標檢測一共有1類(為了試驗方便,我只選了一類),
所以加上背景這一類,一共2類。
(num_classes: 21, 被我修改為2。 如上圖所示 )
第二處是cls_score層:
(num_output: 21 被我改成了2。切記,你要根據你的實際類別修改)
第三處是bbox_pred,這里需將原來的84改成(你的類別數+1)*4, 即(1+1)×4 = 8
還有第四處,roi-data 層(我發現有些博客是沒有寫這一點的,但是如果我沒修改這里則會報錯)
(原先的21被我改成了2)
test.prototxt只需要按照train.prototxt中修改cls_score層以及bbox_pred層即可
(2). 修改lib/datasets/pascal_voc.py,將類別改成自己的類別
如上圖所示,我將原本的類別注釋掉,換成了自己的類別,以方便日后還原。
這里有一點需要注意的是,這里的類別以及你之前的類別名稱最好全部是小寫,假如是大寫的話,則會報Keyerror的錯誤。
這時只需要在pascal_voc.py 中的214行的.lower()去掉即可(我沒試驗,因為我的類名用的小寫,所以沒有遇到這個問題;
看到別的博客給了這么一個答案)
datasets目錄主要有三個文件,分別是
1) factory.py: 這是一個工廠類,用類生成imdb類並且返回數據庫供網絡訓練和測試使用;
2) imdb.py: 是數據庫讀寫類的基類,封裝了許多db的操作;
3) pascal_voc.py Ross用這個類操作。
第三步,開始訓練
注意:訓練前需要將cache中的pkl文件以及VOCdevkti2007中的annotations_cache的緩存刪掉
1. cd py-faster-rcnn
2. ./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc
第四步,測試結果
訓練完成之后,將output中的最終模型拷貝到data/faster_rcnn_models, 修改tools下的demo.py,
我是使用VGG_CNN_M_1024這個中型網絡,不是默認的ZF,所以要修改以下幾個地方:
(1) 修改class
同樣的手法,將原本的CLASSES注釋掉(不建議刪除,留在方便日后還原),新增自己的CLASSES
(2). 增加你自己訓練的模型
myvgg1024為新增的部分
(3) 修改prototxt(demo.py文件的內容), 如果你用的是ZF,就不用修改了
被注釋掉的內容是修改前的,后面是我新增的。
(4) 開始檢測
1) 把你需要檢測的圖片放在data/demo文件夾下
2)demo.py 修改你要檢測的圖片名稱
3)執行命令
1. cd py-fast-rcnn/tools
2. ./demo.py --net myvgg1024
參考博客
https://blog.csdn.net/zhaoluruoyan89/article/details/79088621
https://blog.csdn.net/zcy0xy/article/details/79614862
tf-faster rcnn訓練自己的數據參考博客:https://blog.csdn.net/qq_34108714/article/details/89335642