2019년 7월 13일 토요일

음성인식 메모(kaldi) 5 - gmm training 2

「原作者へ」

連絡先を存じ上げませんでしたので、不本意ながら無断で翻訳しました。 
正式に翻訳を許可されたいです。 
gogyzzz@gmail.comでご連絡ください。

다음 포스트의 번역입니다.

http://work-in-progress.hatenablog.com/entry/2018/03/25/111653


이전 편의 연속

학습용 그래프를 생성했다면, alignment를 생성하자.

초기 모델에 대해서는 「bin/align-equal-compiled」 커맨드를 사용한다.

bin/align-equal-compiled ark:fsts.0 ark:mosimosi.ark ark:equal.align.0

균등분할 alignment의 출력 결과는 아래와 같다.

input으로 전달하는 MFCC 파일의 198 프레임을 transition-id로 치환한다.

우변의 colon(:) 이후는 설명용으로 붙인 것이다.

균등분할 alignment (읽기 편하게 수정한 것)

utterance_id_001
  2   1   1   1   1   1  :sil(state0)                 
  8   5   5   5   5   5  :sil(state1)                    
 18  17  17  17  17  17  :sil(state4)              
206 205 205 205 205 205  :M_B(state0)        
208 207 207 207 207 207  :M_B(state1)        
210 209 209 209 209 209  :M_B(state2)        
242 241 241 241 241 241  :O_I(state0)        
244 243 243 243 243 243  :O_I(state1)        
246 245 245 245 245 245  :O_I(state2)        
266 265 265 265 265 265  :S_I(state0)        
268 267 267 267 267 267  :S_I(state1)        
270 269 269 269 269 269  :S_I(state2)        
194 193 193 193 193 193  :I_I(state0)        
196 195 195 195 195      :I_I(state1) 
198 197 197 197 197      :I_I(state2) 
218 217 217 217 217      :M_I(state0)
220 219 219 219 219      :M_I(state1)
222 221 221 221 221      :M_I(state2)
242 241 241 241 241      :O_I(state0)
244 243 243 243 243      :O_I(state1)
246 245 245 245 245      :O_I(state2)
266 265 265 265 265      :S_I(state0)
268 267 267 267 267      :S_I(state1)
270 269 269 269 269      :S_I(state2)
188 187 187 187 187      :I_E(state0)
190 189 189 189 189      :I_E(state1)
192 191 191 191 191      :I_E(state2)
  2   1   1   1   1      :sil(state0)
  6   5   5   5   5      :sil(state1)
 11  10  10  10  10      :sil(state2)
 13  15  15  15  15      :sil(state3)
  7   5   5   5   5      :sil(state1)
 14  15  15  15  15      :sil(state3)
 11  10  10  10  10      :sil(state2)
 14  15  15  15  15      :sil(state3)
 12  10  10  10  10      :sil(state2)
 18  17  17  17  17      :sil(state4)  

상태 전이(state transition)는 학습용 그래프를 기반으로 생성된다.

(gdb) p path
$25 = std::vector of length 49, capacity 64 = {0, 35, 1, 40, 33, 34, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 47, 28, 50, 29, 54, 30, 56, 28, 51, 30, 57, 29, 54, 30, 57, 29, 55, 31, 32}

숫자는 FST의 State-Id에 해당

    // First select path through ifst.
    vector<StateId> path;

결과는 랜덤이 될거라 생각했지만, 10번 반복해도 같다.

소스코드를 보니 kaldi::RandInt의 호출에서 3번째 변수를 전달하지 않는다.

fstext/fstext-utils-inl.h

size_t arc_offset = static_cast<size_t>(kaldi::RandInt(0, num_arcs_tot-1));

생략할 시 디폴트는 NULL이므로 Rand()의 입력은 같은 초기값이 사용되어 실행 결과가 같아진다.

base/kaldi-math.h

// Returns a random integer between first and last inclusive.
int32 RandInt(int32 first, int32 last, struct RandomState* state = NULL);

base/kaldi-math.cc

int32 RandInt(int32 min_val, int32 max_val, struct RandomState* state) {

균등 분할 alignment가 끝났다면 이것을 바탕으로 원래 통계량(statistics)을 구한다.

gmmbin/gmm-acc-stats-ali 0.mdl ark:mosimosi.ark ark:equal.align.0 0.acc

통계량의 출력 포맷은 아래와 같다.

맨 처음 괄호 안에는 transition-id 마다의 count, 그 후엔 pdf-id(phone、HMM-state로 식별 가능하도록 한 것)에 관한 것으로, 점유 수(OCCUPANCY) 인 것을 확인할 수 있다.

 [ 0 9 2 0 0 13 1 1 1 0 12 2 1 1 2 12 0 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 4 1 4 1 5 1 4 1 4 1 0 0 0 0 0 0 5 1 5 1 5 1 0 0 0 0 0 0 4 1 4 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 9 2 9 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 9 2 9 2 0 0 0 0 0 0 ]
<NUMPDFS> 98
<GMMACCS> <VECSIZE> 13 <NUMCOMPONENTS> 1 <FLAGS> 15 <OCCUPANCY>  [ 11 ]
<MEANACCS>  [
  583.025 -77.64178 -50.17585 77.67705 1.827717 -98.23819 141.6106 68.02332 -25.67511 138.0809 -28.37501 51.49424 -60.51704 ]
<DIAGVARACCS>  [
  31450.12 980.6454 1569.188 971.1459 888.6505 4001.74 2254.043 769.4111 1730.576 2365.113 1063.856 679.8729 789.1522 ]
</GMMACCS>
(도중 생략, 나머지 PDF-ID 97개의 내용이 이어진다)
<total_like> -678789.2 <total_frames> 198

이어서 학습을 진행한다.

gmmbin/gmm-est --min-gaussian-occupancy=3 0.mdl 0.acc 1.mdl

학습용 샘플이 적기 때문에 옵션을 추가하였다. 이렇게 하지 않으면 출현 빈도가 적은 pdf-id에 해당하는 모델이 업데이트 되지 않는다.

일부 모델이 초기 상태 그대로라면, 다음에 이어지는 alignment도 실패한다.

 --min-gaussian-occupancy    : MleDiagGmmOptions: Minimum occupancy to update a Gaussian.(float, default = 10)

이어서 alignment를 진행한다.

gmmbin/gmm-align-compiled 1.mdl ark:fsts.0 ark:mosimosi.ark ark:1.ali

이어서 통계량(statistics)를 생성하고, 모델을 학습한다. input만 바뀐 채로 나머지 과정은 이전과 같다.

gmmbin/gmm-acc-stats-ali 1.mdl ark:mosimosi.ark ark:1.ali 1.acc
gmmbin/gmm-est --min-gaussian-occupancy=3 1.mdl 1.acc 2.mdl

(참고)1.acc

 [ 0 8 2 0 0 8 1 0 1 0 24 1 1 0 1 12 0 5 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 1 4 1 6 1 5 1 4 1 5 1 0 0 0 0 0 0 3 1 7 1 5 1 0 0 0 0 0 0 3 1 4 1 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 2 6 2 14 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 4 2 17 2 0 0 0 0 0 0 ]
<NUMPDFS> 98 

<GMMACCS> <VECSIZE> 13 <NUMCOMPONENTS> 1 <FLAGS> 15 <OCCUPANCY>  [ 10 ]
<MEANACCS>  [
  -115.1633 37.34524 52.23244 40.05222 16.03667 8.719225 85.01067 68.30832 11.52509 34.59558 62.21133 -23.4759 -52.60085 ]
<DIAGVARACCS>  [
  1822.415 538.1805 1578.469 610.5429 804.1371 3180.515 1147.177 790.0551 1260.287 790.6093 1341.816 235.106 707.7091 ]
</GMMACCS> 
(도중 생략, 나머지 PDF-ID 97개의 내용이 이어진다)
<total_like> -8444.121 <total_frames> 198 

가장 아랫 부분을 보면 score가 업데이트 되어 있는 것을 확인할 수 있다.

댓글 없음:

댓글 쓰기