我正在尝试为大量数据训练Doc2vec。我有一个总共72GB的20k文件,并写下这段代码:
def train():
onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))]
data = []
random.shuffle(onlyfiles)
tagged_data = []
t = 0
try:
for file_name in onlyfiles:
with open(mypath+"/"+file_name, 'r', encoding="utf-8") as file:
txt = file.read()
tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
t+=1
except Exception as e:
print(t)
return
print("Files Loaded")
max_epochs = 1000
vec_size = 500
alpha = 0.025
model = Doc2Vec(vector_size=vec_size,
alpha=alpha, workers=1,
min_alpha=0.00025,
min_count=1,
dm=1)
print("Model Works")
print("Building vocabulary")
model.build_vocab(tagged_data)
print("Trainning")
for epoch in range(max_epochs):
print("Iteration {0}".format(epoch))
model.train(tagged_data,
total_examples=model.corpus_count,
epochs=model.iter)
model.alpha -= 0.0002
model.min_alpha = model.alpha
model.save(model_name)
print("Model Saved")
但是当我运行此方法时,会出现此错误:Traceback(最近一次调用最后一次):
File "doc2vec.py", line 20, in train
tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
MemoryError
并且只处理3k个文件。但是当查看内存时,python
进程显示只使用了1.7%的内存。有什么参数我可以通知python
解决?我该如何解决?
你甚至在尝试Doc2Vec
之前就已经得到了错误,所以这不是一个真正的Doc2Vec
问题 - 这是你的Python数据处理的一个问题。你有足够的RAM来加载72GB的磁盘数据(在Python字符串对象中表示可能会扩展一点)到RAM中吗?
而且,你通常不必通过附加到一个巨大的列表来将整个语料库带入内存,以执行任何这些任务。一次读取一个东西,并从迭代/迭代器处理,也许将临时结果(如标记化文本)写回IO源。本文可能会有所帮助:
https://rare-technologies.com/data-streaming-in-python-generators-iterators-iterables/
最后,如果您的代码确实进入了Doc2Vec
部分,那么您还有其他问题。无论您作为模型咨询的在线示例都有许多不良做法。例如:
min_count=1
导致了一个更大的模型;通常丢弃低频词是必要的,甚至可能会改善最终的矢量质量,而较大的数据集(和72GB非常大)倾向于用户更大而不是最小的min_count
设置alpha
/ min_alpha
值,或尝试用自己的计算来管理它们,甚至不止一次调用train()
。 train()
有自己的epochs
参数,如果使用它将顺利处理你的学习率alpha
。据我所知,100%在自己的循环中多次调用train()
的人做错了,我不知道他们在哪里得到这些例子。workers=1
训练速度慢得多;特别是对于大型数据集,您需要尝试更大的workers
值,并且通过3.5.0的gensim版本中训练吞吐量的最佳值通常在3-12的范围内(假设您至少拥有那么多CPU核心) )。因此,您当前的代码可能会导致模型大于RAM,缓慢地训练单线程并且超过必要的1000倍,大部分训练都发生在无意义的负alpha上,这使得模型在每个周期都变得更糟。如果它在模型初始化期间奇迹般地没有MemoryError
,它会运行数月或数年并最终产生无意义的结果。