1. 独自のラベル付き VOC データセットをトレーニングする
Faster-ILOD を使用して、独自のラベル付きデータ セットをトレーニングします. データ セットは VOC 形式に変換されています. 以前に
VOC2007 データ セットを正常にトレーニングできました.
Faster-ILOD と maskrcnn_benchmark のインストール プロセスを参照して、問題に遭遇してください.
主に変更する次のファイル:
1.maskrcnn_benchmark/config/paths_catalog.py
対応するパスを、独自のデータ セットが配置されているパスに変更します。
"voc_2007_train": {
"data_dir": "/data/taxi_data/VOC2007_all",
"split": "train"
},
"voc_2007_val": {
"data_dir": "/data/taxi_data/VOC2007_all",
"split": "val"
},
"voc_2007_test": {
"data_dir": "/data/taxi_data/VOC2007_all",
"split": "test"
},
2.maskrcnn_benchmark/data/voc.py
データセットにカテゴリを含めるように変更します.主にタクシーと自家用車を識別します.
# CLASSES = ("__background__ ", "aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow",
# "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor")
CLASSES = ("__background__ ", "Taxi","Other Car")
3. configs/e2e_faster_rcnn_R_50_C4_1x.yaml を変更します
カテゴリの数などを変更して、両方のカテゴリを一度にトレーニングしました。
NUM_CLASSES: 3 # total classes
NAME_OLD_CLASSES: []
#NAME_NEW_CLASSES: ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog",
# "horse", "motorbike", "person","pottedplant", "sheep", "sofa", "train","tvmonitor"]
# NAME_EXCLUDED_CLASSES: [ ]
NAME_NEW_CLASSES: ["Taxi","Other Car"]
NAME_EXCLUDED_CLASSES: []
4.走る
python tools/train_first_step.py --config-file="./configs/e2e_faster_rcnn_R_50_C4_1x.yaml"
二、遭遇する問題
1.対応するTaxi_train.txtなどのファイルがない
増分学習を行っているため、カテゴリごとに処理されます. 元のダウンロードした voc ファイルには、各カテゴリに対応する train や test などの txt ファイルが含まれていますが、自己ラベル付けされたデータセットを voc 形式のデータセットに変換すると、train に変換されます.txt、test.txt、trainval.txt、および val.txt。対応するtxtファイルがないので、対応するファイルを生成する必要があります。
メタデータ セットの各カテゴリに対応する txt ファイルを確認します。各行は 2 つの列に対応します。1 つの列は画像の名前で、もう 1 つの列は数字です。値は 1.-1.0 である必要があります。-1 は、カテゴリはこの画像には存在しません
.0 は難しいサンプルです(個人的にはそう思うので間違っていたら訂正してください). xmlファイルとtrain.txt, test.txt, val.txtによると、対応するカテゴリの変換が実行されます。コードは次のとおりです:対応するファイルを生成するときは、このカテゴリに存在する画像の名前のみを書き込みます. データの読み取り時にエラーを報告するときは、コードを変更します. コードを変更して保持することができます.元のデータセットと一致しています。
names = locals()
dir_path = "D:/achenf/data/jiaotong_data/1taxi_train_data/VOC/VOC2007/"
# 读取train.txt/test.txt/val.txt文件
f = open("D:/achenf/data/jiaotong_data/1taxi_train_data/VOC/VOC2007/ImageSets/Main/train.txt", 'r')
# 包含类别
classes = ['Taxi','Other Car']
# 写入文档名称
txt_path = dir_path+"by_classes/"+"Other Car_train.txt"
fp_w = open(txt_path, 'w')
for line in f.readlines():
if not line:
break
n= line[:-1]
xmlpath=dir_path+"Annotations/"+n+'.xml'
fp = open(xmlpath)
xmllines = fp.readlines()
ind_start = []
ind_end = []
lines_id_start = xmllines[:]
lines_id_end = xmllines[:]
# 修改对应类别Other Car/Taxi
classes1 = ' <name>Other Car</name>\n'
while " <object>\n" in lines_id_start:
a = lines_id_start.index(" <object>\n")
ind_start.append(a)
lines_id_start[a] = "delete"
while " </object>\n" in lines_id_end:
b = lines_id_end.index(" </object>\n")
ind_end.append(b)
lines_id_end[b] = "delete"
# names中存放所有的object块
i = 0
for k in range(0, len(ind_start)):
names['block%d' % k] = []
for j in range(0, len(classes)):
if classes[j] in xmllines[ind_start[i] + 1]:
a = ind_start[i]
for o in range(ind_end[i] - ind_start[i] + 1):
names['block%d' % k].append(xmllines[a + o])
break
i += 1
# 在给定的类中搜索,若存在则,写入object块信息
a = 0
if len(ind_start)>0:
# xml头
string_start = xmllines[0:ind_start[0]]
# xml尾
string_end = [xmllines[len(xmllines) - 1]]
flag = False
for k in range(0, len(ind_start)):
if classes1 in names['block%d' % k]:
flag = True
a += 1
string_start += names['block%d' % k]
string_start += string_end
# 如果存在写入
if flag:
fp_w.write(n+" "+"1"+'\n')
fp.close()
fp_w.close()
次のファイルを取得します。
2.x[2] == '0' は添字外です
各行を分割するとき、値が 1 の場合、ソース データ セットの txt ファイルは ['000000', '', '1'] に分解され、生成したファイルは ['000000', '1'] に分解されます。 ']、困難なサンプルがないため、これらの行を直接コメントします
for i in range(len(buff)):
x = buff[i]
x = x.split(' ')
if x[1] == '-1':
pass
# elif x[2] == '0': # include difficult level object
# if self.is_train:
# pass
# else:
# img_ids_per_category.append(x[0])
# self.ids.append(x[0])
else:
img_ids_per_category.append(x[0])
self.ids.append(x[0])
そして、私のxmlファイルには難しいタグがないので、difficult = int(obj.find("difficult").text) == 1
このコード行に遭遇するとエラーを報告するので、困難をFalseに直接割り当てます
for obj in target.iter("object"):
difficult = False
# difficult = int(obj.find("difficult").text) == 1
if not self.keep_difficult and difficult:
continue
3.ValueError: 基数 10 の int() の無効なリテラル: '0.0'
この行で報告されているエラーはbndbox = tuple(map(lambda x: x - TO_REMOVE, list(map(int, box))))
、str を int に直接変換する際の問題のはずなので、最初に float に変換してから int に変換し、次のように変更します。新しい知識ポイントを学習しても問題ありませんbndbox = tuple(map(lambda x: x - TO_REMOVE, list(map(int, map(float,box)))))
。
map() 関数は一括データ型変換を実現できます。
参照できます: Python3 で map() を使用して、str から float などのデータ型をバッチで変換します
4. Pytorch が CUDA エラーを報告します: デバイス側のアサートがトリガーされました
参考:https://blog.csdn.net/veritasalice/article/details/111917185