我目前正在尝试训练一个自动编码器,它允许将长度为 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])
我还将上传一个显示训练和验证过程的图形:训练损失图
我怎么可能进一步降低损失。到目前为止我尝试过的方法(两种选择都没有成功(:
- 更长的训练阶段
- 更多图层
当然,没有一件神奇的事情可以立即减少损失,因为它非常特定于问题,但这里有几个我可以建议的技巧:
- 减小小批量大小。具有较小的批大小会使梯度在反向传播时更加嘈杂。这首先可能看起来违反直觉,但梯度下降中的这种噪声可以帮助下降克服可能的局部最小值。这样想;当下降嘈杂时,需要更长的时间,但平台会更低,当下降平稳时,它会花费更少,但会稳定在更早的高原。(非常笼统!
- 尝试使图层具有具有扩展/收缩顺序的单位。因此,与其连续使用 128 个单元层,不如将其设置为 128 到 256。这样,您就不会强制模型用另一包 128 个数字来表示 128 个数字。您可以拥有具有 128 个单元的所有图层,理论上这将产生无损自动编码,其中输入和输出实际上是相同的。但这在实践中并没有发生,因为梯度下降的性质。这就像你随机地从丛林中的某个地方开始,并试图按照领先(负梯度(穿过它,但仅仅因为你有领先并不意味着你可以到达你要去的地方。因此,要从分布中获取有意义的信息,应强制模型表示具有较小单位的信息。这将使梯度下降的工作更容易,因为您正在设置一个先验条件;如果它不能很好地编码信息,它将有很高的损失。所以你有点让它了解你想要从模型中得到什么。
- 误差函数的绝对值。你试图降低你的损失,但目的是什么?您需要它接近 0,还是只需要它尽可能低?因为随着潜在维度的缩小,损失会增加,但自动编码器将能够更好地捕获数据的潜在代表性信息。因为您强制编码器用低维信息表示更高维度的信息。因此,潜在维度越低,自动编码器就越会尝试从输入中提取最有意义的信息,因为它的空间有限。因此,即使损失更大,分布也会更胜任。所以这取决于你的问题,如果你想在图像上降噪,使用更高的编码维度,但如果你想做一些像异常检测这样的事情,最好尝试更低的维度,而不会完全破坏模型的代表能力。
- 这是我的锡纸建议,但您也尝试将数字向下移动,以便范围为 -128 到 128。我观察到 - 不太准确 - 一些激活(尤其是 ReLU(在这些输入下效果稍好。
我希望其中一些对你有用。祝你好运。