理解Keras LSTM(lstm_text_generation.py)- RAM内存问题

3

我正在学习使用KerasTheano后端进行LSTM RNN。在尝试使用keras存储库中的lstm示例(lstm_text_generation.py的完整代码在github上)时,有一件事情让我不太清楚:它是如何对输入数据(文本字符)进行向量化的:

# cut the text in semi-redundant sequences of maxlen characters
maxlen = 40
step = 3
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
    sentences.append(text[i: i + maxlen])
    next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))

#np - means numpy
print('Vectorization...')
X = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
    for t, char in enumerate(sentence):
        X[i, t, char_indices[char]] = 1
    y[i, char_indices[next_chars[i]]] = 1

在这里,你可以看到他们使用Numpy生成一系列零,并将“1”放置在由输入字符编码序列定义的特定位置上。
问题是:为什么他们使用这个算法?是否有可能对其进行优化?也许可以以其他方式编码输入数据,而不是使用大量的列表?问题在于它有严格的输入数据限制:为超过10 Mb的文本生成这样的向量会导致Python的MemoryError(需要数十GB的RAM来处理它!)。
提前感谢大家。

我们在谈论哪种尺寸(您的数据集中len(sentences)len(chars)大约有多大)?你有多少RAM? - ali_m
我有6Gb的RAM,但我也尝试在32Gb的RAM VPS上运行它。关于维度:对于520Kb的输入文本,它们是 len(sentences)=174507 和 _len(chars)=74_,所有运行都正常。但是对于17Mb的输入文本,它们是 len(sentences)=5853627 和 _len(chars)=74_,并且在6Gb RAM 上会抛出MemoryError错误。 - Alex M
1个回答

2
在Keras中,至少有两种优化方法可以减少此情况所需的内存量:
  1. 使用嵌入层,使其能够接受单个整数而不是完整的独热向量。此外,这一层可以在网络训练的最后阶段之前进行预训练,因此您可以将一些先前的知识注入到模型中(并且甚至可以在网络拟合期间微调它)。

  2. 使用fit_generator方法,可以使用预定义的生成器来训练网络,该生成器会产生网络拟合所需的配对(x, y)。例如,您可以将整个数据集保存到磁盘上,并使用生成器接口逐部分读取它。

当然,这两种方法都可以混合使用。我认为,在您提供的示例中,简单性是采用这种实现方式的原因。

非常感谢您的回复,我会尝试您提供的解决方案,并很快在此处提供结果。 - Alex M
我的回答有帮助到您吗? - Marcin Możejko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接