【问题标题】:Word2Vec: Any way to train model fastly?Word2Vec:有什么方法可以快速训练模型?
【发布时间】:2017-04-10 11:03:23
【问题描述】:

我使用Gensim Word2Vec 在我的数据库中训练单词集。

我的PostgreSQL 数据库中有大约 400,000 个短语(每个短语都很短。总共 700MB)。

这就是我使用Django ORM 训练这些数据的方式:

post_vector_list = []
for post in Post.objects.all():
    post_vector = my_tokenizer(post.category.name)
    post_vector.extend(my_tokenizer(post.title))
    post_vector.extend(my_tokenizer(post.contents))
    post_vector_list.append(post_vector)
word2vec_model = gensim.models.Word2Vec(post_vector_list, window=10, min_count=2, size=300) 

但是这份工作需要很多时间,感觉效率不高。

特别是,创建post_vector_list 部分需要大量时间和空间..

我想提高训练速度,但不知道怎么做。

希望得到您的建议。谢谢。

【问题讨论】:

    标签: orm nlp gensim word2vec


    【解决方案1】:

    要优化此类代码,您需要收集有关时间花费的良好信息。

    大部分时间都花在准备post_vector_list上吗?

    如果是这样,您需要确保my_tokenizer(其代码未显示)尽可能高效。您可能希望尽量减少在大型列表中完成的extend()s 和append()s 的数量。您甚至可能需要查看 DB 的配置或选项,以加快在 Post.objects.all() 中启动的 DB 到对象的映射。

    大部分时间都花在了对Word2Vec()的调用上吗?

    如果是这样,其他步骤可能会有所帮助:

    • 确保您使用的是 gensim 的 Cython 优化例程 - 如果没有,您应该会看到记录的警告(训练速度会慢 100 倍)
    • 如果您的机器至少有 4 或 8 个 CPU 内核,请考虑使用 workers=4workers=8 可选参数来使用更多线程
    • 考虑使用更大的min_count,它可以在一定程度上加快训练速度(因为只有几个例子的词的向量通常不是很好,所以不会损失太多,甚至可以提高幸存者的质量字)
    • 考虑使用较小的window,因为较大的窗口需要更长的训练时间
    • 考虑使用较小的vector_size(以前称为size),因为较大尺寸的向量需要更长的训练时间
    • 考虑为可选的sample 参数使用更激进(更小)的值,它会随机跳过更多最常用的词。默认值为1e-04,但1e-051e-06 的值(尤其是在较大的语料库上)可以提供额外的加速,甚至通常会改善最终向量(通过在具有过多使用示例的单词上花费相对较少的训练时间)
    • 考虑为可选的epochs 参数(以前称为iter)使用低于默认值(5) 的值。 (除非语料库非常大,否则我不建议这样做——因此它已经有许多冗余的、同样好的例子,贯穿始终。)

    【讨论】:

      【解决方案2】:

      您可以使用 python 生成器而不是将所有数据加载到列表中。 Gensim 也适用于 python 生成器。代码看起来像这样

      class Post_Vectors(object):
          def __init__(self, Post):
              self.Post = Post
          def __iter__(self):
              for post in Post.objects.all():
                  post_vector = my_tokenizer(post.category.name)
                  post_vector.extend(my_tokenizer(post.title))
                  post_vector.extend(my_tokenizer(post.contents))
                  yield post_vector
      
      post_vectors = Post_Vectors(Post)
      word2vec_model = gensim.models.Word2Vec(post_vectors, window=10, min_count=2, size=300, workers=??)
      

      对于 gensim 加速,如果你有一个多核 CPU,你可以使用workers 参数。 (默认为 3)

      【讨论】:

      • 如果可以非常快速地读取和构建训练示例,这种通过生成器读取通常是一个好主意。但是,如果迭代 Post.objects.all() 经常涉及数据库 IO 延迟,和/或如果 my_tokenizer() 效率低下,而这些事情恰好是令人失望的缓慢的主要原因,那么这种方法可能会使事情变得更糟。 Word2Vec() 默认需要 6 次传递数据,因此这种生成器方法将重复 DB/my_tokenizer 延迟 6 次(而不是原来的一次)。
      • @AshutoshBaheti 我使用 %%timeit 对 1000 个查询集进行了测试,使用生成器的结果比原来的慢 4 倍。
      • @user3595632 那么在这种情况下,IO 可能是瓶颈,word2vec 不是。可以分别查看预加载数组上Post.objects.all()的所有内容的读取时间和word2vec的时间吗?在这种情况下,也许将输入从数据库更改为其他格式可能会有所帮助。
      • 我认为查询数据库是瓶颈...我想我应该继续使用我的 X)...
      • 这解释了为什么生成器一表现不佳
      猜你喜欢
      • 2019-10-18
      • 1970-01-01
      • 2020-07-23
      • 2021-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 2015-08-09
      相关资源
      最近更新 更多