日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fast RCNN 训练自己数据集 (2修改数据读取接口)

發(fā)布時間:2025/7/25 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fast RCNN 训练自己数据集 (2修改数据读取接口) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Fast RCNN 訓(xùn)練自己數(shù)據(jù)集 (2修改數(shù)據(jù)讀取接口)

Fast RCNN訓(xùn)練自己的數(shù)據(jù)集 (2修改讀寫接口)

轉(zhuǎn)載請注明出處,樓燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/

https://github.com/YihangLou/fast-rcnn-train-another-dataset?這是我在github上修改的幾個文件的鏈接,求星星啊,求星星啊(原諒我那么不要臉~~)

這里樓主講解了如何修改Fast RCNN訓(xùn)練自己的數(shù)據(jù)集,首先請確保你已經(jīng)安裝好了Fast RCNN的環(huán)境,具體的編配編制操作請參考我的上一篇文章。首先可以看到fast rcnn的工程目錄下有個Lib目錄
這里下面存在3個目錄分別是:

  • datasets
  • fast_rcnn
  • roi_data_layer
  • utils

在這里修改讀寫數(shù)據(jù)的接口主要是datasets目錄下,fast_rcnn下面主要存放的是python的訓(xùn)練和測試腳本,以及訓(xùn)練的配置文件,roi_data_layer下面存放的主要是一些ROI處理操作,utils下面存放的是一些通用操作比如非極大值nms,以及計算bounding box的重疊率等常用功能

1.構(gòu)建自己的IMDB子類

1.1文件概述

可有看到datasets目錄下主要有三個文件,分別是

  • factory.py
  • imdb.py
  • pascal_voc.py

factory.py 學(xué)過設(shè)計模式的應(yīng)該知道這是個工廠類,用類生成imdb類并且返回數(shù)據(jù)庫共網(wǎng)絡(luò)訓(xùn)練和測試使用
imdb.py 這里是數(shù)據(jù)庫讀寫類的基類,分裝了許多db的操作,但是具體的一些文件讀寫需要繼承繼續(xù)讀寫
pascal_voc.py Ross在這里用pascal_voc.py這個類來操作

1.2 讀取文件函數(shù)分析

接下來我來介紹一下pasca_voc.py這個文件,我們主要是基于這個文件進(jìn)行修改,里面有幾個重要的函數(shù)需要修改

  • def?init(self, image_set, year, devkit_path=None)
    這個是初始化函數(shù),它對應(yīng)著的是pascal_voc的數(shù)據(jù)集訪問格式,其實我們將其接口修改的更簡單一點
  • def image_path_at(self, i)
    根據(jù)第i個圖像樣本返回其對應(yīng)的path,其調(diào)用了image_path_from_index(self, index)作為其具體實現(xiàn)
  • def image_path_from_index(self, index)
    實現(xiàn)了 image_path的具體功能
  • def _load_image_set_index(self)
    加載了樣本的list文件
  • def _get_default_path(self)
    獲得數(shù)據(jù)集地址
  • def gt_roidb(self)
    讀取并返回ground_truth的db
  • def selective_search_roidb
    讀取并返回ROI的db
  • def _load_selective_search_roidb(self, gt_roidb)
    加載預(yù)選框的文件
  • def selective_search_IJCV_roidb(self)
    在這里調(diào)用讀取Ground_truth和ROI db并將db合并
  • def _load_selective_search_IJCV_roidb(self, gt_roidb)
    這里是專門讀取作者在IJCV上用的dataset
  • def _load_pascal_annotation(self, index)
    這個函數(shù)是讀取gt的具體實現(xiàn)
  • def _write_voc_results_file(self, all_boxes)
    voc的檢測結(jié)果寫入到文件
  • def _do_matlab_eval(self, comp_id, output_dir='output')
    根據(jù)matlab的evluation接口來做結(jié)果的分析
  • def evaluate_detections
    其調(diào)用了_do_matlab_eval
  • def competition_mode
    設(shè)置competitoin_mode,加了一些噪點

1.3訓(xùn)練數(shù)據(jù)集格式

在我的檢測任務(wù)里,我主要是從道路卡口數(shù)據(jù)中檢測車,因此我這里只有background 和car兩類物體,為了操作方便,我不像pascal_voc數(shù)據(jù)集里面一樣每個圖像用一個xml來標(biāo)注多類,先說一下我的數(shù)據(jù)格式

這里是所有樣本的圖像列表

我的GroundTruth數(shù)據(jù)的格式,第一個為圖像路徑,之后1代表目標(biāo)物的個數(shù), 后面的坐標(biāo)代表左上右下的坐標(biāo),坐標(biāo)的位置從1開始

這里我要特別提醒一下大家,一定要注意坐標(biāo)格式,一定要注意坐標(biāo)格式,一定要注意坐標(biāo)格式,重要的事情說三遍!!!,要不然你會范很多錯誤都會是因為坐標(biāo)不一致引起的報錯

1.4修改讀取接口

這里是原始的pascal_voc的init函數(shù),在這里,由于我們自己的數(shù)據(jù)集往往比voc的數(shù)據(jù)集要更簡單的一些,在作者額代碼里面用了很多的路徑拼接,我們不用去迎合他的格式,將這些操作簡單化即可,在這里我會一一列舉每個我修改過的函數(shù)。這里按照文件中的順序排列。
原始初始化函數(shù):

def __init__(self, image_set, year, devkit_path=None):datasets.imdb.__init__(self, 'voc_' + year + '_' + image_set)self._year = yearself._image_set = image_setself._devkit_path = self._get_default_path() if devkit_path is None \else devkit_pathself._data_path = os.path.join(self._devkit_path, 'VOC' + self._year)self._classes = ('__background__', # always index 0'aeroplane', 'bicycle', 'bird', 'boat','bottle', 'bus', 'car', 'cat', 'chair','cow', 'diningtable', 'dog', 'horse','motorbike', 'person', 'pottedplant','sheep', 'sofa', 'train', 'tvmonitor')self._class_to_ind = dict(zip(self.classes, xrange(self.num_classes)))self._image_ext = '.jpg'self._image_index = self._load_image_set_index()# Default to roidb handlerself._roidb_handler = self.selective_search_roidb# PASCAL specific config optionsself.config = {'cleanup' : True,'use_salt' : True,'top_k' : 2000}assert os.path.exists(self._devkit_path), \'VOCdevkit path does not exist: {}'.format(self._devkit_path)assert os.path.exists(self._data_path), \'Path does not exist: {}'.format(self._data_path)

修改后的初始化函數(shù):

def __init__(self, image_set, devkit_path=None):datasets.imdb.__init__(self, image_set)#imageset 為train testself._image_set = image_setself._devkit_path = devkit_pathself._data_path = os.path.join(self._devkit_path)self._classes = ('__background__','car')#包含的類self._class_to_ind = dict(zip(self.classes, xrange(self.num_classes)))#構(gòu)成字典{'__background__':'0','car':'1'}self._image_index = self._load_image_set_index('ImageList_Version_S_AddData.txt')#添加文件列表# Default to roidb handlerself._roidb_handler = self.selective_search_roidb# PASCAL specific config optionsself.config = {'cleanup' : True,'use_salt' : True,'top_k' : 2000}assert os.path.exists(self._devkit_path), \'VOCdevkit path does not exist: {}'.format(self._devkit_path)assert os.path.exists(self._data_path), \'Path does not exist: {}'.format(self._data_path)

原始的image_path_from_index:

def image_path_from_index(self, index):"""Construct an image path from the image's "index" identifier."""image_path = os.path.join(self._data_path, 'JPEGImages',index + self._image_ext)assert os.path.exists(image_path), \'Path does not exist: {}'.format(image_path)return image_path

修改后的image_path_from_index:

def image_path_from_index(self, index):#根據(jù)_image_index獲取圖像路徑"""Construct an image path from the image's "index" identifier."""image_path = os.path.join(self._data_path, index)assert os.path.exists(image_path), \'Path does not exist: {}'.format(image_path)return image_path

原始的 _load_image_set_index:

def _load_image_set_index(self):"""Load the indexes listed in this dataset's image set file."""# Example path to image set file:# self._devkit_path + /VOCdevkit2007/VOC2007/ImageSets/Main/val.txtimage_set_file = os.path.join(self._data_path, 'ImageSets', 'Main',self._image_set + '.txt')assert os.path.exists(image_set_file), \'Path does not exist: {}'.format(image_set_file)with open(image_set_file) as f:image_index = [x.strip() for x in f.readlines()]return image_index

修改后的 _load_image_set_index:

def _load_image_set_index(self, imagelist):#已經(jīng)修改"""Load the indexes listed in this dataset's image set file."""# Example path to image set file:# self._devkit_path + /VOCdevkit2007/VOC2007/ImageSets/Main/val.txt#/home/chenjie/KakouTrainForFRCNN_1/DataSet/KakouTrainFRCNN_ImageList.txtimage_set_file = os.path.join(self._data_path, imagelist)# load ImageList that only contain ImageFileNameassert os.path.exists(image_set_file), \'Path does not exist: {}'.format(image_set_file)with open(image_set_file) as f:image_index = [x.strip() for x in f.readlines()]return image_index

函數(shù) _get_default_path,我直接刪除了

原始的gt_roidb:

def gt_roidb(self):"""Return the database of ground-truth regions of interest.This function loads/saves from/to a cache file to speed up future calls."""cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl')if os.path.exists(cache_file):with open(cache_file, 'rb') as fid:roidb = cPickle.load(fid)print '{} gt roidb loaded from {}'.format(self.name, cache_file)return roidbgt_roidb = [self._load_pascal_annotation(index)for index in self.image_index]with open(cache_file, 'wb') as fid:cPickle.dump(gt_roidb, fid, cPickle.HIGHEST_PROTOCOL)print 'wrote gt roidb to {}'.format(cache_file)return gt_roidb

修改后的gt_roidb:

def gt_roidb(self):"""Return the database of ground-truth regions of interest.This function loads/saves from/to a cache file to speed up future calls."""cache_file = os.path.join(self.cache_path, self.name + '_gt_roidb.pkl')if os.path.exists(cache_file):#若存在cache file則直接從cache file中讀取with open(cache_file, 'rb') as fid:roidb = cPickle.load(fid)print '{} gt roidb loaded from {}'.format(self.name, cache_file)return roidbgt_roidb = self._load_annotation() #已經(jīng)修改,直接讀入整個GT文件with open(cache_file, 'wb') as fid:cPickle.dump(gt_roidb, fid, cPickle.HIGHEST_PROTOCOL)print 'wrote gt roidb to {}'.format(cache_file)return gt_roidb

原始的selective_search_roidb(self):

def selective_search_roidb(self):"""Return the database of selective search regions of interest.Ground-truth ROIs are also included.This function loads/saves from/to a cache file to speed up future calls."""cache_file = os.path.join(self.cache_path,self.name + '_selective_search_roidb.pkl')if os.path.exists(cache_file):with open(cache_file, 'rb') as fid:roidb = cPickle.load(fid)print '{} ss roidb loaded from {}'.format(self.name, cache_file)return roidbif int(self._year) == 2007 or self._image_set != 'test':gt_roidb = self.gt_roidb()ss_roidb = self._load_selective_search_roidb(gt_roidb)roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)else:roidb = self._load_selective_search_roidb(None)with open(cache_file, 'wb') as fid:cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)print 'wrote ss roidb to {}'.format(cache_file)return roidb

修改后的selective_search_roidb(self):
這里有個pkl文件我需要特別說明一下,如果你再次訓(xùn)練的時候修改了數(shù)據(jù)庫,比如添加或者刪除了一些樣本,但是你的數(shù)據(jù)庫名字函數(shù)原來那個,比如我這里訓(xùn)練的數(shù)據(jù)庫叫KakouTrain,必須要在data/cache/目錄下把數(shù)據(jù)庫的緩存文件.pkl給刪除掉,否則其不會重新讀取相應(yīng)的數(shù)據(jù)庫,而是直接從之前讀入然后緩存的pkl文件中讀取進(jìn)來,這樣修改的數(shù)據(jù)庫并沒有進(jìn)入網(wǎng)絡(luò),而是加載了老版本的數(shù)據(jù)。

def selective_search_roidb(self):#已經(jīng)修改"""Return the database of selective search regions of interest.Ground-truth ROIs are also included.This function loads/saves from/to a cache file to speed up future calls."""cache_file = os.path.join(self.cache_path,self.name + '_selective_search_roidb.pkl')if os.path.exists(cache_file): #若存在cache_file則讀取相對應(yīng)的.pkl文件with open(cache_file, 'rb') as fid:roidb = cPickle.load(fid)print '{} ss roidb loaded from {}'.format(self.name, cache_file)return roidbif self._image_set !='KakouTest':gt_roidb = self.gt_roidb()ss_roidb = self._load_selective_search_roidb(gt_roidb)roidb = datasets.imdb.merge_roidbs(gt_roidb, ss_roidb)else:roidb = self._load_selective_search_roidb(None)with open(cache_file, 'wb') as fid:cPickle.dump(roidb, fid, cPickle.HIGHEST_PROTOCOL)print 'wrote ss roidb to {}'.format(cache_file)return roidb

原始的_load_selective_search_roidb(self, gt_roidb):

def _load_selective_search_roidb(self, gt_roidb):filename = os.path.abspath(os.path.join(self.cache_path, '..','selective_search_data',self.name + '.mat'))assert os.path.exists(filename), \'Selective search data not found at: {}'.format(filename)raw_data = sio.loadmat(filename)['boxes'].ravel()box_list = []for i in xrange(raw_data.shape[0]):box_list.append(raw_data[i][:, (1, 0, 3, 2)] - 1)return self.create_roidb_from_box_list(box_list, gt_roidb)

修改后的_load_selective_search_roidb(self, gt_roidb):
這里原作者用的是Selective_search,但是我用的是EdgeBox的方法來提取Mat,我沒有修改函數(shù)名,只是把輸入的Mat文件給替換了,Edgebox實際的效果比selective_search要好,速度也要更快,具體的EdgeBox代碼大家可以在Ross的tutorial中看到地址。
注意,這里非常關(guān)鍵!!!!!,由于Selective_Search中的OP返回的坐���順序需要調(diào)整,并不是左上右下的順序,可以看到在下面box_list.append()中有一個(1,0,3,2)的操作,不管你用哪種OP方法,輸入的坐標(biāo)都應(yīng)該是x1 y1 x2 y2,不要弄成w h 那種格式,也不要調(diào)換順序。坐標(biāo)-1,默認(rèn)坐標(biāo)從0開始,樓主提醒各位,一定要非常注意坐標(biāo)順序,大小,邊界,格式問題,否則你會被錯誤折騰死的!!!

def _load_selective_search_roidb(self, gt_roidb):#已經(jīng)修改#filename = os.path.abspath(os.path.join(self.cache_path, '..','selective_search_data',self.name + '.mat'))filename = os.path.join(self._data_path, 'EdgeBox_Version_S_AddData.mat')#這里輸入相對應(yīng)的預(yù)選框文件路徑assert os.path.exists(filename), \'Selective search data not found at: {}'.format(filename)raw_data = sio.loadmat(filename)['boxes'].ravel()box_list = []for i in xrange(raw_data.shape[0]):#box_list.append(raw_data[i][:,(1, 0, 3, 2)] - 1)#原來的Psacalvoc調(diào)換了列,我這里box的順序是x1 ,y1,x2,y2 由EdgeBox格式為x1,y1,w,h經(jīng)過修改box_list.append(raw_data[i][:,:] -1)return self.create_roidb_from_box_list(box_list, gt_roidb)

原始的_load_selective_search_IJCV_roidb,我沒用這個數(shù)據(jù)集,因此不修改這個函數(shù)

原始的_load_pascal_annotation(self, index):

def _load_pascal_annotation(self, index):"""Load image and bounding boxes info from XML file in the PASCAL VOCformat."""filename = os.path.join(self._data_path, 'Annotations', index + '.xml')# print 'Loading: {}'.format(filename)def get_data_from_tag(node, tag):return node.getElementsByTagName(tag)[0].childNodes[0].datawith open(filename) as f:data = minidom.parseString(f.read())objs = data.getElementsByTagName('object')num_objs = len(objs)boxes = np.zeros((num_objs, 4), dtype=np.uint16)gt_classes = np.zeros((num_objs), dtype=np.int32)overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32)# Load object bounding boxes into a data frame.for ix, obj in enumerate(objs):# Make pixel indexes 0-basedx1 = float(get_data_from_tag(obj, 'xmin')) - 1y1 = float(get_data_from_tag(obj, 'ymin')) - 1x2 = float(get_data_from_tag(obj, 'xmax')) - 1y2 = float(get_data_from_tag(obj, 'ymax')) - 1cls = self._class_to_ind[str(get_data_from_tag(obj, "name")).lower().strip()]boxes[ix, :] = [x1, y1, x2, y2]gt_classes[ix] = clsoverlaps[ix, cls] = 1.0overlaps = scipy.sparse.csr_matrix(overlaps)return {'boxes' : boxes,'gt_classes': gt_classes,'gt_overlaps' : overlaps,'flipped' : False}

修改后的_load_pascal_annotation(self, index):

def _load_annotation(self):"""Load image and bounding boxes info from annotationformat."""#,此函數(shù)作用讀入GT文件,我的文件的格式 CarTrainingDataForFRCNN_1\Images\2015011100035366101A000131.jpg 1 147 65 443 361 gt_roidb = []annotationfile = os.path.join(self._data_path, 'ImageList_Version_S_GT_AddData.txt')f = open(annotationfile)split_line = f.readline().strip().split()num = 1while(split_line):num_objs = int(split_line[1])boxes = np.zeros((num_objs, 4), dtype=np.uint16)gt_classes = np.zeros((num_objs), dtype=np.int32)overlaps = np.zeros((num_objs, self.num_classes), dtype=np.float32)for i in range(num_objs):x1 = float( split_line[2 + i * 4])y1 = float (split_line[3 + i * 4])x2 = float (split_line[4 + i * 4])y2 = float (split_line[5 + i * 4])cls = self._class_to_ind['car']boxes[i,:] = [x1, y1, x2, y2]gt_classes[i] = clsoverlaps[i,cls] = 1.0overlaps = scipy.sparse.csr_matrix(overlaps)gt_roidb.append({'boxes' : boxes, 'gt_classes': gt_classes, 'gt_overlaps' : overlaps, 'flipped' : False})split_line = f.readline().strip().split()f.close()return gt_roidb

之后的這幾個函數(shù)我都沒有修改,檢測結(jié)果,我是修改了demo.py這個文件,直接生成txt文件,然后用python opencv直接可視化,沒有用著里面的接口,感覺太麻煩了,先怎么方便怎么來

  • _write_voc_results_file(self, all_boxes)
  • _do_matlab_eval(self, comp_id, output_dir='output')
  • evaluate_detections(self, all_boxes, output_dir)
  • competition_mode(self, on)

記得在最后的__main__下面也修改相應(yīng)的路徑
d = datasets.pascal_voc('trainval', '2007')
改成
d = datasets.kakou('KakouTrain', '/home/chenjie/KakouTrainForFRCNN_1')

并且同時在文件的開頭import 里面也做修改
import datasets.pascal_voc
改成
import datasets.kakou

OK,在這里我們已經(jīng)完成了整個的讀取接口的改寫,主要是將GT和預(yù)選框Mat文件讀取并返回

2.修改factory.py

當(dāng)網(wǎng)絡(luò)訓(xùn)練時會調(diào)用factory里面的get方法獲得相應(yīng)的imdb,
首先在文件頭import 把pascal_voc改成kakou
在這個文件作者生成了多個數(shù)據(jù)庫的路徑,我們自己數(shù)據(jù)庫只要給定根路徑即可,修改主要有以下4個

  • 因此將里面的def _selective_search_IJCV_top_k函數(shù)整個注釋掉
  • 函數(shù)之后有兩個多級的for循環(huán),也將其注釋
  • 直接定義imageset和devkit
  • 修改get_imdb函數(shù)

原始的factory.py:

__sets = {}import datasets.pascal_voc import numpy as npdef _selective_search_IJCV_top_k(split, year, top_k):"""Return an imdb that uses the top k proposals from the selective searchIJCV code."""imdb = datasets.pascal_voc(split, year)imdb.roidb_handler = imdb.selective_search_IJCV_roidbimdb.config['top_k'] = top_kreturn imdb# Set up voc_<year>_<split> using selective search "fast" mode for year in ['2007', '2012']:for split in ['train', 'val', 'trainval', 'test']:name = 'voc_{}_{}'.format(year, split)__sets[name] = (lambda split=split, year=year:datasets.pascal_voc(split, year))# Set up voc_<year>_<split>_top_<k> using selective search "quality" mode # but only returning the first k boxes for top_k in np.arange(1000, 11000, 1000):for year in ['2007', '2012']:for split in ['train', 'val', 'trainval', 'test']:name = 'voc_{}_{}_top_{:d}'.format(year, split, top_k)__sets[name] = (lambda split=split, year=year, top_k=top_k:_selective_search_IJCV_top_k(split, year, top_k))def get_imdb(name):"""Get an imdb (image database) by name."""if not __sets.has_key(name):raise KeyError('Unknown dataset: {}'.format(name))return __sets[name]()def list_imdbs():"""List all registered imdbs."""return __sets.keys()

修改后的factory.py

#import datasets.pascal_voc import datasets.kakou import numpy as np__sets = {} imageset = 'KakouTrain' devkit = '/home/chenjie/DataSet/CarTrainingDataForFRCNN_1/Images_Version_S_AddData' #def _selective_search_IJCV_top_k(split, year, top_k): # """Return an imdb that uses the top k proposals from the selective search # IJCV code. # """ # imdb = datasets.pascal_voc(split, year) # imdb.roidb_handler = imdb.selective_search_IJCV_roidb # imdb.config['top_k'] = top_k # return imdb### Set up voc_<year>_<split> using selective search "fast" mode ##for year in ['2007', '2012']: ## for split in ['train', 'val', 'trainval', 'test']: ## name = 'voc_{}_{}'.format(year, split) ## __sets[name] = (lambda split=split, year=year: ## datasets.pascal_voc(split, year))# Set up voc_<year>_<split>_top_<k> using selective search "quality" mode # but only returning the first k boxes ##for top_k in np.arange(1000, 11000, 1000): ## for year in ['2007', '2012']: ## for split in ['train', 'val', 'trainval', 'test']: ## name = 'voc_{}_{}_top_{:d}'.format(year, split, top_k) ## __sets[name] = (lambda split=split, year=year, top_k=top_k: ## _selective_search_IJCV_top_k(split, year, top_k))def get_imdb(name):"""Get an imdb (image database) by name."""__sets['KakouTrain'] = (lambda imageset = imageset, devkit = devkit: datasets.kakou(imageset,devkit))if not __sets.has_key(name):raise KeyError('Unknown dataset: {}'.format(name))return __sets[name]()def list_imdbs():"""List all registered imdbs."""return __sets.keys()

3.修改 __init__.py
在行首添加上 from .kakou import kakou

總結(jié)

在這里終于改完了讀取接口的所有內(nèi)容,主要步驟是

  • 復(fù)制pascal_voc,改名字,修改GroundTruth和OP預(yù)選框的讀取方式
  • 修改factory.py,修改數(shù)據(jù)庫路徑和獲得方式
  • __init__.py添加上改完的py文件
  • 下面列出一些需要注意的地方

  • 讀取方式怎么方便怎么來,并不一定要按照里面xml的格式,因為大家自己應(yīng)用到工程中去往往不會是非常多的類別,單個對象的直接用txt就可以
  • 坐標(biāo)的順序我再說一次,要左上右下,并且x1必須要小于x2,這個是基本,反了會在坐標(biāo)水平變換的時候會出錯,坐標(biāo)從0開始,如果已經(jīng)是0,則不需要再-1
  • GT的路徑最好用相對,別用絕對,然后路徑拼接的時候要注意,然后如果是txt是windows下生成的,注意斜杠的方向和編碼的格式,中文路徑編碼必須用UTF-8無BOM格式,不能用windows自帶的記事本直接換一種編碼存儲,相關(guān)數(shù)據(jù)集的編碼問題參見我的另一篇文章,linux傳輸亂碼
  • 關(guān)于Mat文件,在訓(xùn)練時是將所有圖像的OP都合在了一起,是一個很大的Mat文件,注意其中圖像list的順序千萬不能錯,并且坐標(biāo)格式要修改為x1 y1 x2 y2,每種OP生成的坐標(biāo)順序要小心,從0開始還是從1開始也要小心
  • 訓(xùn)練圖像的大小不要太大,否則生成的OP也會太多,速度太慢,圖像樣本大小最好調(diào)整到500,600左右,然后再提取OP
  • 如果讀取并生成pkl文件之后,實際數(shù)據(jù)內(nèi)容或者順序還有問題,記得要把data/cache/下面的pkl文件給刪掉
  • 關(guān)于下部訓(xùn)練和檢測網(wǎng)絡(luò),我將在下一篇文章中說明

    總結(jié)

    以上是生活随笔為你收集整理的Fast RCNN 训练自己数据集 (2修改数据读取接口)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。