CTC 是一种用于训练深度神经网络的算法,常用于语音识别、手写识别以及其他序列问题。在这些任务中,输入与输出之间往往没有明确的对齐信息。CTC 为我们在无法确知输入如何映射到输出时提供了一种解决方案。
什么是 CTC 模型?
在序列到序列的问题中,输入序列和目标序列之间可能不存在一对一的对应关系。例如,考虑 ASR(自动语音识别) 的任务。我们将音频片段作为输入,其转录的文本作为输出。问题在于,音频输入和转录文本之间的对齐关系是未知的。此外,对于不同的人来说,这种对齐方式也会有所不同。以单词 ‘hello‘ 为例,人们在说这个词时,可能会强调单词的不同部分,如 ‘hello‘ 或 ‘hello‘。这使得模型训练变得非常困难。一种简单的解决方案是手动标注所有的对齐信息。然而,对于大型数据集来说,这种方法既天真又不切实际。
用数学语言来表达,假设我们有一个输入序列 X = [X1, X2, X3…Xm] 和一个输出序列 [Y1, Y2 …, Yn]。如果我们想要将 x 映射到 y,我们会面临以下问题:
- X 的长度 和 Y 的长度 是不同的。
- X 和 Y 的长度比例会因人而异。
- 我们缺乏对齐信息。
CTC 通过允许模型在训练过程中学习输入和输出序列之间的对齐关系来解决这些问题。我们的目标是找到 X 和 Y 之间最可能的对齐方式。CTC 作为一种神经网络的输出方法,专门设计用于解决与序列相关的挑战,例如在手写和语音识别任务中存在的时序变化问题。采用 CTC 的优势在于它能够在训练期间处理未对齐的数据集,从而显著简化训练过程。
CTC 算法
让我们深入探讨该算法及其工作原理。
我们可以将该算法理解为三个部分:
1. 对齐算法
前向部分主要处理对齐问题。在对齐过程中存在两个问题:
- 输出文本占据多个时间步。
- 字符重复。
为了解决这些问题,CTC 使用了两条规则:
- 将所有重复的字符合并为一个字符。
- 如果字符重复,则在输出文本中的字符之间放置一个称为“空白符号” 的特殊标记。
为了理解这一点,让我们以单词 ‘hello‘ 的输入音频为例。音频 clip 会被转换为声谱图以进行特征提取。假设转换后的音频有 8 个时间步(输入 X1 到 X8)。为了更深入地了解音频输入处理,请参阅 Audio Transformers 这篇文章。因此,输入的长度为 8,而输出的长度为 5。
我们可以通过下面显示的示例来实际理解上述两条规则:
- 在第一个例子中,由于两个 ‘l‘ 之间没有 ‘ϵ‘,我们将它们合并并预测为一个单独的 ‘l‘。
- 在第二个例子中,由于两个 ‘l‘ 之间存在 ‘ ϵ‘,我们将它们推断为不同的字符。
2. 损失计算
为了计算损失,我们需要计算生成输出序列的概率。现在,考虑到上述情况,可能存在许多有效的对齐方式,它们都可以简化为生成正确的输出。一种简单的方法是计算所有这些有效对齐的概率并对所有概率求和。然而,这在计算上是非常昂贵的,并且随着输入/输出长度的增加变得不切实际。
#### 修正序列
为了计算 CTC 损失,我们需要修正输入序列,在每对字符之间包含空白符号。修正序列 是通过在原始标签序列的开头和结尾以及每对不同非空白标签之间插入空白符号来创建的。
因此,输入单词 [‘ h e l l o‘] 被修正为 [‘ϵ h ϵ e ϵ l ϵ l ϵ o ϵ‘]。
引入空白的目的在于允许灵活地将输入序列与输出序列对齐,而不需要输入和输出符号之间存在一对一的对应关系。为什么呢?一旦我们看完下面的前向-后向算法计算,这一点就会变得更加直观。
修正序列中的每个字符被称为状态,由 表示。CTC 算法在每个时间戳计算两个变量:
- 前向变量 α(s, t):该变量表示在时间 "t" 到达状态 "s" 的总概率,此时已发出了截至该点的部分序列。
- 后向变量 β(s, t):该变量表示从时间 "t" 的状态 "s" 开始发出剩余序列的总概率。
这是 CTC 算法的核心。这个算法被称为前向…