Python 如何让自动编码器在小型图像数据集上工作

Python 如何让自动编码器在小型图像数据集上工作,python,image,keras,autoencoder,Python,Image,Keras,Autoencoder,我有一个包含三幅图像的数据集。当我创建一个自动编码器来对这三幅图像进行训练时,我得到的输出对于每幅图像都是完全相同的,看起来就像是所有三幅图像的混合 我的结果如下所示: 输入图像1: 输出图像1: 输入图像2: 输出图像2: 输入图像3: 输出图像3: 因此,您可以看到,输出为每个输入提供了完全相同的内容,虽然它与每个输入都相对匹配,但并不完美 这是一个三幅图像的数据集-它应该是完美的(或者至少每个图像都不同) 我关心的是这个三幅图像数据集,因为当我处理500幅图像数据集时,我得到的

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

我的结果如下所示:

输入图像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,并进行了1400次的训练,然后它就完美地工作了。这让我觉得这可以解决这个问题,但我还不确定

编辑:

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


我们将使用batch size 1进行测试,看看这是否更有帮助,然后尝试对很多时期进行培训,看看这是否完全解决了问题。

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

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

“二进制交叉熵”
损失函数似乎比
“mse”
工作得更快/更好,尽管
“mse”
(均方误差)工作得很好

但在最初的几百年里,它看起来确实在混合图像。然而,当它训练的时间越长,它就越开始分离

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

帮助我理解我做错了什么。我只是复制/粘贴了代码,发现它在我的数据集上起作用,所以其他人都在想我做错了什么

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

500个时代:

2000年:

您是否对图像进行了标准化?训练中的损失是什么?它减少了吗?是的,我已经用公式将图像归一化为0到1之间的值,找到了历元1和10的损失值是多少?如果增加epoch解决了这个问题,我建议提高优化器的学习率。然后,网络可以通过较少的历元进行聚合。超过4000个历元时,损耗从.9降低到.0054左右,然后开始大量跳变,达到.0169或类似值。较小的学习速度可能有助于跳跃。然后,正如你所看到的,损失并没有显著减少。一个可能的解决办法是提高学习率。例如,Adam优化器的默认学习速率为
1e-3
。您可以尝试
1e-2
3e-2
1e-1
(即
keras.optimizers.Adam(lr=学习率\值)
)。尝试不同的学习速度,看看是否有帮助。如果它起作用,它可能会在20、50或100个纪元后收敛(即远少于1400个纪元)。请证实这一点。