【问题标题】:High loss from convolutional autoencoder keras卷积自编码器keras的高损失
【发布时间】:2019-09-24 21:48:21
【问题描述】:

我正在训练一个卷积自动编码器,但我无法降低损失,希望有人能指出一些可能的改进。

我有 1024x1024 的灰度图像(我也用 512x512 尝试过同样的事情),我希望压缩它们以进行无监督聚类。下面是我的完整模型,但它遵循一个非常基本的模式,即几个带最大池化的 Conv2D 层,然后是一个密集层,然后重塑和 Conv2D 层回到原始图像大小。

到目前为止我尝试过的一些事情:

1) 我发现 mse 作为损失函数比二元交叉熵更有效,因为像素亮度值远非均匀分布(二元交叉熵在将所有内容分配为 1 时会卡住,它的误差很低,但没用)。

2)如果我只是去掉中间的密集层并稍微压缩图像,我可以轻松实现非常低的错误和近乎完美(至少在我看来)的图像重建。这很明显,但我想这表明我没有犯某种错误导致无意义的输出。

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

4) 当我的中间密集层使用 ReLU 激活时,我得到了很多垂死的 ReLU,这使得它对最终聚类的用处不大。我用 tanh 代替。我还发现“he_normal”作为密集层的初始化效果更好。

5) 在中间添加更密集的层似乎根本没有帮助。

6) 反转编码器的形状(使其从每层更少的内核变为更多的内核)也无济于事,尽管我知道传统上这是卷积自动编码器的外观。

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

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_4 (InputLayer)         (None, 1024, 1024, 1)     0       
_________________________________________________________________
conv2d_40 (Conv2D)           (None, 1024, 1024, 128)   1280      
_________________________________________________________________
max_pooling2d_19 (MaxPooling (None, 512, 512, 128)     0         
_________________________________________________________________
batch_normalization_4 (Batch (None, 512, 512, 128)     512       
_________________________________________________________________
conv2d_41 (Conv2D)           (None, 512, 512, 64)      73792
_________________________________________________________________
max_pooling2d_20 (MaxPooling (None, 256, 256, 64)      0         
_________________________________________________________________
conv2d_42 (Conv2D)           (None, 256, 256, 32)      18464
_________________________________________________________________
max_pooling2d_21 (MaxPooling (None, 128, 128, 32)      0         
_________________________________________________________________
conv2d_43 (Conv2D)           (None, 128, 128, 16)      4624      
_________________________________________________________________
max_pooling2d_22 (MaxPooling (None, 64, 64, 16)        0         
_________________________________________________________________
conv2d_44 (Conv2D)           (None, 64, 64, 8)         1160      
_________________________________________________________________
max_pooling2d_23 (MaxPooling (None, 32, 32, 8)         0         
_________________________________________________________________
flatten_4 (Flatten)          (None, 8192)              0         
_________________________________________________________________
dense_5 (Dense)              (None, 512)               4194816   
_________________________________________________________________
reshape_4 (Reshape)          (None, 8, 8, 8)           0         
_________________________________________________________________
up_sampling2d_22 (UpSampling (None, 16, 16, 8)         0         
_________________________________________________________________
conv2d_45 (Conv2D)           (None, 16, 16, 16)        1168      
_________________________________________________________________
up_sampling2d_23 (UpSampling (None, 32, 32, 16)        0         
_________________________________________________________________
conv2d_46 (Conv2D)           (None, 32, 32, 16)        2320      
_________________________________________________________________
up_sampling2d_24 (UpSampling (None, 64, 64, 16)        0         
_________________________________________________________________
conv2d_47 (Conv2D)           (None, 64, 64, 32)        4640      
_________________________________________________________________
up_sampling2d_25 (UpSampling (None, 128, 128, 32)      0         
_________________________________________________________________
conv2d_48 (Conv2D)           (None, 128, 128, 64)      18496
_________________________________________________________________
up_sampling2d_26 (UpSampling (None, 256, 256, 64)      0         
_________________________________________________________________
conv2d_49 (Conv2D)           (None, 256, 256, 128)     73856     
_________________________________________________________________
up_sampling2d_27 (UpSampling (None, 512, 512, 128)     0         
_________________________________________________________________
conv2d_50 (Conv2D)           (None, 512, 512, 128)     147584
_________________________________________________________________
up_sampling2d_28 (UpSampling (None, 1024, 1024, 128)   0
_________________________________________________________________
conv2d_51 (Conv2D)           (None, 1024, 1024, 1)     1153
=================================================================
Total params: 4,543,865
Trainable params: 4,543,609
Non-trainable params: 256

【问题讨论】:

  • 你试过用 SELU 代替 ReLU 吗?
  • 对我来说,编码器重建听起来很成功,而且你实现的损失一点也不高
  • 我刚刚尝试切换到 SELU,使用 lecun_normal 作为初始化器,但是损失要高得多。我还需要改变什么才能让它工作吗?
  • 我遇到了同样的问题,想知道您是否解决了这个问题?您是否愿意分享更多关于您用于每个卷积层的过滤器大小的信息,或者您是否有可用的代码?
  • 我从来没有真正修复过它,但我把它归结为 0.015 的 MSE 损失。在中间放置 2 个更密集的层,通过残差连接帮助。例如:
    flat1 = Dense(1024, activation = 'tanh', kernel_initializer = "he_normal", activity_regularizer = l2(0.001))(encoder) <br/> flat2 = Dense(1024, activation = 'tanh', kernel_initializer = "he_normal", activity_regularizer = l2(0.001))(flat1) <br/> encoder = keras.layers.add([flat1, flat2])

标签: keras conv-neural-network convolution autoencoder


【解决方案1】:

您的损失函数可能是问题所在。在网络的 Logit 输出上使用 BCE。应该能解决问题。

  1. 使用:tf.keras.losses.BinaryCrossentropy(from_logits=True)
  2. 从编码器和解码器的最后一层移除激活函数(编码器的最后一个密集层和解码器的最后一个卷积层应该没有激活。)

注意:当您从嵌入重构时,请添加一个 sigmoid 函数。

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

现在应该好好训练!

【讨论】:

    猜你喜欢
    • 2017-11-11
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2020-06-11
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多