This commit is contained in:
tomasz 2020-07-26 00:43:07 +02:00
parent eff752bba2
commit 43a5d4568a
24 changed files with 12336 additions and 152 deletions

View File

@ -633,14 +633,14 @@ activation=leaky
size=1
stride=1
pad=1
filters=72
filters=78
activation=linear
[yolo]
mask = 6,7,8
anchors=26,16, 19,45, 36,27, 54,32, 34,80, 60,49, 74,71, 96,105, 135,145
classes=19
classes=21
num=9
jitter=.3
ignore_thresh = .7
@ -719,14 +719,14 @@ activation=leaky
size=1
stride=1
pad=1
filters=72
filters=78
activation=linear
[yolo]
mask = 3,4,5
anchors=26,16, 19,45, 36,27, 54,32, 34,80, 60,49, 74,71, 96,105, 135,145
classes=19
classes=21
num=9
jitter=.3
ignore_thresh = .7
@ -806,14 +806,14 @@ activation=leaky
size=1
stride=1
pad=1
filters=72
filters=78
activation=linear
[yolo]
mask = 0,1,2
anchors=26,16, 19,45, 36,27, 54,32, 34,80, 60,49, 74,71, 96,105, 135,145
classes=19
classes=21
num=9
jitter=.3
ignore_thresh = .7

View File

@ -640,7 +640,7 @@ activation=linear
[yolo]
mask = 6,7,8
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
classes=19
num=9
jitter=.3
ignore_thresh = .7
@ -726,7 +726,7 @@ activation=linear
[yolo]
mask = 3,4,5
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
classes=19
num=9
jitter=.3
ignore_thresh = .7
@ -813,7 +813,7 @@ activation=linear
[yolo]
mask = 0,1,2
anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
classes=80
classes=19
num=9
jitter=.3
ignore_thresh = .7

View File

@ -1,6 +0,0 @@
classes=18
train=/home/michall/yolov3/data/widok01-11_train_labels.txt
valid=/home/michall/yolov3/data/widok01-11_test_labels.txt
names=/home/michall/yolov3/data/widok01-11.names
backup=backup/
eval=coco

Binary file not shown.

View File

@ -1,6 +0,0 @@
classes=19
train=/home/tomekb/yolov3/data/widok_01_19/widok_01_19_train_labels.txt
valid=/home/tomekb/yolov3/data/widok_01_19/widok_01_19_test_labels.txt
names=/home/tomekb/yolov3/data/widok_01_19/widok_01_19.names
backup=backup/
eval=coco

View File

@ -0,0 +1,6 @@
classes=21
train=./data/widok_01_21/widok_01_21_train_labels.txt
valid=./data/widok_01_21/widok_01_21_test_labels.txt
names=./data/widok_01_21/widok_01_21.names
backup=backup/
eval=coco

View File

@ -0,0 +1,21 @@
1. rower
2. motocykl
3. osobowy
4. osobowy pickup
5. osobowy dostawczy
6. osobowy van 7-9
7. dostawczy blaszak / BUS sredni dostawczy
8. dostawczy zabudowany
9. dostawczy pickup (w tym pomoc drog.)
10. dostawczy VAN (osobowy) / autobus maly 10-24 / BUS sredni osobowy
11. autobus miejski / autobus turystyczny i inny
12. ciezarowy pow. 3,5t zabudowany / ciezarowy z widoczna przyczepa
13. ciezarowy pow. 3,5t otwarty (w tym duzy holownik)
14. ciezarowy pow. 3,5t inny (wanna, gruszka, dzwig itp.)
15. ciagnik siodlowy z widoczna naczepa / ciagnik siodlowy bez naczepy
16. inne pojazdy silnikowe / camper / woz strazacki / ciagnik roliczy, koparka, spychacz
17. przyczepa
18. BUS-karetka/policja
19. BUS brygadowka
20. BUS sredni dostawczy
21. BUS sredni osobowy

View File

@ -0,0 +1,16 @@
1. rower
2. motocykl
3. osobowy
4. osobowy pickup
5. osobowy dostawczy
6. osobowy van 7-9
7. dostawczy blaszak / BUS sredni dostawczy
8. dostawczy zabudowany
9. dostawczy pickup (w tym pomoc drog.)
10. dostawczy VAN (osobowy) / autobus maly 10-24 / BUS sredni osobowy
11. autobus miejski / autobus turystyczny i inny
12. ciezarowy pow. 3,5t zabudowany / ciezarowy z widoczna przyczepa
13. ciezarowy pow. 3,5t otwarty / (w tym duzy holownik)
14. ciezarowy pow. 3,5t inny (wanna, gruszka, dzwig itp.)
15. ciagnik siodlowy z widoczna naczepa /
ciagnik siodlowy bez naczepy

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -133,7 +133,7 @@ def detect(save_img=False):
plot_one_box(xyxy, im0, label=label, color=colors[int(cls)])
# Print time (inference + NMS)
print('%sDone. (%.3fs)' % (s, t2 - t1))
#print('%sDone. (%.3fs)' % (s, t2 - t1))
# Stream results
if view_img:
@ -162,7 +162,7 @@ def detect(save_img=False):
if platform == 'darwin': # MacOS
os.system('open ' + save_path)
print('Done. (%.3fs)' % (time.time() - t0))
#print('Done. (%.3fs)' % (time.time() - t0))
if __name__ == '__main__':
@ -186,7 +186,7 @@ if __name__ == '__main__':
opt = parser.parse_args()
opt.cfg = check_file(opt.cfg) # check file
opt.names = check_file(opt.names) # check file
print(opt)
#print(opt)
with torch.no_grad():
detect(True)

View File

@ -1,11 +1,11 @@
train:
epochs: 1200
batch-size: 3
epochs: 200
batch-size: 14 #
cfg: ./cfg/yolov3-spp-19cls.cfg
data: ./data/widok_01_19.data
multi-scale: false
img-size: '512 1920'
rect: true
img-size: '768 1280'
rect: false
resume: false
nosave: false
notest: false
@ -16,7 +16,8 @@ train:
device: 1
adam: true
single-cls: false
save-every-nth-epoch: 50
snapshot-every: 50
freeze-layers: true
# inne hiperparametry
other-hyps:
@ -36,14 +37,14 @@ train:
hsv_v: 0.36 # image HSV-Value augmentation (fraction)
degrees: 0 # 1.98 * 0 # image rotation (+/- deg)
translate: 0 # 0.05 * 0 # image translation (+/- fraction)
scale: 0 #0 .05 * 0 # image scale (+/- gain)
scale: 0 #0 .05 * 0 # image scale (+/- gain)
shear: 0 # 0.641 * 0 # image shear (+/- deg)
experiments:
dir: ./experiments
detect:
source: /home/tomekb/yolov3/data/widok_01_19/widok_01_19_test_labels.txt
test-img-size: 1920
test-img-size: 1024
conf-thres: 0.3
iou-thres: 0.6
classes:

View File

@ -1,29 +1,7 @@
import yaml
class Args:
def get_args_string(self) -> str:
string = ''
for key, value in self.__dict__.items():
if not isinstance(value, Configuration.Train.OtherHyps) and value is not None:
if key == 'img-size':
string += f' --{key} {value.split(" ")[0]} {value.split(" ")[1]}'
elif type(value) == bool:
if value:
string += f" --{key}"
else:
continue
elif type(value) in [int, str] and value != '':
string += f' --{key} {value}'
else:
raise Exception(f"Cannot parse argument {key} {value}")
return string
class Configuration:
class Train(Args):
class Train:
class OtherHyps:
def __init__(self, config_file) -> None:
@ -36,28 +14,55 @@ class Configuration:
if key != 'other-hyps':
self.__dict__[key] = value
class Experiments(Args):
class Experiments:
def __init__(self, config_file) -> None:
for key, value in config_file['experiments'].items():
self.__dict__[key] = value
class Detect(Args):
class Detect:
def __init__(self, config_file) -> None:
for key, value in config_file['detect'].items():
self.__dict__[key] = value
class ConfussionMatrix(Args):
class ConfussionMatrix:
def __init__(self, config_file) -> None:
for key, value in config_file['confussion-matrix'].items():
self.__dict__[key] = value
def __init__(self, config_path='/home/tomekb/yolov3/our_scripts/config_bayes.yml') -> None:
class Bayes:
def __init__(self, config_file) -> None:
for key, value in config_file['bayes'].items():
self.__dict__[key] = value
def __init__(self, config_path='./config_bayes.yml') -> None:
self.config_path = config_path
file = yaml.load(open(config_path, 'r'), Loader=yaml.Loader)
self.train = self.Train(file)
self.experiments = self.Experiments(file)
self.detect = self.Detect(file)
self.confussion_matrix = self.ConfussionMatrix(file)
self.bayes = self.Bayes(file)
def get_bayes_bounds(self) -> list:
result = []
dicts = {**self.train.__dict__, **self.train.other_hyps.__dict__, **self.detect.__dict__}
for key, value in dicts.items():
if type(value) not in [None, Configuration.Train.OtherHyps] and type(value) == dict:
if value['type'] == 'continuous': # continous value
val = (value['min'], value['max'])
item = {'name': key, 'type': value['type'], 'domain': val}
elif value['type'] == 'discrete' and 'step' in value:
val = tuple(n for n in range(value['min'], value['max'], value['step']))
item = {'name': key, 'type': value['type'], 'domain': val}
elif value['type'] == 'discrete': # discrete values without step
val = tuple(n for n in value['values'])
item = {'name': key, 'type': value['type'], 'domain': val}
else: # unknown type
raise Exception("Invalid type", value['type'])
result.append(item)
return result
if __name__ == '__main__':
config = Configuration()

View File

@ -1,32 +1,47 @@
bayes:
iterations: 2
train:
epochs: 100
epochs:
type: discrete
values: [10]
batch-size:
type: discrete
values: 1,2,3,4
cfg: ./cfg/yolov3-spp-19cls.cfg
data: ./data/widok_01_19.data
#values: [128]
min: 1
max: 5
step: 1
cfg: ./cfg/yolov3-spp-21cls.cfg
data: ./data/widok_01_21.data
multi-scale:
type: discrete
values: true, false
img-size:
values: [true, false]
img-size-start:
type: discrete
values: (512, 1280),(576, 1280),(640, 1280),(704, 1280),(768, 1280),(832,1280),(960, 1280),(1024, 1280) # trzeba wziąć pod uwagę wszystkie kombinacje i warunek img-size-min < img-size_max których jest cała masa
rect: false
min: 512
max: 1088
step: 64
img-size-end:
type: discrete
values: true,false
min: 512
max: 1088
step: 64
rect:
type: discrete
values: [false]
resume: false
nosave: false
notest: false
evolve: false
bucket:
cache-images: false
weights: /home/tomekb/yolov3/weights/yolov3-spp-ultralytics.pt
weights: ./weights/yolov3-spp-ultralytics.pt
device: 1
adam: true
adam:
type: discrete
values: [true]
single-cls: false
snapshot-every: 50
snapshot-every:
freeze-layers: true
other-hyps:
giou:
type: continuous
@ -52,8 +67,14 @@ train:
type: continuous
min: 0.0
max: 1.0
lr0: 0.01 # initial learning rate (SGD=5E-3 Adam=5E-4) # trzeba wziąć pod uwage zależność lr0 < lrf dlatego nie zmieniam
lrf: 0.0005 # final learning rate (with cos scheduler)
lr0:
type: continuous
min: 0.000001
max: 0.1
lrf:
type: continuous
min: 0.000001
max: 0.1
momentum:
type: continuous
min: 0.0
@ -70,7 +91,7 @@ train:
type: continuous
min: 0.0
max: 1.0
hsv_s: 0.678
hsv_s:
type: continuous
min: 0.0
max: 1.0
@ -97,10 +118,12 @@ train:
experiments:
dir: ./experiments
detect:
source: /home/tomekb/yolov3/data/widok_01_19/widok_01_19_test_labels.txt
source: ./data/widok_01_21/widok_01_21_test_labels.txt
test-img-size:
type: discrete
values: 512,576,640,704,768,832,896,960,1024,1088,1152,1216,1280,
min: 512
max: 1088
step: 64
conf-thres:
type: continuous
min: 0.0
@ -113,4 +136,4 @@ detect:
agnostic-nms:
augment:
confussion-matrix:
labels-dir: /home/tomekb/yolov3/data/widok_01_19/widok_01_19_labels
labels-dir: ./data/widok_01_21/widok_01_21_labels

View File

@ -158,10 +158,10 @@ async function main() {
tsvRows.push([ names[row], ...(summaryRows.map(r => summaryPart[r] && (summaryPart[r] / sum).toFixed(2)))].join('\t'))
}
const allLabeled = rows.slice(0, -1).map(r => summary.sum[r]).reduce((a, b) => a + b, 0)
const allDetected = rows.slice(0, -1).map(r => summary[r].sum).reduce((a, b) => a + b, 0)
const falseNegatives = rows.slice(0, -1).map(r => summary.n[r] || 0).reduce((a, b) => a + b, 0)
const falsePositives = rows.slice(0, -1).map(r => summary[r].n || 0).reduce((a, b) => a + b, 0)
const allDetected = rows.slice(0, -1).map(r => summary.sum[r]).reduce((a, b) => a + b, 0)
const allLabeled = rows.slice(0, -1).map(r => summary[r].sum).reduce((a, b) => a + b, 0)
const falsePositives = rows.slice(0, -1).map(r => summary.n[r] || 0).reduce((a, b) => a + b, 0)
const falseNegatives = rows.slice(0, -1).map(r => summary[r].n || 0).reduce((a, b) => a + b, 0)
const right = rows.slice(0, -1).map(r => summary[r][r] || 0).reduce((a, b) => a + b, 0)
const mistakes = rows.slice(0, -1).map(a => rows.slice(0, -1).map(b => (a!=b && summary[a][b]) || 0).reduce((a, b) => a + b, 0)).reduce((a, b) => a + b, 0)

View File

@ -46,7 +46,7 @@ def map_class_name_to_id(class_name, xml_document, class_distribution):
elif class_name in ['6. osobowy van 7-9']:
class_distribution[5] += 1
return 5
elif class_name in ['7. dostawczy blaszak', '27. BUS sredni dostawczy']:
elif class_name in ['7. dostawczy blaszak']:
class_distribution[6] += 1
return 6
elif class_name in ['8. dostawczy zabudowany']:
@ -55,7 +55,7 @@ def map_class_name_to_id(class_name, xml_document, class_distribution):
elif class_name in ['9. dostawczy pickup (w tym pomoc drog.)']:
class_distribution[8] += 1
return 8
elif class_name in ['10. dostawczy VAN (osobowy)', '11. autobus maly 10-24', '28. BUS sredni osobowy']:
elif class_name in ['10. dostawczy VAN (osobowy)', '11. autobus maly 10-24']:
class_distribution[9] += 1
return 9
elif class_name in ['12. autobus miejski', '13. autobus turystyczny i inny']:
@ -85,13 +85,19 @@ def map_class_name_to_id(class_name, xml_document, class_distribution):
elif class_name in ['26. BUS brygadowka']:
class_distribution[18] += 1
return 18
elif class_name in ['27. BUS sredni dostawczy']:
class_distribution[19] += 1
return 19
elif class_name in ['28. BUS sredni osobowy']:
class_distribution[20] += 1
return 20
else:
raise Exception('Unknown Class ', xml_document, class_name)
#print(f'{xml_document.split("/")[-1]} {class_name}')
def generate_txt_from_xml():
class_distribution = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
class_distribution = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0]
filepaths = glob(join(annotations , '*.xml'))

View File

@ -1,4 +1,3 @@
import argparse
import datetime
import glob
import io
@ -12,41 +11,44 @@ from config import Configuration
def call_training_script(config):
cmd = '/home/tomekb/miniconda3/envs/conda3.7/bin/python -u /home/tomekb/yolov3/train.py '
cmd += config.train.get_args_string()
cmd += f"--experiment-dir {config.experiments.dir}"
cmd += config.train.get_args_string() # getting rest of train arguments
print("_______ CALLING TRAINING SCRIPT _______")
print(cmd)
os.chdir('..')
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True)
os.chdir('..') # change to project root directory
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of training process to console
print(line)
return cmd
def move_training_results_to_experiments_dir(config):
training_results_dir_path = os.path.join(config.experiments.dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
training_results_dir_path = os.path.join(config.experiments.dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')) #creating directory accordint to pattern eg: 2020-06-30_17-52-19
print("_______ CALLING MOVING RESULTS _______")
print(f"MOVING RESUTLS TO {training_results_dir_path}")
os.mkdir(training_results_dir_path)
weights_path = os.path.join(training_results_dir_path, 'best.pt')
shutil.move('/home/tomekb/yolov3/weights/best.pt', weights_path) #move best weights
shutil.move('/home/tomekb/yolov3/weights/best.pt', weights_path) # move best weights
names_path = open(config.train.data).readlines()[3].split('=')[-1].rstrip() # read names path from file
names_file_name = ntpath.basename(names_path)
experiment_names_path = os.path.join(training_results_dir_path, names_file_name)
shutil.copy(names_path, experiment_names_path) # copy names to created experiment dir with training results
shutil.copy(names_path, experiment_names_path) # copy names file from *.data file to created experiment dir with training results
tensorboard_dir = './runs'
last_modified_tensorboard_dir = max(glob.glob(os.path.join(tensorboard_dir, '*/')), key=os.path.getmtime)
shutil.move(last_modified_tensorboard_dir, os.path.join(training_results_dir_path)) #saving related tensorboard dir
shutil.copy2(config.config_path, training_results_dir_path) #copying configuration yaml
shutil.move(last_modified_tensorboard_dir, os.path.join(training_results_dir_path)) # saving related tensorboard dir
#for test purposes only
#shutil.copy2('/home/tomekb/yolov3/experiments/1/best.pt', training_results_dir_path)
shutil.copy2(config.config_path, training_results_dir_path) # copying configuration yaml
# for test purposes only
# shutil.copy2('/home/tomekb/yolov3/experiments/1/best.pt', training_results_dir_path)
return weights_path, experiment_names_path, training_results_dir_path
@ -69,11 +71,10 @@ def call_detection_script(config, weights_path, names_path, dir):
cmd = " ".join(cmd.split())
print("_______ CALLING DETECTION SCRIPT _______")
print(cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of process to console
print(line)
@ -84,7 +85,7 @@ def call_generate_confussion_matrix(detect_output_dir, config, names_path, train
labels_dir = getattr(config.confussion_matrix, 'labels-dir')
cmd = f"node ./our_scripts/generate-confusion-matrix.js {detect_output_dir} {labels_dir} {names_path} > {train_results_dir}/confussion-matrix.tsv"
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
print("_______ CALLING CONFUSSION MATRIX SCRIPT _______")
print(cmd)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of process to console
@ -95,6 +96,6 @@ if __name__ == '__main__':
config = Configuration()
train_cmd = call_training_script(config)
weights_path, names_path,train_results_dir = move_training_results_to_experiments_dir(config)
detect_output_dir = call_detection_script(config, weights_path, names_path,train_results_dir)
call_generate_confussion_matrix(detect_output_dir, config, names_path,train_results_dir)
weights_path, names_path, train_results_dir = move_training_results_to_experiments_dir(config)
detect_output_dir = call_detection_script(config, weights_path, names_path, train_results_dir)
call_generate_confussion_matrix(detect_output_dir, config, names_path, train_results_dir)

View File

@ -1,31 +1,56 @@
import datetime
import glob
import io
import ntpath
import os
import shutil
import subprocess
import traceback
from .config import Configuration
import GPyOpt
import numpy as np
from config_bayes import Configuration
from utils import call_subprocess, get_values_from_conff_matrix
config = Configuration()
date_string = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
bayes_params_file = open(os.path.join(config.experiments.dir, f"{date_string}_bayes_params.txt"), 'a+')
def call_training_script(config):
cmd = '/home/tomekb/miniconda3/envs/conda3.7/bin/python -u /home/tomekb/yolov3/train.py '
cmd += f"--experiment-dir {config.experiments.dir}"
cmd += config.train.get_args_string() # getting rest of train arguments
def call_training_script(gaussian_hyps):
cmd = 'python-u /home/tomekb/yolov3/train.py'
cmd += ' --epochs ' + gaussian_hyps['epochs'].__str__()
cmd += ' --batch-size ' + gaussian_hyps['batch-size'].__str__()
cmd += ' --cfg ' + config.train.cfg.__str__()
cmd += ' --data ' + config.train.data.__str__()
cmd += ' --multi-scale ' if gaussian_hyps['multi-scale'] else ""
cmd += ' --img-size ' + gaussian_hyps['img-size']
cmd += ' --rect ' if gaussian_hyps['rect'] else ""
cmd += ' --weights ' + config.train.weights.__str__()
cmd += ' --device ' + config.train.device.__str__()
cmd += ' --adam ' if gaussian_hyps['adam'] else ""
cmd += ' --freeze-layers ' if getattr(config.train, "freeze-layers") else ""
# cmd += ' --snapshot-every ' if getattr(config.train, "snapshot-every") else ""
cmd += ' --experiment-dir ' + config.experiments.dir.__str__()
train_hyps = dict(
(key, gaussian_hyps[key]) for idx, (key, _) in enumerate(gaussian_hyps.items()) if idx in range(6, 24))
cmd += f' --hyp \"{train_hyps}\"'
print("_______ CALLING TRAINING SCRIPT _______")
print(cmd)
os.chdir('..') # change to project root directory
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of training process to console
print(line)
dir_path = os.path.dirname(os.path.realpath(__file__))
os.chdir(os.path.join(dir_path, '..')) # change to project root directory
call_subprocess(cmd)
return cmd
def move_training_results_to_experiments_dir(config):
training_results_dir_path = os.path.join(config.experiments.dir, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')) #creating directory accordint to pattern eg: 2020-06-30_17-52-19
def move_training_results_to_experiments_dir():
training_results_dir_path = os.path.join(config.experiments.dir, datetime.datetime.now().strftime(
'%Y-%m-%d_%H-%M-%S')) # creating directory accordint to pattern eg: 2020-06-30_17-52-19
print("_______ CALLING MOVING RESULTS _______")
print(f"MOVING RESUTLS TO {training_results_dir_path}")
@ -38,22 +63,26 @@ def move_training_results_to_experiments_dir(config):
names_path = open(config.train.data).readlines()[3].split('=')[-1].rstrip() # read names path from file
names_file_name = ntpath.basename(names_path)
experiment_names_path = os.path.join(training_results_dir_path, names_file_name)
shutil.copy(names_path, experiment_names_path) # copy names file from *.data file to created experiment dir with training results
tensorboard_dir = './runs'
last_modified_tensorboard_dir = max(glob.glob(os.path.join(tensorboard_dir, '*/')), key=os.path.getmtime)
shutil.move(last_modified_tensorboard_dir, os.path.join(training_results_dir_path)) # saving related tensorboard dir
shutil.copy(names_path,
experiment_names_path) # copy names file from *.data file to created experiment dir with training results
tensorboard_dir = '/home/tomekb/yolov3/runs'
tensorboard_events_files = glob.glob(os.path.join(tensorboard_dir, '*'))
last_modified_events_file = max(tensorboard_events_files, key=os.path.getmtime)
shutil.move(last_modified_events_file,
os.path.join(training_results_dir_path)) # saving related tensorboard dir
shutil.copy2(config.config_path, training_results_dir_path) # copying configuration yaml
# for test purposes only
# shutil.copy2('/home/tomekb/yolov3/experiments/1/best.pt', training_results_dir_path)
# TODO CHANGE ME AFTER TESTS
shutil.copy2('/home/tomekb/yolov3/experiments/yolov3-spp-100-epochs-freeze-layers/best.pt',
training_results_dir_path)
return weights_path, experiment_names_path, training_results_dir_path
def call_detection_script(config, weights_path, names_path, dir):
def call_detection_script(gaussian_hyps, weights_path, names_path, dir):
detect_output_dir = os.path.join(dir, 'output')
cmd = f"""/home/tomekb/miniconda3/envs/conda3.7/bin/python -u /home/tomekb/yolov3/detect.py
--cfg {config.train.cfg}
@ -61,41 +90,101 @@ def call_detection_script(config, weights_path, names_path, dir):
--output {detect_output_dir}
--names {names_path}
--weights {weights_path}
--test-img-size {getattr(config.detect, 'test-img-size')}
--conf-thres {getattr(config.detect, 'conf-thres')}
--iou-thres {getattr(config.detect, 'iou-thres')}
--test-img-size {gaussian_hyps['test-img-size']}
--conf-thres {gaussian_hyps['conf-thres']}
--iou-thres {gaussian_hyps['iou-thres']}
--save-txt"""
cmd += " --agnostic-nms" if getattr(config.detect, 'agnostic-nms') else ""
cmd += " --agument" if getattr(config.detect, 'augment') else ""
cmd += f" --device {config.train.device}" if config.train.device else ""
cmd = " ".join(cmd.split())
print("_______ CALLING DETECTION SCRIPT _______")
print(cmd)
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of process to console
print(line)
call_subprocess(cmd)
return detect_output_dir
def call_generate_confussion_matrix(detect_output_dir, config, names_path, train_results_dir):
def call_generate_confussion_matrix(detect_output_dir, names_path, train_results_dir):
labels_dir = getattr(config.confussion_matrix, 'labels-dir')
cmd = f"node ./our_scripts/generate-confusion-matrix.js {detect_output_dir} {labels_dir} {names_path} > {train_results_dir}/confussion-matrix.tsv"
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
conff_matrix_path = os.path.join(train_results_dir, 'confussion-matrix.tsv')
cmd = f"node /home/tomekb/yolov3/our_scripts/generate-confusion-matrix.js {detect_output_dir} {labels_dir} {names_path} > {conff_matrix_path}"
print("_______ CALLING CONFUSSION MATRIX SCRIPT _______")
print(cmd)
for line in io.TextIOWrapper(process.stdout, encoding="utf-8"): # print output of process to console
print(line)
call_subprocess(cmd)
return conff_matrix_path
def yolov3(x):
bayes_hyps = {
'epochs': int(x[:, 0]),
'batch-size': int(x[:, 1]),
'multi-scale': bool(x[:, 2]),
'img-size': f"{int(x[:, 3])} {int(x[:, 4])}",
'rect': bool(x[:, 5]),
'adam': bool(x[:, 6]),
'giou': float(x[:, 7]), # train hyps start index
'cls': float(x[:, 8]),
'cls_pw': float(x[:, 9]),
'obj': float(x[:, 10]),
'obj_pw': float(x[:, 11]),
'iou_t': float(x[:, 12]),
'lr0': float(x[:, 13]),
'lrf': float(x[:, 14]),
'momentum': float(x[:, 15]),
'weight_decay': float(x[:, 16]),
'fl_gamma': float(x[:, 17]),
'hsv_h': float(x[:, 18]),
'hsv_s': float(x[:, 19]),
'hsv_v': float(x[:, 20]),
'degrees': float(x[:, 21]),
'translate': float(x[:, 22]),
'scale': float(x[:, 23]),
'shear': float(x[:, 24]), # train hyps end index
'test-img-size': int(x[:, 25]),
'conf-thres': float(x[:, 26]),
'iou-thres': float(x[:, 27])
}
line = ""
try:
call_training_script(bayes_hyps)
weights_path, names_path, train_results_dir = move_training_results_to_experiments_dir()
detect_output_dir = call_detection_script(bayes_hyps, weights_path, names_path, train_results_dir)
conf_matrix_path = call_generate_confussion_matrix(detect_output_dir, names_path, train_results_dir)
y_dict = get_values_from_conff_matrix(conf_matrix_path)
# tutaj wzór na wyliczanie funkcji
y_val = 1 - ((y_dict['match'] * 10 - y_dict['false positives'] * 3) / y_dict['mistakes'])
# zapisywanie do pliku zadeklarowanego globalnie
line = "\t".join([bayes_hyps.__str__(), str(y_val)])
bayes_params_file.writelines([line, '\n'])
return y_val
except:
tb = traceback.format_exc()
print("An error occured during running training-detect-confussion process \n", tb)
print("Returning 1 from current bayessian iteration")
line = "\t".join([bayes_hyps.__str__(), str(1)])
return 1
finally:
bayes_params_file.writelines([line, '\n'])
# uruchamiać z
if __name__ == '__main__':
config = Configuration()
train_cmd = call_training_script(config)
weights_path, names_path, train_results_dir = move_training_results_to_experiments_dir(config)
detect_output_dir = call_detection_script(config, weights_path, names_path, train_results_dir)
call_generate_confussion_matrix(detect_output_dir, config, names_path, train_results_dir)
bounds = config.get_bayes_bounds()
# for b in bounds:
# print(b)
# tutaj będzie wczytywanie z poprzednich eksperymentów plik bayes_params
X = None
Y = None
bayes_optimizer = GPyOpt.methods.BayesianOptimization(f=yolov3, domain=bounds, X=X, Y=Y, verbosity=True,
initial_design_numdata=2)
bayes_optimizer.run_optimization(config.bayes.iterations, verbosity=True)
bayes_params_file.close()

View File

@ -0,0 +1,55 @@
import io
import subprocess
def call_subprocess(cmd):
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
error = False
for process_line_output in io.TextIOWrapper(process.stdout,
encoding="utf-8"): # print output of training process to console
if 'Traceback' in process_line_output:
error = True
print(process_line_output)
if error:
raise RuntimeError("An error occured during calling subprocess")
def get_values_from_conff_matrix(path):
lines = open(path, 'r').readlines()[:7]
d = {}
for l in lines:
key, value, *_ = l.split("\t")
d.update({key.replace(":", ""): int(value)})
return d
def get_bayes_params_as_dict(x):
return {
'epochs': int(x[:, 0]),
'batch-size': int(x[:, 1]),
'multi-scale': bool(x[:, 2]),
'img-size': f"{int(x[:, 3])} {int(x[:, 4])}",
'rect': bool(x[:, 5]),
'adam': bool(x[:, 6]),
'giou': float(x[:, 7]), # train hyps start index
'cls': float(x[:, 8]),
'cls_pw': float(x[:, 9]),
'obj': float(x[:, 10]),
'obj_pw': float(x[:, 11]),
'iou_t': float(x[:, 12]),
'lr0': float(x[:, 13]),
'lrf': float(x[:, 14]),
'momentum': float(x[:, 15]),
'weight_decay': float(x[:, 16]),
'fl_gamma': float(x[:, 17]),
'hsv_h': float(x[:, 18]),
'hsv_s': float(x[:, 19]),
'hsv_v': float(x[:, 20]),
'degrees': float(x[:, 21]),
'translate': float(x[:, 22]),
'scale': float(x[:, 23]),
'shear': float(x[:, 24]), # train hyps end index
'test-img-size': int(x[:, 25]),
'conf-thres': float(x[:, 26]),
'iou-thres': float(x[:, 27])
}

View File

@ -10,6 +10,7 @@ from models import *
from utils.datasets import *
from utils.utils import *
from our_scripts.config import Configuration
import ast
mixed_precision = True
@ -117,7 +118,6 @@ def train(hyp):
best_fitness = 0.0
attempt_download(weights)
if weights.endswith('.pt'): # pytorch format
print("LOADIN MODEL")
# possible weights are '*.pt', 'yolov3-spp.pt', 'yolov3-tiny.pt' etc.
ckpt = torch.load(weights, map_location=device)
@ -364,8 +364,9 @@ def train(hyp):
'model': ema.ema.module.state_dict() if hasattr(model, 'module') else ema.ema.state_dict(),
'optimizer': None if final_epoch else optimizer.state_dict()}
if epoch % opt.save_every_nth_epoch == 0:
torch.save(chkpt, f'yolo_{epoch}.pt')
if opt.snapshot_every and epoch % opt.snapshot_every == 0 :
saving_path = os.path.join(opt.experiment_dir, f'weights_{epoch}.pt')
torch.save(ckpt, saving_path)
# Save last, best and delete
torch.save(ckpt, last)
if (best_fitness == fi) and not final_epoch:
@ -416,8 +417,14 @@ if __name__ == '__main__':
parser.add_argument('--adam', action='store_true', help='use adam optimizer')
parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
parser.add_argument('--freeze-layers', action='store_true', help='Freeze non-output layers')
parser.add_argument('--save-every-nth-epoch', type=int, help='Saving every n-th epoth')
# parametry dodane na cele projektu wykrywania aut
parser.add_argument('--snapshot-every', type=int, help='Saving every n-th state of model weights')
parser.add_argument('--experiment-dir', type=str, help='Directory for experiments')
parser.add_argument('--hyp', type=str, help='String that represents dictionary with hyperparameters ')
opt = parser.parse_args()
#print(opt)
#opt.weights = last if opt.resume and not opt.weights else opt.weights
#check_git_status()
opt.cfg = check_file(opt.cfg) # check file
@ -431,9 +438,10 @@ if __name__ == '__main__':
# scale hyp['obj'] by img_size (evolved at 320)
# hyp['obj'] *= opt.img_size[0] / 320.
hyp = Configuration().train.other_hyps.__dict__
#overriding global hyp variable with our bayessian hyps
hyp = ast.literal_eval(opt.hyp)
#print('### TRAIN HYPERPARAMETERS ###')
#print(hyp)
tb_writer = None
if not opt.evolve: # Train normally

View File

@ -553,6 +553,7 @@ def augment_hsv(img, hgain=0.5, sgain=0.5, vgain=0.5):
img_hsv = cv2.merge((cv2.LUT(hue, lut_hue), cv2.LUT(sat, lut_sat), cv2.LUT(val, lut_val))).astype(dtype)
cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR, dst=img) # no return needed
# Histogram equalization
# if random.random() < 0.2:
# for i in range(3):