You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RGB降噪自编码器输出纯白图像问题求助

降噪自编码器输出纯白图像的问题修复

问题概述

实现降噪自编码器处理CIFAR-100带噪声图像时,预测输出全为纯白图像,相关代码及输出结果如下:

原模型层代码

input_img = keras.Input(shape=(32, 32, 3))
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), padding='same')(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = layers.MaxPooling2D((2, 2), padding='same')(x)
encoded = x  # 此处错误覆盖了池化后的编码特征
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), activation='relu', padding='same')(encoded)
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), activation='relu', padding='same')(x)
decoded = layers.Conv2D(3, (3, 3), activation='relu', padding='same')(x)  # 激活函数错误
autoencoder = keras.Model(input_img, decoded)
s = 20 * 5000
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(0.01, s, 0.1)
autoencoder.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=lr_schedule), loss='mean_squared_error',metrics=['accuracy'])
autoencoder.summary()

原数据加载代码

(x_train, _), (x_test, _) = cifar100.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = np.reshape(x_train, (len(x_train), 32, 32, 3))
x_test = np.reshape(x_test, (len(x_test), 32, 32, 3))
x_train = x_train[:5000]
x_test = x_test[6000:7000]

noise_factor = 0.2
x_train_noisy = x_train + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_train.shape)
x_test_noisy = x_test + noise_factor * np.random.normal(loc=0.0, scale=1.0, size=x_test.shape)
x_train_noisy = np.clip(x_train_noisy, 0., 1.)
x_test_noisy = np.clip(x_test_noisy, 0., 1.)

原训练与预测代码

autoencoder.fit(x_train_noisy, x_train,
                epochs=50,
                batch_size=128,
                shuffle=True)
decoded_imgs = autoencoder.predict(x_test_noisy)

for i in range(5):
    # Display original
    ax = plt.subplot(2, 5, i + 1)
    plt.imshow(x_test_noisy[i])
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
    # Display reconstruction
    ax = plt.subplot(2, 5, i + 1 + 5)
    plt.imshow(decoded_imgs[i])
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

输出结果

纯白输出结果


问题根源与修复方案

1. 编码器特征覆盖错误

原代码中encoded = x直接覆盖了MaxPooling2D后的编码特征,导致编码器未完成下采样,输入维度未被压缩,后续解码器上采样后维度不匹配。删除encoded = x这一行,保留池化后的编码结果。

2. 解码器输出激活函数错误

最后一层Conv2D使用relu激活,输出范围无上限,超出图像数据的[0,1]区间,导致plt.imshow将超过1的像素显示为纯白。将激活函数改为sigmoid,把输出限制在[0,1]范围内。

3. 解码器维度缺失上采样

原编码器经过三次MaxPooling2D后,输入32x32会变为4x4(32→16→8→4),但解码器只有两次Conv2DTranspose(步长2),只能还原到16x16,与输入32x32维度不匹配。增加一次Conv2DTranspose上采样,将维度还原为32x32。

4. 优化器与学习率调整

初始学习率0.01搭配SGD收敛慢且易不稳定,改用Adam优化器(学习率0.001)更适合自编码器任务,收敛速度和稳定性更好。


修改后的完整代码

修复后的模型层代码

input_img = keras.Input(shape=(32, 32, 3))
# 编码器部分
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = layers.MaxPooling2D((2, 2), padding='same')(x)  # 32→16
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), padding='same')(x)  #16→8
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
encoded = layers.MaxPooling2D((2, 2), padding='same')(x)  #8→4,保留此编码结果

# 解码器部分
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), activation='relu', padding='same')(encoded)  #4→8
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), activation='relu', padding='same')(x)  #8→16
x = layers.Conv2DTranspose(32, (3, 3), strides=(2, 2), activation='relu', padding='same')(x)  #16→32,新增上采样
decoded = layers.Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)  # 改用sigmoid激活

autoencoder = keras.Model(input_img, decoded)
# 改用Adam优化器,学习率0.001
autoencoder.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), 
                    loss='mean_squared_error',
                    metrics=['accuracy'])
autoencoder.summary()

训练与预测代码(无需修改)

autoencoder.fit(x_train_noisy, x_train,
                epochs=50,
                batch_size=128,
                shuffle=True)
decoded_imgs = autoencoder.predict(x_test_noisy)

for i in range(5):
    # 显示带噪声原图
    ax = plt.subplot(2, 5, i + 1)
    plt.imshow(x_test_noisy[i])
    plt.axis('off')
    # 显示修复后的图像
    ax = plt.subplot(2, 5, i + 1 + 5)
    plt.imshow(decoded_imgs[i])
    plt.axis('off')
plt.show()

效果验证

修改后重新训练,解码器输出维度与输入一致(32x32x3),输出像素值被限制在[0,1]区间,预测结果将正常还原带噪声图像,不会出现纯白情况。

内容的提问来源于stack exchange,提问作者Mohamed Elsayed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:40:38