Zorba blog
[논문 리뷰] A Simple Data Augmentation Method for Automatic Speech Recognition 본문
[논문 리뷰] A Simple Data Augmentation Method for Automatic Speech Recognition
Zorba blog 2022. 8. 6. 11:26
한국어 음성인식을 공부하기위해 이곳저곳 찾아보다가
아래 Git에 논문 및 공부자료들이 잘 정리되어 있어 그중 한 논문을 리뷰하였다.
GitHub - sooftware/Speech-Recognition-Tutorial: 한국어 음성인식 튜토리얼
한국어 음성인식 튜토리얼. Contribute to sooftware/Speech-Recognition-Tutorial development by creating an account on GitHub.
github.com
Abstract
- 모델의 Overfitting을 막기 위해 가장 좋은 방법은 데이터가 많은 것.
- 하지만 데이터가 그냥 생기는 것은 아니기 때문에 기존 데이터를 활용하여 새로운 데이터를 만들어내는 Augmentation이라는 기법을 사용.
- 본 논문에서는 음성인식을 위한 간단한 Data-Augmentation을 제안하고, 이를 SpecAugment라고 명명.
- 본 논문에서는 오디오에서 뽑은 피쳐 벡터를 input으로 Time warping, Frequency masking, Time masking 3가지 방법으로 Augmentation을 적용.
- 성능 테스트를 위한 모델로는 Listen, Attend and Spell(LAS) 모델을 사용.
- Language Model과의 Shallow Fusion을 통해 인식률 개선을 이뤄냄.
- 본 논문의 모델은 LibriSpeech 960h 데이터셋과 Swichboard 300h 데이터셋에서 State-Of-The-Art(SOTA)를 달성.
shallow Funsion : https://www.secmem.org/blog/2019/09/18/cold-fusion/
*Augmentation을 하는 이유
1. Preprocessing 및 Augmentation을 하면 대부분의 경우 성능이 향상된다.
2. 원본 데이터를 활용하여 추가하는 개념이므로 성능이 저하될 염려가 없다.
3. 방법이 간단하며 패턴이 정해져 있다.
- 단기간에 성능 향상을 원한다면, Ensemble, Augmentation을 활용하라는 말이 있을 정도로 그 효과가 검증.
Introduction
- 딥러닝은 음성인식 분야에 성공적으로 적용되어 있음.
- 하지만, 음성 인식 분야의 연구는 대부분 모델에 초점이 맞춰져서 진행.
- 본 논문은 이러한 모델들은 쉽게 Overfitting 현상이 발생하며, 많은 양의 데이터를 필요로 한다고 지적.
Traditional Data-Augmentation for Audio
- 본 논문은 기존의 Augmentation이 어떤 방식으로 적용되었는지에 대한 설명을 간략하게 함.
Noise injection
- 기존 데이터에 임의의 난수를 더하여 Noise를 추가해주는 방법.
Shifting Time
- 임의의 값만큼 음성 신호를 좌/우로 shift하고 빈 공간은 0으로 채우는 방법.
Changing Pitch
- 기존 음성 신호의 Pitch(음높이, 주파수)를 랜덤하게 변경해주는 방법.
Changing Speed
- 기존 음성 신호의 속도를 빠르게 / 느리게 바꿔주는 방법.
- 기존 음성 신호에 대한 Augmentation은 위와 같이 raw audio를 변형하는 방법들이었음.
- 하지만 본 논문에서는 "어차피 사용하는 피쳐는 MFCC / log mel spectrogram인데, 이쪽을 변형하는게 쉽고 빠르지 않은가?" 라고 주장.
- log mel spectrogram을 이미지처럼 다루는 것.
- 계산 비용이 적게 들기 때문에 학습을 하면서 바로바로 Augmentation을 적용.
Augmentation Policy
- 본 논문에서 제안하는 SpecAugment에 대해 상세하게 알아보자.
1. Time Warping
- Computer Vision에서 사용되는 Image Warping을 응용한 방법.
- 축의 중심을 이동한다는 컨셉.
- 보자기의 중심에 손가락을 가져다가 한쪽으로 밀게되면 우측의 이미지와 같이 보자기가 꾸겨짐.
- 하지만, 우측 이미지를 보더라도 우리는 보자기라는 것을 알 수 있음.
- 이러한 점을 이용하여 Vision에서는 Image Warp라는 Augmentation 방법을 성공적으로 적용하였고, 본 논문은 여기에 영감을 받아, log mel spectrogeam을 이미지라 생각하고 Time Warp 적용.
2. Frequency Masking
- 주파수와 시간 축으로 이루어진 Spectrogram의 주파수 축을 따라 일정 영역을 0으로 마스킹.
def freq_masking(feat, F = 20, freq_mask_num = 2):
feat_size = feat.size(1)
seq_len = feat.size(0)
# freq mask
for _ in range(freq_mask_num):
f = np.random.uniform(low=0.0, high=F)
f = int(f)
f0 = random.randint(0, feat_size - f)
feat[:, f0 : f0 + f] = 0
return feat
3. Time Masking
- 주파수 축이 아닌 시간 축에 대해서 일정 영역을 0으로 마스킹.
def time_masking(feat, T = 70, time_mask_num = 2):
feat_size = feat.size(1)
seq_len = feat.size(0)
# time mask
for _ in range(time_mask_num):
t = np.random.uniform(low=0.0, high=T)
t = int(t)
t0 = random.randint(0, seq_len - t)
feat[t0 : t0 + t, :] = 0
return feat
- Frequency Masking과 Time Masking 적용 시 주의점은 마스킹하는 영역의 범위를 적당하게 지정해주어야 한다는 것.
- 너무 많이 / 적게 적용한다면 Augmentation의 효과가 덜하거나 심한 경우 Noise가 될 수 있음.
- Figure1은 위에서 아래 방향으로 기존 Spectrogram, Time Warp, Frequency Mask, Time Mask가 각각 적용된 Spectrogram.
- 본 논문에서는 Frequency Masking과 Time Masking을 동시에 적용하는 것을 고려.
- 두 마스킹을 동시에 적용하게 되면 Figure2와 같은 Spectrogram이 나오게 됨.
- 본 논문은 각각 적용하는 것과 동시에 적용하는 실험을 진행, 결과로 나온 파라미터는 아래와 같음.
사진 추가.
- LB : LibriSpeech Basic
- LD : LibriSpeech Doucle
- SM : Switchboard Mild
- SS : Switchboard String
- Frequency Masking과 Time Masking을 동시에 적용하는 코드는 아래와 같음.
def spec_augment(feat, T = 70, F = 20, time_mask_num = 2, freq_mask_num = 2):
feat_size = feat.size(1)
seq_len = feat.size(0)
# time mask
for _ in range(time_mask_num):
t = np.random.uniform(low=0.0, high=T)
t = int(t)
t0 = random.randint(0, seq_len - t)
feat[t0 : t0 + t, :] = 0
# freq mask
for _ in range(freq_mask_num):
f = np.random.uniform(low=0.0, high=F)
f = int(f)
f0 = random.randint(0, feat_size - f)
feat[:, f0 : f0 + f] = 0
return feat
Model
- 본 논문은 Listen, Attend and Spell 모델을 사용.
- LAS 모델 같은 경우는 음성 인식 분야에서 end-to-end의 대표적인 모델로써, 구조가 간단하고 관련 연구도 많이 진행.
- 첫번째 절에서 이 모델에 대한 Review 및 파라미터들에 대해서 소개.
- 두번째 절에서 Learning Rate Schedules에 대해서 소개.
- 세번째 절에서 앞에서 언급했던 Shallow Fusion에 대해서 소개.
LAS Network Architectures
- 본 논문은 LAS Network 중 "Model Unit Exploration for Sequence-to-Sequence Speech Recognition"에서 사용된 구조를 사용.
- 해당 논문은 log mel spectrogram을 입력으로 받아, 2-Layer의 maxpooling이 적용된 CNN을 거침.(Stride = 2)
- 이렇게 CNN을 거쳐서 나온 아웃풋을 인코더의 Stacked Bi-LSTM의 입력으로 넣음.
- 그리고 인코딩을 거친 아웃풋을 어텐션 기반의 디코더에 넣어 예측 시퀀스를 뽑아냄.(디코더 레이어 사이즈 = 2)
Learning rate Schedules
- 이 섹션에서는 학습율을 어떻게 관리했는지에 대해서 소개.
- 이처럼 하나의 학습율을 사용하는 것이 아닌, 학습 도중 학습율을 조정하면서 사용하는 것을 Multi-step Learning Rate라고 함.
- 본 논문에서는 총 4단계의 Learning Rate Scheduling을 적용.
- Ramp-up: 학습율이 0부터 시작하여 특정 값까지 급격하게 증가시키는 구간. [0, s_r]
- High Plateau: 특정 값에 다다르면 학습율을 유지시키는 구간. [s_r, s_i]
- Exponential Decay: 스텝이 s_i에 다다르면, s_f까지 High Plateau에서 사용한 학습율의 1 / 100로 지수적으로 감소시키면서 진행. [s_i, s_f]
- Low Plateau: 이 시점 이후에는 학습률을 계속 유지. [s_f, ~]
- High Plateau 구간 중 [s_r, s_noise]까지는 학습율에 deviation이 0.075인 noise를 끼워서 진행, s_noise 이후에는 기존 학습율을 유지.
- 본 논문에서는 이러한 구간을 총 3개로 나눠서 실험을 진행.
- B(asic): (s_r, s_noise, s_i, s_f) = (0.5K, 10K, 20K, 80K)
- D(ouble): (s_r, s_noise, s_i, s_f) = (0.5K, 20K, 40K, 160K)
- L(ong): (s_r, s_noise, s_i, s_f) = (1K, 20K, 140K, 320K)
Label-Smoothing
- 본 논문은 Label-Smoothing을 적용했다고 밝힘.
- Label-Smoothing은 데이터에 대한 Over-Confidence를 조금 덜어주는 역할.
- Over-Confidence란 데이터를 너무 믿는다는 것.
- 아무래도 레이블링이라는 작업을 사람이 하는 것이다 보니, 어느 정도의 오류가 있음.
- 이러한 오류가 있는 데이터를 학습하다보면 아무래도 정확한 학습이 어려움.
- 이러한 Over-Confidence를 줄여주기 위하여 Label-Smoothing을 사용.
- 정확히 말하자면 Label-Smoothing Loss. Loss를 계산할 때 적용.
- Loss 계산시에, 원-핫 인코딩 되어 있는 레이블링에 의해 정답에 대해서만 Loss가 계산.
- 정답 레이블은 1, 나머지 레이블은 0으로 되어 있는 것이 아니라, 정답 레이블은 confidence, 나머지 레이블은 uncertainty로 바꾸어 Loss 계산. (Confidence + Uncertainty = 1.0이 되도록 설정.)
class LabelSmoothingLoss(nn.Module):
def __init__(self, vocab_size, ignore_index, smoothing=0.1, dim=-1):
super(LabelSmoothingLoss, self).__init__()
self.confidence = 1.0 - smoothing
self.smoothing = smoothing
self.vocab_size = vocab_size
self.dim = dim
self.ignore_index = ignore_index
def forward(self, logit, target):
with torch.no_grad():
label_smoothed = torch.zeros_like(logit)
label_smoothed.fill_(self.smoothing / (self.vocab_size - 1))
label_smoothed.scatter_(1, target.data.unsqueeze(1), self.confidence)
label_smoothed[target == self.ignore_index, :] = 0
return torch.sum(-label_smoothed * logit)
>>> criterion = LabelSmoothingLoss(vocab_size, ignore_index, smoothing=0.1, dim=-1)
- 본 논문은 confidence는 0,9, uncertainty는 0.1을 적용.
Shallow Fusion with Language Model
- Augmentation만으로도 State-Of-The-Art를 달성하였지만, 조금 더 개선하기 위해 Language Model과 Shallow Fusion을 진행.
- ASR 모델에서 나온 Log-probability와 LM 모델에서 나온 Log-Probability를 적절히 고려해주어서 y_hat을 결정.
- Ensemble과 비슷한 효과를 내는 방법.
Experiments
- 실험 결과.
Discussion
Time Warping contributes, but is not a major factor in improving performance.
- 제안한 Time Warp, Frequency Masking, Time Masking 중 Time Warp는 계산은 오래 걸리는데 반해 성능이 그리 좋지 않음.
- 학습 시간이 넉넉치 않다면 Frequency Masking, Time Masking만을 적용하더라도 충분한 결과를 얻을 수 있을 것이라 언급.
Label smoothing introduces instability to training.
- Label Smoothing은 Augmentation과 같이 적용될 때 눈에 띄는 성과를 냈다고 언급.
- 그 이유에 대해 추측해보자면, Masking, Warp와 같은 좆가이 들어가게 되면 어느 정도의 변형이 된 것이기 때문에 완벽하게 ~~한 데이터라고 표현할 수 없을 것.
- 그래서 이러한 Confidence를 줄여주는 Label-Smoothing과 Collaboration이 되면 더 큰 효과를 내는 것이 아닐까 추측.
Augmentation converts an over-fitting problem into an under-fitting problem.
- Augmentation은 오버피딩 되는 문제를 언더피딩으로 바꿔주는 효과가 있음.
- Augmentation이 적용되지 않은 데이터셋으로만 학습을 하게 되면, 아무래도 오버피팅이 날 확률이 높음.
- 하지만, Augmentation을 적용해주게 되면 아무래도 기존의 Training 데이터셋에 대하여 Overfitting이 나기 힘든 환경이 될 것.
Common methods of addressing under-fitting yield improvements.
- 위에서 발생하는 Under-Fitting 문제의 경우 네트워크를 깊게 만들고, 학습을 오래시키면 해결.
- 보통 Over-Fitting이 문제지, Under-Fitting의 경우 네트워크를 깊게하고, 학습을 오래시키면 해결 가능.
Conclusion
- 다른 논문들이 인식률 개선을 위해 Network에 집중할 때, Augmentation, Learning Rate Schedule, Loss 계산 등에 집중하여 State-Of-The-Art를 달성한 논문.
- 아직 많이 배우는 입장으로써 모델에 큰 변화를 주기보다는 Data Preprocessing 과정에 좀 더 많은 노력을 기울여야 겠다는 생각이 들었음.