如何编辑 GrammarFst 的权重?
How can I edit the weights of a GrammarFst?
当你有一个标准的 fst 时,你可以将它加载为一个 MutableFst 并执行类似的操作:
MutableArcIterator<StdMutableFst> aiter(graph, state_id);
aiter.Seek(position)
auto arc = aiter.Value();
arc.weight = fst::TropicalWeight(NEW_WEIGHT);
aiter.SetValue(arc);
这将更改内存中弧的值。
然而,当我有 ConstFst 时,我从 GrammarFst.instances_ 向量中得到类似这样的东西:
GrammarFst &fst = const_cast<GrammarFst&>(fst_in);
int32 instance_id = s >> 32;
BaseStateId base_state = static_cast<int32>(s);
const GrammarFst::FstInstance &instance = fst.instances_[instance_id];
const ConstFst<StdArc> *base_fst = instance.fst; // const fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >* const
我无法使用 MutableArcIterator 索引到 base_fst
,因为它是一个 ConstFst。如果不对 Kaldi/Openfst?
进行认真修改,这甚至可能吗?
当我尝试做的时候:
MutableArcIterator<StdConstFst > aiter(base_fst, base_state);
我得到:
test.cpp:91:72: error: invalid conversion from ‘const fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*’ to ‘fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*’ [-fpermissive]
MutableArcIterator<StdConstFst > aiter(base_fst, base_state);
我的问题:
我需要访问 GrammarFst 对象的 instances_
并在 运行 时间内更改弧权重。我目前不能这样做,因为 GrammarFst.instance_ 是 ConstFsts。
可行的解决方案:
- 在 运行 时间内将 GrammarFst.instances_ 转换为 StdFst
- 从磁盘加载时将 GrammarFst.instances_ 转换为 StdFst
- 在保存 GrammarFst 时将 GrammarFst.instances_ 保存为 StdFst
无效的解决方案:
- 将整个 GrammarFst 保存为 StdFst,(因此取消引用 instances_ 并将它们复制到它们出现的主 fst 中的每个位置。这大大增加了文件大小(~10X)并且对我不起作用
在这里结束循环:GrammarFsts 只能由 ConstFsts 组成。我最终向 kaldi 提交了一个 PR 以更改此设置,以便您可以使用 VectorFsts 组合它们,这反过来又允许您使用标准的 MutableArcIterator 修改它们。 https://github.com/kaldi-asr/kaldi/pull/4067
当你有一个标准的 fst 时,你可以将它加载为一个 MutableFst 并执行类似的操作:
MutableArcIterator<StdMutableFst> aiter(graph, state_id);
aiter.Seek(position)
auto arc = aiter.Value();
arc.weight = fst::TropicalWeight(NEW_WEIGHT);
aiter.SetValue(arc);
这将更改内存中弧的值。
然而,当我有 ConstFst 时,我从 GrammarFst.instances_ 向量中得到类似这样的东西:
GrammarFst &fst = const_cast<GrammarFst&>(fst_in);
int32 instance_id = s >> 32;
BaseStateId base_state = static_cast<int32>(s);
const GrammarFst::FstInstance &instance = fst.instances_[instance_id];
const ConstFst<StdArc> *base_fst = instance.fst; // const fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >* const
我无法使用 MutableArcIterator 索引到 base_fst
,因为它是一个 ConstFst。如果不对 Kaldi/Openfst?
当我尝试做的时候:
MutableArcIterator<StdConstFst > aiter(base_fst, base_state);
我得到:
test.cpp:91:72: error: invalid conversion from ‘const fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*’ to ‘fst::ConstFst<fst::ArcTpl<fst::TropicalWeightTpl<float> > >*’ [-fpermissive]
MutableArcIterator<StdConstFst > aiter(base_fst, base_state);
我的问题:
我需要访问 GrammarFst 对象的 instances_
并在 运行 时间内更改弧权重。我目前不能这样做,因为 GrammarFst.instance_ 是 ConstFsts。
可行的解决方案:
- 在 运行 时间内将 GrammarFst.instances_ 转换为 StdFst
- 从磁盘加载时将 GrammarFst.instances_ 转换为 StdFst
- 在保存 GrammarFst 时将 GrammarFst.instances_ 保存为 StdFst
无效的解决方案:
- 将整个 GrammarFst 保存为 StdFst,(因此取消引用 instances_ 并将它们复制到它们出现的主 fst 中的每个位置。这大大增加了文件大小(~10X)并且对我不起作用
在这里结束循环:GrammarFsts 只能由 ConstFsts 组成。我最终向 kaldi 提交了一个 PR 以更改此设置,以便您可以使用 VectorFsts 组合它们,这反过来又允许您使用标准的 MutableArcIterator 修改它们。 https://github.com/kaldi-asr/kaldi/pull/4067