fasttext:有没有办法导出ngrams?

问题描述 投票:0回答:2

我是DL和NLP的新手,最近开始使用预先训练的fastText嵌入模型(cc.en.300.bin)通过gensim。

我希望能够自己计算词汇表外单词的向量,将单词分成n-gram并查找每个n-gram的向量。

我找不到导出作为模型一部分的n-gram向量的方法。我意识到它们已被哈希,但也许有一种方法(不一定使用gensim)来获取它们?

任何见解将不胜感激!

export gensim n-gram fasttext oov
2个回答
0
投票

您可以直接查看gensim代码为FastTextKeyedVectorsword_vec()方法检查其源代码,以查看https://github.com/RaRe-Technologies/gensim/blob/3aeee4dc460be84ee4831bf55ca4320757c72e7b/gensim/models/keyedvectors.py#L2069代码如何为词汇表外单词创建FastText单词向量:

gensim

(请注意,developgensim分支中的源代码可能反映了最近的快速文本修补程序,这些修补程序与通过ngram_weights 3.7.1版本安装的程序包不匹配;您可能需要查阅已安装程序包的本地源代码,或等待这些修复程序正式发布。)

因为Python不保护相关对象的任何部分不受外部访问(例如强制执行的“私有”指定),所以您可以从类外部执行完全相同的操作。

特别要注意的是,在当前代码中(与Facebook的原始实现的行为相匹配),n-gram向量将从哈希表/* note: some dict_ members are public for easier access */ void FastText::quantize(const Args& qargs) { /*if (args_->model != model_name::sup) { throw std::invalid_argument( "For now we only support quantization of supervised models"); }*/ args_->input = qargs.input; args_->qout = qargs.qout; args_->output = qargs.output; std::shared_ptr<DenseMatrix> input = std::dynamic_pointer_cast<DenseMatrix>(input_); std::shared_ptr<DenseMatrix> output = std::dynamic_pointer_cast<DenseMatrix>(output_); bool normalizeGradient = (args_->model == model_name::sup); if (qargs.cutoff > 0 && qargs.cutoff < input->size(0)) { /*auto idx = selectEmbeddings(qargs.cutoff); dict_->prune(idx);*/ int32_t rows = dict_->size_+args_->bucket; dict_->threshold(2000, 2000); std::cerr << "words: " << dict_->size_ << std::endl; std::cerr << "rows: " << rows << std::endl; /*std::shared_ptr<DenseMatrix> ninput = std::make_shared<DenseMatrix>(idx.size(), args_->dim);*/ int32_t new_rows = dict_->size_+args_->bucket; std::shared_ptr<DenseMatrix> ninput = std::make_shared<DenseMatrix>(dict_->size_+args_->bucket, args_->dim); for (auto i = 0; i < dict_->size_; i++) { for (auto j = 0; j < args_->dim; j++) { int32_t index = dict_->getId(dict_->words_[i].word); ninput->at(i, j) = input->at(index, j); } } int32_t offset = rows-new_rows; for (auto i = dict_->size_; i < new_rows; i++) { for (auto j = 0; j < args_->dim; j++) { ninput->at(i, j) = input->at(i+offset, j); } } /*input = ninput;*/ input_ = ninput; if (qargs.retrain) { args_->epoch = qargs.epoch; args_->lr = qargs.lr; args_->thread = qargs.thread; args_->verbose = qargs.verbose; auto loss = createLoss(output_); model_ = std::make_shared<Model>(input, output, loss, normalizeGradient); startThreads(); } } /*input_ = std::make_shared<QuantMatrix>( std::move(*(input.get())), qargs.dsub, qargs.qnorm);*/ /*if (args_->qout) { output_ = std::make_shared<QuantMatrix>( std::move(*(output.get())), 2, qargs.qnorm); } */ /*quant_ = true;*/ auto loss = createLoss(output_); model_ = std::make_shared<Model>(input_, output_, loss, normalizeGradient); } 结构中的桶中提取,无论您当前的n-gram是否在训练数据中真正已知或不。在那些n-gram在训练数据中已知且有意义的情况下,这应该有助于OOV向量。在它获得任意其他向量的情况下,这种随机性不应该伤害太多。


0
投票

我最近自己遇到过这个问题,不得不写一个脚本来减少模型的大小。 fasttext C代码包含一个方便的函数“threshold”来减少字典大小,但它没有暴露给python绑定。字典缩减后,您还需要重新构建输入矩阵,包括主字向量之后的ngram桶。以这种方式保存模型后,将仅从子字信息生成所有单词向量(除了保留的字典单词)

对于单词相似性搜索,不使用输出和模型。要节省更多内存,您还可以注释掉在saveModel中写入输出的部分

请注意,ngram条目本身在英语预训练模型中约为2Gb,因此,即使删除了所有字典单词,也可以创建最小的模型。

qazxswpoi
© www.soinside.com 2019 - 2024. All rights reserved.