如何使用预处理语料库加速 gensim word2vec 初始化?
how to speed up gensim word2vec initialization with pre proccessed corpus?
我正在同一个语料库上训练多个 word2vec 模型。 (我这样做是为了研究学习词向量的变化)
我正在使用本教程作为参考:https://rare-technologies.com/word2vec-tutorial/
建议默认gensim.models.word2vec 至少会迭代语料库两次。一次用于初始化,然后再次用于训练(迭代指定的时期数)
因为我总是使用同一个语料库,所以我想通过只初始化一次并为所有后续模型提供与输入相同的初始化来节省时间。
如何做到这一点?
这是我当前的设置:
subdirectory = 'corpus_directory'
for i in range(10):
sentences = MySentences(subdirectory) # a memory-friendly iterator
model = gensim.models.Word2Vec(sentences, min_count=20, size=100, workers=4)
model.train(sentences, total_examples=model.corpus_count, epochs=1)
word_vectors = model.wv
fname = 'WV{}.kv'
word_vectors.save(fname.format(i))
其中 MySentences 的定义与教程类似:
(我做了一点改动,所以每次初始化都会打乱语料库句子的顺序)
class MySentences(object):
def __init__(self, dirname):
self.dirname = dirname
self.file_list = [fname for fname in os.listdir(dirname) if fname.endswith('.txt')]
random.shuffle(self.file_list)
def __iter__(self):
for article in self.file_list:
for line in open(os.path.join(self.dirname, article)):
yield line.split()
如果您向 class 实例化提供 sentences
的语料库,就像您的代码所做的那样,您不需要调用 train()
。它已经自动完成了,你的第二个 train()
是多余的。 (我建议在 INFO 级别启用日志记录的情况下执行所有此类操作,并在每次 运行 了解正在发生的事情后查看 lgos——诸如两次完整的从开始到结束的培训之类的事情应该在日志中突出显示。)
显式调用 train()
的情况是您希望对临时步骤有更多控制。您将 sentences
排除在 class 实例化之外,但是您需要执行两个显式步骤:一次调用 build_vocab()
(用于初始词汇扫描),然后一次调用调用 train()
(用于实际的多时期训练)。
在那种情况下,您可以使用 gensim 的原生 .save()
来保存模型 在 词汇发现之后,有一个准备好重新训练的模型和不需要报告该步骤。
因此,您可以多次重新加载该词汇构建模型,以不同的变量,以不同的方式进行训练。对于模型的一些元参数——比如 window
甚至 dm
模式——你甚至可以在构建词汇表后直接篡改它们在模型上的值以尝试不同的变体。
但是,如果语料库的 words/word-frequencies 或影响 build_vocab()
期间发生的初始化的其他参数发生任何更改(如向量 size
),则初始化将与您正在尝试的配置不同步,并且您可能会遇到奇怪的错误。
在这种情况下,最好的办法是完全重复 build_vocab()
步骤。 (您还可以查看源代码以查看 build_vocab()
执行的各个步骤,以及 patch/repeat 所需的初始化步骤,但这需要非常熟悉代码。)
我正在同一个语料库上训练多个 word2vec 模型。 (我这样做是为了研究学习词向量的变化)
我正在使用本教程作为参考:https://rare-technologies.com/word2vec-tutorial/
建议默认gensim.models.word2vec 至少会迭代语料库两次。一次用于初始化,然后再次用于训练(迭代指定的时期数)
因为我总是使用同一个语料库,所以我想通过只初始化一次并为所有后续模型提供与输入相同的初始化来节省时间。
如何做到这一点?
这是我当前的设置:
subdirectory = 'corpus_directory'
for i in range(10):
sentences = MySentences(subdirectory) # a memory-friendly iterator
model = gensim.models.Word2Vec(sentences, min_count=20, size=100, workers=4)
model.train(sentences, total_examples=model.corpus_count, epochs=1)
word_vectors = model.wv
fname = 'WV{}.kv'
word_vectors.save(fname.format(i))
其中 MySentences 的定义与教程类似: (我做了一点改动,所以每次初始化都会打乱语料库句子的顺序)
class MySentences(object):
def __init__(self, dirname):
self.dirname = dirname
self.file_list = [fname for fname in os.listdir(dirname) if fname.endswith('.txt')]
random.shuffle(self.file_list)
def __iter__(self):
for article in self.file_list:
for line in open(os.path.join(self.dirname, article)):
yield line.split()
如果您向 class 实例化提供 sentences
的语料库,就像您的代码所做的那样,您不需要调用 train()
。它已经自动完成了,你的第二个 train()
是多余的。 (我建议在 INFO 级别启用日志记录的情况下执行所有此类操作,并在每次 运行 了解正在发生的事情后查看 lgos——诸如两次完整的从开始到结束的培训之类的事情应该在日志中突出显示。)
显式调用 train()
的情况是您希望对临时步骤有更多控制。您将 sentences
排除在 class 实例化之外,但是您需要执行两个显式步骤:一次调用 build_vocab()
(用于初始词汇扫描),然后一次调用调用 train()
(用于实际的多时期训练)。
在那种情况下,您可以使用 gensim 的原生 .save()
来保存模型 在 词汇发现之后,有一个准备好重新训练的模型和不需要报告该步骤。
因此,您可以多次重新加载该词汇构建模型,以不同的变量,以不同的方式进行训练。对于模型的一些元参数——比如 window
甚至 dm
模式——你甚至可以在构建词汇表后直接篡改它们在模型上的值以尝试不同的变体。
但是,如果语料库的 words/word-frequencies 或影响 build_vocab()
期间发生的初始化的其他参数发生任何更改(如向量 size
),则初始化将与您正在尝试的配置不同步,并且您可能会遇到奇怪的错误。
在这种情况下,最好的办法是完全重复 build_vocab()
步骤。 (您还可以查看源代码以查看 build_vocab()
执行的各个步骤,以及 patch/repeat 所需的初始化步骤,但这需要非常熟悉代码。)