본문 바로가기
Linguistic Intelligence/Speech Recognition

[Speech Recognition] 연결주의 시간 분류 (Connectionist Temporal Classification)

by goatlab 2024. 7. 16.
728x90
반응형
SMALL

연결주의 시간 분류 (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와  같은 제한
  • 일반적으로 T는 일반적으로 최종 텍스트 전사보다 훨씬 길기 때문에 이 가정은 자연스럽게 유효하다. 그러나 이 가정이 실패하는 경우가 많다.
  • 음성 모델은 T ≥ U 정도까지 다운샘플링을 수행한다. 다운샘플링을 수행해야 하는 이유는 컨볼루션의 경우 더 긴 시퀀스는 더 많은 보폭 단계와 더 많은 메모리를 사용한다. Attention 기반 모델 (ex: Conformer)의 경우 T에 비례하여 Attention 단계를 계산하는 데 2차 메모리 비용이 발생한다. 따라서, 더 많은 다운샘플링은 메모리 요구 사항을 완화하는 데 크게 도움이 된다.
  • 일반적으로 타겟 시퀀스는 매우 길다. 짧은 영어 단어를 매우 길게 번역한 독일어와 같은 언어를 생각해보면, ASR 작업에서 2배 이상의 다운샘플링이 있고 문자 토큰화가 사용되는 경우 이러한 CTC 제한으로 인해 모델이 학습하지 못하는 경우가 많다.
CTC 손실만으로 훈련된 모델에 의해 예측된 토큰은 조건부 독립 (conditionally independent)인 것으로 가정
  • 이는 입력으로 h-e-l-l에서 o가 hello를 완성할 것으로 예측하는 언어 모델과 달리 CTC 훈련 모델의 경우 영어 알파벳의 모든 문자가 예측 가능성이 동일하다는 것을 의미한다. 따라서, CTC 학습 모델은 오디오 세그먼트를 텍스트로 변환할 때 철자가 틀리거나 토큰이 누락되는 경우가 많다.
  • 모델을 평가할 때 WER (단어 오류율) 측정항목을 자주 사용하기 때문에 단 한 번의 철자 오류라도 "단어"가 부정확해지는 데 큰 영향을 미친다.
  • 이 문제를 완화하려면 외부 언어 모델을 통해 Beam Search를 사용해야 한다. 이는 종종 효과가 있고 전사 (transcription) 정확도를 크게 향상시키지만 프로세스가 느리고 대규모 N-gram 또는 신경 언어 모델이 필요하다.
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이 되지 않는다.

 

 

728x90
반응형
LIST