Validation 对keras使用多个验证集

Validation 对keras使用多个验证集,validation,keras,monitoring,Validation,Keras,Monitoring,我正在使用model.fit()方法培训keras模型。 我想使用多个验证集,这些验证集应该在每个训练阶段后分别进行验证,以便为每个验证集获得一个损失值。如果可能,它们应该在培训期间显示,并且由keras.callbacks.History()callback返回 我在想这样的事情: history = model.fit(train_data, train_targets, epochs=epochs, batch

我正在使用
model.fit()
方法培训keras模型。 我想使用多个验证集,这些验证集应该在每个训练阶段后分别进行验证,以便为每个验证集获得一个损失值。如果可能,它们应该在培训期间显示,并且由
keras.callbacks.History()
callback返回

我在想这样的事情:

history = model.fit(train_data, train_targets,
                    epochs=epochs,
                    batch_size=batch_size,
                    validation_data=[
                        (validation_data1, validation_targets1), 
                        (validation_data2, validation_targets2)],
                    shuffle=True)

我目前不知道如何实现这一点。是否可以通过编写自己的
回调来实现这一点?或者你会如何处理这个问题?

我最终根据
历史记录
回调编写了自己的
回调
,以解决这个问题。我不确定这是否是最好的方法,但以下
回调
记录了培训和验证集的损失和指标,如
历史
回调,以及传递给构造函数的其他验证集的损失和指标

类附加验证集(回调):
def uuu init uuuu(自我、验证集、详细信息=0、批处理大小=None):
"""
:参数验证集:
三元组列表(验证数据、验证目标、验证集名称)
或4元组(验证数据、验证目标、样本权重、验证集名称)
:param verbose:
详细模式,1或0
:参数批次大小:
对附加数据集进行评估时使用的批大小
"""
super(附加验证集,self)。\uu初始化
self.validation\u集=validation\u集
对于self.validation\u集合中的validation\u集合:
如果len(验证集)不在[3,4]中:
提升值错误()
self.epoch=[]
self.history={}
self.verbose=verbose
self.batch\u size=批次大小
列车上的def开始(自身,日志=无):
self.epoch=[]
self.history={}
def on_epoch_end(self、epoch、logs=None):
日志=日志或{}
self.epoch.append(epoch)
#记录与History()相同的值
对于logs.items()中的k,v:
self.history.setdefault(k,[]).append(v)
#对其他验证集进行评估
对于self.validation\u集合中的validation\u集合:
如果len(验证集)=3:
验证数据、验证目标、验证集名称=验证集
样本权重=无
elif len(验证集)=4:
验证数据、验证目标、样本权重、验证集名称=验证集
其他:
提升值错误()
结果=自我、模型、评估(x=验证数据,
y=验证\u目标,
verbose=self.verbose,
样本重量=样本重量,
批次大小=自身。批次大小)
对于度量,结果为zip(self.model.metrics\u名称、结果):
valuename=验证\设置\名称+'\'+度量
self.history.setdefault(valuename,[]).append(result)
我现在用的是:

history = model.fit(train_data, train_targets,
                    epochs=epochs,
                    batch_size=batch_size,
                    validation_data=[
                        (validation_data1, validation_targets1), 
                        (validation_data2, validation_targets2)],
                    shuffle=True)
history=附加验证集([(验证数据2,验证目标2,'val2'))
模型拟合(训练数据、训练目标、,
时代,
批次大小=批次大小,
验证数据=(验证数据1,验证目标1),
回调=[历史记录]
洗牌=真)
考虑到当前情况,您可以将回调传递给
evaluate
evaluate\u generator
。因此,您可以使用不同的数据集多次调用
evaluate


我还没有测试过它,所以如果您在下面评论您的体验,我会很高兴。

我在TensorFlow 2上测试过它,它成功了。在每个历元结束时,可以根据需要对任意多个验证集求值:

class MyCustomCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        res_eval_1 = self.model.evaluate(X_test_1, y_test_1, verbose = 0)
        res_eval_2 = self.model.evaluate(X_test_2, y_test_2, verbose = 0)
        print(res_eval_1)
        print(res_eval_2)
后来:

my_val_callback = MyCustomCallback()
# Your model creation code
model.fit(..., callbacks=[my_val_callback])

我的具体用例是在每个训练历元之后对多个数据集进行评估,而不必在循环中一次只训练一个历元。如果显式调用
evaluate
,那么为每个数据集调用一次应该没有问题,因此不需要回调。在最新版本的Keras中,
self.model.metrics[i-1]
是一个字符串。<代码> .NAMEYEX不再是必要的(并且会产生错误)。您是否考虑将其变成Python包?如果你没有时间,我也可以这样做。@LucaCappelletti我没有用它制作一个包的原因是,在几乎每个项目中,我都会稍微修改回调(例如,为了支持数据生成器)。将代码从一个项目复制并粘贴到另一个项目并不是最好的工作流程,但它更容易一些,而且正如您所猜测的,我没有时间将其打包(除非您想等待一个月左右)。如果你有时间的话,可以随意把它做成一个包裹。我将我的GitHub用户名添加到我的帐户,以便您可以根据需要向我添加项目。谢谢!你能分享这个支持数据生成器的代码的变体吗?@cheesus在github上可以找到一个正在进行的包版本,代码太大,无法在这里共享。