kaldi中hashlist阅读总结

kaldi中的解码算法里,需要记录很多的令牌(token)。每个令牌,都是一条路径的“头”,通过这个令牌回溯,就可以得到一条完整的路径。如果解码到最后一帧,从所有的令牌中,找到得分最优的那个的令牌,回溯得到路径,其路径上的输出,就是识别结果。(one-bese结果)
在解码过程中,会产生很多的令牌。需要设计一种数据结构和相关算法,用来保存和更新令牌。其设计要求可以简单概括如下。
  1、可以快速判断某个令牌是否已经存在
  2、可以快速插入令牌(令牌不存在的时候)
  3、可以很容易地遍历所有的令牌
kaldi的作者设计了一种HashList结果用来保存令牌。HashList跟一般数据结构书籍里介绍的hash表类似,但比它要复杂一些。
这里先介绍一下通常数据结构书籍里描述的hash表。
hash表,是人为设计的一种数据结构。通过一个hash函数,将某个集合中的元素,映射到一个hash表(一般用数组之类的来实现)中。通过这个hash表,可以判断某个元素是否已经存在,并且可以快速插入新数据。
hash函数常用的一种方法是除留余数法,就是对某个数(一般是hash表的大小)做模运算,得到的余数作为索引index,依据index来存放数据。两个数据通过hash函数运算之后,可以得到相同的索引值,就会产生冲突。hash表解决冲突的方法有链表法和开放地址法。

下面举例说明下hash表
  1、hash表大小为5。采用除留余数法作为hash函数。采用链地址法解决冲突。
  2、依次插入的数据分布是1, 8, 3, 10, 15, 5, 21, 18。
通过上面的描述,我们可以得到下面的hash表。




kaldi中HashList也是一种hash表。它跟上面例子中介绍的链地址法hash表类似,但也有不一样的地方。假如还是使用上面例子中的条件,则HashList产生的hash表,画出来如下图所示。


可以看出,HashList的结构,跟普通的链表hash不同的主要有以下几点
1、HashList中hash项指向的元素,是链表的最后一个元素(last_elem)。
2、HashList中hash项有个特定的域(pre_bucket,上面图片中红色的数字),通过这个可以找到上一个hash项,然后找到本链表的头结点
3、有一个额外的头结点(list_head),通过它可以访问所有的结点。

如果想要查找某个数是否在hash表中,通过取模得到余数,也就是索引index。如果对应的hash项为空,表示未找到。如果hash项不为空,则通过上面的1和2两点,可以确定链表的头和尾巴,在链表中搜索即可。


kaldi中每计算一帧数据,都伴随着HashList中元素的新建和销毁。如果调用系统的new和delete操作,会带来很大的影响。HashList中会预先申请一块内存(一个数组),然后new和delete元素,就是在这些数组上操作的。HashList中的变量allocated_和freed_head_是跟内存相关的变量;New()和Delete()是跟分配和回收相关的操作。


下面是hashlist的原代码,大家可以仔细阅读体会。

// util/hash-list.h

// Copyright 2009-2011   Microsoft Corporation
//                2013   Johns Hopkins University (author: Daniel Povey)

// See ../../COPYING for clarification regarding multiple authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值