最大化Keras模型的MSE

10

我有一个生成对抗网络,其中鉴别器通过均方误差得到最小化,而生成器应该被最大化。因为两者都是追求相反目标的对手。

generator = Sequential()
generator.add(Dense(units=50, activation='sigmoid', input_shape=(15,)))
generator.add(Dense(units=1, activation='sigmoid'))
generator.compile(loss='mse', optimizer='adam')

generator.train_on_batch(x_data, y_data)

我需要做哪些调整,才能获得一个从高MSE值中受益的生成器模型?


1
你为什么想要那个?这是一个不适当的问题。最大化均方误差意味着你需要让你的预测达到底层数据类型的边界。但如果你真的想这样做,为优化器提供负学习率可能会完成任务。或者使用均方误差的倒数作为损失函数。 - a_guest
1
我有一个生成对抗网络,其中鉴别器使用MSE最小化,生成器应该得到最大化。因为两者都是追求相反目标的对手。 - Emma
@Geeocode,我已经做了,谢谢。你认为Marco的负号解决方案正确吗? - Emma
@Geeocode 我会的,谢谢。 - Emma
测试了两个答案,Emma? - Geeocode
显示剩余13条评论
2个回答

5

更新:

原始的MSE实现如下:

def mean_squared_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return K.mean(K.square(y_pred - y_true), axis=-1)

我认为正确的最大化器损失函数是:

def mean_squared_error_max(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return K.mean(K.square(1 / (y_pred - y_true)), axis=-1)

这样我们就可以始终获得一个正的损失值,就像MSE函数的情况一样,但效果相反。
更新2: 最初我写道,简单地取反损失的直觉第一想法将不会给出我们期望的结果,因为优化方法的基本概念(您可以在here中阅读有趣的讨论)。 经过我对两种方法进行了头对头的双重检查后,在特定的学习任务中,两种方法都提供了损失最大化,尽管-loss方法收敛速度略快。由于可能存在的问题here,我不确定它是否总是给出最佳解决方案或任何解决方案。 如果有人有其他经验,请告诉我。
因此,如果有人也想尝试-loss,可以试一试:
def mean_squared_error(y_true, y_pred):
    if not K.is_tensor(y_pred):
        y_pred = K.constant(y_pred)
    y_true = K.cast(y_true, y_pred.dtype)
    return - K.mean(K.square(y_pred - y_true), axis=-1)


附加细节:

OP写道:

我有一个生成对抗网络,其中鉴别器通过均方误差最小化,生成器应该最大化。因为两者都是追求相反目标的对手。

来自Ibragil提供的链接:

与此同时,生成器正在创建新的合成图像,并将其传递给鉴别器。它这样做是希望它们也被认为是真实的,尽管它们是虚假的。生成器的目标是生成可以通过的手写数字:在不被发现的情况下说谎。鉴别器的目标是识别来自生成器的图像为假。


因此,这是一个不适定问题:

在GAN中,我们的最终目标是训练两个对手——鉴别器和生成器,使它们相互竞争时表现尽可能好。这意味着两个基本学习算法有不同的任务,但是可以实现最优解的损失函数是相同的,即binary_crossentropy,因此模型的任务是最小化该损失。
一个鉴别器模型的编译方法:
self.discriminator.compile(loss='binary_crossentropy', optimizer=optimizer)

一个生成器模型的编译方法:

self.generator.compile(loss='binary_crossentropy', optimizer=optimizer)

这就像两个赛跑者的目标一样,尽管他们是竞争对手,但都希望缩短到达终点的时间。

因此,“相反的目标”并不意味着相反的任务,即最小化损失(例如在赛跑者的例子中缩短时间)。

希望这可以帮助您。


5

我觉得这个问题不是很清楚。我猜想你想要最大化而不是最小化,同时使用MSE作为标准。

你可以实现自己的自定义损失函数,计算-MSE;改变损失的符号,从而实现梯度下降方向的翻转。

def negative_mse(y,yhat): 
    return - K.mean(K.sum(K.square(y-yhat)))

model.compile(loss=negative_mse, optimizer='adam')

另一种选择是提供一个负的学习步长——但我不确定Keras是否允许您这样做。值得一试。


你的函数里忘记加负号了吗? - Emma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接