「原作者へ」
連絡先を存じ上げませんでしたので、不本意ながら無断で翻訳しました。
正式に翻訳を許可されたいです。
gogyzzz@gmail.comでご連絡ください。
아래 포스트의 번역입니다.
http://work-in-progress.hatenablog.com/entry/2018/08/12/123334
음성인식 메모(kaldi) 20 - Training Dan's DNN(nnet2)의 연장.
mixup 후에 생성된 12개의 모델(14.mdl〜25.mdl)에서 「final.mdl」을 생성하는 과정을 추적해보자.
nnet2에는 결과가 좋은 모델을 하나만 고르지 않고 (여러 모델에?) 스케일을 곱한 다음 더하는 방식을 취한다.
생성은 「nnet2bin/nnet-combine-fast」 커맨드를 사용하여 모델을 combine(합성)한다.
nnet-combine-fast \
--minibatch-size=129 \
exp/nnet4c/14.mdl \
exp/nnet4c/15.mdl \
<snip> \
exp/nnet4c/25.mdl \
ark:exp/nnet4c/egs/combine.egs \ # <valid-examples-in>
exp/nnet4c/final.mdl
이번 케이스에선 모델의 Component 수가 「9」、Updatable-Component 수가 「3」
info 커맨드(nnet2bin/nnet-am-info exp/nnet4c/14.mdl )
num-components 9
num-updatable-components 3
input-dim 40
output-dim 192
component 0 : SpliceComponent, input-dim=40, output-dim=360, ...
component 1 : FixedAffineComponent, input-dim=360, output-dim=360, ...
component 2 : AffineComponentPreconditionedOnline, input-dim=360, output-dim=375, ...
component 3 : TanhComponent, input-dim=375, output-dim=375
component 4 : AffineComponentPreconditionedOnline, input-dim=375, output-dim=375, ...
component 5 : TanhComponent, input-dim=375, output-dim=375
component 6 : AffineComponentPreconditionedOnline, input-dim=375, output-dim=453, ...
component 7 : SoftmaxComponent, input-dim=453, output-dim=453
component 8 : SumGroupComponent, input-dim=453, output-dim=192
index이 2、4、6인 「AffineComponentPreconditionedOnline」 컴포넌트 (Updatable-Component에 해당)가 합성 대상이 된다.
결과를 먼저 쓰자면, 각 모델, 각 컴포넌트에 대해 아래와 같은 스케일이 할당된다.
각 모델, 컴포넌트마다의 스케일
스케일을 구하는 과정을 따라가보자.
업데이트에 있어서의 평가 척도는 Propagate의 값(Log값)이 된다.(값이 작을수록 좋다)
같은 데이터(exp/nnet4c/egs/combine.egs)에 대한 모델의 값은 아래와 같이 되어 있다.
14.mdl : -0.0753596
15.mdl : -0.0679429
16.mdl : -0.0373454
17.mdl : -0.0325585
18.mdl : -0.0286209
19.mdl : -0.0237487
20.mdl : -0.0209156
21.mdl : -0.00755152
22.mdl : -0.0101945
23.mdl : -0.00779286
24.mdl : -0.00615664
25.mdl : -0.00456561
이번 케이스에서는 「25.mdl」의 「-0.00456561」가 가장 좋은 값이므로, 그 값을 기준으로 더욱 좋은 값을 얻을 수 있는 스케일을 구해보자.
스케일의 최적해는 뉴턴 메소드 (L-BFGS)를 사용하여 구한다.
소스 코드의 내용(nnet2/combine-nnet-fast.cc)
OptimizeLbfgs<double> lbfgs(params_,
lbfgs_options);
// Loop 10 times
for (int32 i = 0; i < config_.num_lbfgs_iters; i++) {
// 스케일을 세팅
params_.CopyFromVec(lbfgs.GetProposedValue());
// Propagate의 값과 gradient를 구한다
objf = ComputeObjfAndGradient(&gradient, ®ularizer_objf);
if (i == 0) {
initial_objf = objf;
initial_regularizer_objf = regularizer_objf;
}
// 판정과 스케일을 업데이트
lbfgs.DoStep(objf, gradient);
} // end of for(i)
각 루프 단계에서 Propagate의 값과 판정은 아래와 같았다.
(i=0) -0.00456561
(i=1) -0.310829 action = decrease
(i=2) -0.0201834 action = decrease
(i=3) -0.00512826 action = decrease
(i=4) -0.00410415 action = accept
(i=5) -0.00352887 action = accept
(i=6) -0.00315388 action = accept
(i=7) -0.00228854 action = accept
(i=8) -0.000916785 action = accept
(i=9) -0.000539656 action = accept
루프 카운터가 「9」일 때의 값 「-0.000539656」가 가장 좋았기 때문에, 이 때의 스케일이 최적해가 된다.
params_ = lbfgs.GetValue(&objf);
댓글 없음:
댓글 쓰기