WFST优化算法

  1. Determinization确定化
    DFA仅具有一个单个初始状态,并且对于来自每个状态的任何输入标签,最多只有一个转换,即给定符号在给定状态下的转换是唯一的,因此目标状态也是唯一的,因此,如果输入符号序列被接受,则从初始状态到最终状态只有一条路径。这称之为FA。Determinization就是将NFA转换为FA的过程。
    从一个状态出发的弧当中,输入标签不能重复。如果存在重复的输入标签,就无法判断要从哪一个弧线输入,会造成转换效率降低,因此需要优化。
    算法伪代码:
    在这里插入图片描述
    1-3行为初始化操作,从初始状态初始化,起始状态的权重初始化为 1 ‾ \overline{1} 1
    8-11行是核心操作,用来生成新的状态,连接当前状态和目的状态。
    第8行是输出标签的操作,/\是string半环里取共同元素,如果没有则为空,如X/\Y= ε \varepsilon ε
    第9行是权重的操作,如果是tropical半环,语音识别中一般用tropical半环,则是取权重值小的那条转移。
    第10行是新生成的到达状态,即三元组的集合,里面复杂的那一串造作就是计算残余输出和残余权重的过程。
    14-16行是对结束状态的操作,需要赋一个结束权重值。
    WFA determinization:
    在这里插入图片描述
    2.Weight-pushing权重推移
    weight-pushing就是把权重往前压或向后推,原本每一条路径的权重并不会发生改变。为什么要做weight-pushing呢?在自动机或转换机相关的问题中,目标通常是在图中寻找最大化权值或最小化权值的路径,将权重往前压的好处就是可以提高寻找路线的速度。在寻找路线的前期,我们就已经能够获得一个大致的权值的顺序。我们可以根据这一顺序抛弃一些明显不符合的路径,这对于我们寻找路径的效率有了很大的改善。
    weight-pushing算法大致等价为两个步骤。第一个步骤是为每一个状态计算一个potential值,第二个步骤是根据每一个状态的potential值进行对权值的更新。
    算法伪代码如下:
    在这里插入图片描述
    计算每一个状态的potential值。算法核心是计算一个状态到最后状态的最短距离(以tropical semiring为例)。问题转化为最短距离问题。
    算法核心如下,计算所有路径当中通过 ⊕ \oplus 得到的值(常见是虽短距离):
    [ V [ q ] = ⊕ π ∈ ∏ ( q , F ) w [ π ] ⊗ ρ ( n [ π ] ) [V[q] = \mathop \oplus \limits_{\pi \in \prod {(q,F)} } w[\pi ] \otimes \rho (n[\pi ]) [V[q]=π(q,F)w[π]ρ(n[π])
    当遇到无法计算的情况时(比如说无线条路线),我们使用k-closed。选择一部分路线:
    ⊕ n = 0 l w [ c ] n = ⊕ n = 0 k w [ c ] n \mathop \oplus \limits_{n = 0}^l w{[c]^n}{\rm{ = }}\mathop \oplus \limits_{n = 0}^k w{[c]^n} n=0lw[c]n=n=0kw[c]n
  • 1-6行代码是对每一个状态的potential值进行初始化。最后的状态设置为 ρ ( n [ π ] ) \rho(n[\pi]) ρ(n[π]),而其它的状态值则先设置为 0 ˉ \bar 0 0ˉ
  • 我们将最后的状态先放入队列中。之后就进行一个循环,每次循环从队列里面拿一个状态出来。
  • 使用后向算法,从后往前进行计算。如果我们需要进行最短路径的计算(以tropical 瑟米日那个为例),我们每次循环都可以计算一个r值来存储当前状态到最后状态的最短路径,这样可以大大减少计算量。
  • 伪代码中15行的比较,可以使用k-closed方法。我们可以规定,当两者之差小于某一个值的时候,将两者看作是相等的,这样可以减少很多计算量。
    在这里插入图片描述
    分三种情况更新状态,更新状态依据的是之前计算的potential值和原始的权值。
  • 开始状态的权值
  • 中间状态的权重
  • 结束状态的权重
    在这里插入图片描述
    3.dminimization最小化
    minimization可以让WFST中的状态数量最少,即状态合并。最小化操作可以使得转化的效率得到提高,缩小存储空间,该操作的直接思想就是把能够等价起来的状态合并成一个状态。
    对一个WFST进行最小化操作分为两个步骤:
  • 对WFST进行确定化操作(det),在进行weight-pushing操作;
  • 使用经典的最小化算法对WFST进行最小化,常用的有Hopcroft算法。这里把输入,输出和权重都看作标签。
//基于**等价类的思想**
split(S):
  foreach(character c)
    if(c can split S)
      split S into T1, T2...

# 主函数
hopcroft():
  split all nodes into N, A
  while(set is still changes)
    split(S)

hopcroft算法思想:

  • 首先,将所有状态分成两组,一组是N,一组是A,其中A是指终止状态,N代表其他状态。
  • 对两个组进行拆分:如果组内有状态的前进方向是不一致的,按照前进的状态的组别进行划分。即一个组里有3个状态,2个状态通向另一个组,另一个状态通向自己,则他们被划分为两个组。其中,所有转移到另一个组的弧都需要倍保存下来,作为最后的转移弧。
  1. epsolon-removal空转移去除
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值