我想在大小为400MB的标记化文件上训练word2vec模型。我一直在尝试运行这个python代码:
import operator
import gensim, logging, os
from gensim.models import Word2Vec
from gensim.models import *
class Sentences(object):
def __init__(self, filename):
self.filename = filename
def __iter__(self):
for line in open(self.filename):
yield line.split()
def runTraining(input_file,output_file):
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
sentences = Sentences(input_file)
model = gensim.models.Word2Vec(sentences, size=200)
model.save(output_file)
当我在我的文件上调用此函数时,我得到了这个:
2017-10-23 17:57:00,211 : INFO : collecting all words and their counts
2017-10-23 17:57:04,071 : INFO : PROGRESS: at sentence #0, processed 0 words, keeping 0 word types
2017-10-23 17:57:16,116 : INFO : collected 4735816 word types from a corpus of 47054017 raw words and 1 sentences
2017-10-23 17:57:16,781 : INFO : Loading a fresh vocabulary
2017-10-23 17:57:18,873 : INFO : min_count=5 retains 290537 unique words (6% of original 4735816, drops 4445279)
2017-10-23 17:57:18,873 : INFO : min_count=5 leaves 42158450 word corpus (89% of original 47054017, drops 4895567)
2017-10-23 17:57:19,563 : INFO : deleting the raw counts dictionary of 4735816 items
2017-10-23 17:57:20,217 : INFO : sample=0.001 downsamples 34 most-common words
2017-10-23 17:57:20,217 : INFO : downsampling leaves estimated 35587188 word corpus (84.4% of prior 42158450)
2017-10-23 17:57:20,218 : INFO : estimated required memory for 290537 words and 200 dimensions: 610127700 bytes
2017-10-23 17:57:21,182 : INFO : resetting layer weights
2017-10-23 17:57:24,493 : INFO : training model with 3 workers on 290537 vocabulary and 200 features, using sg=0 hs=0 sample=0.001 negative=5 window=5
2017-10-23 17:57:28,216 : INFO : PROGRESS: at 0.00% examples, 0 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:32,107 : INFO : PROGRESS: at 20.00% examples, 1314 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:36,071 : INFO : PROGRESS: at 40.00% examples, 1728 words/s, in_qsize 0, out_qsize 0
2017-10-23 17:57:41,059 : INFO : PROGRESS: at 60.00% examples, 1811 words/s, in_qsize 0, out_qsize 0
Killed
我知道word2vec需要很多空间,但我仍然认为这里存在问题。如您所见,此型号的估计内存为600MB,而我的计算机有16GB的RAM。然而,在代码运行时监视进程表明它占用了我所有的内存,然后被杀死。
正如其他帖子所说,我试图增加min_count并减小尺寸。但即使有可笑的值(min_count = 50,size = 10),过程也会停止在60%。
我还试图让python成为OOM的一个例外,这样就不会杀死进程。当我这样做时,我有一个MemoryError而不是杀戮。
发生了什么事?
(我最近使用的是Ubuntu 17.04,16GB内存和Nvidia GTX 960M的笔记本电脑。我从Anaconda和gensim 3.0运行python 3.6,但它对gensim 2.3没有做得更好)
答案 0 :(得分:0)
您的文件是一行,如日志输出所示:
2017-10-23 17:57:16,116 : INFO : collected 4735816 word types from a corpus of 47054017 raw words and 1 sentences
这是你想要的,这是值得怀疑的;特别是gensim的Word2Vec
中优化的cython代码只能在截断它们之前处理10,000个单词的句子(并丢弃其余的单词)。因此,大多数数据在培训期间都没有被考虑(即使它已经完成)。
但更大的问题是,单个4700万字的行将作为一个巨大的字符串进入内存,然后split()
成为一个4700万条目的字符串列表。因此,尝试使用内存高效的迭代器并没有任何帮助 - 整个文件被带入内存,两次,一次'迭代'。
我仍然没有看到使用完整的16GB RAM,但也许正在纠正这将解决问题,或使任何剩余的问题更明显。
如果您的标记化数据没有10,000个令牌句长度周围或以下的自然换行符,您可以查看gensim中包含的示例语料库类LineSentence
如何能够处理(也是缺少换行符text8
或text9
语料库,将每个产生的句子限制为10,000个令牌:
(它可能不是一个促成因素,但您可能还想使用with
上下文管理器来确保在迭代器用完后立即关闭open()
ed文件。)