Slyne / ctc_decoder

A ctc decoder for both online and offline asr model
57 stars 26 forks source link

英文识别空格问题 #9

Closed ziyu123 closed 2 years ago

ziyu123 commented 2 years ago

我在训练英文asr,char建模,即dict=['\<blank>', '▁', 'a', 'b', 'c', 'd', 'e', ... ,'z','<sos/eos>']共29个建模单元,空格用“▁”表示, 在用ctc_prefix_beam_search解码后,'▁' 符号都没有了,比如期望输出"how▁are▁you", 现在输出“howareyou”了, 我看ctc_beam_search_decoder函数中,在遇到space_id时,进行LM打分(英文LM是基于word),但是space_id符号是加入了prefix,怎么输出结果没有了呢?需要怎么纠正呢?

Slyne commented 2 years ago

可以把 '_' 替换成 ‘ ’

如果有logits的话方便提供一下吗? 英文的一个测试用例: https://github.com/Slyne/ctc_decoder/blob/master/swig/test/test_en.py 谢谢

ziyu123 commented 2 years ago

可以把 '_' 替换成 ‘ ’

如果有logits的话方便提供一下吗? 英文的一个测试用例: https://github.com/Slyne/ctc_decoder/blob/master/swig/test/test_en.py 谢谢

我改了两个地方, 效果其实是一样的, 一个是你提到的, 把 \'▁\' 替换成 \' \',另一个是把scorer.cpp中if (charlist[i] == \" \") 改为if (charlist[i] == \"▁\"), 不过结果还是错误的 文件test_input.npzdict是test里面的脚本可以直接读取的,谢谢🙏

Slyne commented 2 years ago

@ziyu123 Hi, 我这里下载不了。你如果有google drive或者百度网盘都可以。 另外,可以跟"test_en.py" 比对一下区别,它是可以打印出空格的。你可以用test_en.py里的语言模型替换试一下。

另外,我把dict中的“ ” 改成了 "_" 确实会出现你说的问题。但是改成" " 就没问题了。 我会找时间看一下这个问题,有可能是语言模型对"a_a" 这样的字串的打分比较低。

ziyu123 commented 2 years ago

@ziyu123 Hi, 我这里下载不了。你如果有google drive或者百度网盘都可以。 另外,可以跟"test_en.py" 比对一下区别,它是可以打印出空格的。你可以用test_en.py里的语言模型替换试一下。

另外,我把dict中的“ ” 改成了 "_" 确实会出现你说的问题。但是改成" " 就没问题了。 我会找时间看一下这个问题,有可能是语言模型对"a_a" 这样的字串的打分比较低。

嗯嗯,我也看test_en.py是可以输出空格的,连接是上面的test_input.npz 链接: https://pan.baidu.com/s/11G3gV1luFch7mzLrgWsHyw?pwd=hyeq 提取码: hyeq

我再看看对比一下,谢谢!!!

Slyne commented 2 years ago

换成其他字符不太好,你的语言模型训练的时候语料没有频繁出现这个”_”符号,那它的打分就会很低。如果你想出现这个符号,可以把scorer的权重设为0,它就会忽略语言模型打分,应该就会出现这个符号了。 On Thu, Sep 22, 2022 at 12:11 AM ziyu @.***> wrote:

可能我上面试的有问题,把 '▁' 替换成 ' ' 是可以的,问题是换成其他字符就不行了

— Reply to this email directly, view it on GitHub https://github.com/Slyne/ctc_decoder/issues/9#issuecomment-1254619962, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABP63VGPOU3UN5LG74SBHCTV7QBANANCNFSM6AAAAAAQR2DMXQ . You are receiving this because you commented.Message ID: @.***>

ziyu123 commented 2 years ago

我这边验证的情况是这样的: (1) ctc_beam_search_decoder 函数中参数ext_scorer = NULL的时候,输出正常的,此时,没有经过LM (2) ctc_beam_search_decoder 函数中参数ext_scorer 不为空,但是space_id = -100, 这个时候不经过LM打分,但是经过LM初始化,set_dictionary,set_matcher过程,这个时候输出是没有空格的 (3) 上面的把\'▁\' 替换成 ' ', 虽然能输出空格,但是结果是错误的,有丢失字符 所以,怀疑在有dictionary的时候,添加新路径这里有问题,也就是get_path_trie()函数 对 new_path->dictionarystate = matcher_->Value().nextstate; 行进行判断修改如下:

if(c == space_id){
    new_path->dictionary_state_ = dictionary_->Start();
}else{
   new_path->dictionary_state_ = matcher_->Value().nextstate;
}

这样的话,当遇到space_id时,dictionary 状态跳转回去,输出结果正常。 问题是,现在上面的修改对于,dict中space_id == “ ”的情况是有效的, 对于space_id != “ ”的情况,还是不对,我看代码应该要对这种情况特殊处理。(另外,上面的\'▁\'是特殊字符,不是下划线,跟语言模型分数大小应该没有关系)

Slyne commented 2 years ago

不是很确定这行能不能帮到你,这里的SPACE_ID是根据空格判断的,而这个SPACE_ID也会用来filldictionary. 那么如果你加了"",很有可能导致当前的word OOV,那么在get_path_trie的时候会返回nullptr. (只是猜想,还没测过)。

ziyu123 commented 2 years ago

是的,是这样的,所以如果针对非“ ”的空格,要在 bool found = matcher_->Find(new_char + 1); if (!found) 做判断,然后新建一个PathTrie就可以了, 不过,上面的情况感觉还是要改一下,要不然还是会丢字符

ziyu123 commented 2 years ago

close it