【问题标题】:Keras autoencoder negative loss and val_loss with data in range [-1 1]Keras 自动编码器负损失和 val_loss 数据在 [-1 1] 范围内
【发布时间】:2023-03-11 12:02:01
【问题描述】:

我正在尝试使 keras 自动编码器示例适应我的数据。我有以下网络:

Xtrain = np.reshape(Xtrain, (len(Xtrain), 28, 28, 2))
Xtest = np.reshape(Xtest, (len(Xtest), 28, 28, 2))

input_signal = Input(shape=(28, 28, 2))
x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_signal)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same', name='encoder')(x)

# added Dense layers, is that correct?
encoded2 = Flatten()(encoded)
encoded2 = Dense(128, activation='sigmoid')(encoded2)
encoded2 = Dense(128, activation='softmax')(encoded2)
encoded3 = Reshape((4, 4, 8))(encoded2)

x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded3)
x = UpSampling2D((2, 2))(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(16, (3, 3), activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(2, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(inputs=input_signal, outputs=decoded)
encoder = Model(input_signal, encoded2)
autoencoder.compile(optimizer='adam', loss='binary_crossentropy')
autoencoder.fit(Xtrain, Xtrain, epochs=100, batch_size=128, shuffle=True, validation_data=(Xtest, Xtest))

而且,当我在 MNIST 数据上运行时,这些数据被归一化为 [0,1] 一切正常,但我的数据在 [-1,1] 范围内时,我只看到负损失和 0.0000 准确度,而训练。如果我执行 data = np.abs(data),训练开始并且看起来很顺利,但是对数据执行 abs() 并没有理由训练数据伪造。

我试图提供给网络的数据是信号的 IQ 通道、实部的第一个通道和图像部分的第二个通道,因此两者都归一化为 [-1 1],并且通常都包含非常低的值,例如5e-12。我已将它们塑造成 (28,28,2) 输入。

我还在自动编码器的中间添加了密集层,因为我希望在自动编码器完成训练时对类(自动拟合)进行预测。我这样做是否正确,这会破坏网络吗?

【问题讨论】:

  • 我认为您应该尝试使用 tanh 作为最后一层的激活。 sigmoid 将其输出置于 (0,1) 之间,所以如果你想解码你编码的内容,你的输出应该在 [-1,1] 之间,而这正是 tanh 所做的。

标签: machine-learning keras neural-network conv-neural-network autoencoder


【解决方案1】:

你在二元('sigmoid')和分类('softmax'和'categorical_crossentropy')之间混合。更改以下内容:

  1. 删除中间的密集层并将“编码”而不是“编码3”提供给解码器
  2. 将自动编码器损失更改为“binary_crossentropy”

或者,如果您真的想尝试中间的密集层,只需在没有激活函数的情况下使用它们(无)

【讨论】:

  • 试过了,去掉密集层,改成adam/binary_crossentropy。现在我的训练损失在第一个时期从 0.6 下降到 0.1,val_loss -0.01 和 0.000e+00 到两个精度,然后损失冻结在 -0.0127 和 val_loss 在 -0.032 的所有后续时期。我不确定我是否希望在两者之间使用密集层,我需要以某种方式获取编码的表示类并且我希望它是整数,所以我需要某种输出:autodetected_class1,autodetected_class73
  • 这是 Keras 原始示例中的编写方式,它适用于 [0 .. 1] 范围内的 MNIST 数据,但不适用于 [-1 .. 1 范围内的数据].
【解决方案2】:

您的问题存在几个问题,包括您对自动编码器及其用法的理解。我强烈建议至少阅读一下 Keras 博客文章 Building Autoencoders in Keras(如果你已经阅读过,可以说你必须再做一次,这次更彻底)。

一些一般性的观点,其中大部分都包含在上面的链接帖子中:

  1. 自动编码器用于分类,因此要求准确度等指标毫无意义。同样,由于拟合目标是重建其输入,因此分类交叉熵不是要使用的正确损失函数(请尝试使用二元交叉熵)。
  2. 您使用的中间密集层的存在令人费解,更令人费解的是选择sigmoid 层,然后是softmax 层;这同样适用于您最后的decoded 层中的sigmoid 选择。这两个激活函数通常用于最后层的分类目的,因此请再次参考上面的第 (1) 点。
  3. 我强烈建议您从上面链接的博客文章中演示的模型开始,如有必要,逐步修改它以适合您的目的,因为我不确定您在此处构建的内容是否可以甚至一开始就有资格成为自动编码器。

【讨论】:

  • 首先,我要回复3:这段代码完全是这个Keras博文的模型代码,我现在又在做什么。唯一逐渐改变的是损失函数的改变(并添加了我已经删除的密集层)。同样,这适用于 mnist 数据集,但不适用于包含负值的我的数据集。
  • 确实是 1 和 2:是的,我需要某种无监督分类器,并且认为自动编码器会满足我的需求。我正在使用卷积网络对我的数据进行监督分类,但真的不知道如何使其不受监督。
  • @RandyVogel “在 MNIST 上工作”并没有说太多,如果您的数据与 MNIST 不太相似(甚至有很多东西在 MNIST 上运行良好,但在其他计算机视觉上却不行问题)。无论如何,如果没有关于您的数据的更多详细信息,我怀疑任何人都可以提供更多帮助(即使您怀疑不同的范围是问题可能被证明是无关紧要的)。
  • 这些是 [[[ 1.79...e-16 -5.97...e-17]、[ 7.98123213e-04 1.433128e-09 ] ... 等,形状为 28x28x2。我从我的另一个 conv 网络中获得了这个形状,即“conv2d->pool->conv2d->pool->flatten->dense->dense softmax”,并且在这个数据集上获得了大约 85% 的准确度。我想知道为什么自动编码器不会吃负数,如果我做 abs(data) 它会吃掉我的数据,并显示像 mnist 数据集一样的统计数据,但肯定永远不会很好地收敛。
  • 我不同意(不是反对)第 1 点,上下文向量可以用于任何事情,并且不限于重建。其次,如果您对文本表示进行重构,您的输出可以是分类的(针对相同输入的整数索引进行热编码),您也可以使用分类交叉熵进行重构,不是吗?
猜你喜欢
  • 2018-05-08
  • 2018-03-04
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 2018-12-12
相关资源
最近更新 更多