如何让自动编码器处理小型图像数据集

How to get an autoencoder to work on a small image dataset

我有一个包含三张图片的数据集。当我创建一个自动编码器来训练这三幅图像时,我得到的输出对于每幅图像都是完全相同的,它看起来像是所有三幅图像的混合。

我的结果是这样的:

输入图片1:

输出图片1:

输入图片2:

输出图片2:

输入图片3:

输出图像3:

因此您可以看到输出为每个输入提供了完全相同的内容,虽然它相对较好地匹配了每个输入,但并不完美。

这是一个三图像数据集 - 它应该是完美的(或者至少每幅图像都不同)。

我担心这三个图像数据集,因为当我处理 500 个图像数据集时,我得到的只是一个白色的空白屏幕,因为这是所有图像的最佳平均值。

我用的是Keras,代码真的很简单。

from keras.models                   import Sequential
from keras.layers                   import Dense, Flatten, Reshape
import numpy as np

# returns a numpy array with shape (3, 24, 32, 1)
# there are 3 images that are each 24x32 and are black and white (1 color channel)
x_train = get_data()

# this is the size of our encoded representations
# encode down to two numbers (I have tested using 3; I still have the same issue)
encoding_dim = 2
# the shape without the batch amount
input_shape = x_train.shape[1:]
# how many output neurons we need to create an image
input_dim = np.prod(input_shape)

# simple feedforward network
# I've also tried convolutional layers; same issue
autoencoder = Sequential([
              Flatten(), # flatten
              Dense(encoding_dim), # encode
              Dense(input_dim), # decode
              Reshape(input_shape) # reshape decoding
])

# adadelta optimizer works better than adam, same issue with both
autoencoder.compile(optimizer='adadelta', loss='mse')

# train it to output the same thing it gets as input
# I've tried epochs up to 30000 with no improvement;
# still predicts the same image for all three inputs
autoencoder.fit(x_train, x_train,
            epochs=10,
            batch_size=1,
            verbose=1)

out = autoencoder.predict(x_train)

然后我获取输出(out[0]out[1]out[2])并将它们转换回图像。你可以看到上面的输出图像。

我很担心,因为这表明自动编码器没有保留有关输入图像的任何信息,这不是编码器应该执行的方式。

如何让编码器显示基于输入图像的输出差异?

编辑:

我的一位同事建议甚至不使用自动编码器,而是使用 1 层前馈神经网络。我尝试了这个,同样的事情发生了,直到我将批量大小设置为 1 并训练了 1400 个时期,然后它完美地工作了。这让我认为 more epochs 可以解决这个问题,但我还不确定。

编辑:

训练 10,000 个时期(批量大小为 3)使第二张图像在编码器上看起来与第一张和第三张图像不同,这正是 运行 大约在非编码器版本上发生的情况400 个时期(批次大小也为 3)进一步证明训练更多时期可能是解决方案。

将使用批量大小 1 进行测试,看看是否有更多帮助,然后尝试训练很多轮,看看是否能完全解决问题。

我的编码维度太小了。尝试将 24x32 图像编码为 2 个数字(或 3 个数字)对于自动编码器来说实在是太多了。

通过将 encoding_dim 提高到 32,问题已基本解决。我能够使用 Adadelta 优化器的默认学习率。我的数据甚至不需要标准化(只需将所有像素除以 255 即可)。

"binary_crossentropy" 损失函数似乎比 "mse" 更有效 faster/better,尽管 "mse"(均方误差)工作得很好。

虽然在最初的几百个 epoch 中,它确实看起来像是在混合图像。然而,随着它训练的时间越长,它开始分离的越多。

我还让编码层的输出激活为relu,解码层的激活为sigmoid。我不确定对输出有多大影响 - 我还没有测试过。

This page 帮助我理解了我做错了什么。我只是 copy/pasted 代码并发现它适用于我的数据集,所以剩下的就是弄清楚我做错了什么。

这是他们在我的数据集上工作的简单自动编码器架构的一些图像(这是我的第一个希望迹象):

500 个纪元:

2000 纪元: