卷积自动编码器keras的高损耗

卷积自动编码器keras的高损耗,keras,conv-neural-network,convolution,autoencoder,Keras,Conv Neural Network,Convolution,Autoencoder,我正在训练一个卷积自动编码器,我很难降低损耗,希望有人能指出一些可能的改进 我有1024x1024的灰度图像(我也用512x512做过同样的尝试),我希望压缩它们以实现无监督聚类。下面是我的完整模型,但它遵循了一个非常基本的模式,即几个Conv2D层w/max pooling,然后是一个致密层,然后重塑并将Conv2D层恢复到原始图像大小 到目前为止,我已经尝试了一些事情: 1) 我发现mse作为损失函数比二进制交叉熵更有效,因为像素亮度值远未均匀分布(二进制交叉熵无法将所有值都指定为1,这具有

我正在训练一个卷积自动编码器,我很难降低损耗,希望有人能指出一些可能的改进

我有1024x1024的灰度图像(我也用512x512做过同样的尝试),我希望压缩它们以实现无监督聚类。下面是我的完整模型,但它遵循了一个非常基本的模式,即几个Conv2D层w/max pooling,然后是一个致密层,然后重塑并将Conv2D层恢复到原始图像大小

到目前为止,我已经尝试了一些事情:

1) 我发现mse作为损失函数比二进制交叉熵更有效,因为像素亮度值远未均匀分布(二进制交叉熵无法将所有值都指定为1,这具有较小的误差,但并不有用)

(p>2)如果只去除中间的稠密层,并稍微压缩图像,就可以很容易地实现非常低的误差和近乎完美的(至少在我的眼睛)图像重建。这是相当明显的,但我想这表明我没有犯导致无意义输出的错误

3) 我的损失并没有降到0.02-0.03以下。尽管如此,在0.025左右,图像被重建得足够清晰,以至于很明显输出来自输入,而不是某种随机噪声(比如使每个像素具有相同的强度等)。我想把它降到0.01以下就足够了,我可以集中精力。我的最低值是0.018(尽管数据的子集稍微简单一些),当我在热图中绘制编码值时,我可以在样本中看到清晰的聚类

4) 当我的中密度层使用ReLU激活时,我得到了很多濒死的ReLU,这使得它对最终的集群不太有用。我用tanh代替。我还发现“he_normal”作为稠密层的初始化效果更好

P>5)在中间添加更多的致密层似乎没有帮助。 6) 反转编码器的形状(使其从每层更少的内核变为更多的内核)也没有帮助,尽管我知道卷积自动编码器通常是这样的

这是完整的模型(model.summary()的输出)


您的丢失功能可能就是问题所在。在网络的Logit输出上使用BCE应该可以解决问题

  • 使用:
    tf.keras.loss.BinaryCrossentropy(from_logits=True)
  • 从编码器和解码器的最后一层移除激活功能(编码器的最后一个密集层和解码器的最后一个Conv层应该没有激活。)
  • 注意:从嵌入重建时,请向其添加一个sigmoid函数

    z = encoder(x)
    x_hat_raw = decoder(z)
    reconstruction = sigmoid(x_hat_raw)
    

    你现在应该好好训练了!

    你试过用塞卢斯代替雷卢斯吗?对我来说,编码器重建听起来很成功,你的损失也不高。我只是试着换成塞卢斯,用勒昆·诺曼作为初始值,但损失更大。还有什么我必须改变的吗?我很高兴NG同样的问题,想知道你是否已经解决了这个问题?你能很好地分享你在每一个卷积层中使用的过滤器的大小吗?或者如果你有代码在哪里?我从来没有真正修复它,但是我把它归结为MSE的0.015的损失。在中间放置2个更密集的层,与残留物相连。连接有帮助。例如:
    flat1=Dense(1024,激活='tanh',kernel\u initializer=“he\u normal”,activity\u regulaizer=l2(0.001))(编码器)
    flat2=Dense(1024,激活='tanh',kernel\u initializer=“he\u normal”,activity\u regulaizer=l2(0.001))(flat1)
    编码器=keras.layers.add([flat1,flat2
    z = encoder(x)
    x_hat_raw = decoder(z)
    reconstruction = sigmoid(x_hat_raw)