簡體   English   中英

fasttext:有沒有辦法導出ngram?

[英]fasttext: is there a way export ngrams?

我是DL和NLP的新手,並且最近開始通過gensim使用預先訓練的fastText嵌入模型(cc.en.300.bin)。

我希望自己能夠通過將單詞拆分為n-gram並為每個n-gram查找矢量來計算詞匯量以外的單詞的向量。

我找不到導出模型中n元語法向量的方法。 我知道它們是散列的,但是也許有一種方法(不一定使用gensim)來獲取它們?

任何見識將不勝感激!

您可以通過直接檢查FastTextKeyedVectors代碼的FastTextKeyedVectorsword_vec()方法的源代碼來確切地查看gensim代碼如何為詞匯外單詞創建FastText單詞向量:

https://github.com/RaRe-Technologies/gensim/blob/3aeee4dc460be84ee4831bf55ca4320757c72e7b/gensim/models/keyedvectors.py#L2069

(請注意, gensimdevelop分支中的此源代碼可能反映了最新的FastText修復,這些修復與通過gensim版本3.7.1安裝的軟件包不匹配;您可能要查詢已安裝的軟件包的本地源代碼,或者等待這些修復程序將在正式版本中發布。)

由於Python不會保護相關對象的任何部分免受外部訪問(例如使用強制性的“私有”指定),因此您可以從類外部執行完全相同的操作。

特別要注意的是,在當前代碼(與Facebook原始實現的行為相匹配)中,無論是否在訓練數據中真正知道了您當前的n-gram,還是從哈希表ngram_weights結構的存儲桶中提取了n-gram矢量。不。 在訓練數據中已知這些n-gram且有意義的情況下,這應該對OOV向量有所幫助。 在獲取任意其他向量的情況下,這種隨機性應該不會有太大的傷害。

最近,我本人遇到了這個問題,不得不編寫腳本來減小模型大小。 快速文本C代碼包括一個方便的函數“閾值”以減小字典的大小,但是它沒有暴露給python綁定。 在減少字典之后,您還需要重新構建輸入矩陣,包括主要單詞向量之后的ngram桶。 以這種方式保存模型后,將僅根據子詞信息生成所有詞向量(剩余的詞典詞除外)

對於單詞相似性搜索,不使用output_和model_。 為了節省更多的內存,您還可以在saveModel中注釋掉寫output_的部分

請注意,在英語預訓練模型中,ngram條目本身大約為2Gb,因此即使刪除所有詞典單詞,也可以使模型最小。

/* 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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM