使用Gensim从Fasttext的.bin文件中重新训练FastText模型时出现问题 'FastTextTrainables'对象没有属性'syn1neg'

问题描述

我正在尝试使用gensim包装器对FastText预训练模型进行微调,但遇到了问题。 我像这样从.bin文件成功加载了模型嵌入:

from gensim.models.fasttext import FastText
model=FastText.load_fasttext_format(r_bin)

尽管如此,当我想使用以下三行代码来重新训练模型时,我仍然很努力:

sent = [['i','am ','interested','on','SPGB'],['SPGB' 'is','a','good','choice']]
model.build_vocab(sent,update=True)
model.train(sentences=sent,total_examples = len(sent),epochs=5)

无论如何更改,我都会一遍又一遍地收到此错误

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-91-6456730b1919> in <module>
      1 sent = [['i','am','choice']]
----> 2 model.build_vocab(sent,update=True)
      3 model.train(sentences=sent,epochs=5)

/opt/.../fasttext.py in build_vocab(self,sentences,update,progress_per,keep_raw_vocab,trim_rule,**kwargs)
    380         return super(FastText,self).build_vocab(
    381             sentences,update=update,progress_per=progress_per,--> 382             keep_raw_vocab=keep_raw_vocab,trim_rule=trim_rule,**kwargs)
    383 
    384     def _set_train_params(self,**kwargs):

/opt/.../base_any2vec.py in build_vocab(self,**kwargs)
    484             trim_rule=trim_rule,**kwargs)
    485         report_values['memory'] = self.estimate_memory(vocab_size=report_values['num_retained_words'])
--> 486         self.trainables.prepare_weights(self.hs,self.negative,self.wv,vocabulary=self.vocabulary)
    487 
    488     def build_vocab_from_freq(self,word_freq,keep_raw_vocab=False,corpus_count=None,trim_rule=None,update=False):

/opt/.../fasttext.py in prepare_weights(self,hs,negative,wv,vocabulary)
    752 
    753     def prepare_weights(self,update=False,vocabulary=None):
--> 754         super(FastTextTrainables,self).prepare_weights(hs,vocabulary=vocabulary)
    755         self.init_ngrams_weights(wv,vocabulary=vocabulary)
    756 

/opt/.../word2vec.py in prepare_weights(self,vocabulary)
   1402             self.reset_weights(hs,wv)
   1403         else:
-> 1404             self.update_weights(hs,wv)
   1405 
   1406     def seeded_vector(self,seed_string,vector_size):

/opt/.../word2vec.py in update_weights(self,wv)
   1452             self.syn1 = vstack([self.syn1,zeros((gained_vocab,self.layer1_size),dtype=REAL)])
   1453         if negative:
-> 1454             self.syn1neg = vstack([self.syn1neg,dtype=REAL)])
   1455         wv.vectors_norm = None
   1456 

AttributeError: 'FastTextTrainables' object has no attribute 'syn1neg'

非常感谢您的帮助

解决方法

感谢详细的代码,显示您尝试过的内容和遇到的错误。

确定要使用最新的Gensim版本gensim-3.8.3吗?那个Gensim我无法用您的代码重现错误。

也:在gensim-3.8.3中,您会看到关于该效果的警告:

DeprecationWarning: Call to deprecated 'load_fasttext_format' (use load_facebook_vectors (to use pretrained embeddings) or load_facebook_model (to continue training with the loaded full model,more RAM) instead).

(不建议使用的方法只会为您调用load_facebook_model(),因此使用较旧的方法并不会单独导致问题–但是您的环境应使用最新的Gensim,并且应更新代码以调用首选方法。)

进一步注意:

由于您的小型测试文本中没有新词,因此build_vocab(...,update=True)并不是严格必要的,也不是要做任何相关的事情。模型的已知词汇前后是相同的。 (当然,如果使用带有新单词的实际新句子,那会有所不同–但您的小例子尚未真正测试词汇量的扩展。)

进一步:

这种在现有模型中训练一些新数据或少量新词的方式充满了艰难的权衡。

特别是,在您的新数据仅包含您的新单词和原始模型单词的某些子集的范围内,仅那些新数据单词将根据其 new 用法接受培训更新。 。这会逐渐将新训练数据中的所有单词拉到新位置。这些新职位可能对新文本而言是最佳的,但与原先在早期模型中受过训练的旧职位可能相距甚远,甚至可能相距甚远。

因此,无论您的新词还是接受过新训练的旧词,都将与新数据中未包含的任何旧词在本质上保持可比性。从本质上讲,只有一起训练的单词才有必要移到与之形成对比的位置。

因此,如果您的新数据很大且变化很大,足以覆盖您的应用程序所需的单词,则训练全新模型可能既简单又更好。另一方面,如果您的新数据比较稀疏,则仅将一小部分单词/示例训练到旧模型中仍然会冒着将这些单词从旧单词的有用“对齐”中拉出来的风险。