2016-03-30 94 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

您應該爲每個培訓項目構建一個新的「分類」實例。然後,你可以逐漸將它們送入培訓師,並且他們會收集垃圾,這樣他們就不必全都記憶。 –