Python 基于参与方加载数据的列车Keras模型

Python 基于参与方加载数据的列车Keras模型,python,tensorflow,keras,Python,Tensorflow,Keras,我试图预测长度为100的给定字符串的下一个字符。问题是,当我生成训练数据时,我的整个RAM(AmazonAWS上为32GB-)都被吃掉了,进程也被破坏了 为了构建训练数据,我迭代了一系列文章(每个文章有500-1000个字符)。在每篇文章中,我将前100个字符作为输入,下一个字符作为输出,然后移动一个字符,并重复此操作,直到文本结束。这种方法会产生大量的训练向量,即具有500个字符的文章将产生大约400个测试数据,这就是问题所在 有了15k的文章和100个滑动窗口,将有数百万的训练数据,我的AW

我试图预测长度为100的给定字符串的下一个字符。问题是,当我生成训练数据时,我的整个RAM(AmazonAWS上为32GB-)都被吃掉了,进程也被破坏了

为了构建训练数据,我迭代了一系列文章(每个文章有500-1000个字符)。在每篇文章中,我将前100个字符作为输入,下一个字符作为输出,然后移动一个字符,并重复此操作,直到文本结束。这种方法会产生大量的训练向量,即具有500个字符的文章将产生大约400个测试数据,这就是问题所在

有了15k的文章和100个滑动窗口,将有数百万的训练数据,我的AWS机器(32 GB RAM t2.2xlarge-)正在以大约79%-3500万的训练数据消亡

所以我的问题是——在Keras中有没有一种方法可以开始学习模型,比如说25%的数据,然后加载下一个25%的数据,直到所有数据都被消耗掉

我的学习伪代码:

with open(articles_path, 'rt', encoding="UTF-8") as file:
    for line in file:
        article = line[0:-1]
        article_length = len(article)
        # here is the problematic code 
        for i in range(0, article_length - seq_length, 1):
            seq_in = article[i:i + seq_length]
            seq_out = article[i + seq_length]
            dataX.append([tokens[char] for char in seq_in])
            dataY.append(tokens[seq_out])

model = Sequential()
model.add(LSTM(256, input_shape=(seq_length, 1)))
model.add(Dropout(0.2))
model.add(Dense(len(tokens), activation=activation))
model.compile(loss=loss, optimizer=optimizer)

model.fit(X, y, epochs=epochs, batch_size=batch_size, callbacks=callbacks_list)

注意:当我编写自己的程序时,我使用了本教程

您的数据生成方法很有趣,但您不必从文本中生成每个100字节的样本。将有问题的代码替换为以下内容:

    for i in range(0, article_length - seq_length, 1):
        if random.randint(1,10) not in [5, 6] : continue   # this will skip 80% of the samples
        seq_in = article[i:i + seq_length]
        seq_out = article[i + seq_length]
        dataX.append([tokens[char] for char in seq_in])
        dataY.append(tokens[seq_out])
import random
放在文件开头的某个位置。一旦你把它放入你的代码中,5个序列中只有1个会进入你的训练数据,有效地减少了数据的大小


有一种方法可以提高随机采样字符串的生成效率,但它需要重写代码,这种方法只需增加一行代码。

这看起来是切换到生成器的好时机,基本上你将一次输出一批数据,而不是加载整个数据集:

def data_gen(batch_size=32):
  """Yield single batch at a time."""
  dataX, dataY = list(), list()
  while True: # the generator yields forever
    # here is the problematic code 
    for i in range(0, article_length - seq_length, 1):
      for _ in range(batch_size):
        seq_in = article[i:i + seq_length]
        seq_out = article[i + seq_length]
        dataX.append([tokens[char] for char in seq_in])
        dataY.append(tokens[seq_out])
      yield np.array(dataX), np.array(dataY)
      dataX, dataY = list(), list()
现在,您可以使用
fit_generator
()进行训练,它将从生成器中获取批次。因此,您只处理
batch\u size
样本数,而不是整个集合。您可能希望使用NumPy数组而不是Python列表


对于更具组织性的版本,您可以实现一个封装数据并充当生成器的组件。

但这样我就不会使用我收集的所有数据。这不是一种浪费吗?@MAGx2您可以选择使用更少的数据并运行训练,或者让程序在“内存不足”的情况下失败——这是您的选择=)当您将数据生成文件并将该文件用作训练的输入时,有不同的方法,但对于你的教育项目来说,这将是一种过度的杀伤力。用更少的数据开始训练,会有很多方法出错…@MAGx2 NP,带着更多的问题回来,我相信你会有很多=)谢谢你的回答。这就是我需要的!顺便问一下,你为什么要永远运行这个发电机?
model.fit\u generator
是否以此设置结束?“当模型看到每个历元的
步骤时,历元结束。”因此,您可以指定有多少批次。如果您实现了一个
序列
则使用了
len()
,文档涵盖了所有这些内容,值得一看。