更改Keras模型以进行验证步骤

时间:2018-12-28 16:41:36

标签: python tensorflow keras

我有一个模型,在训练和推理过程中会有所不同。更准确地说,它是一个SSD(单发检测器),需要在其训练对象的顶部添加附加的DetectionOutput层。在Caffe中,可以使用图层定义中的“包含”参数来打开/关闭图层。

但是,如果我希望在每个时期之后(在回调内)运行验证,那么在定义和编译模型之后该怎么办?

我不能在训练期间添加DetectionOutput,因为它与损失的输入不兼容。

我还希望避免在回调或自定义指标内的任何地方创建DetectionOutput层,因为它需要合理的超参数,并且我希望将模型创建逻辑保留在专用模块内。

在下面的示例代码模型中,为推理而创建,存在DetectionOutput层。这样评估就可以了:

model, _, _ = build_model(input_shape=(args.input_height, args.input_width, 3),
                          n_classes=num_classes,
                          mode='inference')
model.load_weights(args.model, by_name=True)

evaluation = SSDEvaluation(model=model,
                           evaluator=PascalDetectionEvaluator(categories),
                           data_files=[args.eval_data])
metrics = evaluation.evaluate()

但是此回调无法正常运行,因为在训练模型期间没有DetectionOutput:

class SSDTensorboard(Callback):
    def __init__(self, evaluator, eval_data):
        self.evaluator = evaluator
        self.eval_data = eval_data

    def on_train_begin(self, logs={}):
        self.metrics = []

    def on_epoch_end(self, epoch, logs={}):
        evaluation = SSDEvaluation(self.model, self.evaluator, self.eval_data)
        metrics = evaluation.evaluate()
        self.metrics.append(metrics)

什么是照常进行训练的正确方法(pythonic,keratonic等),但是对具有相同权重的变更模型执行验证步骤?也许有一个单独的模型用于共享权重的验证?

1 个答案:

答案 0 :(得分:1)

您应该使用无头(无DetectionOutput)模型进行训练,但要为评估提供顶层模型:

def add_detection_output(model):
    # make validation/inference model here

...
evaluation = SSDEvaluation(model=add_detection_output(model),
                           evaluator=PascalDetectionEvaluator(categories),
                           data_files=[args.eval_data])

避免在回调内部使用训练模型,让评估对象保留对验证模型的引用:

class SSDTensorboard(Callback):
    def __init__(self, evaluation):
        self.evaluation = evaluation

    def on_epoch_end(self, epoch, logs={}):
        metrics = self.evaluation.evaluate()