예제 #1
0
 def fit(self, list_IDs, labels):
     train_list_IDs, val_list_IDs, train_labels, val_labels = train_test_split(
         list_IDs, labels, test_size=0.3)
     train_data_dir = self.config.data_dir + 'audio_train/'
     train_generator = DataGenerator(self.config, train_data_dir,
                                     train_list_IDs, train_labels,
                                     audio_norm_min_max)
     val_generator = DataGenerator(self.config, train_data_dir,
                                   val_list_IDs, val_labels,
                                   audio_norm_min_max)
     checkpoint = ModelCheckpoint(self.config.tmp_dir + 'model_1/' +
                                  'best_%d.h5' % self.config.run_time,
                                  monitor='val_loss',
                                  verbose=1,
                                  save_best_only=True)
     early_stop = EarlyStopping(monitor="val_loss", mode="min", patience=5)
     tb = TensorBoard(log_dir=self.config.log_dir + 'model_1',
                      write_graph=True)
     callbacks_list = [checkpoint, early_stop, tb]
     history = self.model.fit_generator(train_generator,
                                        callbacks=callbacks_list,
                                        validation_data=val_generator,
                                        epochs=self.config.max_epochs,
                                        use_multiprocessing=True,
                                        workers=6,
                                        max_queue_size=20)
     return history
예제 #2
0
def load_model(fileName):
    # 实例化配置参数对象
    config = Config()

    # 实例化数据生成对象
    dataGen = DataGenerator(fileName, config)
    dataGen.gen_attr()  # 生成训练集和测试集

    test_seqs = dataGen.test_seqs

    with tf.Session() as sess:

        accuracys = []
        aucs = []
        step = 1

        for params in dataGen.next_batch(test_seqs):
            print("step: {}".format(step))

            checkpoint_file = tf.train.latest_checkpoint("model/")
            saver = tf.train.import_meta_graph("{}.meta".format(checkpoint_file))
            saver.restore(sess, checkpoint_file)

            # 获得默认的计算图结构
            graph = tf.get_default_graph()

            # 获得需要喂给模型的参数,输出的结果依赖的输入值
            input_x = graph.get_operation_by_name("test/dkt/input_x").outputs[0]
            target_id = graph.get_operation_by_name("test/dkt/target_id").outputs[0]
            keep_prob = graph.get_operation_by_name("test/dkt/keep_prob").outputs[0]
            max_steps = graph.get_operation_by_name("test/dkt/max_steps").outputs[0]
            sequence_len = graph.get_operation_by_name("test/dkt/sequence_len").outputs[0]

            # 获得输出的结果
            pred_all = graph.get_tensor_by_name("test/dkt/pred_all:0")
            pred = graph.get_tensor_by_name("test/dkt/pred:0")
            binary_pred = graph.get_tensor_by_name("test/dkt/binary_pred:0")

            target_correctness = params['target_correctness']
            pred_all, pred, binary_pred = sess.run([pred_all, pred, binary_pred],
                                                   feed_dict={input_x: params["input_x"],
                                                              target_id: params["target_id"],
                                                              keep_prob: 1.0,
                                                              max_steps: params["max_len"],
                                                              sequence_len: params["seq_len"]})

            auc, acc = gen_metrics(params["seq_len"], binary_pred, pred, target_correctness)
            print(auc, acc)
            accuracys.append(acc)
            aucs.append(auc)
            step += 1

        aucMean = mean(aucs)
        accMean = mean(accuracys)

        print("inference  auc: {}  acc: {}".format(aucMean, accMean))
예제 #3
0
    def get_features(self, list_IDs, audio_path):
        audio_data_dir = self.config.data_dir + audio_path
        data_generator = DataGenerator(self.config, audio_data_dir, list_IDs, None, audio_norm_min_max)
        if audio_path.endswith('train/'):
            ss = 'train_features'
        else:
            ss = 'test_features'
        save_file = self.config.tmp_dir + self.config.model_name + '_%d/' % self.config.run_time
        if self.config.use_folds:
            for i in range(self.config.n_folds):
                print('Fold: ', i)
                self.model.load_weights(save_file + 'best_%d.h5' % i)
                feature_model = models.Model(inputs=self.model.input, outputs=self.model.layers[-3].output)
                extract_features = feature_model.predict_generator(data_generator,
                                                                   use_multiprocessing=True,
                                                                   workers=6,
                                                                   max_queue_size=20,
                                                                   verbose=1)

                np.save(save_file + ss + '_%d.npy' % i, extract_features)
        else:
            self.model.load_weights(save_file + 'best.h5')
            feature_model = models.Model(inputs=self.model.input, outputs=self.model.layers[-3].output)
            extract_features = feature_model.predict_generator(data_generator,
                                                               use_multiprocessing=True,
                                                               workers=6,
                                                               max_queue_size=20,
                                                               verbose=1)
            np.save(save_file + ss + '.npy', extract_features)
예제 #4
0
    def fit(self, list_IDs, labels):
        train_data_dir = self.config.data_dir + 'audio_train/'
        if self.config.use_folds:
            history = []
            skf = StratifiedKFold(n_splits=self.config.n_folds)
            for i, (train_split, val_split) in enumerate(skf.split(list_IDs, labels)):
                train_list_IDs, val_list_IDs = list_IDs[train_split], list_IDs[val_split]
                train_labels, val_labels = labels[train_split], labels[val_split]
                checkpoint = ModelCheckpoint(self.config.tmp_dir + self.config.model_name
                                             + '_%d/best_%d.h5' % (self.config.run_time, i),
                                             monitor='val_loss',
                                             verbose=1,
                                             save_best_only=True)
                early_stop = EarlyStopping(monitor="val_loss", mode="min", patience=10)
                tb = TensorBoard(log_dir=self.config.log_dir + self.config.model_name
                                         + '_%d/fold_%d' % (self.config.run_time, i),
                                 write_graph=True)
                callbacks_list = [checkpoint, early_stop, tb]

                print("Fold: ", i)
                train_generator = DataGenerator(self.config, train_data_dir, train_list_IDs, train_labels, audio_norm_min_max)
                val_generator = DataGenerator(self.config, train_data_dir, val_list_IDs, val_labels, audio_norm_min_max)
                res = self.model.fit_generator(train_generator,
                                                   callbacks=callbacks_list,
                                                   validation_data=val_generator,
                                                   epochs=self.config.max_epochs,
                                                   use_multiprocessing=True,
                                                   workers=6,
                                                   max_queue_size=20)
                history.append(res)
        else:
            train_list_IDs, val_list_IDs, train_labels, val_labels = train_test_split(list_IDs, labels, test_size=0.3)
            train_generator = DataGenerator(self.config, train_data_dir, train_list_IDs, train_labels, audio_norm_min_max)
            val_generator = DataGenerator(self.config, train_data_dir, val_list_IDs, val_labels, audio_norm_min_max)
            checkpoint = ModelCheckpoint(self.config.tmp_dir + self.config.model_name + '_%d/best.h5' % self.config.run_time,
                                         monitor='val_loss', verbose=1, save_best_only=True)
            early_stop = EarlyStopping(monitor="val_loss", mode="min", patience=10)
            tb = TensorBoard(log_dir=self.config.log_dir + self.config.model_name + '_%d' % self.config.run_time, write_graph=True)
            callbacks_list = [checkpoint, early_stop, tb]
            history = self.model.fit_generator(train_generator,
                                               callbacks=callbacks_list,
                                               validation_data=val_generator,
                                               epochs=self.config.max_epochs,
                                               use_multiprocessing=True,
                                               workers=6,
                                               max_queue_size=20)
        return history
예제 #5
0
 def predict(self, list_IDs):
     test_data_dir = self.config.data_dir + 'audio_test/'
     test_generator = DataGenerator(self.config, test_data_dir, list_IDs,
                                    None, audio_norm_min_max)
     self.model.load_weights(self.config.tmp_dir + 'model_2/' +
                             'best_%d.h5' % self.config.run_time)
     predictions = self.model.predict_generator(test_generator,
                                                use_multiprocessing=True,
                                                workers=6,
                                                max_queue_size=20,
                                                verbose=1)
     return predictions
예제 #6
0
 def get_features(self, list_IDs, audio_path):
     audio_data_dir = self.config.data_dir + audio_path
     feature_model = models.Model(inputs=self.model.input,
                                  outputs=self.model.layers[-2].output)
     data_generator = DataGenerator(self.config, audio_data_dir, list_IDs,
                                    None, audio_norm_min_max)
     self.model.load_weights(self.config.tmp_dir + 'model_2/' +
                             'best_%d.h5' % self.config.run_time)
     extract_features = feature_model.predict_generator(
         data_generator,
         user_multiprocessing=True,
         workers=6,
         max_queue_size=20,
         verbose=1)
     return extract_features
예제 #7
0
 def predict(self, list_IDs):
     test_data_dir = self.config.data_dir + 'audio_test/'
     test_generator = DataGenerator(self.config, test_data_dir, list_IDs, None, audio_norm_min_max)
     if self.config.use_folds:
         for i in range(self.config.n_folds):
             print('Fold: ', i)
             self.model.load_weights(self.config.tmp_dir + self.config.model_name
                                     + '_%d/best_%d.h5' % (self.config.run_time, i))
             predictions = self.model.predict_generator(test_generator,
                                                        use_multiprocessing=True,
                                                        workers=6,
                                                        max_queue_size=20,
                                                        verbose=1)
             np.save(self.config.tmp_dir + self.config.model_name + '_%d/pred_%d.npy' % (self.config.run_time, i),
                     predictions)
     else:
         self.model.load_weights(self.config.tmp_dir + self.config.model_name + '_%d/best.h5' % self.config.model_name)
         predictions = self.model.predict_generator(test_generator,
                                                    use_multiprocessing=True,
                                                    workers=6,
                                                    max_queue_size=20,
                                                    verbose=1)
         np.save(self.config.tmp_dir + self.config.model_name + '_%d/pred.npy' % self.config.run_time, predictions)
예제 #8
0
def train(args,train_dkt):
    run_config = tf.ConfigProto()
    run_config.gpu_options.allow_growth = True

    with tf.Session(config=run_config) as sess:

        print(args.model)

        model = GIKT(args)

        saver = tf.train.Saver()
        index = 0

        if train_dkt:
            # lr = 0.4
            # lr_decay = 0.92
            sess.run(tf.global_variables_initializer())

            model_dir = save_model_dir(args)

            best_valid_auc = 0

            for epoch in tqdm(range(args.num_epochs)):
                train_generator = DataGenerator(args.train_seqs, args.max_step, batch_size=args.batch_size,
                                                feature_size=args.feature_answer_size - 2,
                                                hist_num=args.hist_neighbor_num)
                valid_generator = DataGenerator(args.valid_seqs, args.max_step, batch_size=args.batch_size,
                                                feature_size=args.feature_answer_size - 2,
                                                hist_num=args.hist_neighbor_num)
                #    assign_lr()
                print("epoch:", epoch)
                # self.assign_lr(self.sess,self.args.lr * self.args.lr_decay ** epoch)
                overall_loss = 0
                train_generator.shuffle()
                preds, binary_preds, targets = list(), list(), list()
                train_step = 0
                while not train_generator.end:
                    train_step += 1

                    [features_answer_index,target_answers,seq_lens,hist_neighbor_index] = train_generator.next_batch()
                    binary_pred, pred, loss = model.train(sess,features_answer_index,target_answers,seq_lens,hist_neighbor_index)

                    overall_loss += loss
                    for seq_idx, seq_len in enumerate(seq_lens):
                        preds.append(pred[seq_idx, 0:seq_len])
                        binary_preds.append(binary_pred[seq_idx, 0:seq_len])
                        targets.append(target_answers[seq_idx, 0:seq_len])
                # print("\r idx:{0}, overall_loss:{1}".format(train_generator.pos, overall_loss)),
                train_loss = overall_loss / train_step
                preds = np.concatenate(preds)
                binary_preds = np.concatenate(binary_preds)
                targets = np.concatenate(targets)
                auc_value = roc_auc_score(targets, preds)
                accuracy = accuracy_score(targets, binary_preds)
                precision, recall, f_score, _ = precision_recall_fscore_support(targets, binary_preds)
                print("\ntrain loss = {0},auc={1}, accuracy={2}".format(train_loss, auc_value, accuracy))
                write_log(args,model_dir,auc_value, accuracy, epoch, name='train_')

                # if epoch == self.args.num_epochs-1:
                #     self.save(epoch)

                # valid
                valid_generator.reset()
                preds, binary_preds, targets = list(), list(), list()
                valid_step = 0
                #overall_loss = 0
                while not valid_generator.end:
                    valid_step += 1
                    [features_answer_index,target_answers,seq_lens,hist_neighbor_index] = valid_generator.next_batch()
                    binary_pred, pred = model.evaluate(sess,features_answer_index,target_answers,seq_lens,hist_neighbor_index,valid_step)
                    #overall_loss += loss
                    for seq_idx, seq_len in enumerate(seq_lens):
                        preds.append(pred[seq_idx, 0:seq_len])
                        binary_preds.append(binary_pred[seq_idx, 0:seq_len])
                        targets.append(target_answers[seq_idx, 0:seq_len])
                # compute metrics
                #valid_loss = overall_loss / valid_step
                preds = np.concatenate(preds)
                binary_preds = np.concatenate(binary_preds)
                targets = np.concatenate(targets)
                auc_value = roc_auc_score(targets, preds)
                accuracy = accuracy_score(targets, binary_preds)
                precision, recall, f_score, _ = precision_recall_fscore_support(targets, binary_preds)
                print("\nvalid auc={0}, accuracy={1}, precision={2}, recall={3}".format(auc_value, accuracy, precision,
                                                                                        recall))


                write_log(args,model_dir,auc_value, accuracy, epoch, name='valid_')

                if auc_value > best_valid_auc:
                    print('%3.4f to %3.4f' % (best_valid_auc, auc_value))
                    best_valid_auc = auc_value
                    best_epoch = epoch
                    #np.save('feature_embedding.npy', feature_embedding)
                    checkpoint_dir = os.path.join(args.checkpoint_dir, model_dir)
                    save(best_epoch,sess,checkpoint_dir,saver)
#                print(model_dir)
                print(model_dir+"\t"+str(best_valid_auc))




        else:
            if self.load():
                print('CKPT loaded')
            else:
                raise Exception('CKPT need')
            test_data_generator = DataGenerator(args.test_seqs, args.max_step, batch_size=args.batch_size,
                                                feature_size=args.feature_answer_size - 2,
                                                hist_num=args.hist_neighbor_num)
            data_generator.reset()

            correct_times = np.zeros(self.num_skills + 1)
            preds, binary_preds, targets = list(), list(), list()
            while not test_data_generator.end:

                [features_answer_index, target_answers, seq_lens, hist_neighbor_index] = valid_generator.next_batch()
                binary_pred, pred = model.evaluate(sess, features_answer_index, target_answers, seq_lens,
                                                   hist_neighbor_index)
                # overall_loss += loss
                for seq_idx, seq_len in enumerate(seq_lens):
                    preds.append(pred[seq_idx, 0:seq_len])
                    binary_preds.append(binary_pred[seq_idx, 0:seq_len])
                    targets.append(target_answers[seq_idx, 0:seq_len])



            preds = np.concatenate(preds)
            binary_preds = np.concatenate(binary_preds)
            targets = np.concatenate(targets)
            auc_value = roc_auc_score(targets, preds)
            accuracy = accuracy_score(targets, binary_preds)
            precision, recall, f_score, _ = precision_recall_fscore_support(targets, binary_preds)
            print("\ntest auc={0}, accuracy={1}, precision={2}, recall={3}".format(auc_value, accuracy, precision,
                                                                                   recall))
            print(model_dir)
            write_log(args, model_dir, auc_value, accuracy, epoch, name='test_')
예제 #9
0
파일: train_dkt.py 프로젝트: LidhCS/dkt-1
    def run_epoch(self, fileName):
        """
        训练模型
        :param filePath:
        :return:
        """

        # 实例化配置参数对象
        config = Config()

        # 实例化数据生成对象
        dataGen = DataGenerator(fileName, config)
        dataGen.gen_attr()  # 生成训练集和测试集

        train_seqs = dataGen.train_seqs
        test_seqs = dataGen.test_seqs

        session_conf = tf.ConfigProto(allow_soft_placement=True,
                                      log_device_placement=False)
        sess = tf.Session(config=session_conf)
        self.sess = sess

        with sess.as_default():
            # 实例化dkt模型对象
            with tf.name_scope("train"):
                with tf.variable_scope("dkt", reuse=None):
                    train_dkt = TensorFlowDKT(config)

            with tf.name_scope("test"):
                with tf.variable_scope("dkt", reuse=True):
                    test_dkt = TensorFlowDKT(config)

            self.train_dkt = train_dkt
            self.test_dkt = test_dkt

            global_step = tf.Variable(0, name="global_step", trainable=False)
            self.global_step = global_step

            # 定义一个优化器
            optimizer = tf.train.AdamOptimizer(
                config.trainConfig.learning_rate)
            grads_and_vars = optimizer.compute_gradients(train_dkt.loss)

            # 对梯度进行截断,并且加上梯度噪音
            grads_and_vars = [
                (tf.clip_by_norm(g, config.trainConfig.max_grad_norm), v)
                for g, v in grads_and_vars if g is not None
            ]
            # grads_and_vars = [(self.add_gradient_noise(g), v) for g, v in grads_and_vars]

            # 定义图中最后的节点
            train_op = optimizer.apply_gradients(grads_and_vars,
                                                 global_step=global_step,
                                                 name="train_op")

            # 保存各种变量或结果的值
            grad_summaries = []
            for g, v in grads_and_vars:
                if g is not None:
                    grad_hist_summary = tf.summary.histogram(
                        "{}/grad/hist".format(v.name), g)
                    sparsity_summary = tf.summary.scalar(
                        "{}/grad/sparsity".format(v.name),
                        tf.nn.zero_fraction(g))
                    grad_summaries.append(grad_hist_summary)
                    grad_summaries.append(sparsity_summary)
            grad_summaries_merged = tf.summary.merge(grad_summaries)

            timestamp = str(int(time.time()))
            out_dir = os.path.abspath(
                os.path.join(os.path.curdir, "runs", timestamp))
            print("writing to {}".format(out_dir))

            # 训练时的 Summaries
            train_loss_summary = tf.summary.scalar("loss", train_dkt.loss)
            train_summary_op = tf.summary.merge(
                [train_loss_summary, grad_summaries_merged])
            train_summary_dir = os.path.join(out_dir, "summaries", "train")
            train_summary_writer = tf.summary.FileWriter(
                train_summary_dir, sess.graph)

            # 测试时的 summaries
            test_loss_summary = tf.summary.scalar("loss", test_dkt.loss)
            dev_summary_op = tf.summary.merge([test_loss_summary])
            dev_summary_dir = os.path.join(out_dir, "summaries", "dev")
            dev_summary_writer = tf.summary.FileWriter(dev_summary_dir,
                                                       sess.graph)

            saver = tf.train.Saver(tf.global_variables())

            sess.run(tf.global_variables_initializer())

            print("初始化完毕,开始训练")
            for i in range(config.trainConfig.epochs):
                np.random.shuffle(train_seqs)
                for params in dataGen.next_batch(train_seqs):
                    # 批次获得训练集,训练模型
                    self.train_step(params, train_op, train_summary_op,
                                    train_summary_writer)

                    current_step = tf.train.global_step(sess, global_step)
                    # train_step.run(feed_dict={x: batch_train[0], y_actual: batch_train[1], keep_prob: 0.5})
                    # 对结果进行记录
                    if current_step % config.trainConfig.evaluate_every == 0:
                        print("\nEvaluation:")
                        # 获得测试数据

                        losses = []
                        accuracys = []
                        aucs = []
                        for params in dataGen.next_batch(test_seqs):
                            loss, accuracy, auc = self.dev_step(params,
                                                                dev_summary_op,
                                                                writer=None)
                            losses.append(loss)
                            accuracys.append(accuracy)
                            aucs.append(auc)

                        time_str = datetime.datetime.now().isoformat()
                        print("dev: {}, step: {}, loss: {}, acc: {}, auc: {}".
                              format(time_str, current_step, mean(losses),
                                     mean(accuracys), mean(aucs)))

                    if current_step % config.trainConfig.checkpoint_every == 0:
                        path = saver.save(sess,
                                          "model/my-model",
                                          global_step=current_step)
                        print("Saved model checkpoint to {}\n".format(path))
예제 #10
0
def task_data_ready(task, model_param):  #get all pre processed data
    if task == "wikiqa":
        vocab_all = Vocab("./data/wikiqa/vocab_wiki.txt", max_size=80000)
        data_generator = DataGenerator(vocab_all, model_param,
                                       "./data/wikiqa/wiki_answer_train.pkl")
        embedding_file = "./data/wikiqa/wikiqa_glovec.txt"
        dev_data = data_generator.EvaluateGenerate(
            "./data/wikiqa/wiki_dev.pkl")
        test_data = data_generator.EvaluateGenerate(
            "./data/wikiqa/wiki_test.pkl")
    elif task == "trecqa":
        vocab_all = Vocab("./data/trecqa/vocab_trec.txt", max_size=80000)
        data_generator = DataGenerator(vocab_all, model_param,
                                       "./data/trecqa/trec_answer_train.pkl")
        embedding_file = "./data/trecqa/trecqa_glovec.txt"
        dev_data = data_generator.EvaluateGenerate(
            "./data/trecqa/trec_dev.pkl")
        test_data = data_generator.EvaluateGenerate(
            "./data/trecqa/trec_test.pkl")
    elif task == "insqa":
        vocab_all = Vocab("./data/insqa/vocab_insqa.txt", max_size=80000)
        data_generator = DataGenerator(vocab_all, model_param,
                                       "./data/insqa/insqa_answer_train.pkl")
        embedding_file = "./data/insqa/insqa_glovec.txt"
        dev_data = data_generator.EvaluateGenerate(
            "./data/insqa/insqa_dev.pkl")
        test_data = data_generator.EvaluateGenerate(
            "./data/insqa/insqa_test.pkl")
    elif task == "selqa":
        vocab_all = Vocab("./data/selqa/vocab_selqa.txt", max_size=80000)
        data_generator = DataGenerator(vocab_all, model_param,
                                       "./data/selqa/selqa_answer_train.pkl")
        embedding_file = "./data/selqa/selqa_glovec.txt"
        dev_data = data_generator.EvaluateGenerate(
            "./data/selqa/selqa_dev.pkl")
        test_data = data_generator.EvaluateGenerate(
            "./data/selqa/selqa_test.pkl")
    return vocab_all, data_generator, embedding_file, dev_data, test_data
예제 #11
0
 def __init__(self, width=448, height=448, channels=3):
     self.build_model(width, height, channels)
     self.data_gen = DataGenerator()
예제 #12
0
class Yolo_V1:
    def __init__(self, width=448, height=448, channels=3):
        self.build_model(width, height, channels)
        self.data_gen = DataGenerator()

    def build_model(self, width, height, channels):
        inputs = Input(shape=(height, width, channels))
        x = Conv2D(filters=64,
                   kernel_size=7,
                   strides=2,
                   activation='relu',
                   padding='same')(inputs)
        x = MaxPooling2D(2, strides=2)(x)
        x = Conv2D(filters=192,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = MaxPooling2D(2, strides=2)(x)
        x = Conv2D(filters=128,
                   kernel_size=1,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=256,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=256,
                   kernel_size=1,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=512,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = MaxPooling2D(2, strides=2)(x)
        for i in range(4):
            x = Conv2D(filters=256,
                       kernel_size=1,
                       strides=1,
                       activation='relu',
                       padding='same')(x)
            x = Conv2D(filters=512,
                       kernel_size=3,
                       strides=1,
                       activation='relu',
                       padding='same')(x)
        x = Conv2D(filters=512,
                   kernel_size=1,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=1024,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = MaxPooling2D(2, strides=2)(x)
        for i in range(2):
            x = Conv2D(filters=512,
                       kernel_size=1,
                       strides=1,
                       activation='relu',
                       padding='same')(x)
            x = Conv2D(filters=1024,
                       kernel_size=3,
                       strides=1,
                       activation='relu',
                       padding='same')(x)
        x = Conv2D(filters=1024,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=1024,
                   kernel_size=3,
                   strides=2,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=1024,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Conv2D(filters=1024,
                   kernel_size=3,
                   strides=1,
                   activation='relu',
                   padding='same')(x)
        x = Flatten()(x)
        x = Dense(4096, activation='relu')(x)
        x = Dense(7 * 7 * 30, activation='relu')(x)
        outputs = Reshape((7, 7, 30))(x)
        self.model = Model(inputs, outputs)

    def prepare_data(self,
                     train_path: str,
                     valid_path: str = None,
                     image_type='jpg'):
        labels_path = list(Path(train_path).glob('labels/*'))
        self.train_labels_path = [str(f) for f in labels_path]
        self.train_images_path = [
            os.path.join(train_path, 'images',
                         f.name.replace('xml', image_type))
            for f in labels_path
        ]

    def caculate_iou(self, bbox, ground_truth):
        bbox_x_min = bbox[..., 0] - bbox[..., 2] / 2
        bbox_x_max = bbox[..., 0] + bbox[..., 2] / 2
        bbox_y_min = bbox[..., 1] - bbox[..., 3] / 2
        bbox_y_max = bbox[..., 1] + bbox[..., 3] / 2
        gbox_x_min = ground_truth[..., 0] - ground_truth[..., 2] / 2
        gbox_x_max = ground_truth[..., 0] + ground_truth[..., 2] / 2
        gbox_y_min = ground_truth[..., 1] - ground_truth[..., 3] / 2
        gbox_y_max = ground_truth[..., 1] + ground_truth[..., 3] / 2

        inter_x_min = K.max([bbox_x_min, gbox_x_min], axis=0)
        inter_x_max = K.min([bbox_x_max, gbox_x_max], axis=0)
        inter_y_min = K.max([bbox_y_min, gbox_y_min], axis=0)
        inter_y_max = K.min([bbox_y_max, gbox_y_max], axis=0)
        inter = (inter_x_max - inter_x_min) * (inter_y_max - inter_y_min)
        union = (bbox_x_max - bbox_x_min)*(bbox_y_max - bbox_y_min) + \
            (gbox_x_max - gbox_x_min)*(gbox_y_max - gbox_y_min) - inter
        zeros_array = K.zeros_like(union)
        iou = inter / union
        return K.max([inter / union, zeros_array], axis=0)

    def loss(self, y_true, y_pred):
        loss = 0
        LANDA_coord = 5
        LANDA_noobj = 0.5
        bboxs = [y_pred[:, :, :, 0:5], y_pred[:, :, :, 5:10]]
        ground_truth = [y_true[:, :, :, 0:5], y_true[:, :, :, 5:10]]
        response_array = y_true[:, :, :, 4]
        noobj_array = K.ones_like(response_array)
        category = y_true[:, :, :, 10:]
        category_p = y_pred[:, :, :, 10:]

        for g_box in ground_truth:
            bbox_index = K.argmax([
                self.caculate_iou(bboxs[0], g_box),
                self.caculate_iou(bboxs[1], g_box)
            ],
                                  axis=0)
            for i, bbox in enumerate(bboxs):
                x = g_box[:, :, :, 0]
                y = g_box[:, :, :, 1]
                w = g_box[:, :, :, 2]
                h = g_box[:, :, :, 3]
                c = g_box[:, :, :, 4]
                x_p = bbox[:, :, :, 0]
                y_p = bbox[:, :, :, 1]
                w_p = bbox[:, :, :, 2]
                h_p = bbox[:, :, :, 3]
                c_p = bbox[:, :, :, 4]
                bbox_response_array = K.cast(K.equal(bbox_index, i), 'float32')
                loss += LANDA_coord * K.sum(
                    response_array * bbox_response_array *
                    (K.square(x - x_p) + K.square(y - y_p) +
                     K.square(K.sqrt(w) - K.sqrt(w_p)) +
                     K.square(K.sqrt(h) - K.sqrt(h_p))))
                loss += K.sum(response_array * bbox_response_array *
                              (K.square(c_p - c)))
                loss += K.sum(
                    K.expand_dims(response_array, axis=-1) *
                    K.square(K.softmax(category) - K.softmax(category_p)))
        loss += LANDA_noobj * noobj_array * K.square(c_p - c)
        return loss

    def fit(self, lr=0.0001, epochs=10, batch_size=8, **kwargs):
        train_generator = self.data_gen.generator(self.train_images_path,
                                                  self.train_labels_path,
                                                  batch_size=batch_size)
        steps_per_epoch = ceil(len(self.train_images_path) / batch_size)
        self.model.compile(loss=self.loss, optimizer=Adam(lr=0.0001))
        self.model.fit(train_generator,
                       epochs=epochs,
                       steps_per_epoch=steps_per_epoch,
                       **kwargs)