【问题标题】:How to use tensorflow ctc beam search properly?如何正确使用 tensorflow ctc 光束搜索?
【发布时间】:2019-12-16 14:28:14
【问题描述】:

我想对音素概率值矩阵(给出的 ASR 模型的输出)执行 CTC Beam Search。 Tensorflow 有一个 CTC Beam Search implementation,但它的文档记录很差,我没有给出一个有效的例子。我想编写一个代码以将其用作基准。

到目前为止,这是我的代码:

import numpy as np
import tensorflow as tf

def decode_ctcBeam(matrix, classes):
      matrix = np.reshape(matrix, (matrix.shape[0], 1,matrix.shape[1]))
      aa_ctc_blank_aa_logits = tf.constant(matrix)
      sequence_length = tf.constant(np.array([len(matrix)], dtype=np.int32))

      (decoded_list,), log_probabilities = tf.nn.ctc_beam_search_decoder(inputs=aa_ctc_blank_aa_logits,
                                          sequence_length=sequence_length,
                                          merge_repeated=True,
                                          beam_width=25)

      out = list(tf.Session().run(tf.sparse_tensor_to_dense(decoded_list)[0]))    
      print(out)

      return out

if __name__ == '__main__':
    classes = ['AA', 'B', 'CH']
    mat = np.array([[0.4, 0, 0.6, 0.2], [0.4, 0, 0.6, 0.2]], dtype=np.float32)

    actual = decode_ctcBeam (mat, classes)

我在理解代码方面遇到问题:

  • 在示例中 ma​​t 的形状为 (2, 4),但 tensorflow 模块需要 (2, 1, 4) 形状,因此我将 ma​​t 重塑为 matrix = np.reshape(matrix, (matrix.shape[0], 1,matrix.shape[1])) 但这在数学上意味着什么? ma​​tma​​trix 是一样的吗?还是我在这里混在一起?中间的 1 是我理解的批量大小。
  • decode_ctcBeam 函数返回一个列表,在它给出的示例中 [2],这应该表示已定义类中的“CH”。如果我有一个更大的输入矩阵,比如说 40 个音素,我该如何概括这一点并找到识别的音素序列?

期待您的回答/cmets!谢谢!

【问题讨论】:

    标签: python tensorflow beam-search ctc


    【解决方案1】:

    TF 文档有误 - 波束宽度为 1 的波束搜索与贪婪解码相同(我创建了一个 issue about this some time ago)。

    然后,您可以简单地使用 np.transpose 来重新排序维度,而不是 np.reshape,然后使用 np.expand_dims 添加一个大小为 1 的批量大小的维度。

    最后,关于 TF 波束搜索实现:是的,文档不是很好。 我在文本识别模型中使用了实现,我指出与你相关的行:

    • Create TF beam search operation:注意 merge_repeated=False,因为 TF 的默认设置(即 True)对于 99.99999% 的所有相关用例没有意义。只需按照传递参数的变量名来查看它们的外观,例如输入矩阵是 ctcIn3dTBC,它是 RNN 输出的转置版本
    • Transform output of beam search to a char string:该操作返回一个稀疏张量列表,需要将其解码为 char 字符串

    【讨论】:

    • 嘿哈利!感谢您伸出援手!我不知道波束宽度为 1 的波束搜索与贪婪解码不同。谢谢你整理出来。我已经检查了有关问题的代码和您的文本识别实现,并使用我自己的数据进行了光束搜索。但是,我仍然遇到与其他评论相同的问题。束搜索的输出列表要长得多,对我来说没有意义。
    • 你能提供输入数据(保存的numpy数组.npy)和来自Classes模块的类吗?这样我就可以运行脚本了?
    • 给您发了一封电子邮件!提前谢谢!
    • 截至 21 年 7 月 14 日,两个链接都处于非活动状态
    【解决方案2】:

    所以,自从我提出这个问题以来,我已经取得了一些进展,但仍然没有弄清楚如何正确使用具有 CTC Beam Search 的 Tensorflow。很明显,设置 top_paths = 1 和 beam_width = 1 确实会在整数列表中返回贪婪搜索的预期输出,可以轻松地将其转换为存储在 中的所需音素。这种情况下的输出是:

    --------贪婪---------

    输出整数列表

    [1, 22, 39, 14, 32, 8]

    ['AE', 'N', '', 'G', 'UH', 'D']

    在 Beam Search 的情况下,结果很糟糕

    --------波束搜索----------

    输出整数列表

    [26、19、9、28、5、0、2、31、1、22、39、14、32、20、8、16、39、30、37、8]

    ['P'、'K'、'DH'、'S'、'AY'、'AA'、'AH'、'TH'、'AE'、'N'、''、'G' , 'UH', 'L', 'D', 'IH', ' ', 'T', 'Z', 'D']

    引用是“我很好”。 [1, 22, 39, 14, 32, 8] 的列表在 Beam 搜索结果中,其他部分应该是替代根?这对我来说很可疑。 有人有什么想法吗?

    import numpy as np
    import tensorflow as tf
    import Classes
    
    def decode_ctcBeam(matrix, classes):  
        matrix = np.reshape(matrix, (matrix.shape[0], 1,matrix.shape[1]))
        aa_ctc_blank_aa_logits = tf.constant(matrix)
        sequence_length = tf.constant(np.array([len(matrix)], dtype=np.int32))
        
        (decoded_list,), log_probabilities = tf.nn.ctc_beam_search_decoder(inputs=aa_ctc_blank_aa_logits,
                                                  sequence_length=sequence_length,
                                                  merge_repeated=True,
                                                  top_paths=1,
                                                  beam_width=4)
    
        out = list(tf.Session().run(tf.sparse_tensor_to_dense(decoded_list)[0]))
        print("Output int list")
        print(out)
        seq_list = get_seq_from_list(out, classes)
        return seq_list
            
    def decode_ctcgreedy(matrix, classes):
        
        matrix = np.reshape(matrix, (matrix.shape[0], 1,matrix.shape[1]))
        
        aa_ctc_blank_aa_logits = tf.constant(matrix)
        sequence_length = tf.constant(np.array([len(matrix)], dtype=np.int32))
    
        (decoded_list,), log_probabilities = tf.nn.ctc_beam_search_decoder(inputs=aa_ctc_blank_aa_logits,
                                                  sequence_length=sequence_length,
                                                  merge_repeated=True,
                                                  top_paths=1,
                                                  beam_width=1)
    
        out = list(tf.Session().run(tf.sparse_tensor_to_dense(decoded_list)[0]))
        print("Output int list")
        print(out)
        seq_list = get_seq_from_list(out, classes)
        
        return seq_list
    
    def get_seq_from_list(int_list, classes):
        out_list = []
        for i in range(0, len(int_list)):        
            out_list.append(classes[int_list[i]])
            
        return out_list
    
    if __name__ == '__main__':
    
        mat = np.load('../npy_files/a1003.npy')
        classes = Classes.get_classes()
        
        print("-------Greedy---------")
        actual = decode_ctcgreedy(mat, classes)
        print(actual)    
        
        print("\n-------Beam Search----------")
        actual = decode_ctcBeam(mat, classes)
        print(actual)    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      相关资源
      最近更新 更多