使用有状态 LSTM 进行不同长度的多系列训练

数据挖掘 神经网络 lstm rnn
2021-09-30 14:16:46

我正在训练一个有状态的 LSTM。我的数据存储在一系列文件中,每个文件都与某个城市相关。对于每个城市,我可能有不同数量的数据,因此 City AI 可能有 4000 天,但 City BI 可能只有 500 天。我每天有 20 个特征。

假设我将序列大小设置为 200;对于城市 A,我有一批 20 个完整的序列,但对于城市 B,我只有 2 个。

使用有状态 LSTM,我需要以batch_input_shape[batch size, sequence size, features] 的形式指定,我认为这会给我带来一些问题,因为我处理的每个城市的批大小都会发生变化。

正如我所看到的,我唯一可用的选择是将批量大小定义batch_input_shape为 1,然后为每次迭代有效地发出一个 200 长度的序列。batch_input_shape[1, 200, 20] 也是如此

显然这并不理想,因为每次迭代都向 NN 呈现如此少量的数据(它肯定是小批量!)所以训练网络会很慢。

但是我是对的,由于数据的大小不同,我真的没有其他选择吗?除了训练时间慢之外,批量大小为 1 的训练是否存在任何固有问题?

1个回答

首先,您可以将批量大小视为控制学习曲线平滑度的一种方式。由于批量大小很大,每次更新都会取许多错误的平均值,而这个平均损失(平均而言)并没有很大的差异。

使用 1 的批量大小,每次迭代的成本完全取决于您提供给网络的单个样本。每个样本都希望与其他样本略有不同,这将导致非常嘈杂的损失曲线。

假设模型参数非常合适,并且无论批量大小如何,模型都会收敛,您应该会得到类似的结果。但是,也有一些作品分析批量大小并显示其他权衡,通常是训练时间、内存消耗等。

最近的这篇论文 (Masters, Luschi)分析了标准数据集 (CIFAR10) 上批量大小的权衡。这是论文中的图 15,它非常简洁地显示了这一点:

基于批量大小的性能

警告:然而,所有模型和数据集的行为可能不同,所以不要把这样的任何结果当作事实!


我知道可以通过使用一种称为自适应池化(或 PyTorch 中的自适应平均池化)的技术来训练具有不同输入形状的模型,但是您可能必须想出自己的函数来执行这样的操作有状态LSTM约束内的事物。

因此,由于数据集的形状必须能被批量大小整除,因此有几种方法可以实现这一点:

  1. 使用数据集的最高公倍数:因此,对于具有 4000 天(A 组)和 500 天(B 组)的示例数据集,您将计算

这当然限制了序列长度的可能选择,但是对于 4000 和 500 这两个示例,您可以从以下选项中进行选择:1、2、4、5、10、20、25、50、100

  1. 修剪不同的数据集,以便获得适用于两者的良好序列长度

这意味着可能会遗漏一些数据,这是不可取的,但可能不会太多。

您可能会选择这两种可能性中的哪一种取决于您的特定数据集大小。使用两者可能是最佳的 - 因此修剪一些数据集以允许计算一个很好的Highest Common Factor

您可以使用以下方法在 Python 中计算 HCF:

def hcf(a, b):
    while b:
        a, b = b, b % a
    return a

我在下面的评论中的一个最终想法:

...为了更改数据集之间的批量大小,您可以从经过训练的模型(从您的第一个数据集)复​​制它们的模型权重,然后使用下一个数据集所需的批量大小编译一个新模型,但将权重设置为相等到第一个模型的那些。这几乎就像实现有状态行为的手动方式。看看这里有一个简单的例子