2016-03-30 98 views
0

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

尽管可能增加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个子集的一个循环来供给classifier.handle()。理论上我认为这应该是可能的,因为该模型只需要记住具有它们各自计数的ngram元组来计算MLE。

回答

2

是的,你可以增量训练这些分类器。你只需要编写你自己的数据处理程序,它不会一次读取所有数据。上述内容不会缓冲所有数据,但是每个培训项目都会读取一次,因此应该可以正常工作。如果你仍然内存不足,那可能仅仅是因为如果你有很长的上下文或者没有明确的修剪,那么建立一个超过20GB的语言模型需要大量的内存。

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

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

甚至更​​极端的替代方案,可以节省存储器是分别训练每个类别,然后后来它们合并成一个分级器,其也由LingPipe API支持。

+0

所以基本上如果我只是需要调用'classifier.handle(classified)'具有相同的类别,但不同的字符串? – gidim

+1

您应该为每个培训项目构建一个新的“分类”实例。然后,你可以逐渐将它们送入培训师,并且他们会收集垃圾,这样他们就不必全都记忆。 –