def test_dataset(): classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/tiny_yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (416, 416) # multiple of 32, hw batch_size = 1 annotation_path = 'train.txt' with open(annotation_path) as f: lines = f.readlines() tset = create_dataset(lines[:2000], batch_size, input_shape, anchors, num_classes, False) ter = iter(tset) for i in range(3): a, b = next(ter) img, lb1, lb2 = a[0][0], a[1][0], a[2][0] plt.imshow(img.numpy()) plt.show() true_confidence = lb1[..., 4:5] obj_mask = true_confidence[..., 0] > .7 tf.boolean_mask(lb1, obj_mask) # NOTE 他就是按比例缩小图像的。 np.min(a[0][0]) np.max(a[0][0])
def test_get_random_data(): classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/tiny_yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (416, 416) # multiple of 32, hw batch_size = 1 annotation_path = 'train.txt' with open(annotation_path) as f: lines = f.readlines() for i in range(10): img, box = get_random_data(lines[i], input_shape, False) box = box[np.newaxis, :2, :] # print(box,input_shape,anchors,num_classes) y_true = preprocess_true_boxes(box, input_shape, anchors, num_classes, is_print=True) for a in y_true: true_box = a[np.where(a[..., 4] > 0)] true_box[:, :2] *= input_shape[::-1] true_box[:, 2:4] *= input_shape[::-1] xyxy_box = center_to_corner(true_box) # print(xyxy_box) for b in xyxy_box: cv2.rectangle(img, tuple(b[:2].astype(int)), tuple(b[2:4].astype(int)), (255, 0, 0))
def test_zip_dataset(): """ 尝试zip dataset,但还是失败了 """ annotation_path = 'train.txt' classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) val_split = 0.1 with open(annotation_path) as f: annotation_lines = f.readlines() np.random.seed(10101) np.random.shuffle(annotation_lines) np.random.seed(None) num_val = int(len(annotation_lines) * val_split) num_train = len(annotation_lines) - num_val batch_size = 32 input_shape = (416, 416) num = len(annotation_lines) if num == 0 or batch_size <= 0: raise ValueError def parser(lines): image_data = [] box_data = [] for line in lines: image, box = get_random_data(line.numpy().decode(), input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = [ tf.convert_to_tensor(y, tf.float32) for y in preprocess_true_boxes( box_data, input_shape, anchors, num_classes) ] image_data = tf.convert_to_tensor(image_data, tf.float32) return (image_data, *y_true) x_set = (tf.data.Dataset.from_tensor_slices(annotation_lines).apply( tf.data.experimental.shuffle_and_repeat( batch_size * 300, seed=66)).batch( batch_size, drop_remainder=True).map(lambda lines: py_function( parser, [lines], [tf.float32] * (1 + len(anchors) // 3)))) y_set = tf.data.Dataset.from_tensors(tf.zeros(batch_size, tf.float32)).repeat() dataset = tf.data.Dataset.zip((x_set, y_set)) sample = next(iter(dataset))
def test_resize_img(): classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/tiny_yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (224, 320) # multiple of 32, hw batch_size = 1 annotation_path = 'train.txt' with open(annotation_path) as f: lines = f.readlines() img, box = get_random_data(lines[3], input_shape, False) plt.imshow(img) plt.imsave('')
def test_model_graph(): """ tensorflow.keras 中load weights不支持那个跳过不匹配的层,所以必须手动控制权重 """ yolo = keras.models.load_model( 'model_data/yolo_weights.h5') # type:keras.models.Model tbcback = TensorBoard() tbcback.set_model(yolo) annotation_path = 'train.txt' log_dir = 'logs/000/' classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (416, 416) # multiple of 32, hw h, w = input_shape image_input = keras.Input(shape=(h, w, 3)) num_anchors = len(anchors) y_true = [ keras.Input(shape=(h // { 0: 32, 1: 16, 2: 8 }[l], w // { 0: 32, 1: 16, 2: 8 }[l], num_anchors // 3, num_classes + 5)) for l in range(3) ] model_body = yolo_body(image_input, num_anchors // 3, num_classes) print('Create YOLOv3 model with {} anchors and {} classes.'.format( num_anchors, num_classes)) yolo_weight = yolo.get_weights() for i, w in enumerate(yolo_weight): if w.shape == (1, 1, 1024, 255): yolo_weight[i] = w[..., :(num_anchors // 3) * (num_classes + 5)] if w.shape == (1, 1, 512, 255): yolo_weight[i] = w[..., :(num_anchors // 3) * (num_classes + 5)] if w.shape == (1, 1, 256, 255): yolo_weight[i] = w[..., :(num_anchors // 3) * (num_classes + 5)] if w.shape == (255, ): yolo_weight[i] = w[:(num_anchors // 3) * (num_classes + 5)] model_body.set_weights(yolo_weight)
def test_parser(): """ 测试parser函数以支持eager tensor """ annotation_path = 'train.txt' classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) val_split = 0.1 with open(annotation_path) as f: annotation_lines = f.readlines() np.random.seed(10101) np.random.shuffle(annotation_lines) np.random.seed(None) num_val = int(len(annotation_lines) * val_split) num_train = len(annotation_lines) - num_val batch_size = 32 input_shape = (416, 416) num = len(annotation_lines) if num == 0 or batch_size <= 0: raise ValueError lines = tf.convert_to_tensor(annotation_lines[:10], tf.string) """ start parser """ image_data = [] box_data = [] for line in lines: image, box = get_random_data(line.numpy().decode(), input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = [ tf.convert_to_tensor(y, tf.float32) for y in preprocess_true_boxes( box_data, input_shape, anchors, num_classes) ] image_data = tf.convert_to_tensor(image_data, tf.float32) return (image_data, *y_true)
def test_dict_dataset(): """ 尝试输出字典形式的dataset """ annotation_path = 'train.txt' classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) val_split = 0.1 with open(annotation_path) as f: annotation_lines = f.readlines() np.random.seed(10101) np.random.shuffle(annotation_lines) np.random.seed(None) num_val = int(len(annotation_lines) * val_split) num_train = len(annotation_lines) - num_val batch_size = 32 input_shape = (416, 416) num = len(annotation_lines) if num == 0 or batch_size <= 0: raise ValueError def parser(lines): image_data = [] box_data = [] for line in lines: image, box = get_random_data(line, input_shape, random=True) image_data.append(image) box_data.append(box) image_data = np.array(image_data) box_data = np.array(box_data) y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes) return { 'input_1': image_data, 'input_2': y_true[0], 'input_3': y_true[1], 'input_4': y_true[2] }
"""把 YOLO weights 轉換為能夠提供給 keras 作為訓練新模型的初始權重,注意這部分多了一個 `-w` 的參數,可以參考 https://github.com/qqwweee/keras-yolo3/blob/master/convert.py#L242 以及 https://stackoverflow.com/questions/42621864/difference-between-keras-model-save-and-model-save-weights 理解其中差別""" ''' if not os.path.exists("model_data/yolo_weights.h5"): print("Converting pretrained YOLOv3 weights for training") os.system("python convert.py -w yolov3.cfg yolov3.weights model_data/yolo_weights.h5") else: print("Pretrained weights exists") ''' annotation_path = '2007_train.txt' # 轉換好格式的標註檔案 log_dir = 'logs/000/' # 訓練好的模型儲存的路徑 classes_path = 'model_data/voc_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (416, 416) # multiple of 32, hw is_tiny_version = len(anchors) == 6 # default setting if is_tiny_version: model = create_tiny_model(input_shape, anchors, num_classes, freeze_body=2, weights_path='model_data/tiny_yolo_weights.h5') else: model = create_model(input_shape, anchors, num_classes, freeze_body=2,
MODEL_DIR = './models/' + VERSION_NAME LOG_DIR = './logs/' + VERSION_NAME + '/' TRAINED_BASE_FILE = os.path.join(MODEL_DIR, 'trained_weights_base.h5') TRAINED_FINAL_FILE = os.path.join(MODEL_DIR, 'trained_weights_final.h5') # Create directories if not os.path.exists(MODEL_DIR): os.makedirs(MODEL_DIR) if not os.path.exists(LOG_DIR): os.makedirs(LOG_DIR) # Setup Model class_names = train.get_classes(CLASSES_FILE) num_classes = len(class_names) anchors = train.get_anchors(ANCHORS_FILE) logging = TensorBoard(log_dir=LOG_DIR) checkpoint = ModelCheckpoint(os.path.join(MODEL_DIR, TEMP_MODEL_FORMAT), monitor='val_loss', save_weights_only=True, save_best_only=True, period=3) reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1) early_stopping = EarlyStopping(monitor='val_loss',
def test_get_anchors(self): self.assertEqual(get_anchors(self.yolo_anchors).shape, (9, 2))
def _main(): from train import get_classes, get_anchors annotation_path = 'data/input.csv' log_dir = 'logs/000/' classes_path = 'model_data/stdogs_classes.txt' anchors_path = 'model_data/yolo_anchors.txt' val_split = 0.5 class_names = get_classes(classes_path) num_classes = len(class_names) anchors = get_anchors(anchors_path) input_shape = (416, 416) # multiple of 32, hw is_tiny_version = len(anchors) == 6 # default setting with open(annotation_path) as f: lines = f.readlines() np.random.seed(10101) np.random.shuffle(lines) np.random.seed(None) num_val = int(len(lines) * val_split) num_train = len(lines) - num_val save_interval = 3 num_val = int(num_train * 0.2) batch_size = 4 train_data = data_generator_wrapper(lines[:num_train], batch_size, input_shape, anchors, num_classes) eval_data = data_generator_wrapper(lines[num_train:num_train + num_val], batch_size, input_shape, anchors, num_classes) body = model_body(input_shape, anchors, num_classes, None, freeze_body=2, init_weights='model_data/darknet53.weights.h5', last_save='model_data/tfmodel') num_epoch = 100 optimizer = tf.keras.optimizers.Adam() tf.summary.experimental.set_step(0) step = 0 test_summary_writer = tf.summary.create_file_writer( os.path.join("logs/test/", datetime.now().strftime("%Y%m%d-%H%M%S")), ) train_summary_writer = tf.summary.create_file_writer( os.path.join("logs/train/", datetime.now().strftime("%Y%m%d-%H%M%S")), ) def write_loss(writer, **kwargs): with writer.as_default(): for k, v in kwargs.items(): tf.summary.scalar(k, v, step=step) def train_step(image, y1, y2, y3): with tf.GradientTape() as tape: outputs = body(image) loss, losses = loss_wrapper(outputs, [y1, y2, y3], anchors, num_classes) write_loss(train_summary_writer, **losses) grads = tape.gradient(loss, body.trainable_weights) optimizer.apply_gradients(zip(grads, body.trainable_variables)) return loss def evaluate_step(image, y1, y2, y3): with tf.GradientTape() as tape: outputs = body(image) loss, losses = loss_wrapper(outputs, [y1, y2, y3], anchors, num_classes) write_loss(test_summary_writer, **losses) return loss for epoch in range(num_epoch): print("epoch:", epoch) with tqdm(train_data, total=num_train // batch_size) as tbar: for x in train_data.take(num_train // batch_size): image, y1, y2, y3 = x loss = train_step(image, y1, y2, y3) tbar.update(1) tbar.set_description("loss={:.3f}".format(loss)) step = step + 1 val_loss = 0 for x in eval_data.take(num_val // batch_size): image, y1, y2, y3 = x val_loss += evaluate_step(image, y1, y2, y3) val_loss = val_loss / num_val * batch_size print("val_loss:", val_loss) if epoch + 1 % save_interval == 0: tf.saved_model.save(body, "model_data/tfmodel")
plot_boxes_cv2(img, boxes[0], savename=os.path.join("demo_img", "predictions_{}.jpg".format(i)), class_names=class_names) if __name__ == "__main__": args = getArgs() # import config file and save it to log update_config(cfg, args) print("getting anchors...") anchors = get_anchors(cfg) print(anchors) log_dir = os.path.join("log", os.path.basename(args.config_file)[:-5]) if not args.load: latest_weight = os.path.join( log_dir, "checkpoints", os.listdir(os.path.join(log_dir, "checkpoints"))[0]) elif os.path.exists(args.load): latest_weight = args.load device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') if cfg.use_darknet_cfg: eval_model = Darknet(cfg.cfgfile) else: eval_model = Yolov4(anchors, yolov4conv137weight=None, n_classes=cfg.classes,