[Speech Recognition] 연결주의 시간 분류 (Connectionist Temporal Classification)
연결주의 시간 분류 (Connectionist Temporal Classification)
음성 인식에서 CTC (Connectionist Temporal Classification)는 단조 손실 (monotonic loss)이기 때문에 더 널리 사용되는 접근 방식이다. 시간 단계의 음성 특징은 t₁와 t₂ 시간 단계의 u₁와 u₂ 대상 토큰에 해당된다. 이 단조로운 속성은 ASR 모델의 훈련을 크게 단순화하고 수렴 (convergence) 속도를 높인다.
일반적으로 ASR은 시퀀스 간 예측 작업으로 설명할 수 있다. 원래 시퀀스는 오디오 시퀀스이다 (종종 멜 스펙트로그램으로 변환됨). 대상 시퀀스는 문자 (또는 하위 단어 토큰)의 시퀀스이다. Attention 모델은 동일한 시퀀스 간 예측 작업을 수행할 수 있다. 자동 회귀 (auto-regressive) 디코딩으로 인해 CTC보다 더 나은 성능을 발휘할 수도 있다. 그러나 훈련을 안정화하고 속도를 높이는 데 활용할 수 있는 특정 귀납적 편향 (ex: CTC 손실로 나타나는 단조성)이 부족하다. 또한, 설계상 Attention 모델은 시퀀스를 출력에 정렬하기 위해 전체 시퀀스를 사용할 수 있어야 하므로 스트리밍 추론에 사용되지 않는다.
CTC의 단점
CTC는 ASR 모델을 안정적인 방식으로 훈련하는 데 탁월한 loss이지만 모델 설계에는 특정 제한 사항이 있다. 음성 인식이 시퀀스 간 문제라고 가정하는 경우 음성 모델 출력의 시퀀스 길이를 이라고 하고 대상 텍스트 기록 (문자 또는 하위 단어로 토큰화 후)의 시퀀스 길이를 이라고 한다.
CTC에서 T ≥ U와 같은 제한 |
|
CTC 손실만으로 훈련된 모델에 의해 예측된 토큰은 조건부 독립 (conditionally independent)인 것으로 가정 |
|
import torch
import torch.nn as nn
T = 10 # acoustic sequence length
U = 16 # target sequence length
V = 28 # vocabulary size
def get_sample(T, U, V, require_grad=True):
torch.manual_seed(0)
acoustic_seq = torch.randn(1, T, V + 1, requires_grad=require_grad)
acoustic_seq_len = torch.tensor([T], dtype=torch.int32) # actual seq length in padded tensor (here no padding is done)
target_seq = torch.randint(low=0, high=V, size=(1, U))
target_seq_len = torch.tensor([U], dtype=torch.int32)
return acoustic_seq, acoustic_seq_len, target_seq, target_seq_len
# First, we use CTC loss in the general sense.
loss = torch.nn.CTCLoss(blank=V, zero_infinity=False)
acoustic_seq, acoustic_seq_len, target_seq, target_seq_len = get_sample(T, U, V)
# CTC loss expects acoustic sequence to be in shape (T, B, V)
val = loss(acoustic_seq.transpose(1, 0), target_seq, acoustic_seq_len, target_seq_len)
print("CTC Loss :", val)
val.backward()
print("Grad of Acoustic model (over V):", acoustic_seq.grad[0, 0, :])
# Next, we use CTC loss with `zero_infinity` flag set.
loss = torch.nn.CTCLoss(blank=V, zero_infinity=True)
acoustic_seq, acoustic_seq_len, target_seq, target_seq_len = get_sample(T, U, V)
# CTC loss expects acoustic sequence to be in shape (T, B, V)
val = loss(acoustic_seq.transpose(1, 0), target_seq, acoustic_seq_len, target_seq_len)
print("CTC Loss :", val)
val.backward()
print("Grad of Acoustic model (over V):", acoustic_seq.grad[0, 0, :])
일반적인 경우 CTC 손실은 T ≥ U일 때, 손실이나 기울기를 계산할 수 없다. CTC Loss의 PyTorch 특정 구현에서 그러한 경우를 명시적으로 확인하고, 그러한 경우가 발생할 경우에 손실과 기울기를 0으로 만드는 플래그 zero_infinity를 지정할 수 있다. 플래그를 사용하면 일부 샘플이 실수로 이 제한을 위반할 수 있는 샘플 배치를 훈련할 수 있지만 훈련은 중단되지 않으며 gradients는 NAN이 되지 않는다.