为lstm创建大型热编码时出现内存错误

时间:2018-03-12 16:08:40

标签: numpy nlp keras

我正在尝试使用keras构建一个字符级别的lstm模型,为此我需要为模型中的字符创建一个热编码。我每行约有1000个字符,大约有160,000行。

我试图创建一个零的numpy数组,并使相应的条目1,但由于矩阵的大尺寸,有任何其他方法可以解决内存错误。

2 个答案:

答案 0 :(得分:1)

不确定

  1. 创建批次。一次只处理10,000个条目(字符),计算并在它们需要之前将它们输入到神经网络中(例如,通过使用生成器而不是列表)。 Keras有[[0, 0, 1], [0, 1, 0], [0, 0, 1]]训练功能来完成这项工作。

  2. 将数据块组合在一起。比方说,而不是一行是其字符的单热编码的矩阵,而是使用所有这些列的和/ max来为该行生成单个向量。现在,每一行只是一个向量,维度等于数据集中唯一字符的数量。例如,而不是[0, 1, 1],使用{{1}}代表整行。

答案 1 :(得分:0)

也许更简单,更直观的解决方案是在Keras模型体系结构中添加自定义的一键编码层。

def build_model(self, batch_size, print_summary=False):
    X = Input(shape=(self.sequence_length,), batch_size=batch_size)
    embedding = OneHotEncoding(num_classes=self.vocab_size+1, 
                               sequence_length=self.sequence_length)(X)
    encoder = Bidirectional(CuDNNLSTM(units=self.recurrent_units, 
                                      return_sequences=True))(embedding) 
    ...

我们可以在其中定义OneHotEncoding层,如下所示:

from tensorflow.keras.layers import Lambda
from tensorflow.keras import backend as K
from tensorflow.keras.layers import Layer # for creating custom layers

class OneHotEncoding(Layer):
     def __init__(self, num_classes=None, sequence_length=None):
         if num_classes is None or sequence_length is None:
             raise ValueError("Can't leave params @num_classes or @sequence_length empty")
         super(OneHotEncoding, self).__init__()
         self.num_classes = num_classes
         self.sequence_length = sequence_length
     def encode(self, inputs):
         return K.one_hot(indices=inputs,
                          num_classes=self.num_classes)
     def call(self, inputs):
         return Lambda(function=self.encode,
                       input_shape=(self.sequence_length,))(inputs)

在这里,我们利用了Keras模型以适当的批次大小(具有标准的fit函数)喂入训练样本的事实,而这又不会产生MemoryError