使用LSTM单元进行RNN训练时的RAM内存使用情况

3
我正在跟随一个关于循环神经网络的教程,我正在训练一个RNN去学习如何在给定字母序列的情况下预测下一个字母。问题是,每次我训练网络时,我的RAM使用率都会慢慢上升。由于我只有8192MB RAM内存,在大约100个epochs后就用尽了,我无法完成对这个网络的训练。为什么会这样? 我认为这可能与LSTM的工作方式有关,因为它们会将一些信息保存在内存中,但如果有人能向我解释更多细节就好了。

我使用的代码相对简单,完全自包含(您可以复制/粘贴并运行它,不需要外部数据集,因为数据集只是字母表)。因此,我将其完整包含,以便问题容易重现。

我正在使用的tensorflow版本是1.14。

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.utils import np_utils
from keras_preprocessing.sequence import pad_sequences
np.random.seed(7)

# define the raw dataset
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

# create mapping of characters to integers (0-25) and the reverse
char_to_int = dict((c, i) for i, c in enumerate(alphabet))
int_to_char = dict((i, c) for i, c in enumerate(alphabet))

num_inputs = 1000
max_len = 5
dataX = []
dataY = []
for i in range(num_inputs):
    start = np.random.randint(len(alphabet)-2)
    end = np.random.randint(start, min(start+max_len,len(alphabet)-1))
    sequence_in = alphabet[start:end+1]
    sequence_out = alphabet[end + 1]
    dataX.append([char_to_int[char] for char in sequence_in])
    dataY.append(char_to_int[sequence_out])
    print(sequence_in, "->" , sequence_out)

#Pad sequences with 0's, reshape X, then normalize data
X = pad_sequences(dataX, maxlen=max_len, dtype= "float32" )
X = np.reshape(X, (X.shape[0], max_len, 1))
X = X / float(len(alphabet))
print(X.shape)

#OHE the output variable.
y = np_utils.to_categorical(dataY)

#Create & fit the model
batch_size=1
model = Sequential()
model.add(LSTM(32, input_shape=(X.shape[1], 1)))
model.add(Dense(y.shape[1], activation= "softmax" ))
model.compile(loss= "categorical_crossentropy" , optimizer= "adam" , metrics=[ "accuracy" ])
model.fit(X, y, epochs=500, batch_size=batch_size, verbose=2)

1
这是哪个TF版本? - thushv89
1
版本号为1.14.0。 - Psychotechnopath
1
我也想问一下版本。这段代码看起来还不错。 - Daniel Möller
2
我在使用估计器API的TF 1.10版本时遇到了完全相同的问题。 在我提出问题并得不到解决后,我放弃了,再也没有遇到这个问题......我会在另一个环境中尝试同样的操作 - TensorFlow的响应提到要检查TF版本是否在正确的CUDA上运行。1.14是CUDA 10,您在使用它吗?https://www.tensorflow.org/install/source#gpu - bluesummers
2
Nicholas-Leonard在这个问题(https://github.com/Element-Research/rnn/issues/5)中建议:“内存限制可能位于LSTM代码中,因为它为每个步骤维护一个状态(这是存储在表中的表)。”还要看一下Marcin Możejko的答案(https://dev59.com/xJ7ha4cB1Zd3GeqPh1Yf),他提供了两个建议,可以用来减少内存使用量。 - kevin
显示剩余5条评论
1个回答

2
问题在于您的序列相当长(1000个连续输入)。由于LSTM单元在历次训练中保持某种状态,而您尝试进行500个epoch的训练(这非常多),特别是在使用CPU进行训练时,您的RAM会随着时间的推移而过载。建议您尝试在GPU上进行训练,因为GPU有专用的内存。此外,请查看此问题:https://github.com/Element-Research/rnn/issues/5

1
你可以向CPU投入尽可能多的内存,最坏的情况下,使用交换区将SSD作为“穷人的RAM”。GPU几乎从不超过8GB(最新的可负担得起的怪兽有12GB),如果提问者没有GPU,那么建议购买更多的RAM而不是浪费钱购买GPU。 - user11877195
感谢您的回答。由于您是唯一发布答案的人,我授予了您赏金,而且我不想让赏金白白浪费。我有一个GPU,当我在那里训练模型时,我的RAM内存没有被淹没,训练成功完成。我正在寻找一个具体的解释,为什么在CPU上训练模型会淹没我的RAM,尽管github链接没有给我确切的答案(因此我不会接受它),但它确实给了我一个很好的方向去寻找。如果有人能够提供完整的答案,我会确保接受它。 - Psychotechnopath

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