我正在尝试在大数据集上训练DynamicLMClassifier.createNGramProcess(categories,nGram)
> 20GB。我目前正在将整个培训文件作为字符串提供给培训方法,原因很明显我得到的是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个子集的循环中提供classifier.handle()。从理论上讲,我认为这应该是可能的,因为模型只需要记住ngrams元组及其各自的计数来计算MLE。
答案 0 :(得分:2)
是的,您可以逐步训练这些分类器。您只需要编写自己的数据处理程序,而不是尝试一次读取所有数据。以上内容不会缓冲所有数据,但每个训练项目都会读取一次,因此应该可以正常工作。如果你的内存不足,可能只是因为如果你有很长的上下文或者没有明确修剪,那么构建一个超过20GB的语言模型需要大量的内存。
我写了一篇关于LingPipe缩放如何为语言模型工作的论文,而增量分类器只是构建了一堆并行语言模型。
http://www.aclweb.org/anthology/W05-1107
一个可以节省内存的更极端的替代方案是分别训练每个类别,然后将它们组合到一个分类器中,LingPipe API也支持它。