음성인식에 필요한 기초개념 1
******************************************************************************************************************************
이 글은 ReadyToUseAI에서 무료로 제공하는 강의를 듣고 정리한 내용입니다.
강의내용: 음성인식에서 딥러닝은 어떻게 사용될까? (심규홍 강사님)
유튜브 강의링크 : www.youtube.com/channel/UCpWrFUlwUGZSHVlOT1eD-Wg
오픈채팅방 : open.kakao.com/o/g46ZM7Zc (참여코드 : aiai)
수업 관련 자료 : drive.google.com/drive/folders/1Sd-dQd_b-aKdBLAUQ5jz6lwFmiaTFQ02?usp=sharing
******************************************************************************************************************************
최근 자연어처리와 음성인식에 관심이 생겨 공부를 시작하면서 유익한 곳(?)을 발견해 해당 강의를 베이스로 정리 + 공부한 내용을 남긴다.
목표는 Speeech-To-Text (STT, ASR) 사이드 프로젝트 !!!
AI에서 Speech 분야는 크게 두가지로 나뉘는데, 음성인식과 음성합성으로 나뉜다.
Speech Applications
- 음성인식 (Speech-To-Text, STT, ASR - automatic speech recognition)
- 음성합성 (Text-to-Speech, TTS)
- 응용 예시 : 아이폰 siri (음성비서), 스마트 스피커, 자동 회의록 작성, 동영상 자동자막, 동시통번역, 화자인식(화자가 누구인지 식별), 음성인식 주문/예약 등..
Speech Data
- 음성 파형 (Waveform) - 음성 파일
- 스펙트로그램 (Spectrogram)
- Utterance (사용자의 말 / Text) - 발화 텍스트
- (Optional) Alignment 정렬 - 어디서 부터 어디까지가 텍스트 어느 부분까지 해당되는지
음성 파형 (Waveform)
음성 데이터는 Waveform 파일로 저장이 된다. Waveform은 세기 표현이라고도 할 수 있는데, 16,000 Hz 로 녹음된 음성이라고 하면 1/16,000 초 마다 들어온 소리가 어느정도의 세기를 가지고 있는지 기록한 것이 Waveform이다. 헤르츠(Hertz, 기호: ㎐)에서 1 Hz는 1초에 한 번을 의미한다. 즉 100 Hz는 1초에 100번을 반복 혹은 진동한다. 음성을 헤르츠 단위의 주파수(frequency)로 관측할 수 있고, 우리가 들을 수 있는 모든 소리는 다양한 주파수 성분들의 합으로 이루어져 있다 (주파수가 높을수록 음이 높게 들림).
Waveform 형태의 데이터는 전처리를 통해서 유의미한 정보를 가지고 있는 어떤 형태로 만든다. Waveform은 푸리에 변환(Fourier transform, FT)을 거쳐서 Spectrogram이라는 피쳐로 바꿀 수 있다. 이렇게 음성 파형을 변환하는 이유는 음성에 들어있는 정보 (발음의 종류, 성별, 음색, 높이 등)을 음성 신호/파형에서 바로 얻어낼 수 없고 수학적인 신호처리를 거쳐서 추출할 수 있기 때문이다. 그 중 푸리에 변환이라는 함수를 사용해서 특정 시간 길이의 음성 조각(프레임이라고 함)이 각각의 주파수 성분들을 얼마만큼 갖고 있는지를 의미하는 스펙트럼(Spectrum)을 얻을 수 있다. 음성 전체로부터 얻은 여러개의 스펙트럼을 시간 축에 나열하면 시간 변화에 따른 스펙트럼의 변화인 스펙트로그램(Spectrogram)을 얻게 된다.
참고 : tech.kakaoenterprise.com/66
Traditional Speech To Text -> End-to-End Deep Learning
전통적인 STT에서는 Feature Extraction (푸리에 변환)을 거치고, Acoustic Model + Lexicon + Language Model을 합쳐 Decoder로 만들어 아래 사진처럼 각각의 과정을 거쳐 조합하는 과정이었다면 2010년대 초반 딥러닝이 나와 이 모든 것을 하나로 할 수 있다 = 각각의 과정이 개별적으로 필요 없다는 개념이 등장해 End-to-End (E2E) 라고 부르기 시작했다고 한다.
* 알아두면 좋은 더 deep한 개념 👇
<전통적인 음성인식과 딥러닝>
음성인식에서 최근 주목받고 있는 딥러닝(deep learning)은 자료(입력)에서 목표한 결과(출력)을 별도의 중간 매개 없이 학습하는 end-to-end 학습을 가능케 했다. E2E 학습을 이용한 음성인식에서는 주어진 음성을 음소 및 형태소를 거치지 않고 바로 단어나 문장으로 변환할 수 있다. 음성인식의 여러 중간 단계들을 생략하면 음소 단위로 훈련을 할 필요 없고, 음소를 매개로 하는 중간 단계와 렉시콘 사전이 생략할 수 있어 과정이 간소화된다.
대표적인 음성인식의 E2E 모형으로는 Graves 등 (2006)이 제안한 연결성 시계열 분류기(connectionist temporal classification; CTC) 모형과 Chan 등 (2015)가 제안한 listen, attend, and spell (LAS) 모형이 있다.
<디코더란? + 빔 탐색 + 언어 모형>
딥러닝을 기반으로 한 음성 인식 모형은 음성 자료를 잠재 변수로 변환하는 인코더(encoder)와 잠재 변수로부터 문자열을 얻어내는 디코더(decoder)로 구성되어 있다.
일반적으로 디코딩을 할 때는 모든 문자열이 가지는 확률을 계산해 가장 높은 확률을 지닌 문자열을 찾는 방식으로 한다 (yˆ = argmax(p(y|x, θ))). 그러나 시간이나 문자열의 길이에 따라서 가능한 문자의 개수가 지수적으로 증가하므로 비효율적이다. 따라서 모든 가능한 문자열을 탐색하는 대신 빔 탐색(beam search)을 이용하여 기억해야 하는 노드를 제한하는 기법을 사용하였다. 빔 탐색은 주어진 문자 다음에 선택될 수 있는 문자의 모든 가능한 경우의 수를 계산한 후, 미리 정한 상위 B개 확률의 문자 조합만을 취하여 목표 문자열를 찾을때까지 반복하는 경험적 탐색 알고리듬이다. 여기서, B는 빔너비(beam width)라고 부른다.
추가로 디코딩 시에 따로 훈련된 언어 모형을 이용하여 정확도를 높일 수 있다. 일반적으로 음성인식 모형에 입력으로 들어오는 음성은 아무 의미 없는 발음들이 아니라 언어적 맥락이나 문법과 같이 음성과 독립적인 언어적 특성이 존재하는 문장이다. 따라서, 이러한 정보를 따로 학습한 뒤에 모형에 추가하여 인식의 정확도를 높일 수 있다.
참고 : Korean speech recognition using deep learning (2019) http://www.kss.or.kr/jounalDown.php?IDX=4245
E2E로 훈련되더라도 아직 필요한 것들
- Feature Extraction 과정 - 스펙트로그램 (Spectrogram)을 뽑아내는 푸리에 변환 과정
- Beam search decoder
- Language model - (Beam search)에 필요
- 모델의 학습과 별개로 음성 자료를 문자열로 바꾸는 디코딩에 이용되는 빔 탐색(beam search) 및 언어 모형(language model) => 위에 "* 알아두면 좋은 더 deep한 개념 👇" 참고
모델 1. Acoustic Model (Deep Speech 2)
2015년에 나온 Deep Speech 2 논문 (중국 대표 IT 기업 ‘바이두(baidu)’에서 공개한 End-to-End 음성 인식 모델)
Input으로 Spectrogram을 받고 Output으로 CTC(connectionist temporal classification) 반환하는 것을 볼 수 있다. 이 모델에서 살펴봐야할 점은 아래와 같다.
- 음성 인식에 유리한 모델 아키텍처
- 효율적인 학습 테크닉 : Connectionist Temporal Classification(CTC) loss 직접 구현 등
입력받은 Spectrogram에서 중요한 특징 (feature) 을 뽑아내는 레이어로 Convolutional Neural Network를 사용한다. 이후 양방향(bidirectional) Recurrent Neural Network를 두고, 마지막에는 Fully Connected Layer가 있다.
참고 : ratsgo.github.io/speechbook/docs/neuralam/deepspeech
CTC : Connectionist Temporal Classification (연결성 시계열 분류기)
핵심 아이디어는 음성의 길이에 맞게 텍스트의 길이를 늘린다는 개념이다. 음성의 길이(S)가 7, 텍스트(T)가 3이라면 모자란 만큼 Blank ("_")로 채운다. 하지만 우리는 어디서 Blank가 들어가고 어디서 실제 Text가 들어가야되는지 알지 못한다. 그럼으로 가능한 모든 조합의 합으로 확률을 표시한다. CTC는 최적의 정렬(Alignment)를 찾아내기 위해 가능한 모든 시퀀스들을 나열한다.
CTC는 현재 다이다믹 프로그래밍을 통해 연산속도도 극적으로 빨라져 있으며, PyTorch, TensorFlow에 기본으로 내장이 되있어 사용하기 쉽다. CTC의 장점은 Encoder만 쌓고, 그 위에 CTC Loss만 넣으면 음성인식이 가능하다는 점이다. 또한 어느정도 정렬 위치를 추출할 수 있다 (Probability, Distribution을 보고 어느정도 정렬 위치를 역산할 수 있다 - 정확하진 않음). 단점은 추가적인 LM decoding (Beam Search Decoding)이 없으면 성능이 극적으로 좋아지지 않는다.
* 알아두면 좋은 더 deep한 개념 👇
from : m.blog.naver.com/PostView.nhn?blogId=sogangori&logNo=221183469708&proxyReferer=https:%2F%2Fwww.google.com%2F'
CTC 네트워크는 softmax output layer 를 갖는다. 소프트맥스는 클래스 갯수 L개 보다 하나 많은 L + 1 개의 액티베이션을 갖는다. 추가 1 은'blank' 혹은 no label 의 확률이다. 어느 하나의 라벨시퀀스 {DOG} 에 대한 네트워크의 ouput은 {-D-OOGG} 혹은 {-DD-OGG-} 등으로 다양하게 나타날 수 있다. (-: blank label ,공백)
예를 들어 네트워크의 출력의 max 채널값이 {0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8} 이고 해당 채널은 {-D-OOGG} 였다고 하자. 첫번째 자리가 - 일 확률이 0.5 , 두번째 자리가 D 일 확률이 0.55 라고 해석된다. 이 네트워크의 출력이 paths 인데 이 paths 의 모든 확률을 전부 곱한 것이 paths 의 확률이다.
0.5*0.55*0.6*0.65*0.7*0.75*0.8 ~= 0.01 보다 작겠다.
다음으로는 many-to-one map인 B 함수가 필요하다. 한 라벨에 대해서 paths 는 {-D-OOGG},{-DD-OGG-} 처럼 다양하게 나타날 수 있다. B 함수는 paths 의 빈칸과 중복을 제거한다.
예) B(paths) = 라벨시퀀스
B(ab) = B(aab) = B(abb) = B(-ab) = B(a-b) = B(ab-)= ab
B(-D-OOGG) = B(-DD-OGG-) = DOG
한 라벨의 paths 는 다양하게 나타날 수 있는데 라벨에 대한 B의 역함수를 통해 모든 가능한 paths 를 얻을 수 있다. 모든 가능한 paths 들의 확률들(paths의 모든 요소의 확률들을 전부 곱한것)을 모두 더한것이 x가 주어졌을때 라벨의 조건부 확률이다.
=> 이 모든 가능한 라벨의 총확률을 높이는 것이 학습의 목표이다.
주어진 x 로부터 분류를 가장 적절하게 해야 하므로 p(L|x) 가 가장 큰 path 를 선택해야 한다. 탐색을 하면서 적절한 라벨링을 찾는다 => CTC의 단점과 연결 (단점은 추가적인 LM decoding (Beam Search Decoding)이 없으면 성능이 극적으로 좋아지지 않는다.)
모델 2. LAS: Listen, Attend, Spell
Deep Speech2와 비슷한 시기에 Google Brain에서 제안한 Listen, Attend and Spell(LAS) 모델이다. Listener, Attention, 그리고 Speller로 나눠지는 부분에 주목해서 살펴보면 된다. CTC, RNN-T와 달리 Attention 알고리즘을 이용하여 음향 입력과 레이블 출력 사이의 정렬(Alignment)을 계산한다.
Listener는 피라미드 형식으로 구된 bidirectional LSTM(BLSTM) 인코더이며 입력 시퀀스 x로부터 특징을 뽑아낸다. Listener는 BLSTM을 Pyramidal 형식으로 3개를 붙여서 사용하고 있다. 논문에서는 이를 pBLSTM으로 부르고 있으며, pyramidal 하게 사용하는 이유는 pBLSTM 1개당 연산속도를 2배로 줄여주기 때문이다. 3개의 BLSTM의 top of the bottom에 쌓은 pBLSTM은 time resolution을 2의 3승만큼, 즉 8 배만큼 줄여준다고 한다.
Speller는 attention을 사용해서 출력을 하는 디코더 decoder이다. AttendAndSpell 함수는 attention 기반의 LSTM 변환기인 decoder를 통해서 계산된다. decoder는 매 time step마다 이전에 결정된 문자들에 대한 다음 문자의 분포를 생성한다. (모든 출력 단계에서 변환기는 이전에 본 모든 문자를 조건으로 한 다음 문자에 대한 확률 분포를 생성한다)
이 모델의 학습은, 입력 음성에 대해 알맞는 sequence의 log probability를 maximize한다. 그리고 디코딩 관련하여, test 시에 가장 근접한 character sequence를 주어진 음향에 대해 찾는다.
Content based Attention Mechanism은 문자와 오디오 신호 사이의 명확한 정렬을 만든다. 아래 사진에서 오른쪽 아래에 있는 그리드는 문자와 입력 음성간의 할당 (Alignment / 정렬)을 보여준다. "how much would a woodchuck chuck" 라는 음성 input에 따른 character alignment인데, Content based attention mechanism은 첫 번째 문자에 대한 오디오 시퀀스의 시작 위치를 올바르게 식별할 수 있었다고 한다. => 어떤 텍스트를 만들 때 어디를 봐야 하나
www.secmem.org/blog/2019/07/21/Listen,-Attend-and-Spell/
모델 3. RNN-T: Recurrent Neural Network Transducer
CTC와 유사하다. CTC와 마찬가지로 최적의 정렬(Alignment)을 찾아내기 위해 모든 시퀀스를 나열한 후 구한다. 하지만 CTC와 달리 조건부 독립을 가정하지 않기 때문에 최적 경로 계산이 CTC와는 다르며, CTC보다 더 복잡하게 계산된다고 한다. CTC에선 다음 라벨이 나올 때 까지 유지가 된다. "나는 학교를 간다"라고 문장을 예측한다고 하면 나는을 예측 후에 학교에 라는 음성이 들어가면 학교를 예측한다. Alignment 데이터가 필요없다. 음성 프레임이 넘어가는 매 순간마다 지금 단어 (라벨)를 유지할 지, 다음 단어로 진행할지 찾아낸다. CTC와 마찬가지로 가능한 모든 경로, path의 조합으로 확률을 계산하고, 그 확률을 높이는 방향으로 훈련을 한다. 아래는 기존 CTC 모델과의 차이를 보여주는 그림인데, RNN-T는 Encoder에 Prediction Network를 연결해서 사용한다. prediction network를 연결시켜줌으로써 후처리 언어모델의 효과를 얻을 수 있다고 한다.
최근의 모델들은 LAS, RNN-T 중 하나로 주로 훈련을 한다고 한다. RNN-T가 더 각광 받는 추세이다 (다음시간에 Streaming과 관련).
모델 요약
요약 : n to m 갯수를 맞춰라! (음성의 길이에 맞게 텍스트의 길이) 어떻게?
SOTA (State Of The Art) in ASR
Summary
=> Speech 는 데이터가 엄청난 영향을 준다. (학습 안한 노이즈가 섞이면 못맞출 가능성이 높다)
=> 대부분의 모델은 이미 엄청난 성능을 보여준다. ==.. 상용 음성 API를 쓰면 성능이 잘나온다.
=> 가지는 데이터가 특수하다면 (noisy), 또는 환경에 맞는 훈련이 필요하다면 라이브러리를 사용하면 된다
=> 또는 사전에 훈련된 음성 인식 모델을 사용하면 된다 (음성인식도 이제 pre-training, fine-tuning... 영어로 사전학습 되있어도 사람의 발음기호가 비슷해서 다른 언어로 바꿨을 때도 잘된다?).
=> 가장 대표적인 것이 Wav2Vec 모델 (다음시간에...)
=> HuggingFace 를 쓰자...
'AI > Self-Study' 카테고리의 다른 글
yolov5 학습 튜토리얼 1 (6) | 2021.05.11 |
---|---|
한줄로 Train/Test/Validation 나누기 (splitfolders : annotation도 함께 나누는법) (0) | 2021.05.11 |
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 2 (0) | 2021.04.12 |
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 1 (0) | 2021.04.12 |
Keras에서 predict와 predict_generator 가 다른 값을 내는 경우 (Image Data Generator) (0) | 2021.04.09 |
댓글
이 글 공유하기
다른 글
-
yolov5 학습 튜토리얼 1
yolov5 학습 튜토리얼 1
2021.05.11 -
한줄로 Train/Test/Validation 나누기 (splitfolders : annotation도 함께 나누는법)
한줄로 Train/Test/Validation 나누기 (splitfolders : annotation도 함께 나누는법)
2021.05.11 -
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 2
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 2
2021.04.12 -
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 1
Keras : ImageDataGenerator 대신에 tf.data로 빠르게 학습하기 1
2021.04.12