2019. 10. 7. 00:26 ㆍ개발 이야기/머신러닝(딥러닝)
기초로 돌아가서 음성인식 머신러닝 툴인 kaldi에 홈페이지에 존재한
레시피를 참고해서 zeroth 프로젝트의 스크립트를 분석해보고
이에 따라 +@로 가지고 있는 음성 데이터를
어떻게 분리해서 러닝을 시켜야 인식률이 증가할지 리서치해 보았습니다.
먼저 기본적으로 러닝 할 때 사용하고 있는 스크립트를 분석했습니다.
순서대로 흐름을 읽어가 보도록 하겠습니다.
(단순 압축 해제, 다운로드 등의 스크립트는 생략하겠습니다)
압축 해제된 데이터의 모든 파일들을
local/data_prep.sh를 통해 필요한 정보를 추출해 내는 과정입니다.
제로스 데이터에 있는 젠더 정보를 추출합니다 output : spk2gender (추후 사용되지는 않는 것으로 판단됨)
flac 명령어를 통해 음원을 디코딩해서 웨이브로 데이터셋을 만들어줍니다 output : wav.scp
음원 대본 추출 output : text
audio 파일의 발화자 맵핑 output : utt2spk
디렉터리 별로 발화자가 분리되어 있는 것을 확인할 수 있습니다.
utt2spk의 반대 개념의 파일 작성 output : spk2utt
오디오 파일의 duration을 파일명과 매핑합니다 output : utt2dur
위에서 구한 wav.scp를 이용해서 duration을 추출합니다(get_utt2dur.sh 내부 내용)
데이터 split 스크립트에 있는 $nj값에 따라 split을 진행합니다
MFCC 알고리즘에서 사용하는 프레임 개수를 맵핑 output : utt2num_frames
MFCC(Mel Frequency Cepstral Coefficient)는
소리의 특징을 추출하는 기법으로 입력된 소리 전체를 대상으로 하는 것이 아닌, 일정 구간으로 나누어, 이 구간에 대한 스펙트럼을 분석하여 특징을 추출하는 알고리즘
(일반적으로 20~40ms 정도로 Frame을 자름)
칼디 레시피에서는 위에 존재하는 output 들의 설명을 달아 놨는데요
그중에 강조한 부분이 있습니다.
바로 utt2spk 부분인데요 발화자와 오디오를 매핑한 파일로
번역한 코멘트를 참고하면
utt2spk는 해당 스피커에 대한 각 발언의 매핑을 포함한다. 사이드 노트로서, 엔지니어들은 종종 각 녹음 세션이 다른 "스피커"가 되도록 녹음 세션과 함께 스피커라는 용어를 설득할 것이다. 따라서, "스피커"의 개념은 개인과 관련될 필요가 없다. 즉, 녹음 작업에 영향을 미칠 수 있는 방, 억양, 성별 또는 모든 것이 될 수 있다. 그때 스피커 정상화를 수행할 때, 녹음 품질이나 특정 억양 유형으로 인해 실제로 정상화가 효과를 제거하는 것일 수 있다. 이 "스피커"의 정의는 모델러에게 맡겨진다.
추후 스크립트를 분석했을 때 발화자를 기준으로 데이터를 통계내는 것을 알 수 있습니다.
local/updateSegmentaion.sh 에서
형태소(morpheme)를 찾아내서 문장에서 단어를 쪼개서 다시 기입함(data_prep.sh 의 결과물 중
text를 이용하고 기존 결과물을 text.old로 만들고 쪼개진 결과물을 text로 만듭니다.
local/generateExtraLexicon.sh 에서 기존 Lexicon에 존재하지 않는 단어를 추가합니다.
MFCC 과정(특징 벡터 추출)
data_prep.sh 단계에서 생성된 데이터를 이용해서 데이터 아카이브를 생성합니다
마찬가지로 data_prep.sh단계에서 생성된 데이터로 cmvn 데이터를 만듭니다
Cepstral mean and variance normalization(CMVN)
강력한 음성 인식을 위한 계산 효율적인 정규화 기술입니다. CMVN의 성능은 짧은 발화로 인해 저하되는 것으로 알려져 있습니다. 이는 모든 발언이 제로 평균 및 단위 분산을 갖도록 강요되기 때문에 파라미터 추정 및 식별 가능한 정보 손실에 대한 데이터가 충분하지 않기 때문입니다.
CMVN 은 동일한 계수 통계를 갖도록 cepstral 계수를 선형으로 변환하여 강력한 특징 추출을 위해 노이즈 오염에 의한 왜곡을 최소화합니다. Cepstral Normalization은 CMU Sphinx 에서 다양한 음향 환경에서 높은 수준의 인식 정확도를 유지하는 데 효과적입니다
입력 오디오 신호에 대한 cepstral-domin 평균과 분산
이후에 데이터를 split 하고 subset 데이터로 분류해
테스트 데이터를 나누고 train 데이터를 나눠 monophone 모델과 triphone 모델을 만드는 데 사용합니다
Monophone Training steps/train_mono.sh 과정
Triphone Training steps/train_deltas.sh 과정
Monophone 과 Triphone이 뭐냐?
이후에
Triphone Training LDA+MLLT
Triphone Training LDA+MLLT+SAT
트레이닝과 데이터 정렬을 여러 차례 하게 됩니다.
online chain 트레이닝 진입
0.9, 1.1 속도의 데이터 생성하여 다시 make_mfcc.sh, align_fmllr.sh 진행
노이즈를 섞은 음원 데이터 생성
해당 데이터를 이용해 데이터의 subset을 분리함
다시 LDA-MLLT 훈련
train_diag_ubm.sh iVector 추정에 사용할 대각성 UBM을 훈련
모든 train 데이터에 대해 iVector를 추출. 그것이 우리가 시스템을 훈련시키는 것이 될 것이다. --utts-per-spk-max 2로 대본은 발언 내용을 2개로 묶고, 이 두 쌍을 각각 하나의 스피커로 처리한다. 이러한 항목은 '온라인'으로 추출된다는 점에 유의하십시오.
더 많은 수의 스피커를 갖는 것은 일반화에 도움이 되고, 관용 디코딩을 잘 처리한다(iVector는 0에서 시작한다).
연속적인 발언들을 가짜 연설자 ID에 결합해서 일종의 '가짜 연설자 ID'를 만들어라. 불쌍한 남자의 분할 표준 입력에서 이전 utt2spk 읽기,
표준 출력에 새 utt2spk 출력
발화 당 하나의 iVector를 추출하는 대신, 몇 개 프레임마다 하나씩 추출한다(예: --ivector-주기 옵션, 예를 들어 계산 저장용 10에 의해 제어됨). 이것은 온라인 디코딩을 위한 신경 네트워크의 훈련(그리고 실제가 아닌 온라인 테스트)에 사용됨
topo 생성
잔향 데이터(rev1-), 클린 데이터(rev0-)를 생성
'체인' 시스템에서 사용할 트리 작성
xconfig 구문 분석기를 사용하여 신경망 구성 만들기
chain을 이용한 RNN 및 DNN 음향 모델 학습
이후 테스트 데이터 디코딩 로직
다음과 같이 스크립트가 진행이 되며, 얻을 수 있는 힌트는 몇 가지가 있었지만 요약하자면
러닝에 필요한 데이터의 발화자 분리
utt2spk가 적절히 분리되어야만 한다
제로스에서 제공하는 기본 음성 데이터 51시간의 데이터를
발화자가 1명인 것으로 데이터 정보를 바꿔서 러닝을 했습니다(테스트 용도)
무려 30프로나 WER이 높아졌습니다.
음성 데이터를 모아도 적절히 분리되지 않는다면 큰 효과를 볼 수 없습니다.
또한, 데이터 양에 따라 스크립트 내에 파라미터를 변경이 필요
이 외에도 노이즈를 키워서 러닝을 시키거나,
노이즈를 삽입한 데이터를 이용해 러닝을 시키는 등
노이즈를 이용한 많은 부분 테스트를 해보고 싶지만 물리적으로 시간이 주워지지 않았습니다.
(테스트를 진행 예정입니다)
분명히 효과를 볼 수 있는 방법들이 더 존재할 거라 생각합니다.
다른 부분들도 많이 테스트해주시고 혹시 추가적으로 효과를 볼 수 있는 방법이 있다면 댓글로 알려주시면 감사하겠습니다.
'개발 이야기 > 머신러닝(딥러닝)' 카테고리의 다른 글
#1 인공신경망 동작 원리 - 예측자, 분류자 (0) | 2020.02.05 |
---|---|
#6 음성인식 노이즈 제거2 (0) | 2019.10.11 |
#Back to basic 머신러닝이란? (0) | 2019.09.29 |
#5 음성인식 노이즈 제거 (15) | 2019.09.20 |
#4 음성인식 KALDI 툴을 이용한 한국어 음성인식(zeroth project) (69) | 2019.08.18 |