使用Python和Doc2V的MemoryError

2024-04-20 11:07:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我在训练一个Doc2vec来处理海量数据。我有一个20k文件,总共72GB,并编写以下代码:

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")

但当我运行此方法时,会出现以下错误: 回溯(最近一次呼叫):

File "doc2vec.py", line 20, in train
    tagged_data.append([word_tokenize(txt.lower()), [str(t)]])
MemoryError

只处理3k文件。但是当查看内存时,python过程显示只使用了1.7%来自内存。 有什么参数我可以通知python去解决吗? 我该怎么修?你知道吗


Tags: nameinalphatxtfordatasizemodel
1条回答
网友
1楼 · 发布于 2024-04-20 11:07:52

您在尝试Doc2Vec之前就已经得到了这个错误,所以这不是一个Doc2Vec问题—这是Python数据处理的问题。您是否有足够的RAM将72GB的磁盘数据(用Python字符串对象表示时可能会扩展一点)加载到RAM中?你知道吗

但是,你通常不需要把一个完整的语料库放到内存中,通过添加一个巨大的列表来完成这些任务。一次读取一个内容,然后从iterable/迭代器进行处理,可能会将临时结果(如标记化文本)写回IO源。本文可能有帮助:

https://rare-technologies.com/data-streaming-in-python-generators-iterators-iterables/

最后,如果您的代码确实进入了Doc2Vec部分,那么您还有其他问题。无论你在网上咨询什么样的例子,都有很多不好的做法。例如:

  • 典型的交互计数是10-20;对于72GB的数据集,当然不会使用1000

  • min_count=1导致了一个更大的模型;通常丢弃低频词是必要的,甚至可能改善结果向量的质量,更大的数据集(72GB非常大)倾向于使用更大的而不是最小的min_count设置

  • 大多数人不应该使用非默认的alpha/min_alpha值,或者尝试用自己的计算来管理它们,甚至不应该多次调用train()train()有自己的epochs参数,如果使用该参数,将为您平滑地处理alpha学习率。据我所知,100%在自己的循环中多次调用train()的人都做错了,我不知道他们从哪里得到这些例子。

  • 使用workers=1进行训练要慢得多;特别是对于大型数据集,您需要尝试更大的workers值,并且gensim版本到3.5.0的训练吞吐量的最佳值通常在3-12之间(假设您至少有那么多CPU核)。

因此,您当前的代码可能会导致一个比RAM更大的模型,训练单线程的速度很慢,比需要的时间长1000倍,而且大部分训练都是用一个荒谬的负alpha进行的,这使得模型在每个周期都变得更糟。如果它在模型初始化过程中奇迹般地没有MemoryError,那么它将运行数月或数年,最终得到无意义的结果。你知道吗

相关问题 更多 >