减少自动编码器的损失
Reducing Losses of Autoencoder
我目前正在尝试训练一个自动编码器,它允许将长度为 128 个整数变量的数组表示为压缩为 64。该数组包含 128 个整数值,范围从 0 到 255。
我用每个时期超过 200 万个数据点训练模型。每个数组的形式如下:[ 1, 9, 0, 4, 255, 7, 6, ..., 200]
input_img = Input(shape=(128,))
encoded = Dense(128, activation=activation)(input_img)
encoded = Dense(128, activation=activation)(encoded)
encoded = Dense(64, activation=activation)(encoded)
decoded = Dense(128, activation=activation)(encoded)
decoded = Dense(128, activation='linear')(decoded)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
history = autoencoder.fit(np.array(training), np.array(training),
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(np.array(test), np.array(test)),
callbacks=[checkpoint, early_stopping])
我还将上传一张显示训练和验证过程的图形:Loss graph of Training
我怎么可能进一步降低损失。到目前为止我尝试过的(两种选择都没有成功):
- 更长的训练阶段
- 更多层
当然没有什么神奇的事情可以立即减少损失,因为它是非常具体的问题,但这里有一些我可以建议的技巧:
- 减少小批量大小。具有较小的批量大小会使梯度在反向传播时更加嘈杂。这乍一看似乎违反直觉,但梯度下降中的这种噪声可以帮助下降克服可能的局部最小值。这样想;当下降嘈杂时,它会花费更长的时间但高原会更低,当下降平稳时,它会花费更少但会稳定在更早的高原。 (非常笼统!)
- 尝试使图层具有 expanding/shrinking 顺序的单元。因此,与其背靠背使用 128 个单元层,不如将其设为 128 到 256。这样,您就不会强迫模型用另一组 128 个数字来表示 128 个数字。您可以拥有 128 个单元的所有层,理论上 会产生 无损 自动编码,其中输入和输出实际上是相同的.但由于梯度下降的性质,这在实践中不会发生。这就像你随机从丛林中的某个地方开始,并尝试沿着领先(负梯度)穿过它,但仅仅因为你有领先并不意味着你可以到达你所在的位置为首。因此,要从您的分布中获取有意义的信息,您应该强制您的模型以较小的单位表示信息。这将使梯度下降的工作更容易,因为你设置了先验条件;如果它不能足够好地编码信息,就会有很高的损失。所以你有点让理解你想要从模型中得到什么。
- 误差函数的绝对值。您正在努力降低损失,但目的是什么?您需要它接近 0,还是只需要它尽可能低?因为随着你的潜在维度缩小,损失会增加但是自动编码器将能够更好地捕获数据的潜在代表信息。因为你强迫编码器用低维信息来表示高维信息。因此,潜在维度越低,自动编码器就越会尝试 从输入中提取 最有意义的信息,因为它限制了 space。因此,即使损失越大,也能更有效地捕获分布。所以这取决于你的问题,如果你想要图像降噪之类的东西,使用更高的编码维度,但如果你想要做异常检测之类的事情,最好尝试更低的维度而不完全破坏模型的代表性能力.
- 这是我的更多 tinfoil 建议,但您也尝试将数字向下移动,以便范围为 -128 到 128。我 - 不太准确 -观察到某些激活(尤其是 ReLU)在这些类型的输入下效果稍好。
我希望其中一些对你有用。祝你好运。
我目前正在尝试训练一个自动编码器,它允许将长度为 128 个整数变量的数组表示为压缩为 64。该数组包含 128 个整数值,范围从 0 到 255。
我用每个时期超过 200 万个数据点训练模型。每个数组的形式如下:[ 1, 9, 0, 4, 255, 7, 6, ..., 200]
input_img = Input(shape=(128,))
encoded = Dense(128, activation=activation)(input_img)
encoded = Dense(128, activation=activation)(encoded)
encoded = Dense(64, activation=activation)(encoded)
decoded = Dense(128, activation=activation)(encoded)
decoded = Dense(128, activation='linear')(decoded)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
history = autoencoder.fit(np.array(training), np.array(training),
epochs=50,
batch_size=256,
shuffle=True,
validation_data=(np.array(test), np.array(test)),
callbacks=[checkpoint, early_stopping])
我还将上传一张显示训练和验证过程的图形:Loss graph of Training
我怎么可能进一步降低损失。到目前为止我尝试过的(两种选择都没有成功):
- 更长的训练阶段
- 更多层
当然没有什么神奇的事情可以立即减少损失,因为它是非常具体的问题,但这里有一些我可以建议的技巧:
- 减少小批量大小。具有较小的批量大小会使梯度在反向传播时更加嘈杂。这乍一看似乎违反直觉,但梯度下降中的这种噪声可以帮助下降克服可能的局部最小值。这样想;当下降嘈杂时,它会花费更长的时间但高原会更低,当下降平稳时,它会花费更少但会稳定在更早的高原。 (非常笼统!)
- 尝试使图层具有 expanding/shrinking 顺序的单元。因此,与其背靠背使用 128 个单元层,不如将其设为 128 到 256。这样,您就不会强迫模型用另一组 128 个数字来表示 128 个数字。您可以拥有 128 个单元的所有层,理论上 会产生 无损 自动编码,其中输入和输出实际上是相同的.但由于梯度下降的性质,这在实践中不会发生。这就像你随机从丛林中的某个地方开始,并尝试沿着领先(负梯度)穿过它,但仅仅因为你有领先并不意味着你可以到达你所在的位置为首。因此,要从您的分布中获取有意义的信息,您应该强制您的模型以较小的单位表示信息。这将使梯度下降的工作更容易,因为你设置了先验条件;如果它不能足够好地编码信息,就会有很高的损失。所以你有点让理解你想要从模型中得到什么。
- 误差函数的绝对值。您正在努力降低损失,但目的是什么?您需要它接近 0,还是只需要它尽可能低?因为随着你的潜在维度缩小,损失会增加但是自动编码器将能够更好地捕获数据的潜在代表信息。因为你强迫编码器用低维信息来表示高维信息。因此,潜在维度越低,自动编码器就越会尝试 从输入中提取 最有意义的信息,因为它限制了 space。因此,即使损失越大,也能更有效地捕获分布。所以这取决于你的问题,如果你想要图像降噪之类的东西,使用更高的编码维度,但如果你想要做异常检测之类的事情,最好尝试更低的维度而不完全破坏模型的代表性能力.
- 这是我的更多 tinfoil 建议,但您也尝试将数字向下移动,以便范围为 -128 到 128。我 - 不太准确 -观察到某些激活(尤其是 ReLU)在这些类型的输入下效果稍好。
我希望其中一些对你有用。祝你好运。