自编码器的损失函数

机器算法验证 毫秒 自动编码器 张量流 交叉熵
2022-01-31 07:46:16

我正在尝试一些自动编码器,并使用 tensorflow 创建了一个尝试重建 MNIST 数据集的模型。

我的网络非常简单:X, e1, e2, d1, Y,其中 e1 和 e2 是编码层,d2 和 Y 是解码层(Y 是重建的输出)。

X 有 784 个单位,e1 有 100,e2 有 50,d1 再次有 100,Y 再次有 784。

我使用 sigmoids 作为层 e1、e2、d1 和 Y 的激活函数。输入在 [0,1] 中,输出也应该是。

好吧,我尝试使用交叉熵作为损失函数,但输出总是一个 blob,我注意到从 X 到 e1 的权重总是会收敛到一个零值矩阵。

另一方面,使用均方误差作为损失函数,会产生一个不错的结果,我现在能够重建输入。

为什么呢?我以为我可以将这些值解释为概率,因此使用交叉熵,但显然我做错了什么。

2个回答

我认为最好的答案是交叉熵损失函数不适合这个特定的任务。

在采用这种方法时,您实际上是在说真正的 MNIST 数据是二进制的,并且您的像素强度表示每个像素“打开”的概率。但我们知道事实并非如此。这种隐含假设的不正确性导致了我们的问题。

我们还可以查看成本函数,看看为什么它可能不合适。假设我们的目标像素值为 0.8。如果我们绘制 MSE 损失和交叉熵损失(将其标准化,使其最小值为零),我们得到:[(target)log(prediction)+(1target)log(1prediction)]

交叉熵与 mse 损失

我们可以看到交叉熵损失是不对称的。我们为什么要这个?为这个 0.8 像素预测 0.9 真的比预测 0.7 更糟糕吗?我会说这可能会更好,如果有的话。

我们可能会更详细地了解为什么这会导致您看到的特定斑点。我冒险猜测这是因为在您看到斑点的区域中像素强度平均高于 0.5。但总的来说,这是您所做的隐式建模假设不适合数据的情况。

希望有帮助!

我浏览了https://colab.research.google.com/github/ageron/handson-ml2/blob/master/17_autoencoders_and_gans.ipynb中列出的自动编码器示例。作者使用了二元交叉熵损失函数,看起来效果不错。我换成mse损失函数,结果差不多。注意作者使用了 selu 激活函数。(此外,笔记本还有助于可视化“预测”输出)