如何让自动编码器处理小型图像数据集
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 纪元:
我有一个包含三张图片的数据集。当我创建一个自动编码器来训练这三幅图像时,我得到的输出对于每幅图像都是完全相同的,它看起来像是所有三幅图像的混合。
我的结果是这样的:
输入图片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 纪元: