Module 1_gluoncv_finetune.lib.detector_prototype
Expand source code
import os
import sys
import time
from matplotlib import pyplot as plt
import numpy as np
import mxnet as mx
from mxnet import autograd, gluon
import gluoncv as gcv
from gluoncv.utils import download, viz
import pandas as pd
import cv2
from PIL import Image
Image.LOAD_TRUNCATED_IMAGES = True
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
def isnotebook():
try:
shell = get_ipython().__class__.__name__
if shell == 'ZMQInteractiveShell':
return True # Jupyter notebook or qtconsole
elif shell == 'TerminalInteractiveShell':
return False # Terminal running IPython
else:
return False # Other type (?)
except NameError:
return False
if(isnotebook()):
from tqdm.notebook import tqdm
else:
from tqdm import tqdm as tqdm
from gluoncv.data.batchify import Tuple, Stack, Pad
from gluoncv.data.transforms.presets.ssd import SSDDefaultTrainTransform
from gluoncv.data.transforms.presets.yolo import YOLO3DefaultTrainTransform
class Detector():
'''
Class to train a detector
Args:
verbose (int): Set verbosity levels
0 - Print Nothing
1 - Print desired details
'''
def __init__(self, verbose=1):
self.system_dict = {};
self.system_dict["verbose"] = verbose;
self.system_dict["local"] = {};
self.system_dict["model_set_1"] = ["ssd_300_vgg16_atrous_coco", "ssd_300_vgg16_atrous_voc"];
self.system_dict["model_set_2"] = ["ssd_512_vgg16_atrous_coco", "ssd_512_vgg16_atrous_voc"];
self.system_dict["model_set_3"] = ["ssd_512_resnet50_v1_coco", "ssd_512_resnet50_v1_voc"];
self.system_dict["model_set_4"] = ["ssd_512_mobilenet1.0_voc", "ssd_512_mobilenet1.0_coco"];
self.system_dict["model_set_5"] = ["yolo3_darknet53_voc", "yolo3_darknet53_coco"];
self.system_dict["model_set_6"] = ["yolo3_mobilenet1.0_voc", "yolo3_mobilenet1.0_coco"];
def Dataset(self, root, img_dir, anno_file, batch_size=4, num_workers=0):
'''
User function: Set dataset parameters
Dataset Directory Structure
Parent_Directory (root)
|
|-----------Images (img_dir)
| |
| |------------------img1.jpg
| |------------------img2.jpg
| |------------------.........(and so on)
|
|
|-----------train_labels.csv (anno_file)
Annotation file format
| Id | Labels |
| img1.jpg | x1 y1 x2 y2 label1 x1 y1 x2 y2 label2 |
Labels: xmin ymin xmax ymax label
xmin, ymin - top left corner of bounding box
xmax, ymax - bottom right corner of bounding box
Args:
root (str): Path to root_dir
img_dir (str): Name of image dir
anno_file (str): Name of Labels files containing annotations in monk format
batch_size (int): Mini batch sampling size for training epochs
num_workers (int): Number of parallel processors for data loader
Returns:
None
'''
self.system_dict["root"] = root;
self.system_dict["img_dir"] = img_dir;
self.system_dict["anno_file"] = anno_file;
self.system_dict["batch_size"] = batch_size;
self.system_dict["num_workers"] = num_workers;
df = pd.read_csv(self.system_dict["root"] + "/" + self.system_dict["anno_file"]);
columns = df.columns;
classes = [];
for i in tqdm(range(len(df))):
tmp = df[columns[1]][i].split(" ");
for j in range(len(tmp)//5):
label = tmp[j*5+4];
if(label not in classes):
classes.append(label)
self.system_dict["classes"] = sorted(classes)
with open('train.lst', 'w') as fw:
for i in tqdm(range(len(df))):
img_name = df[columns[0]][i];
tmp = df[columns[1]][i].split(" ");
class_names = [];
bbox = [];
ids = [];
for j in range(len(tmp)//5):
x1 = int(float(tmp[j*5+0]));
y1 = int(float(tmp[j*5+1]));
x2 = int(float(tmp[j*5+2]));
y2 = int(float(tmp[j*5+3]));
label = tmp[j*5+4]
class_names.append(label);
bbox.append([x1, y1, x2, y2]);
ids.append(classes.index(label));
if(not os.path.isfile(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name)):
continue;
img = cv2.imread(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name);
all_boxes = np.array(bbox);
all_ids = np.array(ids);
line = self.write_line(img_name, img.shape, all_boxes, all_ids, i)
fw.write(line)
cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/im2rec.py " + os.getcwd() + "/";
os.system(cmd1);
cmd2 = "python im2rec.py train.lst " + self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/ --pass-through --pack-label"
os.system(cmd2);
self.system_dict["local"]["train_dataset"] = gcv.data.RecordFileDetection('train.rec')
def write_line(self, img_path, im_shape, boxes, ids, idx):
'''
Internal function: Convert labels to required gluoncv format
Args:
img_path (str): Relative path to image
im_shape (tuple): Image shape in order - height, width, channel
boxes (list): List of object bounding boxes in the image
ids (list): List of label ids for object bounding boxes
idx (idx): Unique image index
Returns:
str: A String containing image index, headers, labels, and image path
'''
h, w, c = im_shape
# for header, we use minimal length 2, plus width and height
# with A: 4, B: 5, C: width, D: height
A = 4
B = 5
C = w
D = h
# concat id and bboxes
labels = np.hstack((ids.reshape(-1, 1), boxes)).astype('float')
# normalized bboxes (recommanded)
labels[:, (1, 3)] /= float(w)
labels[:, (2, 4)] /= float(h)
# flatten
labels = labels.flatten().tolist()
str_idx = [str(idx)]
str_header = [str(x) for x in [A, B, C, D]]
str_labels = [str(x) for x in labels]
str_path = [img_path]
line = '\t'.join(str_idx + str_header + str_labels + str_path) + '\n'
return line
def Model(self, model_name, use_pretrained=True, use_gpu=True, gpu_devices=[0]):
'''
User function: Set Model parameters
Available models
ssd_300_vgg16_atrous_coco
ssd_300_vgg16_atrous_voc
ssd_512_vgg16_atrous_coco
ssd_512_vgg16_atrous_voc
ssd_512_resnet50_v1_coco
ssd_512_resnet50_v1_voc
ssd_512_mobilenet1.0_voc
ssd_512_mobilenet1.0_coco
yolo3_darknet53_voc
yolo3_darknet53_coco
yolo3_mobilenet1.0_voc
yolo3_mobilenet1.0_coco
Args:
model_name (str): Select from available models
use_pretrained (bool): If True use pretrained weights else randomly initialized weights
use_gpu (bool): If True use GPU else run on CPU
gpu_devices (list): List of GPU device Ids
Returns:
None
'''
self.system_dict["model_name"] = model_name;
self.system_dict["use_pretrained"] = use_pretrained;
if(self.system_dict["model_name"] in self.system_dict["model_set_1"]):
self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"],
pretrained=self.system_dict["use_pretrained"]);
self.system_dict["local"]["net"].reset_class(self.system_dict["classes"])
self.system_dict["img_shape"] = (300, 300);
width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1]
with autograd.train_mode():
_, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width)))
batchify_fn = Tuple(Stack(), Stack(), Stack())
self.system_dict["local"]["train_loader"] = gluon.data.DataLoader(
self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)),
self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover',
num_workers=self.system_dict["num_workers"])
self.set_device(use_gpu=use_gpu ,gpu_devices=gpu_devices);
self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"])
elif((self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"])
or (self.system_dict["model_name"] in self.system_dict["model_set_4"])):
self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"],
pretrained=self.system_dict["use_pretrained"]);
self.system_dict["local"]["net"].reset_class(self.system_dict["classes"])
self.system_dict["img_shape"] = (512, 512);
width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1]
with autograd.train_mode():
_, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width)))
batchify_fn = Tuple(Stack(), Stack(), Stack())
self.system_dict["local"]["train_loader"] = gluon.data.DataLoader(
self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)),
self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover',
num_workers=self.system_dict["num_workers"])
self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices);
self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"])
elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])) :
self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"],
pretrained=self.system_dict["use_pretrained"]);
self.system_dict["local"]["net"].reset_class(self.system_dict["classes"])
self.system_dict["img_shape"] = (416, 416);
width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1]
train_transform = YOLO3DefaultTrainTransform(width, height, self.system_dict["local"]["net"])
batchify_fn = Tuple(*([Stack() for _ in range(6)] + [Pad(axis=0, pad_val=-1) for _ in range(1)]))
self.system_dict["local"]["train_loader"] = gluon.data.DataLoader(
self.system_dict["local"]["train_dataset"].transform(train_transform),
self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover',
num_workers=self.system_dict["num_workers"])
self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices);
self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"])
def set_device(self, use_gpu=True ,gpu_devices=[0]):
'''
Internal function: Prepares GPU and CPU devices as per the model parameters set
Args:
use_gpu (bool): If True use GPU else run on CPU
gpu_devices (list): List of GPU device Ids
Returns:
None
'''
self.system_dict["use_gpu"] = use_gpu;
if self.system_dict["use_gpu"]:
self.system_dict["gpu_devices"] = gpu_devices;
self.system_dict["local"]["ctx"]= [mx.gpu(int(i)) for i in self.system_dict["gpu_devices"]]
else:
self.system_dict["local"]["ctx"] = [mx.cpu()]
def Set_Learning_Rate(self, lr):
'''
User function: Set initial learning rate
Args:
lr (float): Base learning rate
Returns:
None
'''
self.system_dict["local"]["trainer"] = gluon.Trainer(
self.system_dict["local"]["net"].collect_params(), 'sgd',
{'learning_rate': lr, 'wd': 0.0005, 'momentum': 0.9})
if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"])
or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])):
self.system_dict["local"]["mbox_loss"] = gcv.loss.SSDMultiBoxLoss()
self.system_dict["local"]["ce_metric"] = mx.metric.Loss('CrossEntropy')
self.system_dict["local"]["smoothl1_metric"] = mx.metric.Loss('SmoothL1');
elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])):
self.system_dict["local"]["loss"] = gcv.loss.YOLOV3Loss()
self.system_dict["local"]["obj_metrics"] = mx.metric.Loss('ObjLoss')
self.system_dict["local"]["center_metrics"] = mx.metric.Loss('BoxCenterLoss')
self.system_dict["local"]["scale_metrics"] = mx.metric.Loss('BoxScaleLoss')
self.system_dict["local"]["cls_metrics"] = mx.metric.Loss('ClassLoss')
def Train(self, epochs, params_file):
'''
User function: Start training
Args:
epochs (int): Number of epochs to train for
params_file (str): Trained weights file name with extension as ".params"
Returns:
None
'''
self.system_dict["num_epochs"] = epochs;
self.system_dict["params_file"] = params_file;
self.system_dict["training_metrics"] = [];
self.system_dict["training_time"] = 0.0;
if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"])
or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])):
for epoch in range(self.system_dict["num_epochs"]):
self.system_dict["local"]["ce_metric"].reset()
self.system_dict["local"]["smoothl1_metric"].reset()
tic = time.time()
btic = time.time()
self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True)
for i, batch in enumerate(self.system_dict["local"]["train_loader"]):
batch_size = batch[0].shape[0]
data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0)
cls_targets = gluon.utils.split_and_load(batch[1], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0)
box_targets = gluon.utils.split_and_load(batch[2], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0)
with autograd.record():
cls_preds = []
box_preds = []
for x in data:
cls_pred, box_pred, _ = self.system_dict["local"]["net"](x)
cls_preds.append(cls_pred)
box_preds.append(box_pred)
sum_loss, cls_loss, box_loss = self.system_dict["local"]["mbox_loss"](
cls_preds, box_preds, cls_targets, box_targets)
autograd.backward(sum_loss)
# since we have already normalized the loss, we don't want to normalize
# by batch-size anymore
self.system_dict["local"]["trainer"].step(batch_size)
self.system_dict["local"]["ce_metric"].update(0, [l * batch_size for l in cls_loss])
self.system_dict["local"]["smoothl1_metric"].update(0, [l * batch_size for l in box_loss])
name1, loss1 = self.system_dict["local"]["ce_metric"].get()
name2, loss2 = self.system_dict["local"]["smoothl1_metric"].get()
if i % 20 == 0:
print('[Epoch {}][Batch {}], Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}'.format(
epoch, i, batch_size/(time.time()-btic), name1, loss1, name2, loss2))
tmp = {};
tmp["epoch"] = epoch;
tmp["batch"] = batch;
tmp["name1"] = loss1;
tmp["name2"] = loss2;
self.system_dict["training_metrics"].append(tmp);
btic = time.time()
self.system_dict["training_time"] += time.time() - tic;
self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"])
if((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])):
for epoch in range(self.system_dict["num_epochs"]):
tic = time.time()
btic = time.time()
self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True)
self.system_dict["local"]["obj_metrics"].reset()
self.system_dict["local"]["center_metrics"].reset()
self.system_dict["local"]["scale_metrics"].reset()
self.system_dict["local"]["cls_metrics"].reset()
for i, batch in enumerate(self.system_dict["local"]["train_loader"]):
batch_size = batch[0].shape[0]
data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0)
# objectness, center_targets, scale_targets, weights, class_targets
fixed_targets = [gluon.utils.split_and_load(batch[it], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0) for it in range(1, 6)]
gt_boxes = gluon.utils.split_and_load(batch[6], ctx_list=self.system_dict["local"]["ctx"],
batch_axis=0)
sum_losses = []
obj_losses = []
center_losses = []
scale_losses = []
cls_losses = []
with autograd.record():
for ix, x in enumerate(data):
obj_loss, center_loss, scale_loss, cls_loss = self.system_dict["local"]["net"](x, gt_boxes[ix],
*[ft[ix] for ft in fixed_targets])
sum_losses.append(obj_loss + center_loss + scale_loss + cls_loss)
obj_losses.append(obj_loss)
center_losses.append(center_loss)
scale_losses.append(scale_loss)
cls_losses.append(cls_loss)
autograd.backward(sum_losses)
self.system_dict["local"]["trainer"].step(batch_size)
self.system_dict["local"]["obj_metrics"].update(0, obj_losses)
self.system_dict["local"]["center_metrics"].update(0, center_losses)
self.system_dict["local"]["scale_metrics"].update(0, scale_losses)
self.system_dict["local"]["cls_metrics"].update(0, cls_losses)
if i % 20 == 0:
name1, loss1 = self.system_dict["local"]["obj_metrics"].get()
name2, loss2 = self.system_dict["local"]["center_metrics"].get()
name3, loss3 = self.system_dict["local"]["scale_metrics"].get()
name4, loss4 = self.system_dict["local"]["cls_metrics"].get()
tmp = {};
tmp["epoch"] = epoch;
tmp["batch"] = batch;
tmp["name1"] = loss1;
tmp["name2"] = loss2;
tmp["name3"] = loss3;
tmp["name4"] = loss4;
self.system_dict["training_metrics"].append(tmp);
print('[Epoch {}][Batch {}], LR: {:.2E}, Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}, {}={:.3f}, {}={:.3f}'.format(
epoch, i, self.system_dict["local"]["trainer"].learning_rate, batch_size/(time.time()-btic), name1, loss1, name2, loss2, name3,
loss3, name4, loss4))
btic = time.time()
self.system_dict["training_time"] += time.time() - tic;
self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"])
Functions
def isnotebook()
-
Expand source code
def isnotebook(): try: shell = get_ipython().__class__.__name__ if shell == 'ZMQInteractiveShell': return True # Jupyter notebook or qtconsole elif shell == 'TerminalInteractiveShell': return False # Terminal running IPython else: return False # Other type (?) except NameError: return False
Classes
class Detector (verbose=1)
-
Class to train a detector
Args
verbose
:int
- Set verbosity levels 0 - Print Nothing 1 - Print desired details
Expand source code
class Detector(): ''' Class to train a detector Args: verbose (int): Set verbosity levels 0 - Print Nothing 1 - Print desired details ''' def __init__(self, verbose=1): self.system_dict = {}; self.system_dict["verbose"] = verbose; self.system_dict["local"] = {}; self.system_dict["model_set_1"] = ["ssd_300_vgg16_atrous_coco", "ssd_300_vgg16_atrous_voc"]; self.system_dict["model_set_2"] = ["ssd_512_vgg16_atrous_coco", "ssd_512_vgg16_atrous_voc"]; self.system_dict["model_set_3"] = ["ssd_512_resnet50_v1_coco", "ssd_512_resnet50_v1_voc"]; self.system_dict["model_set_4"] = ["ssd_512_mobilenet1.0_voc", "ssd_512_mobilenet1.0_coco"]; self.system_dict["model_set_5"] = ["yolo3_darknet53_voc", "yolo3_darknet53_coco"]; self.system_dict["model_set_6"] = ["yolo3_mobilenet1.0_voc", "yolo3_mobilenet1.0_coco"]; def Dataset(self, root, img_dir, anno_file, batch_size=4, num_workers=0): ''' User function: Set dataset parameters Dataset Directory Structure Parent_Directory (root) | |-----------Images (img_dir) | | | |------------------img1.jpg | |------------------img2.jpg | |------------------.........(and so on) | | |-----------train_labels.csv (anno_file) Annotation file format | Id | Labels | | img1.jpg | x1 y1 x2 y2 label1 x1 y1 x2 y2 label2 | Labels: xmin ymin xmax ymax label xmin, ymin - top left corner of bounding box xmax, ymax - bottom right corner of bounding box Args: root (str): Path to root_dir img_dir (str): Name of image dir anno_file (str): Name of Labels files containing annotations in monk format batch_size (int): Mini batch sampling size for training epochs num_workers (int): Number of parallel processors for data loader Returns: None ''' self.system_dict["root"] = root; self.system_dict["img_dir"] = img_dir; self.system_dict["anno_file"] = anno_file; self.system_dict["batch_size"] = batch_size; self.system_dict["num_workers"] = num_workers; df = pd.read_csv(self.system_dict["root"] + "/" + self.system_dict["anno_file"]); columns = df.columns; classes = []; for i in tqdm(range(len(df))): tmp = df[columns[1]][i].split(" "); for j in range(len(tmp)//5): label = tmp[j*5+4]; if(label not in classes): classes.append(label) self.system_dict["classes"] = sorted(classes) with open('train.lst', 'w') as fw: for i in tqdm(range(len(df))): img_name = df[columns[0]][i]; tmp = df[columns[1]][i].split(" "); class_names = []; bbox = []; ids = []; for j in range(len(tmp)//5): x1 = int(float(tmp[j*5+0])); y1 = int(float(tmp[j*5+1])); x2 = int(float(tmp[j*5+2])); y2 = int(float(tmp[j*5+3])); label = tmp[j*5+4] class_names.append(label); bbox.append([x1, y1, x2, y2]); ids.append(classes.index(label)); if(not os.path.isfile(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name)): continue; img = cv2.imread(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name); all_boxes = np.array(bbox); all_ids = np.array(ids); line = self.write_line(img_name, img.shape, all_boxes, all_ids, i) fw.write(line) cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/im2rec.py " + os.getcwd() + "/"; os.system(cmd1); cmd2 = "python im2rec.py train.lst " + self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/ --pass-through --pack-label" os.system(cmd2); self.system_dict["local"]["train_dataset"] = gcv.data.RecordFileDetection('train.rec') def write_line(self, img_path, im_shape, boxes, ids, idx): ''' Internal function: Convert labels to required gluoncv format Args: img_path (str): Relative path to image im_shape (tuple): Image shape in order - height, width, channel boxes (list): List of object bounding boxes in the image ids (list): List of label ids for object bounding boxes idx (idx): Unique image index Returns: str: A String containing image index, headers, labels, and image path ''' h, w, c = im_shape # for header, we use minimal length 2, plus width and height # with A: 4, B: 5, C: width, D: height A = 4 B = 5 C = w D = h # concat id and bboxes labels = np.hstack((ids.reshape(-1, 1), boxes)).astype('float') # normalized bboxes (recommanded) labels[:, (1, 3)] /= float(w) labels[:, (2, 4)] /= float(h) # flatten labels = labels.flatten().tolist() str_idx = [str(idx)] str_header = [str(x) for x in [A, B, C, D]] str_labels = [str(x) for x in labels] str_path = [img_path] line = '\t'.join(str_idx + str_header + str_labels + str_path) + '\n' return line def Model(self, model_name, use_pretrained=True, use_gpu=True, gpu_devices=[0]): ''' User function: Set Model parameters Available models ssd_300_vgg16_atrous_coco ssd_300_vgg16_atrous_voc ssd_512_vgg16_atrous_coco ssd_512_vgg16_atrous_voc ssd_512_resnet50_v1_coco ssd_512_resnet50_v1_voc ssd_512_mobilenet1.0_voc ssd_512_mobilenet1.0_coco yolo3_darknet53_voc yolo3_darknet53_coco yolo3_mobilenet1.0_voc yolo3_mobilenet1.0_coco Args: model_name (str): Select from available models use_pretrained (bool): If True use pretrained weights else randomly initialized weights use_gpu (bool): If True use GPU else run on CPU gpu_devices (list): List of GPU device Ids Returns: None ''' self.system_dict["model_name"] = model_name; self.system_dict["use_pretrained"] = use_pretrained; if(self.system_dict["model_name"] in self.system_dict["model_set_1"]): self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (300, 300); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] with autograd.train_mode(): _, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width))) batchify_fn = Tuple(Stack(), Stack(), Stack()) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu ,gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"]) elif((self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (512, 512); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] with autograd.train_mode(): _, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width))) batchify_fn = Tuple(Stack(), Stack(), Stack()) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"]) elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])) : self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (416, 416); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] train_transform = YOLO3DefaultTrainTransform(width, height, self.system_dict["local"]["net"]) batchify_fn = Tuple(*([Stack() for _ in range(6)] + [Pad(axis=0, pad_val=-1) for _ in range(1)])) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(train_transform), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"]) def set_device(self, use_gpu=True ,gpu_devices=[0]): ''' Internal function: Prepares GPU and CPU devices as per the model parameters set Args: use_gpu (bool): If True use GPU else run on CPU gpu_devices (list): List of GPU device Ids Returns: None ''' self.system_dict["use_gpu"] = use_gpu; if self.system_dict["use_gpu"]: self.system_dict["gpu_devices"] = gpu_devices; self.system_dict["local"]["ctx"]= [mx.gpu(int(i)) for i in self.system_dict["gpu_devices"]] else: self.system_dict["local"]["ctx"] = [mx.cpu()] def Set_Learning_Rate(self, lr): ''' User function: Set initial learning rate Args: lr (float): Base learning rate Returns: None ''' self.system_dict["local"]["trainer"] = gluon.Trainer( self.system_dict["local"]["net"].collect_params(), 'sgd', {'learning_rate': lr, 'wd': 0.0005, 'momentum': 0.9}) if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): self.system_dict["local"]["mbox_loss"] = gcv.loss.SSDMultiBoxLoss() self.system_dict["local"]["ce_metric"] = mx.metric.Loss('CrossEntropy') self.system_dict["local"]["smoothl1_metric"] = mx.metric.Loss('SmoothL1'); elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])): self.system_dict["local"]["loss"] = gcv.loss.YOLOV3Loss() self.system_dict["local"]["obj_metrics"] = mx.metric.Loss('ObjLoss') self.system_dict["local"]["center_metrics"] = mx.metric.Loss('BoxCenterLoss') self.system_dict["local"]["scale_metrics"] = mx.metric.Loss('BoxScaleLoss') self.system_dict["local"]["cls_metrics"] = mx.metric.Loss('ClassLoss') def Train(self, epochs, params_file): ''' User function: Start training Args: epochs (int): Number of epochs to train for params_file (str): Trained weights file name with extension as ".params" Returns: None ''' self.system_dict["num_epochs"] = epochs; self.system_dict["params_file"] = params_file; self.system_dict["training_metrics"] = []; self.system_dict["training_time"] = 0.0; if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): for epoch in range(self.system_dict["num_epochs"]): self.system_dict["local"]["ce_metric"].reset() self.system_dict["local"]["smoothl1_metric"].reset() tic = time.time() btic = time.time() self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True) for i, batch in enumerate(self.system_dict["local"]["train_loader"]): batch_size = batch[0].shape[0] data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) cls_targets = gluon.utils.split_and_load(batch[1], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) box_targets = gluon.utils.split_and_load(batch[2], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) with autograd.record(): cls_preds = [] box_preds = [] for x in data: cls_pred, box_pred, _ = self.system_dict["local"]["net"](x) cls_preds.append(cls_pred) box_preds.append(box_pred) sum_loss, cls_loss, box_loss = self.system_dict["local"]["mbox_loss"]( cls_preds, box_preds, cls_targets, box_targets) autograd.backward(sum_loss) # since we have already normalized the loss, we don't want to normalize # by batch-size anymore self.system_dict["local"]["trainer"].step(batch_size) self.system_dict["local"]["ce_metric"].update(0, [l * batch_size for l in cls_loss]) self.system_dict["local"]["smoothl1_metric"].update(0, [l * batch_size for l in box_loss]) name1, loss1 = self.system_dict["local"]["ce_metric"].get() name2, loss2 = self.system_dict["local"]["smoothl1_metric"].get() if i % 20 == 0: print('[Epoch {}][Batch {}], Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}'.format( epoch, i, batch_size/(time.time()-btic), name1, loss1, name2, loss2)) tmp = {}; tmp["epoch"] = epoch; tmp["batch"] = batch; tmp["name1"] = loss1; tmp["name2"] = loss2; self.system_dict["training_metrics"].append(tmp); btic = time.time() self.system_dict["training_time"] += time.time() - tic; self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"]) if((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])): for epoch in range(self.system_dict["num_epochs"]): tic = time.time() btic = time.time() self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True) self.system_dict["local"]["obj_metrics"].reset() self.system_dict["local"]["center_metrics"].reset() self.system_dict["local"]["scale_metrics"].reset() self.system_dict["local"]["cls_metrics"].reset() for i, batch in enumerate(self.system_dict["local"]["train_loader"]): batch_size = batch[0].shape[0] data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) # objectness, center_targets, scale_targets, weights, class_targets fixed_targets = [gluon.utils.split_and_load(batch[it], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) for it in range(1, 6)] gt_boxes = gluon.utils.split_and_load(batch[6], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) sum_losses = [] obj_losses = [] center_losses = [] scale_losses = [] cls_losses = [] with autograd.record(): for ix, x in enumerate(data): obj_loss, center_loss, scale_loss, cls_loss = self.system_dict["local"]["net"](x, gt_boxes[ix], *[ft[ix] for ft in fixed_targets]) sum_losses.append(obj_loss + center_loss + scale_loss + cls_loss) obj_losses.append(obj_loss) center_losses.append(center_loss) scale_losses.append(scale_loss) cls_losses.append(cls_loss) autograd.backward(sum_losses) self.system_dict["local"]["trainer"].step(batch_size) self.system_dict["local"]["obj_metrics"].update(0, obj_losses) self.system_dict["local"]["center_metrics"].update(0, center_losses) self.system_dict["local"]["scale_metrics"].update(0, scale_losses) self.system_dict["local"]["cls_metrics"].update(0, cls_losses) if i % 20 == 0: name1, loss1 = self.system_dict["local"]["obj_metrics"].get() name2, loss2 = self.system_dict["local"]["center_metrics"].get() name3, loss3 = self.system_dict["local"]["scale_metrics"].get() name4, loss4 = self.system_dict["local"]["cls_metrics"].get() tmp = {}; tmp["epoch"] = epoch; tmp["batch"] = batch; tmp["name1"] = loss1; tmp["name2"] = loss2; tmp["name3"] = loss3; tmp["name4"] = loss4; self.system_dict["training_metrics"].append(tmp); print('[Epoch {}][Batch {}], LR: {:.2E}, Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}, {}={:.3f}, {}={:.3f}'.format( epoch, i, self.system_dict["local"]["trainer"].learning_rate, batch_size/(time.time()-btic), name1, loss1, name2, loss2, name3, loss3, name4, loss4)) btic = time.time() self.system_dict["training_time"] += time.time() - tic; self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"])
Methods
def Dataset(self, root, img_dir, anno_file, batch_size=4, num_workers=0)
-
User function: Set dataset parameters
Dataset Directory Structure
Parent_Directory (root) | |-----------Images (img_dir) | | | |------------------img1.jpg | |------------------img2.jpg | |------------------.........(and so on) | | |-----------train_labels.csv (anno_file)
Annotation file format
| Id | Labels | | img1.jpg | x1 y1 x2 y2 label1 x1 y1 x2 y2 label2 | Labels: xmin ymin xmax ymax label xmin, ymin - top left corner of bounding box xmax, ymax - bottom right corner of bounding box
Args
root
:str
- Path to root_dir
img_dir
:str
- Name of image dir
anno_file
:str
- Name of Labels files containing annotations in monk format
batch_size
:int
- Mini batch sampling size for training epochs
num_workers
:int
- Number of parallel processors for data loader
Returns
None
Expand source code
def Dataset(self, root, img_dir, anno_file, batch_size=4, num_workers=0): ''' User function: Set dataset parameters Dataset Directory Structure Parent_Directory (root) | |-----------Images (img_dir) | | | |------------------img1.jpg | |------------------img2.jpg | |------------------.........(and so on) | | |-----------train_labels.csv (anno_file) Annotation file format | Id | Labels | | img1.jpg | x1 y1 x2 y2 label1 x1 y1 x2 y2 label2 | Labels: xmin ymin xmax ymax label xmin, ymin - top left corner of bounding box xmax, ymax - bottom right corner of bounding box Args: root (str): Path to root_dir img_dir (str): Name of image dir anno_file (str): Name of Labels files containing annotations in monk format batch_size (int): Mini batch sampling size for training epochs num_workers (int): Number of parallel processors for data loader Returns: None ''' self.system_dict["root"] = root; self.system_dict["img_dir"] = img_dir; self.system_dict["anno_file"] = anno_file; self.system_dict["batch_size"] = batch_size; self.system_dict["num_workers"] = num_workers; df = pd.read_csv(self.system_dict["root"] + "/" + self.system_dict["anno_file"]); columns = df.columns; classes = []; for i in tqdm(range(len(df))): tmp = df[columns[1]][i].split(" "); for j in range(len(tmp)//5): label = tmp[j*5+4]; if(label not in classes): classes.append(label) self.system_dict["classes"] = sorted(classes) with open('train.lst', 'w') as fw: for i in tqdm(range(len(df))): img_name = df[columns[0]][i]; tmp = df[columns[1]][i].split(" "); class_names = []; bbox = []; ids = []; for j in range(len(tmp)//5): x1 = int(float(tmp[j*5+0])); y1 = int(float(tmp[j*5+1])); x2 = int(float(tmp[j*5+2])); y2 = int(float(tmp[j*5+3])); label = tmp[j*5+4] class_names.append(label); bbox.append([x1, y1, x2, y2]); ids.append(classes.index(label)); if(not os.path.isfile(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name)): continue; img = cv2.imread(self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/" + img_name); all_boxes = np.array(bbox); all_ids = np.array(ids); line = self.write_line(img_name, img.shape, all_boxes, all_ids, i) fw.write(line) cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/im2rec.py " + os.getcwd() + "/"; os.system(cmd1); cmd2 = "python im2rec.py train.lst " + self.system_dict["root"] + "/" + self.system_dict["img_dir"] + "/ --pass-through --pack-label" os.system(cmd2); self.system_dict["local"]["train_dataset"] = gcv.data.RecordFileDetection('train.rec')
def Model(self, model_name, use_pretrained=True, use_gpu=True, gpu_devices=[0])
-
User function: Set Model parameters
Available models ssd_300_vgg16_atrous_coco ssd_300_vgg16_atrous_voc ssd_512_vgg16_atrous_coco ssd_512_vgg16_atrous_voc ssd_512_resnet50_v1_coco ssd_512_resnet50_v1_voc ssd_512_mobilenet1.0_voc ssd_512_mobilenet1.0_coco yolo3_darknet53_voc yolo3_darknet53_coco yolo3_mobilenet1.0_voc yolo3_mobilenet1.0_coco
Args
model_name
:str
- Select from available models
use_pretrained
:bool
- If True use pretrained weights else randomly initialized weights
use_gpu
:bool
- If True use GPU else run on CPU
gpu_devices
:list
- List of GPU device Ids
Returns
None
Expand source code
def Model(self, model_name, use_pretrained=True, use_gpu=True, gpu_devices=[0]): ''' User function: Set Model parameters Available models ssd_300_vgg16_atrous_coco ssd_300_vgg16_atrous_voc ssd_512_vgg16_atrous_coco ssd_512_vgg16_atrous_voc ssd_512_resnet50_v1_coco ssd_512_resnet50_v1_voc ssd_512_mobilenet1.0_voc ssd_512_mobilenet1.0_coco yolo3_darknet53_voc yolo3_darknet53_coco yolo3_mobilenet1.0_voc yolo3_mobilenet1.0_coco Args: model_name (str): Select from available models use_pretrained (bool): If True use pretrained weights else randomly initialized weights use_gpu (bool): If True use GPU else run on CPU gpu_devices (list): List of GPU device Ids Returns: None ''' self.system_dict["model_name"] = model_name; self.system_dict["use_pretrained"] = use_pretrained; if(self.system_dict["model_name"] in self.system_dict["model_set_1"]): self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (300, 300); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] with autograd.train_mode(): _, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width))) batchify_fn = Tuple(Stack(), Stack(), Stack()) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu ,gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"]) elif((self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (512, 512); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] with autograd.train_mode(): _, _, anchors = self.system_dict["local"]["net"](mx.nd.zeros((1, 3, height, width))) batchify_fn = Tuple(Stack(), Stack(), Stack()) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(SSDDefaultTrainTransform(width, height, anchors)), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"]) elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])) : self.system_dict["local"]["net"] = gcv.model_zoo.get_model(self.system_dict["model_name"], pretrained=self.system_dict["use_pretrained"]); self.system_dict["local"]["net"].reset_class(self.system_dict["classes"]) self.system_dict["img_shape"] = (416, 416); width, height = self.system_dict["img_shape"][0], self.system_dict["img_shape"][1] train_transform = YOLO3DefaultTrainTransform(width, height, self.system_dict["local"]["net"]) batchify_fn = Tuple(*([Stack() for _ in range(6)] + [Pad(axis=0, pad_val=-1) for _ in range(1)])) self.system_dict["local"]["train_loader"] = gluon.data.DataLoader( self.system_dict["local"]["train_dataset"].transform(train_transform), self.system_dict["batch_size"], True, batchify_fn=batchify_fn, last_batch='rollover', num_workers=self.system_dict["num_workers"]) self.set_device(use_gpu=use_gpu, gpu_devices=gpu_devices); self.system_dict["local"]["net"].collect_params().reset_ctx(self.system_dict["local"]["ctx"])
def Set_Learning_Rate(self, lr)
-
User function: Set initial learning rate
Args
lr
:float
- Base learning rate
Returns
None
Expand source code
def Set_Learning_Rate(self, lr): ''' User function: Set initial learning rate Args: lr (float): Base learning rate Returns: None ''' self.system_dict["local"]["trainer"] = gluon.Trainer( self.system_dict["local"]["net"].collect_params(), 'sgd', {'learning_rate': lr, 'wd': 0.0005, 'momentum': 0.9}) if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): self.system_dict["local"]["mbox_loss"] = gcv.loss.SSDMultiBoxLoss() self.system_dict["local"]["ce_metric"] = mx.metric.Loss('CrossEntropy') self.system_dict["local"]["smoothl1_metric"] = mx.metric.Loss('SmoothL1'); elif((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])): self.system_dict["local"]["loss"] = gcv.loss.YOLOV3Loss() self.system_dict["local"]["obj_metrics"] = mx.metric.Loss('ObjLoss') self.system_dict["local"]["center_metrics"] = mx.metric.Loss('BoxCenterLoss') self.system_dict["local"]["scale_metrics"] = mx.metric.Loss('BoxScaleLoss') self.system_dict["local"]["cls_metrics"] = mx.metric.Loss('ClassLoss')
def Train(self, epochs, params_file)
-
User function: Start training
Args
epochs
:int
- Number of epochs to train for
params_file
:str
- Trained weights file name with extension as ".params"
Returns
None
Expand source code
def Train(self, epochs, params_file): ''' User function: Start training Args: epochs (int): Number of epochs to train for params_file (str): Trained weights file name with extension as ".params" Returns: None ''' self.system_dict["num_epochs"] = epochs; self.system_dict["params_file"] = params_file; self.system_dict["training_metrics"] = []; self.system_dict["training_time"] = 0.0; if((self.system_dict["model_name"] in self.system_dict["model_set_1"]) or (self.system_dict["model_name"] in self.system_dict["model_set_2"]) or (self.system_dict["model_name"] in self.system_dict["model_set_3"]) or (self.system_dict["model_name"] in self.system_dict["model_set_4"])): for epoch in range(self.system_dict["num_epochs"]): self.system_dict["local"]["ce_metric"].reset() self.system_dict["local"]["smoothl1_metric"].reset() tic = time.time() btic = time.time() self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True) for i, batch in enumerate(self.system_dict["local"]["train_loader"]): batch_size = batch[0].shape[0] data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) cls_targets = gluon.utils.split_and_load(batch[1], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) box_targets = gluon.utils.split_and_load(batch[2], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) with autograd.record(): cls_preds = [] box_preds = [] for x in data: cls_pred, box_pred, _ = self.system_dict["local"]["net"](x) cls_preds.append(cls_pred) box_preds.append(box_pred) sum_loss, cls_loss, box_loss = self.system_dict["local"]["mbox_loss"]( cls_preds, box_preds, cls_targets, box_targets) autograd.backward(sum_loss) # since we have already normalized the loss, we don't want to normalize # by batch-size anymore self.system_dict["local"]["trainer"].step(batch_size) self.system_dict["local"]["ce_metric"].update(0, [l * batch_size for l in cls_loss]) self.system_dict["local"]["smoothl1_metric"].update(0, [l * batch_size for l in box_loss]) name1, loss1 = self.system_dict["local"]["ce_metric"].get() name2, loss2 = self.system_dict["local"]["smoothl1_metric"].get() if i % 20 == 0: print('[Epoch {}][Batch {}], Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}'.format( epoch, i, batch_size/(time.time()-btic), name1, loss1, name2, loss2)) tmp = {}; tmp["epoch"] = epoch; tmp["batch"] = batch; tmp["name1"] = loss1; tmp["name2"] = loss2; self.system_dict["training_metrics"].append(tmp); btic = time.time() self.system_dict["training_time"] += time.time() - tic; self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"]) if((self.system_dict["model_name"] in self.system_dict["model_set_5"]) or (self.system_dict["model_name"] in self.system_dict["model_set_6"])): for epoch in range(self.system_dict["num_epochs"]): tic = time.time() btic = time.time() self.system_dict["local"]["net"].hybridize(static_alloc=True, static_shape=True) self.system_dict["local"]["obj_metrics"].reset() self.system_dict["local"]["center_metrics"].reset() self.system_dict["local"]["scale_metrics"].reset() self.system_dict["local"]["cls_metrics"].reset() for i, batch in enumerate(self.system_dict["local"]["train_loader"]): batch_size = batch[0].shape[0] data = gluon.utils.split_and_load(batch[0], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) # objectness, center_targets, scale_targets, weights, class_targets fixed_targets = [gluon.utils.split_and_load(batch[it], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) for it in range(1, 6)] gt_boxes = gluon.utils.split_and_load(batch[6], ctx_list=self.system_dict["local"]["ctx"], batch_axis=0) sum_losses = [] obj_losses = [] center_losses = [] scale_losses = [] cls_losses = [] with autograd.record(): for ix, x in enumerate(data): obj_loss, center_loss, scale_loss, cls_loss = self.system_dict["local"]["net"](x, gt_boxes[ix], *[ft[ix] for ft in fixed_targets]) sum_losses.append(obj_loss + center_loss + scale_loss + cls_loss) obj_losses.append(obj_loss) center_losses.append(center_loss) scale_losses.append(scale_loss) cls_losses.append(cls_loss) autograd.backward(sum_losses) self.system_dict["local"]["trainer"].step(batch_size) self.system_dict["local"]["obj_metrics"].update(0, obj_losses) self.system_dict["local"]["center_metrics"].update(0, center_losses) self.system_dict["local"]["scale_metrics"].update(0, scale_losses) self.system_dict["local"]["cls_metrics"].update(0, cls_losses) if i % 20 == 0: name1, loss1 = self.system_dict["local"]["obj_metrics"].get() name2, loss2 = self.system_dict["local"]["center_metrics"].get() name3, loss3 = self.system_dict["local"]["scale_metrics"].get() name4, loss4 = self.system_dict["local"]["cls_metrics"].get() tmp = {}; tmp["epoch"] = epoch; tmp["batch"] = batch; tmp["name1"] = loss1; tmp["name2"] = loss2; tmp["name3"] = loss3; tmp["name4"] = loss4; self.system_dict["training_metrics"].append(tmp); print('[Epoch {}][Batch {}], LR: {:.2E}, Speed: {:.3f} samples/sec, {}={:.3f}, {}={:.3f}, {}={:.3f}, {}={:.3f}'.format( epoch, i, self.system_dict["local"]["trainer"].learning_rate, batch_size/(time.time()-btic), name1, loss1, name2, loss2, name3, loss3, name4, loss4)) btic = time.time() self.system_dict["training_time"] += time.time() - tic; self.system_dict["local"]["net"].save_parameters(self.system_dict["params_file"])
def set_device(self, use_gpu=True, gpu_devices=[0])
-
Internal function: Prepares GPU and CPU devices as per the model parameters set
Args
use_gpu
:bool
- If True use GPU else run on CPU
gpu_devices
:list
- List of GPU device Ids
Returns
None
Expand source code
def set_device(self, use_gpu=True ,gpu_devices=[0]): ''' Internal function: Prepares GPU and CPU devices as per the model parameters set Args: use_gpu (bool): If True use GPU else run on CPU gpu_devices (list): List of GPU device Ids Returns: None ''' self.system_dict["use_gpu"] = use_gpu; if self.system_dict["use_gpu"]: self.system_dict["gpu_devices"] = gpu_devices; self.system_dict["local"]["ctx"]= [mx.gpu(int(i)) for i in self.system_dict["gpu_devices"]] else: self.system_dict["local"]["ctx"] = [mx.cpu()]
def write_line(self, img_path, im_shape, boxes, ids, idx)
-
Internal function: Convert labels to required gluoncv format
Args
img_path
:str
- Relative path to image
im_shape
:tuple
- Image shape in order - height, width, channel
boxes
:list
- List of object bounding boxes in the image
ids
:list
- List of label ids for object bounding boxes
idx
:idx
- Unique image index
Returns
str
- A String containing image index, headers, labels, and image path
Expand source code
def write_line(self, img_path, im_shape, boxes, ids, idx): ''' Internal function: Convert labels to required gluoncv format Args: img_path (str): Relative path to image im_shape (tuple): Image shape in order - height, width, channel boxes (list): List of object bounding boxes in the image ids (list): List of label ids for object bounding boxes idx (idx): Unique image index Returns: str: A String containing image index, headers, labels, and image path ''' h, w, c = im_shape # for header, we use minimal length 2, plus width and height # with A: 4, B: 5, C: width, D: height A = 4 B = 5 C = w D = h # concat id and bboxes labels = np.hstack((ids.reshape(-1, 1), boxes)).astype('float') # normalized bboxes (recommanded) labels[:, (1, 3)] /= float(w) labels[:, (2, 4)] /= float(h) # flatten labels = labels.flatten().tolist() str_idx = [str(idx)] str_header = [str(x) for x in [A, B, C, D]] str_labels = [str(x) for x in labels] str_path = [img_path] line = '\t'.join(str_idx + str_header + str_labels + str_path) + '\n' return line