ctcdecode
ctcdecode third party files
CTCDecode是CTC(连接派时间分类)梁搜索解码的实现。 C ++代码从桨桨的DeepSpeech中自由借来。它包括可交换得分手支持启用标准光束搜索和基于KENLM的解码。如果您是CTC和Beam搜索概念的新手,请访问“资源”部分,在其中链接一些教程,以解释为什么需要它们。
该图书馆在很大程度上是独立的,只需要Pytorch。构建C ++库需要GCC或Clang。还可以选择包括Kenlm语言建模支持,并默认启用。
以下安装也适用于Google Colab。
# get the code
git clone --recursive https://github.com/parlance/ctcdecode.git
cd ctcdecode && pip install . from ctcdecode import CTCBeamDecoder
decoder = CTCBeamDecoder (
labels ,
model_path = None ,
alpha = 0 ,
beta = 0 ,
cutoff_top_n = 40 ,
cutoff_prob = 1.0 ,
beam_width = 100 ,
num_processes = 4 ,
blank_id = 0 ,
log_probs_input = False
)
beam_results , beam_scores , timesteps , out_lens = decoder . decode ( output )CTCBeamDecoderlabels是您用来训练模型的令牌。它们应该与您的输出相同。例如,如果您的令牌是英文字母,并且您将0用作空白令牌,那么您将通过列表(“ _ abcdefghijklmopqrstuvwxyz”)作为您的论点model_path是您外部KENLM语言模型(LM)的途径。默认值无。alpha加权。重量为0表示LM无效。beta重量与我们光束内的单词数相关。cutoff_top_n截止号码。仅在Beam搜索中,只有最高概率的顶级cutoff_top_n字符才能使用。cutoff_prob截止概率。 1.0意味着没有修剪。beam_width这控制了光束搜索的宽度。更高的值更有可能找到顶梁,但它们也会使您的光束搜索成倍缓慢。此外,输出的时间越长,大型光束的时间就越多。这是一个重要的参数,代表您需要根据数据集和需求进行的权衡。num_processes工人平行批处理。您可能想传递计算机的CPU数量。您可以在python中找到它,然后import multiprocessing ,然后n_cpus = multiprocessing.cpu_count() 。默认4。blank_id这应该是CTC空白令牌的索引(可能为0)。log_probs_input如果您的输出通过SoftMax并表示概率,则应该是错误的,如果它们通过LogSoftMax并表示负log可能性,则需要传递true。如果您不了解这一点,请运行print(output[0][0].sum()) ,如果是一个负数,则您可能会有NLL,并且需要通过True(如果总计为〜1.0),则应通过false。默认错误。decode方法的输入output应为您的模型的输出激活。如果您的输出已经通过SoftMax层,则不需要更改(除了转置除外),但是如果您的output代表负日志可能性(原始logits),则您要么需要通过额外的torch.nn.functional.softmax将其传递给log_probs_input=False fords false fords false decdoder。您的输出应进行批处理X n_timesteps x n_labels,因此您可能需要将其转换为解码器。请注意,如果您以错误的顺序传递内容,那么梁搜索可能仍会运行,您将获得废话结果。decode方法的输出4件事从decode中返回
beam_results形状:批处理x n_beams x n_timesteps包含一系列字符的批次(这些是ints,您仍然需要将它们解码回文本),代表给定的光束搜索的结果。请注意,光束几乎总是比时间步的总数短,并且附加数据是非敏感的,因此要查看批处理中的第一个项目的顶梁(作为int标签),您需要运行beam_results[0][0][:out_len[0][0]] 。beam_scores形状:批处理X n_beams批量,每个梁的CTC分数大致(在此处查看代码以获取更多信息)。如果这是真的,您可以相信模型对梁正确使用p=1/np.exp(beam_score)的信心。timesteps形状:批处理x n_beams nth输出字符具有峰值概率的时间步。可以用作音频和笔录之间的对齐。out_lens形状:批处理x n_beams。 out_lens[i][j]是您批处理I项目的jth beam_result的长度。 from ctcdecode import OnlineCTCBeamDecoder
decoder = OnlineCTCBeamDecoder (
labels ,
model_path = None ,
alpha = 0 ,
beta = 0 ,
cutoff_top_n = 40 ,
cutoff_prob = 1.0 ,
beam_width = 100 ,
num_processes = 4 ,
blank_id = 0 ,
log_probs_input = False
)
state1 = ctcdecode . DecoderState ( decoder )
probs_seq = torch . FloatTensor ([ probs_seq ])
beam_results , beam_scores , timesteps , out_seq_len = decoder . decode ( probs_seq [:, : 2 ], [ state1 ], [ False ])
beam_results , beam_scores , timesteps , out_seq_len = decoder . decode ( probs_seq [:, 2 :], [ state1 ], [ True ])在线解码器正在复制ctcbeamdecoder接口,但需要状态和is_eos_s序列。
状态用于累积与一个数据源相对应的块序列。 IS_EOS_S告诉解码器,这些块是否已停止被推到相应的状态。
获取批处理beam_results[0][0][:out_len[0][0]]中第一项的顶梁
获取批处理中第一项的前50个光束
for i in range ( 50 ):
print ( beam_results [ 0 ][ i ][: out_len [ 0 ][ i ]])请注意,这些将是需要解码的INT列表。您可能已经有一个从INT到文本解码的函数,但是如果没有,则可以做类似的事情。 “”。使用您传递给CTCBeamDecoder的"".join[labels[n] for n in beam_results[0][0][:out_len[0][0]]]