def main(): # Set seed. np.random.seed(SEED) tf.set_random_seed(SEED) # Read config. C = config.Config() class_mapping = C.class_mapping # Read training data. data_train, class_count, _ = get_data(TRAIN_ANNOT_PATH, TRAIN_DATA_PATH, C.img_types) # Load base model. if C.network == 'vgg16': from faster_rcnn.base_models import vgg16 as base_model elif C.network == 'resnet50': from faster_rcnn.base_models import resnet50 as base_model else: print('Not a valid base model!') sys.exit(1) # Read validation data. if USE_VALIDATION: data_val, _, _ = get_data(VAL_ANNOT_PATH, VAL_DATA_PATH, C.img_types) # Create paths. if MODEL_NAME != None: #model_name = C.model_path + '_' + datetime.today().strftime('%y%m%d') + '_' + MODEL_NAME model_name = C.model_path + '_' + MODEL_NAME if os.path.exists(os.path.join(MODELS_PATH, model_name)): print('Model already exist.') sys.exit(1) else: model_name = C.model_path + '_' + datetime.today().strftime('%y%m%d') + '_' + silly_name_gen() model_path = os.path.join(MODELS_PATH, model_name) weights_path = os.path.join(model_path, 'weights.hdf5') config_path = os.path.join(model_path, 'config.pickle') config_json_path = os.path.join(model_path, 'config.json') record_path = os.path.join(model_path, 'record.csv') C.weights_path = weights_path # Create model folder. create_model_folder(model_name) # Save config. with open(config_path, 'wb') as f: pickle.dump(C, f) with open(config_json_path, 'w') as f: json.dump(C.__dict__, f, indent=4) # Create generators. data_train_gen = get_tile_generator(data_train, C, base_model.get_img_output_length, class_count, base_model.preprocess, train_mode=True, verbose=False) if USE_VALIDATION: data_val_gen = get_tile_generator(data_val, C, base_model.get_img_output_length, class_count, base_model.preprocess, train_mode=False, verbose=False) # Define shapes. img_input_shape = (None, None, 3) img_input = Input(shape=img_input_shape) roi_input = Input(shape=(None, 4)) n_anchors = len(C.anchor_box_scales) * len(C.anchor_box_ratios) # Define base network with shared layers, RPN and classifier. base_net_output_layer = base_model.nn_base(img_input, trainable=C.base_net_trainable, weights=C.base_net_weights) rpn = rpn_layer(base_net_output_layer, n_anchors) classifier = base_model.classifier_layer( base_net_output_layer, roi_input, C.n_rois, nb_classes=len(class_mapping) ) # Create models. model_rpn = Model(img_input, rpn[:2]) model_classifier = Model([img_input, roi_input], classifier) model_all = Model([img_input, roi_input], rpn[:2] + classifier) # Create var for recording training process. df_record = pd.DataFrame( columns=[ 'elapsed_time', 'mean_overlapping_bboxes', 'val_mean_overlapping_bboxes', 'loss_rpn_cls', 'val_loss_rpn_cls', 'loss_rpn_regr', 'val_loss_rpn_regr', 'loss_detector_cls', 'val_loss_detector_cls', 'loss_detector_regr', 'val_loss_detector_regr', 'total_loss', 'val_total_loss', 'detector_acc', 'val_detector_acc', 'model_improvement' ] ) # Compile models. model_rpn.compile( optimizer=Adam(lr=1e-5 * 5.0), #SGD(lr=1e-3, momentum=0.9, decay=0.0005), loss=[ rpn_loss_cls(n_anchors), rpn_loss_regr(n_anchors) ] ) model_classifier.compile( optimizer=Adam(lr=1e-5 * 5.0), #SGD(lr=1e-3, momentum=0.9, decay=0.0005), loss=[ class_loss_cls, class_loss_regr(len(class_mapping)-1) ], metrics={ 'dense_class_{}'.format(len(class_mapping)): 'accuracy' } ) model_all.compile( optimizer='sgd', loss='mae' ) # Setup Tensorboard. callback = TensorBoard(model_path) callback.set_model(model_all) # Training settings. iter_num = 0 train_step = 0 losses = np.zeros((EPOCH_LENGTH, 5)) rpn_accuracy_for_epoch = [] best_total_loss = np.Inf # Start training. start_time = time.time() print('\n\nStart training.') for epoch_num in range(N_EPOCHS): pbar = generic_utils.Progbar(EPOCH_LENGTH) print('Epoch {}/{}'.format(epoch_num + 1, N_EPOCHS)) while True: # Get next batch (image). img, Y, img_data, img_debug, best_anchor_for_bbox, debug_n_pos = next(data_train_gen) # If no GT boxes. if len(img_data['bboxes']) == 0: continue # Train on batch. loss_rpn = model_rpn.train_on_batch(img, Y) # Get predicted RPN from RPN model [rpn_cls, rpn_regr]. P_rpn = model_rpn.predict_on_batch(img) ''' if iter_num == 0: colormap = [ ((166,206,227), (31,120,180)), # Light Blue, Blue ((178,223,138), (51,160,44)), # Light Green, Green ((251,154,153), (227,26,28)), # Light Red, Red ((253,191,111), (255,127,0)), # Light Orange, Orange ((202,178,214), (106,61,154)), # Light Purple, Purple ] img_debug = cv2.cvtColor(img_debug, cv2.COLOR_BGR2GRAY) img_debug = cv2.cvtColor(img_debug, cv2.COLOR_GRAY2RGB) _cls = Y[0][0] _regr = Y[1][0] pos_cls = np.where(_cls==1) pos_regr = np.where(_regr==1) for i in range(debug_n_pos): color = colormap[i%len(colormap)][0] idx = pos_regr[2][i*4]/4 anchor_size = C.anchor_box_scales[int(idx/len(C.anchor_box_ratios))] anchor_ratio = C.anchor_box_ratios[int(idx%len(C.anchor_box_ratios))] center = (pos_regr[1][i*4]*C.rpn_stride, pos_regr[0][i*4]*C.rpn_stride) anchor_width = anchor_size*anchor_ratio[0] anchor_height = anchor_size*anchor_ratio[1] cv2.circle(img_debug, center, 3, color, -1) cv2.rectangle( img_debug, (center[0]-int(anchor_width/2), center[1]-int(anchor_height/2)), (center[0]+int(anchor_width/2), center[1]+int(anchor_height/2)), color, 2 ) plt.figure(figsize=(8,8)) plt.imshow(img_debug) plt.title(img_data['filepath']) plt.show() for i in range(9): fig, ax = plt.subplots() im = ax.imshow(Y[0][0, :, :, i]) plt.colorbar(im) plt.title('isValid' + str(i)) plt.show() fig, ax = plt.subplots() im = ax.imshow(Y[0][0, :, :, i+9]) plt.colorbar(im) plt.title('isObject' + str(i)) plt.show() fig, ax = plt.subplots() im = ax.imshow(P_rpn[0][0, :, :, i]) plt.colorbar(im) plt.title('Prediction' + str(i)) plt.show() ''' # R: bboxes (shape=(300,4)) # Convert RPN layer to ROI bboxes. R = rpn_to_roi( P_rpn[0], P_rpn[1], C, use_regr=True, overlap_thresh=0.7, max_boxes=300 ) # Note: calc_iou converts from (x1,y1,x2,y2) to (x,y,w,h) format # X2: bboxes that iou > C.classifier_min_overlap for all gt bboxes in 300 non_max_suppression bboxes. # Y1: one hot code for bboxes from above => x_roi (X) # Y2: corresponding labels and corresponding gt bboxes X2, Y1, Y2, IouS = calc_iou(R, img_data, C, class_mapping) # If X2 is None means there are no matching bboxes if X2 is None: rpn_accuracy_for_epoch.append(0) continue sel_samples, n_pos_samples = get_selected_samples(Y1, C) rpn_accuracy_for_epoch.append(n_pos_samples) # training_data: [img, X2[:, sel_samples, :]] # labels: [Y1[:, sel_samples, :], Y2[:, sel_samples, :]] # img => img_data resized image # X2[:, sel_samples, :] => n_rois (4 in here) bboxes which contains selected neg and pos # Y1[:, sel_samples, :] => one hot encode for n_rois bboxes which contains selected neg and pos # Y2[:, sel_samples, :] => labels and gt bboxes for n_rois bboxes which contains selected neg and pos loss_detector = model_classifier.train_on_batch( [ img, X2[:, sel_samples, :] ], [ Y1[:, sel_samples, :], Y2[:, sel_samples, :] ] ) # Log losses. losses[iter_num, 0] = loss_rpn[1] losses[iter_num, 1] = loss_rpn[2] write_log( callback, ['rpn_cls_loss', 'rpn_reg_loss'], [loss_rpn[1], loss_rpn[2]], train_step ) losses[iter_num, 2] = loss_detector[1] losses[iter_num, 3] = loss_detector[2] losses[iter_num, 4] = loss_detector[3] write_log( callback, ['detector_cls_loss', 'detector_reg_loss', 'detector_acc'], [loss_detector[1], loss_detector[2], loss_detector[3]], train_step ) iter_num += 1 train_step += 1 pbar.update( iter_num, [ ('rpn_cls', losses[iter_num-1, 0]), ('rpn_regr', losses[iter_num-1, 1]), ('detector_cls', losses[iter_num-1, 2]), ('detector_regr', losses[iter_num-1, 3]) ] ) if iter_num == EPOCH_LENGTH: # Compute epoch losses. loss_rpn_cls = np.mean(losses[:, 0]) loss_rpn_regr = np.mean(losses[:, 1]) loss_detector_cls = np.mean(losses[:, 2]) loss_detector_regr = np.mean(losses[:, 3]) class_acc = np.mean(losses[:, 4]) mean_overlapping_bboxes = float(sum(rpn_accuracy_for_epoch)) / len(rpn_accuracy_for_epoch) rpn_accuracy_for_epoch = [] elapsed_time = (time.time() - start_time) curr_total_loss = loss_rpn_cls + loss_rpn_regr + loss_detector_cls + loss_detector_regr iter_num = 0 if C.verbose: print('') if mean_overlapping_bboxes == 0: print('RPN is not producing bounding boxes that overlap the ground truth boxes. Check RPN settings or keep training.') else: print('(TRAINING) Mean number of bounding boxes from RPN overlapping ground truth boxes: {}'.format(mean_overlapping_bboxes)) print('(TRAINING) Loss RPN classifier: {}'.format(loss_rpn_cls)) print('(TRAINING) Loss RPN regression: {}'.format(loss_rpn_regr)) print('(TRAINING) Loss Detector classifier: {}'.format(loss_detector_cls)) print('(TRAINING) Loss Detector regression: {}'.format(loss_detector_regr)) print('(TRAINING) Detector accuracy for bounding boxes from RPN: {}'.format(class_acc)) print('(TRAINING) Total Loss: {}'.format(curr_total_loss)) print('Elapsed time: ' + ms_output(elapsed_time)) print('') # Validation. record_row = {} if USE_VALIDATION: val_start_time = time.time() print('\nPerforming Validation.') val_rpn_accuracy = [] val_rpn_cls_loss = [] val_rpn_reg_loss = [] val_detector_cls_loss = [] val_detector_reg_loss = [] val_detector_acc = [] while True: try: img_val, Y_val, img_data_val, _, _, _ = next(data_val_gen) # Validate on batch. val_loss_rpn = model_rpn.test_on_batch(img_val, Y_val) P_rpn_val = model_rpn.predict_on_batch(img_val) R_val = rpn_to_roi( P_rpn_val[0], P_rpn_val[1], C, use_regr=True, overlap_thresh=0.7, max_boxes=300 ) X2_val, Y1_val, Y2_val, _ = calc_iou(R_val, img_data_val, C, class_mapping) if X2_val is None: continue val_sel_samples, val_n_pos_samples = get_selected_samples(Y1_val, C) val_loss_detector = model_classifier.test_on_batch( [ img_val, X2_val[:, val_sel_samples, :] ], [ Y1_val[:, val_sel_samples, :], Y2_val[:, val_sel_samples, :] ] ) val_rpn_accuracy.append(val_n_pos_samples) val_rpn_cls_loss.append(val_loss_rpn[1]) val_rpn_reg_loss.append(val_loss_rpn[2]) val_detector_cls_loss.append(val_loss_detector[1]) val_detector_reg_loss.append(val_loss_detector[2]) val_detector_acc.append(val_loss_detector[3]) except RuntimeError: break except StopIteration: break except: print(traceback.print_exc()) sys.exit(1) data_val_gen = get_tile_generator(data_val, C, base_model.get_img_output_length, class_count, base_model.preprocess, train_mode=False, verbose=False) val_mean_overlapping_bboxes = float(sum(val_rpn_accuracy)) / len(val_rpn_accuracy) val_total_loss = np.mean(val_rpn_cls_loss) + np.mean(val_rpn_reg_loss) + np.mean(val_detector_cls_loss) + np.mean(val_detector_reg_loss) print('(VALIDATION) Mean number of bounding boxes from RPN overlapping ground truth boxes: {}'.format(val_mean_overlapping_bboxes)) print('(VALIDATION) Mean Loss RPN classifier: {}'.format(np.mean(val_rpn_cls_loss))) print('(VALIDATION) Mean Loss RPN regression: {}'.format(np.mean(val_rpn_reg_loss))) print('(VALIDATION) Mean Loss Detector classifier: {}'.format(np.mean(val_detector_cls_loss))) print('(VALIDATION) Mean Loss Detector regression: {}'.format(np.mean(val_detector_reg_loss))) print('(VALIDATION) Mean Detector accuracy for bounding boxes from RPN: {}'.format(np.mean(val_detector_acc))) print('(VALIDATION) Total Loss: {}'.format(val_total_loss)) record_row['val_mean_overlapping_bboxes'] = round(val_mean_overlapping_bboxes, 3) record_row['val_detector_acc'] = round(np.mean(val_detector_acc), 3) record_row['val_loss_rpn_cls'] = round(np.mean(val_rpn_cls_loss), 3) record_row['val_loss_rpn_regr'] = round(np.mean(val_rpn_reg_loss), 3) record_row['val_loss_detector_cls'] = round(np.mean(val_detector_cls_loss), 3) record_row['val_loss_detector_regr'] = round(np.mean(val_detector_reg_loss), 3) record_row['val_total_loss'] = round(val_total_loss, 3) val_elapsed_time = (time.time() - val_start_time) print('Validation execution time: ' + ms_output(val_elapsed_time)) print('') if val_total_loss < best_total_loss: record_row['model_improvement'] = val_total_loss - best_total_loss if C.verbose: print('Total loss decreased from {} to {}, saving weights'.format(best_total_loss, val_total_loss)) print('') best_total_loss = val_total_loss model_all.save_weights(weights_path) else: record_row['model_improvement'] = None else: record_row['val_mean_overlapping_bboxes'] = None record_row['val_detector_acc'] = None record_row['val_loss_rpn_cls'] = None record_row['val_loss_rpn_regr'] = None record_row['val_loss_detector_cls'] = None record_row['val_loss_detector_regr'] = None record_row['val_total_loss'] = None if curr_total_loss < best_total_loss: record_row['model_improvement'] = curr_total_loss - best_total_loss if C.verbose: print('Total loss decreased from {} to {}, saving weights'.format(best_total_loss, curr_total_loss)) print('') best_total_loss = curr_total_loss model_all.save_weights(weights_path) else: record_row['model_improvement'] = None # Log epoch averages. write_log( callback, [ 'Elapsed_time', 'mean_overlapping_bboxes', 'mean_rpn_cls_loss', 'mean_rpn_reg_loss', 'mean_detector_cls_loss', 'mean_detector_reg_loss', 'mean_detector_acc', 'total_loss' ], [ elapsed_time/60, mean_overlapping_bboxes, loss_rpn_cls, loss_rpn_regr, loss_detector_cls, loss_detector_regr, class_acc, curr_total_loss ], epoch_num ) record_row['mean_overlapping_bboxes'] = round(mean_overlapping_bboxes, 3) record_row['detector_acc'] = round(class_acc, 3) record_row['loss_rpn_cls'] = round(loss_rpn_cls, 3) record_row['loss_rpn_regr'] = round(loss_rpn_regr, 3) record_row['loss_detector_cls'] = round(loss_detector_cls, 3) record_row['loss_detector_regr'] = round(loss_detector_regr, 3) record_row['total_loss'] = round(curr_total_loss, 3) record_row['elapsed_time'] = round(elapsed_time/60, 3) df_record = df_record.append(record_row, ignore_index=True) df_record.to_csv(record_path, index=0) break print('Training Complete! Exiting.') fig = plt.figure(figsize=(15,5)) plt.subplot(1,2,1) plt.plot(np.arange(0, df_record.shape[0]), df_record['mean_overlapping_bboxes'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_mean_overlapping_bboxes'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['mean_overlapping_bboxes'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_mean_overlapping_bboxes'].rolling(window=20).mean(), 'b', label='Val') plt.title('mean_overlapping_bboxes') plt.legend() plt.subplot(1,2,2) plt.plot(np.arange(0, df_record.shape[0]), df_record['detector_acc'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_detector_acc'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['detector_acc'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_detector_acc'].rolling(window=20).mean(), 'b', label='Val') plt.title('class_acc') plt.legend() fig.savefig(os.path.join(model_path, 'viz/accuracy.png')) fig = plt.figure(figsize=(15,5)) plt.subplot(1,2,1) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_rpn_cls'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_rpn_cls'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_rpn_cls'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_rpn_cls'].rolling(window=20).mean(), 'b', label='Val') plt.title('loss_rpn_cls') plt.legend() plt.subplot(1,2,2) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_rpn_regr'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_rpn_regr'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_rpn_regr'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_rpn_regr'].rolling(window=20).mean(), 'b', label='Val') plt.title('loss_rpn_regr') plt.legend() fig.savefig(os.path.join(model_path, 'viz/rpn_loss.png')) fig = plt.figure(figsize=(15,5)) plt.subplot(1,2,1) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_detector_cls'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_detector_cls'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_detector_cls'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_detector_cls'].rolling(window=20).mean(), 'b', label='Val') plt.title('loss_detector_cls') plt.legend() plt.subplot(1,2,2) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_detector_regr'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_detector_regr'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['loss_detector_regr'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_loss_detector_regr'].rolling(window=20).mean(), 'b', label='Val') plt.title('loss_detector_regr') plt.legend() fig.savefig(os.path.join(model_path, 'viz/detector_loss.png')) fig = plt.figure(figsize=(16,8)) plt.plot(np.arange(0, df_record.shape[0]), df_record['total_loss'], 'r', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['val_total_loss'], 'b', alpha=0.3) plt.plot(np.arange(0, df_record.shape[0]), df_record['total_loss'].rolling(window=20).mean(), 'r', label='Train') plt.plot(np.arange(0, df_record.shape[0]), df_record['val_total_loss'].rolling(window=20).mean(), 'b', label='Val') plt.title('total_loss') plt.legend() fig.savefig(os.path.join(model_path, 'viz/total_loss.png'))
parser.add_option( "--rot", "--rot_90", dest="rot_90", help="Augment with 90 degree rotations in training. (Default=false).", action="store_true", default=False) (options, args) = parser.parse_args() if not options.train_path: # if filename is not given parser.error( 'Error: path to training data must be specified. Pass --path to command line' ) # pass the settings from the command line, and persist them in the config object C = config.Config() C.use_horizontal_flips = bool(options.horizontal_flips) C.use_vertical_flips = bool(options.vertical_flips) C.rot_90 = bool(options.rot_90) all_imgs, classes_count, class_mapping = get_data(options.train_path) C.class_mapping = class_mapping with open(C.config_filename, 'wb') as config_f: pickle.dump(C, config_f) print( 'Config has been written to {}, and can be loaded when testing to ensure correct results' .format(C.config_filename)) train_imgs = [s for s in all_imgs if s['imageset'] == 'trainval'] val_imgs = [s for s in all_imgs if s['imageset'] == 'test']
def main(): # Set seed. np.random.seed(SEED) # Read config. C = config.Config() # Read training data. data_train, class_count, _ = get_data(TRAIN_ANNOT_PATH, TRAIN_DATA_PATH, C.img_types) # Load base model. if C.network == 'vgg16': from faster_rcnn.base_models import vgg16 as base_model elif C.network == 'resnet50': from faster_rcnn.base_models import resnet50 as base_model else: print('Not a valid base model!') sys.exit(1) # Counting epoch length. ''' if True: print('Computing Epoch Length and Anchors Ratios/Sizes.') df = pd.DataFrame() data_train_gen = get_tile_generator( data_train, C, base_model.get_img_output_length, class_count, base_model.preprocess, train_mode=False, verbose=False ) anchors_summary = {} for size in C.anchor_box_scales: anchors_summary[str(size)] = {} for ratio in C.anchor_box_ratios: anchors_summary[str(size)][str(ratio)] = 0 n_objects = [] epoch_length_counter = 0 while True: try: img, Y, img_data, img_debug, best_anchor_for_bbox, debug_n_pos = next(data_train_gen) n_objects.append(len(img_data['bboxes'])) for i in range(len(img_data['bboxes'])): gt_x1 = int(img_data['bboxes'][i]['x1']*(img.shape[2]/img_data['width'])) gt_x2 = int(img_data['bboxes'][i]['x2']*(img.shape[2]/img_data['width'])) gt_y1 = int(img_data['bboxes'][i]['y1']*(img.shape[1]/img_data['height'])) gt_y2 = int(img_data['bboxes'][i]['y2']*(img.shape[1]/img_data['height'])) ar_x = (gt_x2 - gt_x1) ar_y = (gt_y2 - gt_y1) df = df.append( { 'new_width': img.shape[1], 'new_height': img.shape[2], 'bbox_width': gt_x2 - gt_x1, 'bbox_height': gt_y2 - gt_y1, 'bbox_aspect_ratio': max(ar_x, ar_y) / min(ar_x, ar_y) }, ignore_index=True ) _cls = Y[0][0] _regr = Y[1][0] pos_cls = np.where(_cls==1) pos_regr = np.where(_regr==1) for i in range(debug_n_pos): idx = pos_regr[2][i*4]/4 try: anchor_size = C.anchor_box_scales[int(idx/len(C.anchor_box_ratios))] anchor_ratio = C.anchor_box_ratios[int(idx%len(C.anchor_box_ratios))] except: print(debug_n_pos) print(i) print(idx) print(pos_regr[2]) anchors_summary[str(anchor_size)][str(anchor_ratio)] += 1 epoch_length_counter += 1 #if epoch_length_counter > 20: # break except RuntimeError: break except StopIteration: break print('Epoch Length: ' + str(epoch_length_counter)) print('Min Nr of Objects: ' + str(min(n_objects))) print('Average Nr of Objects: ' + str(np.average(n_objects))) print('Max Nr of Objects: ' + str(max(n_objects))) print(anchors_summary) print('\n') # Count Base Sizes base_sizes = [32, 64, 96, 128, 196, 212, 256, 512, 768, 1024] base_sizes_results = {bs: 0 for bs in base_sizes} base_sizes_results['rest'] = 0 for index, row in df.iterrows(): width = row['bbox_width'] height = row['bbox_height'] done = False for bs in base_sizes: if width <= bs and height <= bs: base_sizes_results[bs] += 1 done = True if done == False: base_sizes_results['rest'] += 1 plt.figure(figsize=(12,8)) plt.bar( range(len(base_sizes_results)), [base_sizes_results[key] for key in base_sizes_results], align='center' ) plt.xticks(range(len(base_sizes_results)), base_sizes_results.keys()) plt.show() plt.figure(figsize=(12,8)) sns.distplot(df['bbox_aspect_ratio'], bins=20) plt.show() # Clustering Scales. X = df.as_matrix(columns=['bbox_width', 'bbox_height']) K = KMeans(3, random_state=SEED) labels = K.fit(X) plt.figure(figsize=(12,8)) plt.scatter(X[:, 0], X[:, 1], c=labels.labels_, s=50, alpha=0.5, cmap='viridis') plt.show() ''' # Test generator. print('Testing generator for training data.') data_train_gen = get_tile_generator( data_train, C, base_model.get_img_output_length, class_count, base_model.preprocess, train_mode=True, verbose=True ) continue_test = 'Y' while continue_test.upper() == 'Y': img, Y, img_data, img_debug, best_anchor_for_bbox, debug_n_pos = next(data_train_gen) print('Image: ' + img_data['filepath']) print('Original image: height=%d width=%d'%(img_data['height'], img_data['width'])) print('Resized image: height=%d width=%d C.img_size=%d'%(img.shape[1], img.shape[2], C.img_size)) print('Feature Map Size: height=%d width=%d C.rpn_stride=%d'%(Y[0].shape[1], Y[0].shape[2], C.rpn_stride)) print('Nr of GT Bounding Boxes: ' + str(len(img_data['bboxes']))) print('Shape of y_rpn_cls {}'.format(Y[0].shape)) print('Shape of y_rpn_regr {}'.format(Y[1].shape)) print('Number of positive anchors for this image: ' + str(debug_n_pos)) img_debug_gray = img_debug.copy() img_debug = cv2.cvtColor(img_debug, cv2.COLOR_BGR2RGB) img_debug_gray = cv2.cvtColor(img_debug_gray, cv2.COLOR_BGR2GRAY) img_debug_gray = cv2.cvtColor(img_debug_gray, cv2.COLOR_GRAY2RGB) img_debug_gray_anchors = np.copy(img_debug_gray) colormap = [ ((166,206,227), (31,120,180)), # Light Blue, Blue ((178,223,138), (51,160,44)), # Light Green, Green ((251,154,153), (227,26,28)), # Light Red, Red ((253,191,111), (255,127,0)), # Light Orange, Orange ((202,178,214), (106,61,154)), # Light Purple, Purple ] cc = 0 #for i in np.random.choice(len(img_data['bboxes']), min(5, len(img_data['bboxes'])), replace=False): for i in range(len(img_data['bboxes'])): gt_label = img_data['bboxes'][i]['class'] gt_x1 = int(img_data['bboxes'][i]['x1']*(img.shape[2]/img_data['width'])) gt_x2 = int(img_data['bboxes'][i]['x2']*(img.shape[2]/img_data['width'])) gt_y1 = int(img_data['bboxes'][i]['y1']*(img.shape[1]/img_data['height'])) gt_y2 = int(img_data['bboxes'][i]['y2']*(img.shape[1]/img_data['height'])) cv2.putText( img_debug_gray, gt_label, (gt_x1, gt_y1-10), cv2.FONT_HERSHEY_DUPLEX, 0.7, colormap[cc%len(colormap)][1], 1 ) cv2.rectangle( img_debug_gray, (gt_x1, gt_y1), (gt_x2, gt_y2), colormap[cc%len(colormap)][1], 3 ) center = (best_anchor_for_bbox[i, 1]*C.rpn_stride, best_anchor_for_bbox[i, 0]*C.rpn_stride) anchor_size = C.anchor_box_scales[best_anchor_for_bbox[i, 3]] anchor_ratio = C.anchor_box_ratios[best_anchor_for_bbox[i, 2]] anchor_width = anchor_size*anchor_ratio[0] anchor_height = anchor_size*anchor_ratio[1] cv2.circle(img_debug_gray, center, 3, colormap[cc%len(colormap)][0], -1) cv2.rectangle( img_debug_gray, (center[0]-int(anchor_width/2), center[1]-int(anchor_height/2)), (center[0]+int(anchor_width/2), center[1]+int(anchor_height/2)), colormap[cc%len(colormap)][0], 3 ) overlay = img_debug.copy() cv2.rectangle( overlay, (gt_x1, gt_y1), (gt_x2, gt_y2), (227,26,28), 3 ) alpha = 0.6 img_debug = cv2.addWeighted(overlay, alpha, img_debug, 1 - alpha, 0) cc += 1 _cls = Y[0][0] _regr = Y[1][0] pos_cls = np.where(_cls==1) pos_regr = np.where(_regr==1) for i in range(debug_n_pos): color = colormap[i%len(colormap)][0] idx = pos_regr[2][i*4]/4 anchor_size = C.anchor_box_scales[int(idx/len(C.anchor_box_ratios))] anchor_ratio = C.anchor_box_ratios[int(idx%len(C.anchor_box_ratios))] center = (pos_regr[1][i*4]*C.rpn_stride, pos_regr[0][i*4]*C.rpn_stride) anchor_width = anchor_size*anchor_ratio[0] anchor_height = anchor_size*anchor_ratio[1] cv2.circle(img_debug_gray_anchors, center, 3, color, -1) cv2.rectangle( img_debug_gray_anchors, (center[0]-int(anchor_width/2), center[1]-int(anchor_height/2)), (center[0]+int(anchor_width/2), center[1]+int(anchor_height/2)), color, 2 ) plt.figure(figsize=(8,8)) plt.imshow(img_debug_gray) plt.figure(figsize=(8,8)) plt.imshow(img_debug_gray_anchors) plt.figure(figsize=(8,8)) plt.imshow(img_debug) plt.show() cv2.imwrite('test.png', cv2.cvtColor(img_debug, cv2.COLOR_RGB2BGR)) continue_test = input('Do you want to continue generator test round? Y or N?') print('')