评价此页

CTCLoss#

class torch.nn.CTCLoss(blank=0, reduction='mean', zero_infinity=False)[source]#

连接主义时间分类损失。

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

参数
  • blank (int, optional) – blank 标签。默认值为 00

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

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

形状
  • Log_probs: 大小为 (T,N,C)(T, N, C)(T,C)(T, C) 的 Tensor,其中 T=输入长度T = \text{input length}N=批次大小N = \text{batch size},以及 C=类别数量(包括 blank)C = \text{number of classes (including blank)}。输出的对数概率(例如,通过 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})) 形式中,目标被假定为未填充的,并在一个维度上连接起来。

  • 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 对于批次中的每个目标 target_n 实际上是停止索引 sns_n,使得 target_n = targets[n,0:s_n]。长度必须分别 S\leq S。如果目标以单独目标连接的 1D 张量形式给出,则 target_lengths 的总和必须等于张量的总长度。

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

示例

>>> # Target are to be padded
>>> T = 50  # Input sequence length
>>> C = 20  # Number of classes (including blank)
>>> N = 16  # Batch size
>>> S = 30  # Target sequence length of longest target in batch (padding length)
>>> S_min = 10  # Minimum target length, for demonstration purposes
>>>
>>> # Initialize random batch of input vectors, for *size = (T,N,C)
>>> input = torch.randn(T, N, C).log_softmax(2).detach().requires_grad_()
>>>
>>> # Initialize random batch of targets (0 = blank, 1:C = classes)
>>> 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()
>>>
>>>
>>> # Target are to be un-padded
>>> T = 50  # Input sequence length
>>> C = 20  # Number of classes (including blank)
>>> N = 16  # Batch size
>>>
>>> # Initialize random batch of input vectors, for *size = (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)
>>>
>>> # Initialize random batch of targets (0 = blank, 1:C = classes)
>>> 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()
>>>
>>>
>>> # Target are to be un-padded and unbatched (effectively N=1)
>>> T = 50  # Input sequence length
>>> C = 20  # Number of classes (including blank)
>>>
>>> # Initialize random batch of input vectors, for *size = (T,C)
>>> input = torch.randn(T, C).log_softmax(1).detach().requires_grad_()
>>> input_lengths = torch.tensor(T, dtype=torch.long)
>>>
>>> # Initialize random batch of targets (0 = blank, 1:C = classes)
>>> target_lengths = torch.randint(low=1, high=T, size=(), dtype=torch.long)
>>> target = torch.randint(
...     low=1,
...     high=C,
...     size=(target_lengths,),
...     dtype=torch.long,
... )
>>> ctc_loss = nn.CTCLoss()
>>> loss = ctc_loss(input, target, input_lengths, target_lengths)
>>> loss.backward()
参考

A. Graves et al.: Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Networks: https://www.cs.toronto.edu/~graves/icml_2006.pdf

注意

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

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

注意

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