繁体   English   中英

Keras 功能 API:我的 model 仅针对一个损失函数进行优化,而不是训练损失函数 ZC1C425268E68385D14AB5074C17A

[英]Keras functional API: My model is only optimizing for one loss function instead of 2 loss functions while training

我的 model 中有 2 个损失函数——交叉熵和均方。 我希望我的 model 最大限度地减少损失,但 model 仅在训练期间最大限度地减少均方误差。

def buildGenerator(dmodel, batch=100):
    
    inputs = Input(shape=(256,256,1))
    
    x = Conv2D(
            filters = 32,
            kernel_size = 3,
            padding = 'same',
            strides = 1
        )(inputs)
    x = BatchNormalization(momentum = 0.9)(x)
    x = LeakyReLU(alpha=0.2)(x)
    .........................
    ...........................

    outputs1 = Conv2D(
            filters = 2,
            kernel_size = 3,
            padding = 'same',
            strides = 1
        )(x)
    
    
    outputs2 = dmodel(outputs1)
    
    model = Model(inputs = inputs, outputs = [ outputs2, outputs1], name = 'functional_model')
    
    model.compile(
        loss = ['binary_crossentropy','mse' ],
        optimizer = 'Adam',
        loss_weights = [1.0, 0.6],
        metrics=['accuracy', 'mse']
        )
    
    return model

在这段代码中,dmodel 是另一个 model。 我正在使用 dmodel 对 model 生成的输出 1 进行分类,然后找到输入标签和 output 标签之间的交叉熵。

我就是这样训练的

dmodel = buildDiscriminator()
dmodel.load_weights('./GAN/discriminator')
dmodel.trainable = False
x, y1 =  getGeneratorData()
y2 = np.ones((batch, 1))
model = buildGenerator(dmodel)
model.fit(x,[y2, y1],epochs=1)

我尝试了很多方法,例如更改 loss_weights、更改损失函数,但没有任何效果。 我的 model 只是最小化了 MSE function。

我不明白我做错了什么。

我认为在生成器内部使用鉴别器 model 是问题,但我不确定。

不知道有没有简单的语法可以组合不同的损失函数,但是可以尝试定义一个自己的损失class。 在另一个线程中,我发现这个代码片段定义了一个自己的损失 class ,它结合了其他两个损失函数:

rho = 0.05

class loss_with_KLD(losses.Loss):

    def __init__(self, rho):
        super(loss_with_KLD, self).__init__()
        self.rho = rho
        self.kl = losses.KLDivergence()
        self.mse = losses.MeanSquaredError(reduction=tf.keras.losses.Reduction.SUM)
    
    def call(self, y_true, y_pred):
        mse = self.mse(y_true, y_pred)
        kl = self.kl(self.rho, y_pred)
        return mse + kl

如果您只是用二进制交叉熵替换 KLDivergence,那么这应该可以工作。 此外,您需要更改 call() function,因为此实现在相同的预测 y 值上应用了两个损失 function,但您实际上预测了两个不同的 y 值。 在这种情况下,您的 y_true 和 y_pred 都将包含两个值,并且您只需要在其中一个上应用每个损失 function。 我不知道是否可以轻松地从向量中获取单个元素(以 y_true[0] 的样式),但如果不是,您可以通过乘以对向量应用“掩码”来解决此问题它们使用 [0, 1] 或 [1, 0],具体取决于您需要的值。 完成此操作后,您可以使用 reduce_sum() function 获取单个值并在新的 y_true 和 y_pred 上应用损失 function。

这有点复杂,但它应该可以完成工作。

当您指定 2 个损失函数时,它们适用于您的 2 个不同的输出。 即在您的示例中,binary_crossentropy 适用于 output2,它的 y_true 值全为 1。 并且是不可训练的 model 的 output。

您似乎想从 model 返回单个值,因为您似乎没有 output2 的标签。 虽然您可以定义自己的自定义损失 function 将两个损失结合在相同的值上,但我建议不要这样做。 如果 output 值是单个 class 预测(即像素开/关),则 binary_crossentrophy 有意义; 如果它应该是一个离散值,那么 mse 是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM