def parse_model_config(path): """Parse the yolov3 layer configuration file and returns module definitions.""" lines = utils.get_lines(path) module_defs = [] for line in lines: if line.startswith("["): # This marks the start of a new block module_defs.append({}) module_defs[-1]["type"] = line[1:-1].rstrip() if module_defs[-1]["type"] == "convolutional": module_defs[-1]["batch_normalize"] = 0 else: key, value = line.split("=") value = value.strip() module_defs[-1][key.rstrip()] = value.strip() return module_defs
def load_splits(self, folder): """Load previously-generated text file splits into the current folder if found. Returns a boolean value indicating if the operation was successful. """ split_paths = [ f"{folder}/{self.prefix}_{name}.txt" for name in self.sets ] if all(os.path.exists(path) for path in split_paths): file_lists = [get_lines(path) for path in split_paths] labeled_sets = self.convert_splits(file_lists) for name, split_set in zip(self.sets, labeled_sets): setattr(self, name, split_set) return True return False
def get_batch_test_set(config, reserve_batches): out_dir = config["output"] num_classes = len(utils.load_classes(config["class_list"])) batch_sets = sorted(glob.glob(f"{out_dir}/sample*.txt"), key=utils.get_sample) test_imgs = list() batches_removed = 0 for batch_set in reversed(batch_sets): imgs = utils.get_lines(batch_set) if len(imgs) < config["sampling_batch"] or reserve_batches != 0: test_imgs += imgs batches_removed += 1 if not (len(imgs) < config["sampling_batch"]): reserve_batches -= 1 return LabeledSet(test_imgs, num_classes), batches_removed
def get_batch_splits(self, batch_size, output): """Output text files lists of random image batches of the specified size. Does not stratify by class, and the last batch may have fewer images than desired. """ batches = math.ceil(len(self) / batch_size) batch_files = [ f"{output}/{self.prefix}{i}.txt" for i in range(batches) ] if all(os.path.exists(path) for path in batch_files): batch_splits = [get_lines(path) for path in batch_files] print("Previous batch splits found") else: batch_splits = self.split_batch(batch_size) for i, path in enumerate(batch_files): with open(path, "w+") as out: out.write("\n".join(batch_splits[i])) return self.convert_splits(batch_splits)
def get_test_sets(config, prefix): out_dir = config["output"] num_classes = len(utils.load_classes(config["class_list"])) epoch_splits = utils.get_epoch_splits(config, prefix) # Initial test set init_test_set = f"{out_dir}/init_test.txt" init_test_folder = LabeledSet(init_test_set, num_classes) # Only data from the (combined) iteration test sets (75% sampling + 25% seen data) iter_test_sets = [ f"{out_dir}/{prefix}{i}_test.txt" for i in range(len(epoch_splits)) ] iter_img_files = list() for file in iter_test_sets: iter_img_files += utils.get_lines(file) all_iter_sets = LabeledSet(iter_img_files, num_classes) # Test sets filtered for only sampled images sampled_imgs = [ img for img in iter_img_files if config["sample_set"] in img ] sample_test = LabeledSet(sampled_imgs, num_classes) # Data from all test sets all_test = LabeledSet(sampled_imgs, num_classes) all_test += init_test_folder test_sets = { "init": init_test_folder, "all_iter": all_iter_sets, "sample": sample_test, "all": all_test, } if prefix != "init": for i in range(len(epoch_splits)): test_sets[f"cur_iter{i + 1}"] = LabeledSet(iter_test_sets[i], num_classes) return test_sets
def load_data(output, by_actual=True, add_all=True, filter=None, conf_thresh=0.5): samples = dict() all_data = list() actual = list() pred = list() with open(output, newline="\n") as csvfile: reader = csv.DictReader(csvfile) if filter is not None: filter_list = utils.get_lines(filter) for row in reader: if filter is not None and row["file"] not in filter_list: continue actual.append(row["actual"]) pred.append(row["detected"]) all_data.append(row) key_val = ( row["actual"] if by_actual or row["detected"] == str() else row["detected"] ) if key_val in samples.keys(): samples[key_val].append(row) else: samples[key_val] = [row] samples = {k: samples[k] for k in sorted(samples)} results = [ClassResults(k, v, conf_thresh=conf_thresh) for k, v in samples.items()] mat = confusion_matrix(actual, pred, labels=list(samples.keys()) + [""]) if add_all: results.append(ClassResults("All", all_data, conf_thresh=conf_thresh)) return results, mat
def __init__(self, src, img_size, prefix=str()): """ Parameters: src (str): source of the image folder. Can be a list or set of image paths, a text file of image paths, or a Darknet-labeled folder img_size (int): square resolution to pad or downsize images to prefix (str): string to represent the image folder. used in output filenames """ if isinstance(src, (list, set)): self.imgs = set(src) elif ".txt" in src: if os.path.isfile(src): self.imgs = get_lines(src) else: self.imgs = list() print(f"{src} is an invalid file. Ignoring...") elif os.path.isdir(src): self.imgs = get_images(src) else: raise TypeError("ImageFolder source must be file list or folder") self.prefix = prefix self.img_size = img_size
def get_classes(self, label_path): """Get a list of classes from a Darknet label.""" labels = get_lines(label_path) classes = [int(lab.split(" ")[0]) for lab in labels if lab != ""] return [c for c in classes if c in range(self.num_classes)]