Module 3_mxrcnn.lib.train_base
Expand source code
import os
import sys
sys.path.append("mx-rcnn");
import ast
import pprint
os.environ['MXNET_CUDNN_AUTOTUNE_DEFAULT'] = "0";
import mxnet as mx
from mxnet.module import Module
from symdata.loader import AnchorGenerator, AnchorSampler, AnchorLoader
from symnet.logger import logger
from symnet.model import load_param, infer_data_shape, check_shape, initialize_frcnn, get_fixed_params
from symnet.metric import RPNAccMetric, RPNLogLossMetric, RPNL1LossMetric, RCNNAccMetric, RCNNLogLossMetric, RCNNL1LossMetric
system_dict = {};
#######################################################################################################################################
def set_dataset_params(root_dir="data", coco_dir="coco", imageset="traincustom"):
'''
User function: Set dataset parameters
Dataset Directory Structure
root_dir_name
|
|------coco_dir_name
| |
| |---imageset
| |----|
| |-------------------img1.jpg
| |-------------------img2.jpg
| |-------------------.........(and so on)
|
|
| |---anno_dir_name
| |----|
| |--------------------instances_<imageset>.json
| |--------------------classes.txt
- instances_<imageset>.json -> In proper COCO format
- classes.txt -> A list of classes in alphabetical order
Args:
root_dir (str): Path to root directory containing coco_dir
coco_dir (str): Name of coco_dir containing image folder and annotation folder
imageset (str): Name of folder containing all training images
Returns:
None
'''
system_dict["dataset_root"] = root_dir;
system_dict["dataset"] = coco_dir;
system_dict["dataset_dir"] = root_dir + "/" + coco_dir;
system_dict["imageset"] = imageset;
system_dict["rcnn_num_classes"] = 1;
def set_img_preproc_params(img_short_side=600, img_long_side=1000, mean=(123.68, 116.779, 103.939), std=(1.0, 1.0, 1.0)):
'''
User function: Set image preprocessing parameters
Args:
img_short_side (int): Minimum image size for rescaling
img_long_side (int): Maximum image size for rescaling
mean (tuple): 3-Channel mean for subtraction in preprocessing
std (tuple): 3-Channel standard deviation for normalizing in preprocessing
Returns:
None
'''
system_dict["img_short_side"] = img_short_side;
system_dict["img_long_side"] = img_long_side;
system_dict["img_pixel_means"] = str(mean);
system_dict["img_pixel_stds"] = str(std);
system_dict["img_pixel_means"] = ast.literal_eval(system_dict["img_pixel_means"])
system_dict["img_pixel_stds"] = ast.literal_eval(system_dict["img_pixel_stds"])
#network options - vgg16, renet50, resnet101
def set_model_params(model_name="vgg16", resume=False, start_epoch=0):
'''
User function: Set model parameters
Available models
vgg16
resnet50
resnet101
Args:
model_name (str): Select from available models
resume (bool): If True resume training from start_epoch
start_epoch (int): Set resume epoch
Returns:
None
'''
system_dict["network"] = model_name;
if(model_name == "vgg16"):
system_dict["pretrained"] = "pretrained/vgg16-0000.params";
if(not os.path.isdir("pretrained")):
os.mkdir("pretrained");
system_dict["resume"] = resume;
if(not system_dict["resume"] ):
if(not os.path.isfile( system_dict["pretrained"])):
cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_vgg.sh " + os.getcwd() + "/.";
os.system(cmd1);
os.system("chmod +x download_vgg.sh");
os.system("./download_vgg.sh");
system_dict["start_epoch"] = 0;
else:
system_dict["start_epoch"] = start_epoch;
system_dict["net_fixed_params"] = '["conv1", "conv2", "conv3", "conv4"]';
system_dict["rcnn_feat_stride"] = 16;
system_dict["rcnn_pooled_size"] = '(7, 7)';
elif(model_name == "resnet50"):
system_dict["pretrained"] = "pretrained/resnet-50-0000.params";
if(not os.path.isdir("pretrained")):
os.mkdir("pretrained");
system_dict["resume"] = resume;
if(not system_dict["resume"]):
if(not os.path.isfile( system_dict["pretrained"])):
cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_resnet50.sh " + os.getcwd() + "/.";
os.system(cmd1);
os.system("chmod +x download_resnet50.sh");
os.system("./download_resnet50.sh");
system_dict["start_epoch"] = 0;
else:
system_dict["start_epoch"] = start_epoch;
system_dict["net_fixed_params"] = '["conv0", "stage1", "gamma", "beta"]';
system_dict["rcnn_feat_stride"] = 16;
system_dict["rcnn_pooled_size"] = '(14, 14)';
elif(model_name == "resnet101"):
system_dict["pretrained"] = "pretrained/resnet-101-0000.params";
if(not os.path.isdir("pretrained")):
os.mkdir("pretrained");
system_dict["resume"] = resume;
if(not system_dict["resume"]):
if(not os.path.isfile( system_dict["pretrained"])):
cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_resnet101.sh " + os.getcwd() + "/.";
os.system(cmd1);
os.system("chmod +x download_resnet101.sh");
os.system("./download_resnet101.sh");
system_dict["start_epoch"] = 0;
else:
system_dict["start_epoch"] = start_epoch;
system_dict["net_fixed_params"] = '["conv0", "stage1", "gamma", "beta"]';
system_dict["rcnn_feat_stride"] = 16;
system_dict["rcnn_pooled_size"] = '(14, 14)';
system_dict["net_fixed_params"] = ast.literal_eval(system_dict["net_fixed_params"])
def set_hyper_params(gpus=[0], lr=0.001, lr_decay_epoch="7", epochs=10, batch_size=1):
'''
User function: Set hyper parameters
Args:
gpus (list): List of gpu device IDs to train on
lr (float): Initial learning rate for training
lr_decay_epoch (str): Reduce learning rate at these epochs. epochs provided by a comma in string, eg. "7, 10, 15"
epochs (int): No of epochs to train the detector
batch_size (int): Data loader mini batch size for every epoch
Returns:
None
'''
if gpus == '0':
system_dict["gpus"] = list(gpus)
else :
system_dict["gpus"] = gpus;
system_dict["lr"] = lr;
system_dict["lr_decay_epoch"] = lr_decay_epoch;
system_dict["epochs"] = epochs;
system_dict["rcnn_batch_size"] = batch_size;
def set_output_params(log_interval=100, save_prefix="model_vgg16"):
'''
User function: Set output parameters
Args:
log_interval (int): Log-prints training status after every specified interval of iterations inside an epoch
save_prefix (str): Common prefix to be attached to intermediate models
Returns:
None
'''
system_dict["log_interval"] = log_interval;
if(not os.path.isdir("trained_model")):
os.mkdir("trained_model");
system_dict["save_prefix"] = "trained_model/" + save_prefix;
#######################################################################################################################################
#######################################################################################################################################
def initialize_rpn_params():
'''
User function: Initialize all RPN parameters
Args:
None
Returns:
None
'''
system_dict["rpn_feat_stride"] = 16;
system_dict["rpn_anchor_scales"] = '(8, 16, 32)';
system_dict["rpn_anchor_ratios"] = '(0.5, 1, 2)';
system_dict["rpn_pre_nms_topk"] = 12000;
system_dict["rpn_post_nms_topk"] = 2000;
system_dict["rpn_nms_thresh"] = 0.7;
system_dict["rpn_min_size"] = 16;
system_dict["rpn_batch_rois"] = 256;
system_dict["rpn_allowed_border"] = 0;
system_dict["rpn_fg_fraction"] = 0.5;
system_dict["rpn_fg_overlap"] = 0.7;
system_dict["rpn_bg_overlap"] = 0.3;
system_dict["rpn_anchor_scales"] = ast.literal_eval(system_dict["rpn_anchor_scales"])
system_dict["rpn_anchor_ratios"] = ast.literal_eval(system_dict["rpn_anchor_ratios"])
def initialize_rcnn_params():
'''
User function: Initialize all RCNN parameters
Args:
None
Returns:
None
'''
system_dict["rcnn_batch_rois"] = 128;
system_dict["rcnn_fg_fraction"] = 0.25;
system_dict["rcnn_fg_overlap"] = 0.5;
system_dict["rcnn_bbox_stds"] = '(0.1, 0.1, 0.2, 0.2)';
system_dict["rcnn_pooled_size"] = ast.literal_eval(system_dict["rcnn_pooled_size"])
system_dict["rcnn_bbox_stds"] = ast.literal_eval(system_dict["rcnn_bbox_stds"])
#######################################################################################################################################
#######################################################################################################################################
def get_coco(system_dict):
'''
Internal function: Get coco dataset as per dataset params
Args:
system_dict (dict): Dictionary of all the parameters selected for training
Returns:
list: List of all the images and labels in coco-db format
'''
from symimdb.coco import coco
if not system_dict["imageset"]:
system_dict["imageset"] = 'train2017'
isets = system_dict["imageset"].split('+')
roidb = []
for iset in isets:
imdb = coco(iset, system_dict["dataset_root"], system_dict["dataset_dir"])
system_dict["rcnn_num_classes"] = len(imdb.classes)
imdb.filter_roidb()
imdb.append_flipped_images()
roidb.extend(imdb.roidb)
return roidb
def set_dataset():
'''
User function: Set dataloader
Args:
None
Returns:
list: List of all the images and labels in coco-db format
'''
dataset = system_dict["dataset"];
datasets = {
dataset: get_coco
}
if dataset not in datasets:
raise ValueError("dataset {} not supported".format(dataset))
return datasets[dataset](system_dict)
#######################################################################################################################################
#######################################################################################################################################
def get_resnet101_train(system_dict):
'''
Internal function: Select resnet101 params
Args:
system_dict (dict): Dictionary of all the parameters selected for training
Returns:
mxnet model: Resnet101 model
'''
from symnet.symbol_resnet import get_resnet_train
return get_resnet_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"],
rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"],
rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"],
rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"],
num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"],
rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"],
rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"],
rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"],
units=(3, 4, 23, 3), filter_list=(256, 512, 1024, 2048))
def get_resnet50_train(system_dict):
'''
Internal function: Select resnet50 params
Args:
system_dict (dict): Dictionary of all the parameters selected for training
Returns:
mxnet model: Resnet50 model
'''
from symnet.symbol_resnet import get_resnet_train
return get_resnet_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"],
rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"],
rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"],
rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"],
num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"],
rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"],
rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"],
rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"],
units=(3, 4, 6, 3), filter_list=(256, 512, 1024, 2048))
def get_vgg16_train(system_dict):
'''
Internal function: Select vgg16 params
Args:
system_dict (dict): Dictionary of all the parameters selected for training
Returns:
mxnet model: Vgg16 model
'''
from symnet.symbol_vgg import get_vgg_train
return get_vgg_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"],
rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"],
rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"],
rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"],
num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"],
rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"],
rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"],
rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"])
def set_network():
'''
User function: Set the train model
Args:
None
Returns:
mxnet model: Model as per selected params
'''
network = system_dict["network"]
networks = {
'vgg16': get_vgg16_train,
'resnet50': get_resnet50_train,
'resnet101': get_resnet101_train
}
if network not in networks:
raise ValueError("network {} not supported".format(network))
return networks[network](system_dict)
#######################################################################################################################################
#######################################################################################################################################
def train(sym, roidb):
'''
User function: Start training
Args:
sym (mxnet model): Mxnet model returned from set_network() function
roidb (dataloader): Dataloader returned from set_model() function
Returns:
None
'''
# print config
#logger.info('called with system_dict\n{}'.format(pprint.pformat(vars(system_dict))))
#print(system_dict)
# setup multi-gpu
if(len(system_dict["gpus"]) == 0):
ctx = [mx.cpu(0)];
else:
ctx = [mx.gpu(int(i)) for i in system_dict["gpus"]]
batch_size = system_dict["rcnn_batch_size"] * len(ctx)
# load training data
feat_sym = sym.get_internals()['rpn_cls_score_output']
ag = AnchorGenerator(feat_stride=system_dict["rpn_feat_stride"],
anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"])
asp = AnchorSampler(allowed_border=system_dict["rpn_allowed_border"], batch_rois=system_dict["rpn_batch_rois"],
fg_fraction=system_dict["rpn_fg_fraction"], fg_overlap=system_dict["rpn_fg_overlap"],
bg_overlap=system_dict["rpn_bg_overlap"])
train_data = AnchorLoader(roidb, batch_size, system_dict["img_short_side"], system_dict["img_long_side"],
system_dict["img_pixel_means"], system_dict["img_pixel_stds"], feat_sym, ag, asp, shuffle=True)
# produce shape max possible
_, out_shape, _ = feat_sym.infer_shape(data=(1, 3, system_dict["img_long_side"], system_dict["img_long_side"]))
feat_height, feat_width = out_shape[0][-2:]
rpn_num_anchors = len(system_dict["rpn_anchor_scales"]) * len(system_dict["rpn_anchor_ratios"])
data_names = ['data', 'im_info', 'gt_boxes']
label_names = ['label', 'bbox_target', 'bbox_weight']
data_shapes = [('data', (batch_size, 3, system_dict["img_long_side"], system_dict["img_long_side"])),
('im_info', (batch_size, 3)),
('gt_boxes', (batch_size, 100, 5))]
label_shapes = [('label', (batch_size, 1, rpn_num_anchors * feat_height, feat_width)),
('bbox_target', (batch_size, 4 * rpn_num_anchors, feat_height, feat_width)),
('bbox_weight', (batch_size, 4 * rpn_num_anchors, feat_height, feat_width))]
# print shapes
data_shape_dict, out_shape_dict = infer_data_shape(sym, data_shapes + label_shapes)
logger.info('max input shape\n%s' % pprint.pformat(data_shape_dict))
logger.info('max output shape\n%s' % pprint.pformat(out_shape_dict))
# load and initialize params
if system_dict["resume"]:
arg_params, aux_params = load_param(system_dict["resume"])
else:
arg_params, aux_params = load_param(system_dict["pretrained"])
arg_params, aux_params = initialize_frcnn(sym, data_shapes, arg_params, aux_params)
# check parameter shapes
check_shape(sym, data_shapes + label_shapes, arg_params, aux_params)
# check fixed params
fixed_param_names = get_fixed_params(sym, system_dict["net_fixed_params"])
logger.info('locking params\n%s' % pprint.pformat(fixed_param_names))
# metric
rpn_eval_metric = RPNAccMetric()
rpn_cls_metric = RPNLogLossMetric()
rpn_bbox_metric = RPNL1LossMetric()
eval_metric = RCNNAccMetric()
cls_metric = RCNNLogLossMetric()
bbox_metric = RCNNL1LossMetric()
eval_metrics = mx.metric.CompositeEvalMetric()
for child_metric in [rpn_eval_metric, rpn_cls_metric, rpn_bbox_metric, eval_metric, cls_metric, bbox_metric]:
eval_metrics.add(child_metric)
# callback
batch_end_callback = mx.callback.Speedometer(batch_size, frequent=system_dict["log_interval"], auto_reset=False)
epoch_end_callback = mx.callback.do_checkpoint(system_dict["save_prefix"])
# learning schedule
base_lr = system_dict["lr"]
lr_factor = 0.1
lr_epoch = [int(epoch) for epoch in system_dict["lr_decay_epoch"].split(',')]
lr_epoch_diff = [epoch - system_dict["start_epoch"] for epoch in lr_epoch if epoch > system_dict["start_epoch"]]
lr = base_lr * (lr_factor ** (len(lr_epoch) - len(lr_epoch_diff)))
lr_iters = [int(epoch * len(roidb) / batch_size) for epoch in lr_epoch_diff]
logger.info('lr %f lr_epoch_diff %s lr_iters %s' % (lr, lr_epoch_diff, lr_iters))
lr_scheduler = mx.lr_scheduler.MultiFactorScheduler(lr_iters, lr_factor)
# optimizer
optimizer_params = {'momentum': 0.9,
'wd': 0.0005,
'learning_rate': lr,
'lr_scheduler': lr_scheduler,
'rescale_grad': (1.0 / batch_size),
'clip_gradient': 5}
# train
mod = Module(sym, data_names=data_names, label_names=label_names,
logger=logger, context=ctx, work_load_list=None,
fixed_param_names=fixed_param_names)
mod.fit(train_data, eval_metric=eval_metrics, epoch_end_callback=epoch_end_callback,
batch_end_callback=batch_end_callback, kvstore='device',
optimizer='sgd', optimizer_params=optimizer_params,
arg_params=arg_params, aux_params=aux_params, begin_epoch=system_dict["start_epoch"], num_epoch=system_dict["epochs"])
#######################################################################################################################################
Functions
def get_coco(system_dict)
-
Internal function: Get coco dataset as per dataset params
Args
system_dict
:dict
- Dictionary of all the parameters selected for training
Returns
list
- List of all the images and labels in coco-db format
Expand source code
def get_coco(system_dict): ''' Internal function: Get coco dataset as per dataset params Args: system_dict (dict): Dictionary of all the parameters selected for training Returns: list: List of all the images and labels in coco-db format ''' from symimdb.coco import coco if not system_dict["imageset"]: system_dict["imageset"] = 'train2017' isets = system_dict["imageset"].split('+') roidb = [] for iset in isets: imdb = coco(iset, system_dict["dataset_root"], system_dict["dataset_dir"]) system_dict["rcnn_num_classes"] = len(imdb.classes) imdb.filter_roidb() imdb.append_flipped_images() roidb.extend(imdb.roidb) return roidb
def get_resnet101_train(system_dict)
-
Internal function: Select resnet101 params
Args
system_dict
:dict
- Dictionary of all the parameters selected for training
Returns
mxnet model
- Resnet101 model
Expand source code
def get_resnet101_train(system_dict): ''' Internal function: Select resnet101 params Args: system_dict (dict): Dictionary of all the parameters selected for training Returns: mxnet model: Resnet101 model ''' from symnet.symbol_resnet import get_resnet_train return get_resnet_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"], rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"], rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"], rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"], num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"], rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"], rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"], rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"], units=(3, 4, 23, 3), filter_list=(256, 512, 1024, 2048))
def get_resnet50_train(system_dict)
-
Internal function: Select resnet50 params
Args
system_dict
:dict
- Dictionary of all the parameters selected for training
Returns
mxnet model
- Resnet50 model
Expand source code
def get_resnet50_train(system_dict): ''' Internal function: Select resnet50 params Args: system_dict (dict): Dictionary of all the parameters selected for training Returns: mxnet model: Resnet50 model ''' from symnet.symbol_resnet import get_resnet_train return get_resnet_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"], rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"], rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"], rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"], num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"], rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"], rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"], rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"], units=(3, 4, 6, 3), filter_list=(256, 512, 1024, 2048))
def get_vgg16_train(system_dict)
-
Internal function: Select vgg16 params
Args
system_dict
:dict
- Dictionary of all the parameters selected for training
Returns
mxnet model
- Vgg16 model
Expand source code
def get_vgg16_train(system_dict): ''' Internal function: Select vgg16 params Args: system_dict (dict): Dictionary of all the parameters selected for training Returns: mxnet model: Vgg16 model ''' from symnet.symbol_vgg import get_vgg_train return get_vgg_train(anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"], rpn_feature_stride=system_dict["rpn_feat_stride"], rpn_pre_topk=system_dict["rpn_pre_nms_topk"], rpn_post_topk=system_dict["rpn_post_nms_topk"], rpn_nms_thresh=system_dict["rpn_nms_thresh"], rpn_min_size=system_dict["rpn_min_size"], rpn_batch_rois=system_dict["rpn_batch_rois"], num_classes=system_dict["rcnn_num_classes"], rcnn_feature_stride=system_dict["rcnn_feat_stride"], rcnn_pooled_size=system_dict["rcnn_pooled_size"], rcnn_batch_size=system_dict["rcnn_batch_size"], rcnn_batch_rois=system_dict["rcnn_batch_rois"], rcnn_fg_fraction=system_dict["rcnn_fg_fraction"], rcnn_fg_overlap=system_dict["rcnn_fg_overlap"], rcnn_bbox_stds=system_dict["rcnn_bbox_stds"])
def initialize_rcnn_params()
-
User function: Initialize all RCNN parameters
Args
None
Returns
None
Expand source code
def initialize_rcnn_params(): ''' User function: Initialize all RCNN parameters Args: None Returns: None ''' system_dict["rcnn_batch_rois"] = 128; system_dict["rcnn_fg_fraction"] = 0.25; system_dict["rcnn_fg_overlap"] = 0.5; system_dict["rcnn_bbox_stds"] = '(0.1, 0.1, 0.2, 0.2)'; system_dict["rcnn_pooled_size"] = ast.literal_eval(system_dict["rcnn_pooled_size"]) system_dict["rcnn_bbox_stds"] = ast.literal_eval(system_dict["rcnn_bbox_stds"])
def initialize_rpn_params()
-
User function: Initialize all RPN parameters
Args
None
Returns
None
Expand source code
def initialize_rpn_params(): ''' User function: Initialize all RPN parameters Args: None Returns: None ''' system_dict["rpn_feat_stride"] = 16; system_dict["rpn_anchor_scales"] = '(8, 16, 32)'; system_dict["rpn_anchor_ratios"] = '(0.5, 1, 2)'; system_dict["rpn_pre_nms_topk"] = 12000; system_dict["rpn_post_nms_topk"] = 2000; system_dict["rpn_nms_thresh"] = 0.7; system_dict["rpn_min_size"] = 16; system_dict["rpn_batch_rois"] = 256; system_dict["rpn_allowed_border"] = 0; system_dict["rpn_fg_fraction"] = 0.5; system_dict["rpn_fg_overlap"] = 0.7; system_dict["rpn_bg_overlap"] = 0.3; system_dict["rpn_anchor_scales"] = ast.literal_eval(system_dict["rpn_anchor_scales"]) system_dict["rpn_anchor_ratios"] = ast.literal_eval(system_dict["rpn_anchor_ratios"])
def set_dataset()
-
User function: Set dataloader
Args
None
Returns
list
- List of all the images and labels in coco-db format
Expand source code
def set_dataset(): ''' User function: Set dataloader Args: None Returns: list: List of all the images and labels in coco-db format ''' dataset = system_dict["dataset"]; datasets = { dataset: get_coco } if dataset not in datasets: raise ValueError("dataset {} not supported".format(dataset)) return datasets[dataset](system_dict)
def set_dataset_params(root_dir='data', coco_dir='coco', imageset='traincustom')
-
User function: Set dataset parameters
Dataset Directory Structure
root_dir_name | |------coco_dir_name | | | |---imageset | |----| | |-------------------img1.jpg | |-------------------img2.jpg | |-------------------.........(and so on) | | | |---anno_dir_name | |----| | |--------------------instances_<imageset>.json | |--------------------classes.txt - instances_<imageset>.json -> In proper COCO format - classes.txt -> A list of classes in alphabetical order
Args
root_dir
:str
- Path to root directory containing coco_dir
coco_dir
:str
- Name of coco_dir containing image folder and annotation folder
imageset
:str
- Name of folder containing all training images
Returns
None
Expand source code
def set_dataset_params(root_dir="data", coco_dir="coco", imageset="traincustom"): ''' User function: Set dataset parameters Dataset Directory Structure root_dir_name | |------coco_dir_name | | | |---imageset | |----| | |-------------------img1.jpg | |-------------------img2.jpg | |-------------------.........(and so on) | | | |---anno_dir_name | |----| | |--------------------instances_<imageset>.json | |--------------------classes.txt - instances_<imageset>.json -> In proper COCO format - classes.txt -> A list of classes in alphabetical order Args: root_dir (str): Path to root directory containing coco_dir coco_dir (str): Name of coco_dir containing image folder and annotation folder imageset (str): Name of folder containing all training images Returns: None ''' system_dict["dataset_root"] = root_dir; system_dict["dataset"] = coco_dir; system_dict["dataset_dir"] = root_dir + "/" + coco_dir; system_dict["imageset"] = imageset; system_dict["rcnn_num_classes"] = 1;
def set_hyper_params(gpus=[0], lr=0.001, lr_decay_epoch='7', epochs=10, batch_size=1)
-
User function: Set hyper parameters
Args
gpus
:list
- List of gpu device IDs to train on
lr
:float
- Initial learning rate for training
lr_decay_epoch
:str
- Reduce learning rate at these epochs. epochs provided by a comma in string, eg. "7, 10, 15"
epochs
:int
- No of epochs to train the detector
batch_size
:int
- Data loader mini batch size for every epoch
Returns
None
Expand source code
def set_hyper_params(gpus=[0], lr=0.001, lr_decay_epoch="7", epochs=10, batch_size=1): ''' User function: Set hyper parameters Args: gpus (list): List of gpu device IDs to train on lr (float): Initial learning rate for training lr_decay_epoch (str): Reduce learning rate at these epochs. epochs provided by a comma in string, eg. "7, 10, 15" epochs (int): No of epochs to train the detector batch_size (int): Data loader mini batch size for every epoch Returns: None ''' if gpus == '0': system_dict["gpus"] = list(gpus) else : system_dict["gpus"] = gpus; system_dict["lr"] = lr; system_dict["lr_decay_epoch"] = lr_decay_epoch; system_dict["epochs"] = epochs; system_dict["rcnn_batch_size"] = batch_size;
def set_img_preproc_params(img_short_side=600, img_long_side=1000, mean=(123.68, 116.779, 103.939), std=(1.0, 1.0, 1.0))
-
User function: Set image preprocessing parameters
Args
img_short_side
:int
- Minimum image size for rescaling
img_long_side
:int
- Maximum image size for rescaling
mean
:tuple
- 3-Channel mean for subtraction in preprocessing
std
:tuple
- 3-Channel standard deviation for normalizing in preprocessing
Returns
None
Expand source code
def set_img_preproc_params(img_short_side=600, img_long_side=1000, mean=(123.68, 116.779, 103.939), std=(1.0, 1.0, 1.0)): ''' User function: Set image preprocessing parameters Args: img_short_side (int): Minimum image size for rescaling img_long_side (int): Maximum image size for rescaling mean (tuple): 3-Channel mean for subtraction in preprocessing std (tuple): 3-Channel standard deviation for normalizing in preprocessing Returns: None ''' system_dict["img_short_side"] = img_short_side; system_dict["img_long_side"] = img_long_side; system_dict["img_pixel_means"] = str(mean); system_dict["img_pixel_stds"] = str(std); system_dict["img_pixel_means"] = ast.literal_eval(system_dict["img_pixel_means"]) system_dict["img_pixel_stds"] = ast.literal_eval(system_dict["img_pixel_stds"])
def set_model_params(model_name='vgg16', resume=False, start_epoch=0)
-
User function: Set model parameters
Available models vgg16 resnet50 resnet101
Args
model_name
:str
- Select from available models
resume
:bool
- If True resume training from start_epoch
start_epoch
:int
- Set resume epoch
Returns
None
Expand source code
def set_model_params(model_name="vgg16", resume=False, start_epoch=0): ''' User function: Set model parameters Available models vgg16 resnet50 resnet101 Args: model_name (str): Select from available models resume (bool): If True resume training from start_epoch start_epoch (int): Set resume epoch Returns: None ''' system_dict["network"] = model_name; if(model_name == "vgg16"): system_dict["pretrained"] = "pretrained/vgg16-0000.params"; if(not os.path.isdir("pretrained")): os.mkdir("pretrained"); system_dict["resume"] = resume; if(not system_dict["resume"] ): if(not os.path.isfile( system_dict["pretrained"])): cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_vgg.sh " + os.getcwd() + "/."; os.system(cmd1); os.system("chmod +x download_vgg.sh"); os.system("./download_vgg.sh"); system_dict["start_epoch"] = 0; else: system_dict["start_epoch"] = start_epoch; system_dict["net_fixed_params"] = '["conv1", "conv2", "conv3", "conv4"]'; system_dict["rcnn_feat_stride"] = 16; system_dict["rcnn_pooled_size"] = '(7, 7)'; elif(model_name == "resnet50"): system_dict["pretrained"] = "pretrained/resnet-50-0000.params"; if(not os.path.isdir("pretrained")): os.mkdir("pretrained"); system_dict["resume"] = resume; if(not system_dict["resume"]): if(not os.path.isfile( system_dict["pretrained"])): cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_resnet50.sh " + os.getcwd() + "/."; os.system(cmd1); os.system("chmod +x download_resnet50.sh"); os.system("./download_resnet50.sh"); system_dict["start_epoch"] = 0; else: system_dict["start_epoch"] = start_epoch; system_dict["net_fixed_params"] = '["conv0", "stage1", "gamma", "beta"]'; system_dict["rcnn_feat_stride"] = 16; system_dict["rcnn_pooled_size"] = '(14, 14)'; elif(model_name == "resnet101"): system_dict["pretrained"] = "pretrained/resnet-101-0000.params"; if(not os.path.isdir("pretrained")): os.mkdir("pretrained"); system_dict["resume"] = resume; if(not system_dict["resume"]): if(not os.path.isfile( system_dict["pretrained"])): cmd1 = "cp " + os.path.dirname(os.path.realpath(__file__)) + "/download_resnet101.sh " + os.getcwd() + "/."; os.system(cmd1); os.system("chmod +x download_resnet101.sh"); os.system("./download_resnet101.sh"); system_dict["start_epoch"] = 0; else: system_dict["start_epoch"] = start_epoch; system_dict["net_fixed_params"] = '["conv0", "stage1", "gamma", "beta"]'; system_dict["rcnn_feat_stride"] = 16; system_dict["rcnn_pooled_size"] = '(14, 14)'; system_dict["net_fixed_params"] = ast.literal_eval(system_dict["net_fixed_params"])
def set_network()
-
User function: Set the train model
Args
None
Returns
mxnet model
- Model as per selected params
Expand source code
def set_network(): ''' User function: Set the train model Args: None Returns: mxnet model: Model as per selected params ''' network = system_dict["network"] networks = { 'vgg16': get_vgg16_train, 'resnet50': get_resnet50_train, 'resnet101': get_resnet101_train } if network not in networks: raise ValueError("network {} not supported".format(network)) return networks[network](system_dict)
def set_output_params(log_interval=100, save_prefix='model_vgg16')
-
User function: Set output parameters
Args
log_interval
:int
- Log-prints training status after every specified interval of iterations inside an epoch
save_prefix
:str
- Common prefix to be attached to intermediate models
Returns
None
Expand source code
def set_output_params(log_interval=100, save_prefix="model_vgg16"): ''' User function: Set output parameters Args: log_interval (int): Log-prints training status after every specified interval of iterations inside an epoch save_prefix (str): Common prefix to be attached to intermediate models Returns: None ''' system_dict["log_interval"] = log_interval; if(not os.path.isdir("trained_model")): os.mkdir("trained_model"); system_dict["save_prefix"] = "trained_model/" + save_prefix;
def train(sym, roidb)
-
User function: Start training
Args
sym
:mxnet model
- Mxnet model returned from set_network() function
roidb
:dataloader
- Dataloader returned from set_model() function
Returns
None
Expand source code
def train(sym, roidb): ''' User function: Start training Args: sym (mxnet model): Mxnet model returned from set_network() function roidb (dataloader): Dataloader returned from set_model() function Returns: None ''' # print config #logger.info('called with system_dict\n{}'.format(pprint.pformat(vars(system_dict)))) #print(system_dict) # setup multi-gpu if(len(system_dict["gpus"]) == 0): ctx = [mx.cpu(0)]; else: ctx = [mx.gpu(int(i)) for i in system_dict["gpus"]] batch_size = system_dict["rcnn_batch_size"] * len(ctx) # load training data feat_sym = sym.get_internals()['rpn_cls_score_output'] ag = AnchorGenerator(feat_stride=system_dict["rpn_feat_stride"], anchor_scales=system_dict["rpn_anchor_scales"], anchor_ratios=system_dict["rpn_anchor_ratios"]) asp = AnchorSampler(allowed_border=system_dict["rpn_allowed_border"], batch_rois=system_dict["rpn_batch_rois"], fg_fraction=system_dict["rpn_fg_fraction"], fg_overlap=system_dict["rpn_fg_overlap"], bg_overlap=system_dict["rpn_bg_overlap"]) train_data = AnchorLoader(roidb, batch_size, system_dict["img_short_side"], system_dict["img_long_side"], system_dict["img_pixel_means"], system_dict["img_pixel_stds"], feat_sym, ag, asp, shuffle=True) # produce shape max possible _, out_shape, _ = feat_sym.infer_shape(data=(1, 3, system_dict["img_long_side"], system_dict["img_long_side"])) feat_height, feat_width = out_shape[0][-2:] rpn_num_anchors = len(system_dict["rpn_anchor_scales"]) * len(system_dict["rpn_anchor_ratios"]) data_names = ['data', 'im_info', 'gt_boxes'] label_names = ['label', 'bbox_target', 'bbox_weight'] data_shapes = [('data', (batch_size, 3, system_dict["img_long_side"], system_dict["img_long_side"])), ('im_info', (batch_size, 3)), ('gt_boxes', (batch_size, 100, 5))] label_shapes = [('label', (batch_size, 1, rpn_num_anchors * feat_height, feat_width)), ('bbox_target', (batch_size, 4 * rpn_num_anchors, feat_height, feat_width)), ('bbox_weight', (batch_size, 4 * rpn_num_anchors, feat_height, feat_width))] # print shapes data_shape_dict, out_shape_dict = infer_data_shape(sym, data_shapes + label_shapes) logger.info('max input shape\n%s' % pprint.pformat(data_shape_dict)) logger.info('max output shape\n%s' % pprint.pformat(out_shape_dict)) # load and initialize params if system_dict["resume"]: arg_params, aux_params = load_param(system_dict["resume"]) else: arg_params, aux_params = load_param(system_dict["pretrained"]) arg_params, aux_params = initialize_frcnn(sym, data_shapes, arg_params, aux_params) # check parameter shapes check_shape(sym, data_shapes + label_shapes, arg_params, aux_params) # check fixed params fixed_param_names = get_fixed_params(sym, system_dict["net_fixed_params"]) logger.info('locking params\n%s' % pprint.pformat(fixed_param_names)) # metric rpn_eval_metric = RPNAccMetric() rpn_cls_metric = RPNLogLossMetric() rpn_bbox_metric = RPNL1LossMetric() eval_metric = RCNNAccMetric() cls_metric = RCNNLogLossMetric() bbox_metric = RCNNL1LossMetric() eval_metrics = mx.metric.CompositeEvalMetric() for child_metric in [rpn_eval_metric, rpn_cls_metric, rpn_bbox_metric, eval_metric, cls_metric, bbox_metric]: eval_metrics.add(child_metric) # callback batch_end_callback = mx.callback.Speedometer(batch_size, frequent=system_dict["log_interval"], auto_reset=False) epoch_end_callback = mx.callback.do_checkpoint(system_dict["save_prefix"]) # learning schedule base_lr = system_dict["lr"] lr_factor = 0.1 lr_epoch = [int(epoch) for epoch in system_dict["lr_decay_epoch"].split(',')] lr_epoch_diff = [epoch - system_dict["start_epoch"] for epoch in lr_epoch if epoch > system_dict["start_epoch"]] lr = base_lr * (lr_factor ** (len(lr_epoch) - len(lr_epoch_diff))) lr_iters = [int(epoch * len(roidb) / batch_size) for epoch in lr_epoch_diff] logger.info('lr %f lr_epoch_diff %s lr_iters %s' % (lr, lr_epoch_diff, lr_iters)) lr_scheduler = mx.lr_scheduler.MultiFactorScheduler(lr_iters, lr_factor) # optimizer optimizer_params = {'momentum': 0.9, 'wd': 0.0005, 'learning_rate': lr, 'lr_scheduler': lr_scheduler, 'rescale_grad': (1.0 / batch_size), 'clip_gradient': 5} # train mod = Module(sym, data_names=data_names, label_names=label_names, logger=logger, context=ctx, work_load_list=None, fixed_param_names=fixed_param_names) mod.fit(train_data, eval_metric=eval_metrics, epoch_end_callback=epoch_end_callback, batch_end_callback=batch_end_callback, kvstore='device', optimizer='sgd', optimizer_params=optimizer_params, arg_params=arg_params, aux_params=aux_params, begin_epoch=system_dict["start_epoch"], num_epoch=system_dict["epochs"])