modelscope / kws-training-suite

MIT License
73 stars 15 forks source link

请教kws相关问题 #1

Closed Sundy1219 closed 7 months ago

Sundy1219 commented 1 year ago

1 你们的kws模型是分类模型吗?类似wekws那种;还是它其实asr模型?你们的置信度是怎么算的? 2 force_align对齐为啥只对正样本对齐,而不对负样本对齐? 谢谢

bincard commented 1 year ago

你好,欢迎关注,以上问题答复如下:

  1. 我们的kws模型是分类模型
  2. force_align作用是替代人工数据标注,负样本不需要标注
Sundy1219 commented 1 year ago

你们的尾部输出是5个标签, xiao ya tong xue 这四个标签,还有一个Filler,总共五个标签,请问你们的唤醒词的score是怎么计算的?

bincard commented 1 year ago

你好,我看您在modelscope项目中也提了类似问题,就直接把那边的答复复制过来了,供有类似疑问的开发者参考。 声学模型输出后面是有解码器的,不过目前解码器是用C代码实现的,打包在python库py_sound_connect里,安装modelscope时会作为依赖安装。 这个项目采用的解码器是一种自适应HMM结构,一方面用于对网络的输出做平滑,另外还利用了Viterbi算法做了解码,把网络[0, 1]之间的输出转化为了最优状态序列。比如“你好米雅”,所看到的最优状态序列就类似于0001112233344440这种,根据这个序列可以判断是否出现了疑似唤醒词。最后再根据平滑后的概率和最优状态序列就可以计算置信度了。关于解码器和置信度更加详细的算法介绍可以参考这篇文章:Joint Ego-Noise Suppression and Keyword Spotting on Sweeping Robots。

Sundy1219 commented 1 year ago

很感谢您的回复,我觉得这个问题,对于理解你们的模型架构至关重要.还有一些问题,望指点下 1, 对于一段窗口内的音频比如1.5s,先要viterbi解码,如果解码序列有疑似唤醒词,再去计算置信度score. 如果解码出的best path没有疑似唤醒词,就不去进行置信度计算,是这么理解吗?

2,  唤醒词的阈值怎么确定,一般的阈值确定都是根据长的负样本(比如24小时电视音频). 负样本的音频也是先去viterbi解码,再看是不是有疑似唤醒词,如果有,计算置信度score,并保存起来,便于画ROC,是这么理解吗?

3, 在训练的时候,正样本需要对齐标注,这个可以理解;那负样本如果有关键词中的某个字,也就是负样本里含有发音单元,比如,某个负样本音频的内容为" 小明去学习了", 这个内容包括了发音单元"小"还有"同",那这个负样本怎么处理,标签怎么打?还是说这样的音频就不会作为负样本? 4, 有这样的一种情况,如果某个唤醒词说的时候,中间稍微停顿了一下,出现了最优状态序列0000111222003334444000这样的情况,怎么处理? 谢谢,期待您的指点,谢谢!!!

bincard commented 1 year ago

您好,很高兴和您交流,针对您的问题逐条答复如下:

  1. 这么理解基本是对的,但后面有点偏差。基本流程是无论什么情况都会计算置信度。置信度计算方法是根据bestpath对应的每个建模单元的数据中选择观测概率最大的数作为该建模单元的观测概率;之后使用四个建模单元中概率最大的三个相乘作为置信度。这样的话,如果bestpath中没有出现疑似唤醒词则置信度都是0,判断唤醒的标准是置信度>=阈值,置信度为0就不会报唤醒。

  2. 阈值需要通过ROC曲线来确定。画ROC的基本流程是先准备若干正、负样本测试集,正样本测试集相当于设备在各种日常工作场景中的带唤醒词的长音频录音,例如音箱在安静、播放音乐、旁边有电视干扰时候的带唤醒词的录音;负样本测试集同样为设备在日常场景中的长音频录音,但是不包含唤醒词。正、负样本测试集的规模视具体问题来定,例如正样本大约包含5000个唤醒词,负样本大约为100小时。注意,正负样本测试集都需要为多通道长音频,跟实际项目中使用的对应。之后用阈值为0的参数分别在正负测试集上进行测试,打印出唤醒log和相应的置信度。之后再用阈值0, 0.01, 0.02, ... 0.99, 1分别来卡唤醒log,从而得到ROC曲线。最后从ROC曲线上选出唤醒率和虚警率都合格的工作阈值即可。

  3. 负样本不用进行打标。一是因为负样本出现完整关键词的概率非常小,即使出现了,数量也非常少。二是关键词检测是利用了上下文信息的,例如ABCD关键词,要ABCD同时出现,或者AB,BC,CD这种组合同时出现时观测概率才高,如果只出现一个或几个不连续的单元,例如AEFGC这种对训练影响不大。所以为了节省数据准备的时间,对负样本训练集一般不筛查唤醒词。但是需要确保负样本中不能大批量混入正样本数据。

  4. 在求得最优路径后,有个步骤是把这类少量的0(例如2个0)用后面一个非0的状态补上,这样序列就连续了。但是如果出现太多0,比如2个以上0,那这次唤醒词就检测不出来了。

Sundy1219 commented 1 year ago

您好,很感谢您的解疑.现在还有一个问题,就是针对疑似唤醒词的   1, 怎么判断是疑似唤醒词? 是严格按照建模单元的顺序出现,是吗? 比如 00001111222233344440000,这个可以理解出现了疑似唤醒词,没毛病.如果000111332222433334444000,这个算疑似吗?. 怎么处理? 还是说和您说的第四点一样,把少量的建模单元用后面的建模单元补上?如果出现太多,就不是疑似了? 谢谢,期待您的回复

bincard commented 1 year ago

您好, 上面的两种情况都算疑似唤醒。目前的解码策略是出现四个建模单元中的三个都算,不论顺序怎样,不对非0路径进行填补。然后根据最优路径寻找每个建模单元的最大观测概率计算置信度,置信度超过阈值才算唤醒。 当然,解码策略并不是唯一的,也可以根据不同应用来灵活配置。例如限制顺序,限制必须出现四个建模单元等。

Sundy1219 commented 1 year ago

好的,明白了,感谢!!!!

nicktao9 commented 7 months ago

您好, 想咨询您们的方案, 希望能得到回复, 谢谢啦 方案分成5个类别, 那打标注后, 再把相应的打标值映射成5类0,1,2,3,4是这样吗, 比如说一个正样本音频的标签是11122233444,负样本标签是0000000 这样送进网络做监督训练吗

bincard commented 7 months ago

@nicktao9 是的