Shortcuts

CTCLoss

class torch.nn.CTCLoss(blank=0, reduction='mean', zero_infinity=False)[源代码]

连接时序分类损失。

计算连续(未分段)时间序列与目标序列之间的损失。CTCLoss 对输入到目标的可能对齐概率进行求和,生成一个可微分的损失值,该值相对于每个输入节点。输入到目标的对齐假设为“多对一”,这限制了目标序列的长度,使其必须小于或等于输入长度。

Parameters
  • 空白 (int, 可选) – 空白标签。默认值 00

  • reduction (str, 可选) – 指定应用于输出的reduction方式: 'none' | 'mean' | 'sum''none':不进行reduction, 'mean':输出损失将被目标长度除,然后对批次取平均值,'sum':输出损失将被求和。 默认值:'mean'

  • zero_infinity (布尔值, 可选) – 是否将无限损失和相关的梯度归零。 默认值: False 无限损失主要发生在输入太短而无法与目标对齐时。

Shape:
  • Log_probs: 大小为 (T,N,C)(T, N, C)(T,C)(T, C), 其中 T=输入长度T = \text{输入长度}, N=批次大小N = \text{批次大小}, 和 C=类别数量(包括空白)C = \text{类别数量(包括空白)}. 输出对数概率(例如通过 torch.nn.functional.log_softmax()获得)。

  • 目标:大小为 (N,S)(N, S)(sum(target_lengths))(\operatorname{sum}(\text{target\_lengths})) 的张量, 其中 N=batch sizeN = \text{batch size}S=max target length, if shape is (N,S)S = \text{max target length, if shape is } (N, S)。 它表示目标序列。目标序列中的每个元素都是一个类别索引。目标索引不能为空白(默认=0)。 在 (N,S)(N, S) 形式中,目标被填充到最长序列的长度,并堆叠。 在 (sum(target_lengths))(\operatorname{sum}(\text{target\_lengths})) 形式中, 目标被假定为未填充并在1维内连接。

  • Input_lengths: 大小为 (N)(N)()() 的元组或张量, 其中 N=batch sizeN = \text{batch size}。它表示输入的长度(每个长度必须为 T\leq T)。并且这些长度是为每个序列指定的,以在假设序列被填充到相同长度的情况下实现掩码。

  • Target_lengths: 元组或大小为 (N)(N)()(), 其中 N=batch sizeN = \text{batch size}。它表示目标的长度。 长度是为每个序列指定的,以在假设序列被填充到相同长度的情况下实现掩码。如果目标形状是 (N,S)(N,S), target_lengths 实际上是停止索引 sns_n 对于每个目标序列,使得 target_n = targets[n,0:s_n] 对于 批次中的每个目标。长度必须每个都 S\leq S 如果目标作为1维张量给出,该张量是各个目标的连接,则 target_lengths 必须加起来等于张量的总长度。

  • 输出:如果 reduction'mean'(默认)或 'sum',则为标量。如果 reduction'none',则为 (N)(N)(如果输入是批量的)或 ()()(如果输入是非批量的),其中 N=batch sizeN = \text{batch size}

示例:

```html
>>> # 目标需要填充
>>> T = 50      # 输入序列长度
>>> C = 20      # 类别数量(包括空白)
>>> N = 16      # 批次大小
>>> S = 30      # 批次中最长目标序列的长度(填充长度)
>>> S_min = 10  # 最小目标长度,用于演示目的
>>>
>>> # 初始化随机批次输入向量,大小为 (T,N,C)
>>> input = torch.randn(T, N, C).log_softmax(2).detach().requires_grad_()
>>>
>>> # 初始化随机批次目标(0 = 空白,1:C = 类别)
>>> target = torch.randint(low=1, high=C, size=(N, S), dtype=torch.long)
>>>
>>> input_lengths = torch.full(size=(N,), fill_value=T, dtype=torch.long)
>>> target_lengths = torch.randint(low=S_min, high=S, size=(N,), dtype=torch.long)
>>> ctc_loss = nn.CTCLoss()
>>> loss = ctc_loss(input, target, input_lengths, target_lengths)
>>> loss.backward()
>>>
>>>
>>> # 目标需要去填充
>>> T = 50      # 输入序列长度
>>> C = 20      # 类别数量(包括空白)
>>> N = 16      # 批次大小
>>>
>>> # 初始化随机批次输入向量,大小为 (T,N,C)
>>> input = torch.randn(T, N, C).log_softmax(2).detach().requires_grad_()
>>> input_lengths = torch.full(size=(N,), fill_value=T, dtype=torch.long)
>>>
>>> # 初始化随机批次目标(0 = 空白,1:C = 类别)
>>> target_lengths = torch.randint(low=1, high=T, size=(N,), dtype=torch.long)
>>> target = torch.randint(low=1, high=C, size=(sum(target_lengths),), dtype=torch.long)
>>> ctc_loss = nn.CTCLoss()
>>> loss = ctc_loss(input, target, input_lengths, target_lengths)
>>> loss.backward()
>>>
>>>
>>> # 目标需要去填充和去批次化(相当于 N=1)
>>> T = 50      # 输入序列长度
>>> C = 20      # 类别数量(包括空白)
>>>
>>> # 初始化随机批次输入向量,大小为 (T,C)
>>> input = torch.randn(T, C).log_softmax(1).detach().requires_grad_()
>>> input_lengths = torch.tensor(T, dtype=torch.long)
>>>
>>> # 初始化随机批次目标(0 = 空白,1:C = 类别)
>>> target_lengths = torch.randint(low=1, high=T, size=(), dtype=torch.long)
>>> target = torch.randint(low=1, high=C, size=(target_lengths,), dtype</span
Reference:

A. Graves 等人:连接主义时间分类:使用循环神经网络对未分割的序列数据进行标注: https://www.cs.toronto.edu/~graves/icml_2006.pdf

注意

为了使用 CuDNN,必须满足以下条件:targets 必须为 连接格式,所有 input_lengths 必须为 Tblank=0blank=0, target_lengths 256\leq 256,整数参数必须为 dtype torch.int32

常规实现使用(在 PyTorch 中更常见)torch.long 数据类型。

注意

在某些情况下,当使用CUDA后端与CuDNN时,此操作符可能会选择一个非确定性算法以提高性能。如果这是不可取的,您可以尝试通过设置torch.backends.cudnn.deterministic = True来使操作具有确定性(可能会以性能为代价)。 请参阅可重复性的背景说明。

优云智算