def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 获得种类和先验框的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.num_classes = self.num_classes + 1 #---------------------------------------------------# # 创建一个工具箱,用于进行解码 # 最大使用min_k个建议框,默认为150 #---------------------------------------------------# self.bbox_util = BBoxUtility(self.num_classes, nms_iou=self.nms_iou, min_k=150) #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.generate()
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 获得种类和先验框的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.anchors, self.num_anchors = get_anchors(self.anchors_path) #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.input_image_shape = K.placeholder(shape=(2, )) self.sess = K.get_session() self.boxes, self.scores, self.classes = self.generate() show_config(**self._defaults)
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 计算总的类的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.anchors = torch.from_numpy( get_anchors(self.input_shape, self.anchors_size, self.backbone)).type(torch.FloatTensor) if self.cuda: self.anchors = self.anchors.cuda() self.num_classes = self.num_classes + 1 #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list( map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.bbox_util = BBoxUtility(self.num_classes) self.generate() show_config(**self._defaults)
def __init__(self, **kwargs): super(YOLO, self).__init__() self.__dict__.update(self._defaults) # 还能这样? self.__dict__.update(kwargs) # update with user overrides self.class_names = get_classes(self.classes_path) self.anchors = get_anchors(self.anchors_path) self.colors = get_colors(self.class_names) K.set_learning_phase(0) self.inference_model = self._generate_model()
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 获得种类 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.generate()
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) self.input_shape = [image_sizes[self.phi], image_sizes[self.phi]] #---------------------------------------------------# # 计算总的类的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.generate()
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 计算总的类的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.bbox_util = BBoxUtility(nms_thresh=self.nms_iou) self.generate()
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) self._defaults[name] = value #---------------------------------------------------# # 获得种类和先验框的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.anchors, self.num_anchors = get_anchors(self.anchors_path) self.bbox_util = DecodeBox(self.anchors, self.num_classes, (self.input_shape[0], self.input_shape[1]), self.anchors_mask) #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) self.generate() show_config(**self._defaults)
def _main(): # parse command line arguments parser = argparse.ArgumentParser() parser.add_argument( '--train_from_checkpoint', type=str, help= "The path to where a previously trained model's weights are stored. To use the default\n\ coco weights, use the path 'model_weights/coco_pretrained_weights.ckpt'. Otherwise, the model\n\ weights will be initialized randomly. ") parser.add_argument( '--class_path', default='utils/coco_classes.txt', type=str, help= 'The path that points towards where the class names for the dataset are stored.\n\ The default path is "utils/coco_classes.txt".') parser.add_argument( '--anchors_path', default='utils/anchors.txt', type=str, help= 'The path that points towards where the anchor values for the model are stored.\n\ The default path is "utils/anchors.txt", which contains anchors trained on the coco dataset.' ) parser.add_argument( '--data_path', default='training_data/image_paths_and_box_info.txt', type=str, help= 'The path that points towards where the training data text file is stored.\n\ The default path is "training_data/image_paths_and_box_info.txt".') parser.add_argument( '--input_height', default=416, type=int, help= 'The input height of the yolov3 model. The height must be a multiple of 32.\n\ The default height is 416.') parser.add_argument( '--input_width', default=416, type=int, help= 'The input width of the yolov3 model. The width must be a mutliple of 32.\n\ The default width is 416.') parser.add_argument( '--batch_size', default=32, type=int, help= 'The training batch size, whose default value is set to 32 images per batch.' ) parser.add_argument( '--max_num_boxes_per_image', default=20, type=int, help= 'The max number of boxes that can be detected within one image. Default is 20.' ) parser.add_argument( '--num_training_epochs', default=150, type=int, help='The number of training epochs. The default is 150.') parser.add_argument( '--learning_rate', default=0.001, type=float, help='The learning rate of the model. The default is 0.001.') parser.add_argument( '--ignore_threshold', default=0.5, type=float, help= 'Impacts how the loss is calculated. Must be between zero and one, and the default is set to 0.5.' ) parser.add_argument( '--train_val_data_split', default=0.9, type=float, help= 'The split between the data that will be used for training and data that will be used\n\ for validation. Default value is 0.9.') parser.add_argument( '--train_save_path', default='model_weights/', help= "The training model's checkpoint save path. The default path is 'model_weights/'." ) parser.add_argument( '--model_name', default='model.ckpt', help= 'The name that should be given to the checkpoint file. The default name is "model.ckpt".' ) parser.add_argument( '--tensorboard_save_path', default='tensorboard/tensorboard_train/', help= 'The path where the event files to be used with tensorboard will be saved at. The default\n\ path is "tensorboard/tensorboard_train/".') parser.add_argument( '--test_model_overfit', nargs='?', default=False, type=str2bool, const=True, help= 'Whether or not to purposefully overfit the model by training it on only one image.\n\ This option is useful in testing out if the loss function is working correctly.' ) parser.add_argument( '--save_every_x_iterations', default=100, type=int, help= "How frequently the model's training weights are saved. The default value is every\n\ 100 iterations.") parser.add_argument( '--log_every_x_iterations', default=5, type=int, help= "How frequently the model's loss is logged for it to be inspected in Tensorboard.\n\ The default value is every 5 iterations.") args = vars(parser.parse_args()) args[ 'data_path'] = '/home/yl/CNN/Yolo/keras-yolo3-fine-tune/dataset/train_label.txt' # read inputs h = args['input_height'] w = args['input_width'] ignore_thresh = args['ignore_threshold'] max_num_boxes_per_image = args['max_num_boxes_per_image'] anchors = get_anchors(args['anchors_path']) lr = args['learning_rate'] num_anchors_per_detector = len(anchors) // 3 num_detectors_per_image = num_anchors_per_detector * (((h / 32) * (w / 32)) + ((h / 16) * (w / 16)) + ((h / 8) * (w / 8))) class_names = get_classes(args['class_path']) num_classes = len(class_names) tb_train_path = args['tensorboard_save_path'] + 'train/' tb_val_path = args['tensorboard_save_path'] + 'val/' training_data, validation_data, batch_size = prepare_data( args['data_path'], args['train_val_data_split'], args['batch_size'], args['test_model_overfit']) tf.reset_default_graph() # build graph with tf.variable_scope('y_true'): y_true_data = tf.placeholder( dtype=tf.float32, shape=[None, num_detectors_per_image, num_classes + 5]) with tf.variable_scope('y_true_boxes'): y_true_box_data = tf.placeholder(dtype=tf.float32, shape=[ None, max_num_boxes_per_image * num_anchors_per_detector, 4 ]) with tf.variable_scope('x_input'): X = tf.placeholder(dtype=tf.float32, shape=[None, h, w, 3]) yolo_outputs = yolo_v3(inputs=X, num_classes=len(class_names), anchors=anchors, h=h, w=w, training=True) # output loss = yolo_v3_loss(yolo_outputs, y_true_data, y_true_box_data, ignore_threshold=ignore_thresh, anchors=anchors, num_classes=num_classes, h=h, w=w, batch_size=batch_size) tf.summary.scalar('loss', loss) global_step = tf.get_variable(name='global_step', trainable=False, initializer=0, dtype=tf.int32) # returns a varlist containing only the vars of the conv layers right before the yolo layers trainable_var_list = tf.trainable_variables() last_layer_var_list = [ i for i in trainable_var_list if i.shape[-1] == (5 + num_classes) * num_anchors_per_detector ] train_op_with_frozen_variables = tf.train.AdamOptimizer( learning_rate=lr).minimize(loss, global_step=global_step, var_list=last_layer_var_list) train_op_with_all_variables = tf.train.AdamOptimizer( learning_rate=lr).minimize(loss, global_step=global_step, var_list=trainable_var_list) summ = tf.summary.merge_all() # info print('--info--') print('model weights will be saved with filename: ', args['model_name']) print('tensorboard event files located at path: ', args['tensorboard_save_path']) # build training loop with tf.Session() as sess: train_writer = tf.summary.FileWriter(tb_train_path, sess.graph) val_writer = tf.summary.FileWriter(tb_val_path) # initialize model weights either randomly or from a saved checkpoint saver = tf.train.Saver() if args['train_from_checkpoint'] is None: print('initializing variables...') sess.run(tf.global_variables_initializer()) else: print('restoring weights from checkpoint: ', args['train_from_checkpoint']) saver.restore(sess, args['train_from_checkpoint']) num_iterations = args['num_training_epochs'] * len(training_data) print('beginning to train the model...') for i in range(num_iterations): input_images, y_true, y_true_boxes = get_training_batch( training_data, anchors, num_classes, batch_size=batch_size, h=h, w=w, random=not args['test_model_overfit']) # For the first epochs, train with the frozen layers. Then, unfreeze the entire graph. if i < num_iterations // 3: sess.run(train_op_with_frozen_variables, feed_dict={ X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes }) else: sess.run(train_op_with_all_variables, feed_dict={ X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes }) if i % args['log_every_x_iterations'] == 0: # write the training loss to tensorboard lt, st = sess.run( [loss, summ], feed_dict={ X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes }) train_writer.add_summary(st, i) #write the validation loss to tensorboard if we are not in overfit mode if not args['test_model_overfit']: input_images, y_true, y_true_boxes = get_training_batch( validation_data, anchors, num_classes, batch_size=batch_size, h=h, w=w, random=not args['test_model_overfit']) lv, sv = sess.run( [loss, summ], feed_dict={ X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes }) val_writer.add_summary(sv, i) print("iteration: " + str(i) + ", training loss: " + str(round(lt, 2)) + ", validation loss: " + str(round(lv, 2))) else: print("iteration: " + str(i) + ", training loss: " + str(round(lt, 2))) if i % args['save_every_x_iterations'] == 0: print('saving model weights at path: ', args['train_save_path']) saver.save( sess, os.path.join(args['train_save_path'], args['model_name']), global_step) train_writer.close() val_writer.close()
classes_path = 'model_data/voc_classes.txt' #--------------------------------------------------------------------------------------------------------------------------------# # trainval_percent用于指定(训练集+验证集)与测试集的比例,默认情况下 (训练集+验证集):测试集 = 9:1 # train_percent用于指定(训练集+验证集)中训练集与验证集的比例,默认情况下 训练集:验证集 = 9:1 # 仅在annotation_mode为0和1的时候有效 #--------------------------------------------------------------------------------------------------------------------------------# trainval_percent = 0.9 train_percent = 0.9 #-------------------------------------------------------# # 指向VOC数据集所在的文件夹 # 默认指向根目录下的VOC数据集 #-------------------------------------------------------# VOCdevkit_path = 'VOCdevkit' VOCdevkit_sets = [('2007', 'train'), ('2007', 'val')] classes, _ = get_classes(classes_path) #-------------------------------------------------------# # 统计目标数量 #-------------------------------------------------------# photo_nums = np.zeros(len(VOCdevkit_sets)) nums = np.zeros(len(classes)) def convert_annotation(year, image_id, list_file): in_file = open(os.path.join(VOCdevkit_path, 'VOC%s/Annotations/%s.xml' % (year, image_id)), encoding='utf-8') tree = ET.parse(in_file) root = tree.getroot()
if not os.path.exists(PREPROCESSED_DIR): os.makedirs(PREPROCESSED_DIR) with open(results.model) as json_data: model = model_from_json(json.load(json_data)) model.load_weights(results.weights) ############### PREPROCESSING ############### classes = results.classes.replace(" ", "").split(',') preprocess_dir(VAL_DIR, PREPROCESSED_DIR, REORIENT_SCRIPT_PATH, ROBUSTFOV_SCRIPT_PATH, classes, results.numcores) # get class encodings class_encodings = get_classes(classes) ############### DATA IMPORT ############### X, y, filenames, num_classes, _ = load_data(PREPROCESSED_DIR, classes) print("Test data loaded.") ############### PREDICT ############### PRED_DIR = results.OUT_DIR if not os.path.exists(PRED_DIR): os.makedirs(PRED_DIR) BATCH_SIZE = 1 # make predictions with best weights and save results
pred_boxes, pred_classes, pred_scores = yolo.detect_image(image) pbar.update(1) # save prediction result to txt result_file.write(image_name) for box, cls, score in zip(pred_boxes, pred_classes, pred_scores): pred_class_name = class_names[cls] xmin, ymin, xmax, ymax = box box_annotation = " %d,%d,%d,%d,%d,%f" % ( int(xmin), int(ymin), int(xmax), int(ymax), cls, score) result_file.write(box_annotation) result_file.write('\n') result_file.flush() pbar.close() result_file.close() if __name__ == '__main__': annotation_file = '/home/xia/Documents/1_code/16_target_detection/target_detection/2_yolov4/yolov4_pycharm/outputs/val2017.txt' class_names = get_classes( '/home/xia/Documents/1_code/16_target_detection/target_detection/2_yolov4/yolov4_pycharm/configs/coco_classes.txt' ) print(class_names) annotation_records, gt_classes_records = annotation_parse( annotation_file, class_names) # print(annotation_records) get_prediction_class_records(annotation_records, class_names, (416, 416))
def __init__(self, **kwargs): self.__dict__.update(self._defaults) for name, value in kwargs.items(): setattr(self, name, value) #---------------------------------------------------# # 计算总的类的数量 #---------------------------------------------------# self.class_names, self.num_classes = get_classes(self.classes_path) self.num_classes += 1 #---------------------------------------------------# # 画框设置不同的颜色 #---------------------------------------------------# if self.num_classes <= 81: self.colors = np.array( [[0, 0, 0], [244, 67, 54], [233, 30, 99], [156, 39, 176], [103, 58, 183], [100, 30, 60], [63, 81, 181], [33, 150, 243], [3, 169, 244], [0, 188, 212], [20, 55, 200], [0, 150, 136], [76, 175, 80], [139, 195, 74], [205, 220, 57], [70, 25, 100], [255, 235, 59], [255, 193, 7], [255, 152, 0], [255, 87, 34], [90, 155, 50], [121, 85, 72], [158, 158, 158], [96, 125, 139], [15, 67, 34], [98, 55, 20], [21, 82, 172], [58, 128, 255], [196, 125, 39], [75, 27, 134], [90, 125, 120], [121, 82, 7], [158, 58, 8], [96, 25, 9], [115, 7, 234], [8, 155, 220], [221, 25, 72], [188, 58, 158], [56, 175, 19], [215, 67, 64], [198, 75, 20], [62, 185, 22], [108, 70, 58], [160, 225, 39], [95, 60, 144], [78, 155, 120], [101, 25, 142], [48, 198, 28], [96, 225, 200], [150, 167, 134], [18, 185, 90], [21, 145, 172], [98, 68, 78], [196, 105, 19], [215, 67, 84], [130, 115, 170], [255, 0, 255], [255, 255, 0], [196, 185, 10], [95, 167, 234], [18, 25, 190], [0, 255, 255], [255, 0, 0], [0, 255, 0], [0, 0, 255], [155, 0, 0], [0, 155, 0], [0, 0, 155], [46, 22, 130], [255, 0, 155], [155, 0, 255], [255, 155, 0], [155, 255, 0], [0, 155, 255], [0, 255, 155], [18, 5, 40], [120, 120, 255], [255, 58, 30], [60, 45, 60], [75, 27, 244], [128, 25, 70]], dtype='uint8') else: hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)] self.colors = list( map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples)) self.colors = list( map( lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors)) class InferenceConfig(Config): GPU_COUNT = 1 IMAGES_PER_GPU = 1 NUM_CLASSES = self.num_classes DETECTION_MIN_CONFIDENCE = self.confidence DETECTION_NMS_THRESHOLD = self.nms_iou RPN_ANCHOR_SCALES = self.RPN_ANCHOR_SCALES IMAGE_MAX_DIM = self.IMAGE_MAX_DIM self.config = InferenceConfig() self.config.display() self.generate()
def _main(): # parse command line arguments parser = argparse.ArgumentParser() parser.add_argument( '--train-from-checkpoint', type=str, help="the path to where a previously trained model's weights are stored") parser.add_argument('--class-path', default='utils/coco_classes.txt', type=str, help='the path that points to the class names for the dataset') parser.add_argument( '--anchors-path', default='utils/anchors.txt', type=str, help='the path that points to the anchor values for the models') parser.add_argument( '--data-path', default='data/image_paths_and_box_info.txt', type=str, help='the path that points to the training data text file') parser.add_argument( '--input-height', default=416, type=int, help='the input height of the yolov3 model. The height must be a multiple of 32') parser.add_argument( '--input-width', default=416, type=int, help='The input width of the yolov3 model. The width must be a multiple of 32') parser.add_argument( '--batch-size', default=32, type=int, help='the training batch size') parser.add_argument( '--max-num-boxes-per-image', default=20, type=int, help='the max number of boxes that can be detected within one image') parser.add_argument( '--num-training-epochs', default=150, type=int, help='the number of training epochs') parser.add_argument( '--learning-rate', default=0.001, type=float, help='the learning rate') parser.add_argument( '--ignore-threshold', default=0.5, type=float, help='impacts how the loss is calculated. Must be between zero and one') parser.add_argument( '--train-val-data-split', default=0.9, type=float, help='the split between the data that will be used for training and data that will be used\n\ for validation') parser.add_argument( '--train-save-path', default='model-weights/', help="the training model's checkpoint save path") parser.add_argument( '--model-name', default='model.ckpt', help='the name that should be given to the checkpoint file') parser.add_argument( '--tensorboard-save-path', default='tb-logs/tb-train/', help='the path where the event files to be used with tensorboard will be saved at') parser.add_argument( '--test-model-overfit', nargs='?', default=False, type=str2bool, const=True, help='this option is useful in testing out if the loss function is working correctly') parser.add_argument( '--save-iterations', default=100, type=int, help="how frequently the model's training weights are saved") parser.add_argument( '--log-iterations', default=5, type=int, help="how frequently the model's loss is logged for it to be inspected in Tensorboard") args = parser.parse_args() # args info print('[i] checkpoint: ', args.train_from_checkpoint) print('[i] path of class file: ', args.class_path) print('[i] path of anchors file: ', args.anchors_path) # read inputs h = args.input_height w = args.input_width ignore_thresh = args.ignore_threshold max_num_boxes_per_image = args.max_num_boxes_per_image anchors = get_anchors(args.anchors_path) lr = args.learning_rate num_anchors_per_detector = len(anchors) // 3 num_detectors_per_image = num_anchors_per_detector * ( ((h / 32) * (w / 32)) + ((h / 16) * (w / 16)) + ((h / 8) * (w / 8))) class_names = get_classes(args.class_path) num_classes = len(class_names) # tensorboard path tb_train_path = args.tensorboard_save_path + 'train/' tb_val_path = args.tensorboard_save_path + 'val/' training_data, validation_data, batch_size = prepare_data( args.data_path, args.train_val_data_split, args.batch_size, args.test_model_overfit) tf.reset_default_graph() # build graph with tf.variable_scope('y_true'): y_true_data = tf.placeholder(dtype=tf.float32, shape=[None, num_detectors_per_image, num_classes + 5]) with tf.variable_scope('y_true_boxes'): y_true_box_data = tf.placeholder(dtype=tf.float32, shape=[None, max_num_boxes_per_image * num_anchors_per_detector, 4]) with tf.variable_scope('x_input'): X = tf.placeholder(dtype=tf.float32, shape=[None, h, w, 3]) yolo_outputs = yolo_v3(inputs=X, num_classes=len(class_names), anchors=anchors, h=h, w=w, training=True) # output loss = yolo_v3_loss(yolo_outputs, y_true_data, y_true_box_data, ignore_threshold=ignore_thresh, anchors=anchors, num_classes=num_classes, h=h, w=w, batch_size=batch_size) tf.summary.scalar('loss', loss) global_step = tf.get_variable(name='global_step', trainable=False, initializer=0, dtype=tf.int32) # returns a varlist containing only the vars of the conv layers right before the yolo layers trainable_var_list = tf.trainable_variables() last_layer_var_list = [i for i in trainable_var_list if i.shape[-1] == (5 + num_classes) * num_anchors_per_detector] train_op_with_frozen_variables = tf.train.AdamOptimizer(learning_rate=lr).minimize(loss, global_step=global_step, var_list=last_layer_var_list) train_op_with_all_variables = tf.train.AdamOptimizer(learning_rate=lr).minimize(loss, global_step=global_step, var_list=trainable_var_list) summ = tf.summary.merge_all() # info print('-------info-------') print('[i] model weights will be saved with filename: ', args.model_name) print('[i] tensorboard event files located at path: ', args.tensorboard_save_path) # build training loop with tf.Session() as sess: train_writer = tf.summary.FileWriter(tb_train_path, sess.graph) val_writer = tf.summary.FileWriter(tb_val_path) # initialize model weights either randomly or from a saved checkpoint saver = tf.train.Saver() if args['train_from_checkpoint'] is None: print('[i] initializing variables...') sess.run(tf.global_variables_initializer()) else: print('[i] restoring weights from checkpoint: ', args.train_from_checkpoint) saver.restore(sess, args.train_from_checkpoint) num_iterations = args.num_epochs * len(training_data) print('[i] beginning to train the model...') for i in range(num_iterations): input_images, y_true, y_true_boxes = get_training_batch(training_data, anchors, num_classes, batch_size=batch_size, h=h, w=w, random=not args.test_model_overfit) # For the first epochs, train with the frozen layers. Then, unfreeze the entire graph. if i < num_iterations // 3: sess.run(train_op_with_frozen_variables, feed_dict={X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes}) else: sess.run(train_op_with_all_variables, feed_dict={X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes}) if i % args.log_iterations == 0: # write the training loss to tensorboard lt, st = sess.run([loss, summ], feed_dict={X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes}) train_writer.add_summary(st, i) # write the validation loss to tensorboard if we are not in overfit mode if not args.test_model_overfit: input_images, y_true, y_true_boxes = get_training_batch(validation_data, anchors, num_classes, batch_size=batch_size, h=h, w=w, random=not args.test_model_overfit) lv, sv = sess.run([loss, summ], feed_dict={X: input_images, y_true_data: y_true, y_true_box_data: y_true_boxes}) val_writer.add_summary(sv, i) print( "| iteration: " + str(i) + ", training loss: " + str(round(lt, 2)) + ", validation loss: " + str( round(lv, 2))) else: print("| iteration: " + str(i) + ", training loss: " + str(round(lt, 2))) if i % args.save_iterations == 0: print('[i] saving model weights at path: ', args.train_save_path) saver.save(sess, os.path.join(args.train_save_path, args.model_name), global_step) print('################################################################################') train_writer.close() val_writer.close()
elif datasets.lower() == 'voc2012': image_ids = open( os.path.join( VOCdevkit_path, "VOC2012/ImageSets/Main/train.txt")).read().strip().split() if not os.path.exists(map_out_path): os.makedirs(map_out_path) if not os.path.exists(os.path.join(map_out_path, 'ground-truth')): os.makedirs(os.path.join(map_out_path, 'ground-truth')) if not os.path.exists(os.path.join(map_out_path, 'detection-results')): os.makedirs(os.path.join(map_out_path, 'detection-results')) if not os.path.exists(os.path.join(map_out_path, 'images-optional')): os.makedirs(os.path.join(map_out_path, 'images-optional')) class_names, _ = get_classes(classes_path) if map_mode == 0 or map_mode == 1: print("Load model.") # onenet = OneNet(confidence=0.2, nms_iou=0.5) onenet = OneNet(confidence=0.2, nms_iou=0.5) print("Load model done.") print("Get predict result.") for image_id in tqdm(image_ids): if 'coco' in datasets.lower(): image_path = os.path.join( VOCdevkit_path, "Pascal_COCO/JPEGImages/" + image_id + ".jpg") elif datasets.lower() == 'voc2007': image_path = os.path.join(
def main(): """ """ exp_path = Path.cwd() torch.cuda.empty_cache() # get user to choose training config config_file = "ResNet.json" # Load Test Parameters with open(config_file, "r") as f: x = json.load(f) hyperparams = x["HYPERPARAMETERS"] name = x["model"] n_bands = hyperparams['n_bands'] patch_size = hyperparams['patch_size'] _, path = utils.experiment_path_build(x) c_drive_docs = Path(x["LOGGING"]["log_location"]) log_file = Path(x["LOGGING"]["log_file"]) default_device = torch.device( 'cuda:0' if torch.cuda.is_available() else 'cpu') # Parameters validation_split = hyperparams["validation_split"] test_split = hyperparams["test_split"] random_seed = x["BASIC_PARAMETERS"]["random_seed"] shuffle_dataset = x["LOCATIONS"]["shuffle_dataset"] disp_batch = hyperparams["disp_batch"] # images to display on test epochs = hyperparams["epoch"] bs = hyperparams["batch_size"] n_jobs = x["BASIC_PARAMETERS"]["n_jobs"] lr = hyperparams["learning_rate"] HSI_ds = HSI_Dataset(path) _, classes = utils.get_classes(path) num_classes = len(classes) train_ds_sampler, valid_ds_sampler, test_ds_sampler = train_test_valid_split( HSI_ds, shuffle_dataset, validation_split, test_split, random_seed) phases = make_phases(HSI_ds, train_ds_sampler, valid_ds_sampler, test_ds_sampler, bs=32, n_jobs=4, disp_batch=disp_batch) model = Net(ResidualBlock, [2, 4, 8], in_channels=n_bands, num_classes=num_classes).to(default_device) # Lee Model Call # model = Net(n_bands, n_classes, patch_size) opt = optim.Adam(model.parameters(), lr=1e-2) training_params = {'Dataset Path': path, 'Experiment Path': exp_path, 'number of classes': num_classes, 'number of bands': n_bands, 'patch size': patch_size, 'test_train Split': { 'validation split': validation_split, 'shuffle dataset': shuffle_dataset, 'random seed': random_seed}, 'Batch Size': bs, "Number of Jobs": n_jobs, "Learning Rate": lr, "Scheduler": "One Cycle Schedule" } cb = CallbacksGroup([ RollingLoss(), Accuracy(), Scheduler( OneCycleSchedule(t=len(phases[0].loader) * epochs), mode='batch' ), StreamLogger(), CSVLogger(c_drive_docs.joinpath(log_file), training_params), ProgressBar(), save_model(c_drive_docs, name), test_images(path=c_drive_docs, batch_size=5, classes=classes) ]) # save_model(exp_path, name) train(model, opt, phases, cb, epochs=epochs, device=default_device, loss_fn=F.cross_entropy) lr_history = pd.DataFrame(cb['scheduler'].parameter_history('lr')) ax = lr_history.plot(figsize=(8, 6)) ax.set_xlabel('Training Batch Index') ax.set_ylabel('Learning Rate') fig = ax.get_figure() file_loc = [str(c_drive_docs) + "\\checkpoints\\lr-test.jpg"] s = "" s = s.join(file_loc) conf_path = Path(s) fig.savefig(conf_path)
def train(self, classes_path, anchors_path): ''' Args: classes_path:classes路径 anchors_path:anchor路径 ''' classes_names = get_classes(classes_path) num_classes = len(classes_names) anchors = get_anchors(anchors_path) is_tiny_version = len(anchors) == 6 # default setting if is_tiny_version: model = create_tiny_model(input_shape, anchors, num_classes, freeze_body=2) else: model = create_model(input_shape, anchors, num_classes, load_pretrained=False) logging = TensorBoard(log_dir=log_dir) # checkpoint = ModelCheckpoint(log_dir + 'car_mobilenet_yolov3.ckpt', # monitor='val_loss', save_weights_only=False, period=1) checkpoint = ModelCheckpoint( log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5', monitor='val_loss', save_weights_only=False, save_best_only=True, period=3) # reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1) reduce_lr = ReduceLROnPlateau(monitor="val_loss", factor=0.1, min_lr=1e-9, patience=5, verbose=1) # early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1) with open(train_path) as t_f: t_lines = t_f.readlines() np.random.seed(666) np.random.shuffle(t_lines) num_val = int(len(t_lines) * val_split) num_train = len(t_lines) - num_val t_lines = t_lines[:num_train] v_lines = t_lines[num_train:] # train with frozen layers first ,to get a stable loss. # adjust num epochs to your dataset,This step is enough to obtrain a not bad model if True: model.compile( optimizer=Adam(lr=1e-3), loss={ # use custom yolo_loss Lambda layer. 'yolo_loss': lambda y_true, y_pred: y_pred }) print('Train on {} samples, val on {} samples, with batch size {}.'. format(num_train, num_val, batch_num)) model.fit_generator(data_generator_wrapper(t_lines, batch_num, input_shape, anchors, num_classes), steps_per_epoch=max(1, num_train // batch_num), validation_data=data_generator_wrapper( v_lines, batch_num, input_shape, anchors, num_classes), validation_steps=max(1, num_val // batch_num), epochs=epochs, initial_epoch=0, callbacks=[logging, checkpoint]) model.save(log_dir + 'trained_weights_stage_1.h5') # Unfreeze and continue training, to fine-tune. # Train longer if the result is not good. if True: print("Unfreeze and continue training, to fine-tune.") for i in range(len(model.layers)): model.layers[i].trainable = True model.compile(optimizer=Adam(lr=1e-4), loss={ 'yolo_loss': lambda y_true, y_pred: y_pred }) # recompile to apply the change batch_size = 16 # note that more GPU memory is required after unfreezing the body print( 'Train on {} samples, val on {} samples, with batch size {}.'. format(num_train, num_val, batch_size)) model.fit_generator( data_generator_wrapper(t_lines, batch_size, input_shape, anchors, num_classes), steps_per_epoch=max(1, num_train // batch_size), validation_data=data_generator_wrapper(v_lines, batch_size, input_shape, anchors, num_classes), validation_steps=max(1, num_val // batch_size), epochs=20, initial_epoch=0, callbacks=[logging, checkpoint, reduce_lr]) model.save(log_dir + 'trained_weights_final.h5')
#------------------------------------------------------# # 判断当前使用的GPU数量与机器上实际的GPU数量 #------------------------------------------------------# if ngpus_per_node > 1 and ngpus_per_node > len(gpus): raise ValueError("The number of GPUs specified for training is more than the GPUs on the machine") if ngpus_per_node > 1: strategy = tf.distribute.MirroredStrategy() else: strategy = None print('Number of devices: {}'.format(ngpus_per_node)) #----------------------------------------------------# # 获取classes和anchor #----------------------------------------------------# class_names, num_classes = get_classes(classes_path) anchors, num_anchors = get_anchors(anchors_path) #----------------------------------------------------# # 判断是否多GPU载入模型和预训练权重 #----------------------------------------------------# if ngpus_per_node > 1: with strategy.scope(): #------------------------------------------------------# # 创建yolo模型 #------------------------------------------------------# model_body = yolo_body((None, None, 3), anchors_mask, num_classes, backbone, alpha, weight_decay=weight_decay) if model_path != '': #------------------------------------------------------# # 载入预训练权重 #------------------------------------------------------#
def _main(): # parse command line arguments parser = argparse.ArgumentParser() requiredNamed = parser.add_argument_group('required named arguments') requiredNamed.add_argument( '--path_to_input_image', type=str, required=True, help= 'The path to the input image on which object detection will be performed on.\n\ This argument is required.') parser.add_argument( '--path_to_trained_model', default='model_weights/coco_pretrained_weights.ckpt', type=str, help= "The path to the location of pretrained model weights, which will be loaded into\n\ the model and then used for object detection. The default pretrained weights path is\n\ 'model_weights/coco_pretrained_weights.ckpt', which contains weights trained on\n\ the coco dataset.") parser.add_argument( '--save_as', type=str, default=None, help= 'The filename for the image on which object detection was performed. If no filename\n\ is provided, the image will be saved as "[original_name] + _yolo_v3.jpg".' ) parser.add_argument('--tensorboard_save_path', default='tensorboard/tensorboard_detect/', help="") parser.add_argument( '--class_path', default='utils/coco_classes.txt', type=str, help= 'The path that points towards where the class names for the dataset are stored.\n\ The default path is "utils/coco_classes.txt".') parser.add_argument( '--anchors_path', default='utils/anchors.txt', type=str, help= 'The path that points towards where the anchor values for the model are stored.\n\ The default path is "utils/anchors.txt", which contains anchors trained on the coco dataset.' ) parser.add_argument( '--input_height', default=416, type=int, help= 'The input height of the yolov3 model. The height must be a multiple of 32.\n\ The default height is 416.') parser.add_argument( '--input_width', default=416, type=int, help= 'The input width of the yolov3 model. The width must be a mutliple of 32.\n\ The default width is 416.') args = vars(parser.parse_args()) h = args['input_height'] w = args['input_width'] anchors = get_anchors(args['anchors_path']) classes = get_classes(args['class_path']) save_as = args['save_as'] if save_as is None: filename_w_ext = os.path.basename(args['path_to_input_image']) filename, file_extension = os.path.splitext(filename_w_ext) save_as = filename + '_yolo_v3' + file_extension image, original_im = process_image(args['path_to_input_image'], h, w) tf.reset_default_graph() # build graph with tf.variable_scope('x_input'): X = tf.placeholder(dtype=tf.float32, shape=[None, h, w, 3]) yolo_outputs = yolo_v3(inputs=X, num_classes=len(classes), anchors=anchors, h=h, w=w, training=False) # output with tf.variable_scope('obj_detections'): raw_outputs = tf.concat(yolo_outputs, axis=1) # pass image through model with tf.Session() as sess: writer = tf.summary.FileWriter(args['tensorboard_save_path'], sess.graph) writer.close() saver = tf.train.Saver() print('restoring model weights...') saver.restore(sess, save_path=args['path_to_trained_model']) print('feeding image found at filepath: ', args['path_to_input_image']) start = time.time() ro = sess.run(raw_outputs, feed_dict={X: [np.array(image, dtype=np.float32)]}) end = time.time() total_time = end - start print("total inference time was: " + str(round(total_time, 2)) + " seconds (that's " + str(round(60.0 / total_time, 2)) + " fps!)") # convert box coordinates, apply nms, and draw boxes boxes = convert_box_coordinates(ro) filtered_boxes = non_max_suppression(boxes, confidence_threshold=0.5, iou_threshold=0.4) draw_boxes(save_as, args['class_path'], filtered_boxes, original_im, image) print('image with detections saved as: ', save_as)