0

我正在尝试DynamicLMClassifier.createNGramProcess(categories,nGram)在大于 20GB 的大数据集上训练 a。我目前正在将整个培训文件作为字符串提供给培训方法,出于显而易见的原因,我得到了一个java.lang.OutOfMemoryError: Java heap space

尽管可能增加 JVM 堆大小以支持此类训练,但我有兴趣找到一种增量方法。

训练代码如下所示:

char[] csBuf = new char[numChars];
for (int i = 0; i < categories.length; ++i) {
    String category = categories[i];
    File trainingFile = new File(new File(dataDir,category),
                                 category + ".txt");
    FileInputStream fileIn
        = new FileInputStream(trainingFile);
    InputStreamReader reader
        = new InputStreamReader(fileIn,Strings.UTF8);
    reader.read(csBuf);
    String text = new String(csBuf,0,numChars);
    Classification c = new Classification(category);
    Classified<CharSequence> classified
        = new Classified<CharSequence>(text,c);
    classifier.handle(classified);
    reader.close();
}

理想的解决方案是在训练集的 N 个子集的循环中提供分类器.handle()。从理论上讲,我认为这应该是可能的,因为模型只需要记住具有各自计数的 ngram 元组来计算 MLE。

4

1 回答 1

2

是的,您可以逐步训练这些分类器。您只需要编写自己的数据处理程序,它不会尝试一次读取所有数据。上面没有缓冲所有数据,而是在每个训练项目中读取一次,所以应该可以。如果你的内存仍然不足,那可能只是因为如果你有很长的上下文或者没有在你去的时候明确地修剪,那么构建一个超过 20GB 的语言模型需要大量的内存。

我写了一篇关于 LingPipe 的缩放如何适用于语言模型的论文,而增量分类器只是构建了一堆并行语言模型。

http://www.aclweb.org/anthology/W05-1107

可以节省内存的更极端的替代方法是分别训练每个类别,然后将它们组合成分类器,LingPipe API 也支持该分类器。

于 2016-03-31T22:15:10.020 回答