我在tensorflow中构建了一个自动编码器,它接受一个带有缺失值(-999.)的输入,然后将其屏蔽。目标/标签是没有缺失值的输入的干净版本。模型如下:
inputs = Input(shape=(input_size, 1))
model = Masking(mask_value=-999.)(inputs)
...
model = CustomLossLayer(2.)([model, inputs])
model = Model(inputs, model)
model.compile(loss=None, optimizer='adam')
我想在损失函数中加入一个权重,这样缺失值的误差会被放大,这样做的目的是为了鼓励模型更好地预测缺失值。
我找到的最接近的解决方案使用这两个类:
class CustomLossClass(Loss):
def __init__(self, weights):
super().__init__()
self.weights = weights
def call(self, y_true, y_pred):
return reduce_mean(square(multiply(subtract(y_true, y_pred), self.weights)))
class CustomLossLayer(Layer):
def __init__(self, weight, name="custom_loss"):
super().__init__(name=name)
self.weight = float(weight)
def call(self, inputs):
where_missing = equal(inputs[1], -999.)
weights = where(where_missing, self.weight, 1.)
self.add_loss(CustomLossClass(weights))
return inputs[0]`
函数reduce_mean、square、multiply、subtract、where和equal都是从基础tensorflow 模块导入的。
当我运行代码时,给出的错误是:
TypeError: __call__() missing 2 required positional arguments: 'y_true' and 'y_pred'
我不知道如何将y_true和y_pred变量传递给loss类,我的理解是,如果您将loss定义为一个层(CustomLossLayer)并使用add_loss,那么它会在训练期间自动将这些变量传递给CustomLossClass。
我也尝试过将loss()函数封装在另一个函数中,并将其包含在model.compile(loss=...)中,但似乎无法将当前批处理的输入传递给loss函数以确定缺失数据的位置,也许我需要为此执行自定义训练循环,但我希望避免这种情况。
有人能给我一些建议或工作代码,以实现我在这里试图做什么?
1条答案
按热度按时间yyhrrdl81#
我已经写了一个工作代码的例子,试图实现重量更新的损失函数。使用一个自定义损失函数,而不是损失类可能是你正在寻找:
我还添加了print语句来查看权重是否按预期工作。