Skip to content

Commit c91ce88

Browse files
timmoon10nv-kkudrynski
authored andcommitted
[FastPitch/PyT] Batched CTC loss
1 parent d3ba35a commit c91ce88

1 file changed

Lines changed: 32 additions & 15 deletions

File tree

PyTorch/SpeechSynthesis/FastPitch/fastpitch/attn_loss_function.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,44 @@
2020
class AttentionCTCLoss(torch.nn.Module):
2121
def __init__(self, blank_logprob=-1):
2222
super(AttentionCTCLoss, self).__init__()
23-
self.log_softmax = torch.nn.LogSoftmax(dim=3)
23+
self.log_softmax = torch.nn.LogSoftmax(dim=-1)
2424
self.blank_logprob = blank_logprob
2525
self.CTCLoss = nn.CTCLoss(zero_infinity=True)
2626

2727
def forward(self, attn_logprob, in_lens, out_lens):
2828
key_lens = in_lens
2929
query_lens = out_lens
30-
attn_logprob_padded = F.pad(input=attn_logprob,
31-
pad=(1, 0, 0, 0, 0, 0, 0, 0),
32-
value=self.blank_logprob)
33-
cost_total = 0.0
34-
for bid in range(attn_logprob.shape[0]):
35-
target_seq = torch.arange(1, key_lens[bid]+1).unsqueeze(0)
36-
curr_logprob = attn_logprob_padded[bid].permute(1, 0, 2)
37-
curr_logprob = curr_logprob[:query_lens[bid], :, :key_lens[bid]+1]
38-
curr_logprob = self.log_softmax(curr_logprob[None])[0]
39-
ctc_cost = self.CTCLoss(
40-
curr_logprob, target_seq, input_lengths=query_lens[bid:bid+1],
41-
target_lengths=key_lens[bid:bid+1])
42-
cost_total += ctc_cost
43-
cost = cost_total/attn_logprob.shape[0]
30+
max_key_len = attn_logprob.size(-1)
31+
32+
# Reorder input to [query_len, batch_size, key_len]
33+
attn_logprob = attn_logprob.squeeze(1)
34+
attn_logprob = attn_logprob.permute(1, 0, 2)
35+
36+
# Add blank label
37+
attn_logprob = F.pad(
38+
input=attn_logprob,
39+
pad=(1, 0, 0, 0, 0, 0),
40+
value=self.blank_logprob)
41+
42+
# Convert to log probabilities
43+
# Note: Mask out probs beyond key_len
44+
key_inds = torch.arange(
45+
max_key_len+1,
46+
device=attn_logprob.device,
47+
dtype=torch.long)
48+
attn_logprob.masked_fill_(
49+
key_inds.view(1,1,-1) > key_lens.view(1,-1,1), # key_inds >= key_lens+1
50+
-float("inf"))
51+
attn_logprob = self.log_softmax(attn_logprob)
52+
53+
# Target sequences
54+
target_seqs = key_inds[1:].unsqueeze(0)
55+
target_seqs = target_seqs.repeat(key_lens.numel(), 1)
56+
57+
# Evaluate CTC loss
58+
cost = self.CTCLoss(
59+
attn_logprob, target_seqs,
60+
input_lengths=query_lens, target_lengths=key_lens)
4461
return cost
4562

4663

0 commit comments

Comments
 (0)