STT

2021. 4. 26. 01:25음성 인식 프로젝트

 

 

 

제일 중요한 것은 UTF-8

AM이 중요한 모델이기 때문에 전사할 때 일관성 있게 작업해야 한다.

 

AM 모델에 들어가는 데이터가 크게 2가지로 되어 있다.

(front end는 음성을 전 처리하는 부분이다.)

프론트 앤드 결과를 보통 이미지라고 표현하는데, 이미지로 표현한 것을 특성 추출하고 분류하는 모델이다.

음성이 가지는 요소가 아주 중요하다. 글자가 가진 요소는 별로 중요하지 않음.

linear - mel - mfcc로 가는데 갈수록 정보가 날아간다.

tts에서는 mel을 보통 쓴다.

오른쪽 밑의 그림이 초록색 부분. 딥러닝 모델. 성능 차이가 크지 않다. 이 모델 자체는 굳이 안 쓰고 있다. 

이 부분이 제일 중요하다.

멜 스펙트로그램에서부터 하이레벨의 글자에 가까운 특성 추출하는 것이 이 단계

지금 쓰는 모델은 컨볼루션에다가 데프리션 유닛?렐루와는 조금 다른? 파라미터가 조금 있는 레이어를 따로 쓰고 있다. 

용량이 1GB.

음성만 가지고 원하는 텍스트를 추출할 수 있게 모델을 바꿀 예정. 

WAV2VEC은 프론트앤드 다 있다. 

하단 그림에서 오디오에서 CNN이 프론트 앤드 역할, 노란 박스가 특성 추출 부분

raw audio에서 cnn으로 들어가 feature 만들어내고 transformer에서 더 high level feature 만들어내는 구조.

음성만 6만 시간 학습했다.

대부분 딥러닝으로 했다. 히든 피쳐가 나온다. 하단의 그림 방법이 있어서 앞의 방법은 사용하지 않는다. 

letter : 한글 자소 or 알파벳

자소? 한 언어의 문자 체계에서 음소를 표시하는 최소의 변별적 단위로서의 문자 혹은 문자 결합

seq2seq(시퀀스투시퀀스)방식 = 크로스 엔트로피로 계산하는 방식

eos : 한 사람이 여러 문장을 말했을 때 문장 분류를 했으면 좋겠다는 니즈가 있었다.  문장 분류를 위한 enter도 학습.

오픈데이터는 enter가 없다. 여러 문장을 발화한 데이터가 없음.

input과 output이 똑같으면 그냥 분리하면 된다.

만약 음성은 10 프레임이고 글자는 3 글자면 인풋이 길어서 매칭을 해줘야 한다. 

seq2seq를 하면 알아서 해줘서 괜찮은데, 인코딩을 10개로 하고 디코딩을 10개 이용해서 3개를 아웃풋 하면 된다.

디코더를 안 쓰는 경우, 음성 10개에 대해서 분류를 하고 나면 이 10개가 3개로 매칭이 되겠는가?

그럴 경우 CTC 사용.

CCCAAT라고 예측한다면 CAT으로 한다.

중복되는 것을 합쳐서 1개가 음성 프레임이라고 생각한다. MFCC나 MEL로 한다. 

음성 트레인마다 예측해서 중복되는 것을 합쳐서 만든다. 

만약 실제로 소리가 없을 때 텍스트가 들어가면 노이즈에서도 그걸 받아서 문제가 생긴다. 

음성 길게 하면 텍스트도 길어지기 때문에 길게 안 하는 것이 좋다.

seq2 seq 일 경우에도 인코더 디코더 사이에 음성이 길어진이면 학습이 잘 안된다. 

왜 문장단위로 하는가? 문장을 벗어나버리면 소리 가지고 다음의 문장에 영향을 주지 않는다. 

문장 단위로 넘어가면 의미 없다. 

왜  10분을 하냐? 자르기 어려워서. 권장되는 방식은 문장단위로 자르는 것이 좋다. 

사람이 10분 자르는 것과 1분 자르는 것.. 고통의 차이..^^

"네"라고 하는 것도 문장으로 자르나요?질문있는데 이런 것 골치 아파~ 애매함..

학습 데이터가 10분이니 문장이 되게 많다. 콜센터의 대화 내용을 통째로 잘라서 넣어놨다. 

오픈데이터는 대부분 30초 이내인데 사내 데이터는 더 길다.

실제로 쓰는 것은 ASG이다.

 

 

블랭크를 없애려고 숫자로 대체한다. 

학습 설정에 replabel로 설정. 한국은 연속되는 경우가 없기 때문에 한국어에선 뺐다. 

ASG는 페이스북에서 만든 것

노이즈를 잘 인식하면 큰일 날 것 같다?

이런 걸 고려 안 하면 골방에서 조용히 녹음하면 오히려 인식을 못하는 경우가 생긴다. 

10시간 ~ 100시간 이하로 학습하면 이 기능이 좋다.

비슷한 노이즈가 많으면 좋다. 

전사할 때 그 데이터에서 나오는 노이즈를 따로 모아놓으면 좋다. 

따로 모아놓은 노이즈를 랜덤 하게 학습시키면 좋다. 

소리 없는 부분을 따로 빼서 저장해 놓으면 위와 같이 사용할 수 있다. 

lexicon : 어휘

AM 학습할 때 발음기호와 음성을 학습하고 쓸 때도 am이 발음기호를 예측하니까 어떻게 바뀌는지에 대한 지식이 필요

발음기호와 음성의 관계는 언어마다 다르다. 

 

AM은 순수하게 소리만 명확하게 듣는 모델.

LM은 애매하게 들린 소리를 보정해주는 모델

딥러닝 쓰면 좋다. 근데 왜 안 쓰냐? 안 끝난다. 

특수하게 쓰는 단어를 반영하는 것이 LM. (콜센터, 갤럭시, 아이폰 등)

콜센터 같은 경우는 잘 된다. 

보통 N-gram을 쓴다. 

lexicon을 쓴다? 텍스트라는 것이 단어 안에 토큰으로 이루어져 있고. 

LM 할 때 없던 단어는 아예 안 나온다. 

단어별로 LM을 썼다는 이야기는 사과, 먹다 이런 것이 아니라 LM의 단위로 쓴 것이 아니라 

ㄱ,ㄴ,ㄷ이런 걸 썼다면 사실 단어는 무제한으로 아무렇게 나온다. 굳이 단어를 제한하고 싶다면  LEXICON사용

사람 이름의 경우 Lexicon에는 없다. LM이 강하면 더 인식 못함. 단어가 없기 때문에

사람 이름이나 주민번호를 강하게 하고 싶으면 AM, Lexicon을 써버리면 인식 떨어진다. 

word LM에서 스코어 자체가 안 나오기 때문에 

ㄱ, ㅏ, ㄴ, 가 스코어면 점수가 나오는데 나는, 사과 이런 레벨이면 아예 점수가 없다. 

LM을 word로 할지 letter로 할지 선택이고 word LM을 쓰면 lexicon을 써야 하는데 lexicon에 추가적인 단어를 넣어도 이 LM 만들 때 없는 단어는 애초에 안 나오기 때문에,, 만약 사람 이름 인식이 중요하다면 토큰 LM에 렉시콘 안 쓰는 게 좋다.

근데 토큰 LM에 렉시콘 써도 되고 추가해도 된다. LM에 안 나왔던 단어를 추가하고 싶다면  토큰 LM에 추가 가능하다. 

WORDLM은 추가해도 안 나온다. AM 학습하는 건 무슨 말 해도 상관없음. AM은 단어가 문제가 아니기 때문. 

사전에 없는 게 많이 나오면 토큰 LM이 낫다. 

한국어에 한해서는 LM을 강하게 안 거는 이유는 한국어는 들리는 대로 써도 에러가 10프로 이하. (너무 발음그대로만 쓰면 이상하기 때문에 LM 사용).

영어는 LM이 중요.

들리는데로 쓰면 안 되는 것이 많기 때문.

AM은 음성 트레인마다 글자에 대한 숫자가 어떤 것인지 나오는 것. 띄어쓰기에 대한 스코어가 나오는 것

LM은 텍스트를 ABD, CED가 몇 점인지 스코어가 나오는 것.

AM이 예측한 스코어가 있고, LM이 예측한 스코어가 있을 것.

AM 스코어, LM스코어의 조합상 어느 것이 가장 좋은 것인지 찾는 것

A를 찍으면 몇 점 C를 찍으면 몇점 , 그거에 대한 가중치가 있다.

lexicon을 안 쓰면 저런 스코어 의미 없음.

빔 트레쉬 홀드랑 몇 가지 더 있는데 서치 할 때 사이즈를 얼마로 할지 등등 있다.(사이트 주소 들어가기)

스코어를 어떻게 산출하냐에 따라 결과도 많이 달라진다. 

LM을 무시하고 싶으면 lmseight를 낮추면 되는 것

silweight(silence weight) : 소리가 있는데 묵음으로 나온다? 그럼 silweight를 낮춰서 더 많은 텍스트를 찍게 한다.

띄어쓰기, 사람 소리를 무시하게 할지를 고려하는 것. 

빔 사이즈랑 트레쉬 홀드를 넘어갈 때 바로 써버리는 것도 있다.

통상적으로 트뤠시홀드를 낮추면 서치를 덜하고 높이면 더 한다. 

트뤠시홀드를 낮춰도 결과가 큰 차이가 없다. 높이면 이것저것 탐색해서 결과 아주 미미하게 향상. 

timestep그림에서 제일 높은 스코어에서 나와서 찾게 되는 것.

AM이 어느 정도 성능이 좋으면 이런 스코어 안 따져도 된다. 

그리드 서치와 비슷한 것이라고 보면 된다. 엄밀히 따지면 아니긴 한데 개념이~

 

정답이  a b c가 있고 예측한 것이 a a c 면 중간의 a만 바꿔주면 된다. 차이가 1인 것

정답이 3개고 바꾸는 것이 1개면 에러가 1/3이다.

이렇게 분자와 분모로 계산해서 사용

한국어는 word error rate(띄어쓰기를 기준으로 나눈 것)를 쓰면 을,를, 이, 다가 떨어지지 않는다. 

이거 쓰는 목적이 콜센터에서 사용. 동시에 사용

모델이 RNN계열이면 동시에 해도 순차적으로 돌아가기 때문에 CPU

CNN이면 동시에 돌아가기 때문에?

 

음성파일 들어가서 text로 나오면 끝.

스트리밍은 콜센터의 니즈. 전화기에서 pcm이 바로 떨어져서 스트림으로 넘겨줘서 

VAD는 한 덩이로 ㅈ줬는데 음성인식이 2개더라. 

그럼 두 덩이가 되겠지

vad는 한 사람인지 여러 사람인지 고려 안 하고 한 덩이 던져줌

엔터를 인식했을 때 엔터를 지는 기준? 화자가 바뀌면 엔터를 치고, 문장이 여러 개면 엔터를 치고 등을 하면 한 덩어리라도 여러 사람, 문장을 인식할 수 있다. 그래서 segment start end가 다른 것으로 표시

기본 설정은 문장으로 떨어진다. 띄어쓰기로 떨어지는 것도 가능하다. 

전처리가 프런트 앤드, 탐색 엔진이 빔 서치, 언어 모델은 비슷

언어 모델이 사과를 먹었다 -> 사과/ 를/ 먹는/다 음절단위로 쪼개지는 레벨 ( 기존 ) 

렉시콘은 안 넣었겠지

우리 회사의 경우에는 사전에 안 나온 것을 쓰기 위해 굳이 토큰 lm 쓰고 있다.

발음 사전, 발성 모델은 없다. g2p 강제되고 언어 확장하기 어려움.

g2p 왜 문제? 데이터를 준비할 때 음성과 텍스트를 준비하고 해야 하는데

텍스트로 g2p로 학습시킨 것인데 실제로 텍스트로 발음되는 경우가 없다. 

발음기호로 말한다는 보장이 없다. 

 

그래서 학습이 잘 안된다. 

사람들이 발음이 그대로 하는 것이기 아니기 때문

그렇다고 전사를 다 들을 수도 없다.

음향 모델도 etri는 gmm, lstm, hmm을 썼다. 

음향 모델 우리는 dnn 썼다. 속도 차이 난다. 

etri결과 보면 원래 말을 어떻게 예측할 수 없을 정도로 틀린 결과 내보냄. 

한국어는 굳이 lm을 써야 할까요?