ichou1のブログ

主に音声認識、時々、データ分析のことを書く

音声認識メモ(Kaldi)その9(pre-training Karel's DNN)

事前学習の流れを追ってみる。

インプットとなる音声は連続値であるから、GB(Gaussian-Bernoulli)型の制限付きボルツマンマシン(RBM)を使う。

  • 可視層(visible):Gaussian、連続値をとる
  • 隠れ層(hidden):Bernoulli、離散値をとる


nnet(Karel's DNN)では、「nnetbin/rbm-train-cd1-frmshuff」コマンドを実行する。

nnetbin/rbm-train-cd1-frmshuff 1.rbm.init ark:mosimosi.ark 1.rbm

「1.rbm.init」は「nnetbin/nnet-initialize」コマンドに以下のprototypeをインプットとして渡して生成。

<NnetProto>
<Rbm> <InputDim> 13 <OutputDim> 16 <VisibleType> gauss <HiddenType> bern <ParamStddev> 0.1
</NnetProto>

下図は可視層を「13」、隠れ層を「16」として図示したもの。
データを保持する行列は、ソース中の変数名で記している。
f:id:ichou1:20180409193159p:plain
mini : mini-batch size
( ) x ( )は行列を表す(row x col)

まず、forward-passを求める。

pos_vis

特徴量からミニバッチファイル分(今回の例ではデフォルト値の「100」)取り出して、フレームの順番をランダムに並べかえる
f:id:ichou1:20180409195957p:plain

vis_hid

「1.rbm.init」、隠れ層のパラメータ
f:id:ichou1:20180409200628p:plain

pos_hid

「pos_vis」と「vis_hid」(Transpose)の乗算
f:id:ichou1:20180409201714p:plain

pos_hid(sigmoid適用後)

f:id:ichou1:20180409201838p:plain

これにランダム値を加え、[-1..1]の範囲になるように調整する。
さらに、Heaviside step functionを適用する(0より大きければ「1」、0以下なら「0」)

pos_hid_aux

f:id:ichou1:20180409203649p:plain

これに、「vis_hid」(隠れ層パラメータ、16row x 13col)を乗算したものが「neg_vis」になる。

neg_vis

f:id:ichou1:20180409204305p:plain

「pos_vis」と同様に、「neg_vis」に対してforward-passを求める。

neg_hid(sigmoid適用後)

f:id:ichou1:20180409204344p:plain

これまでに得られた4つの行列「pos_vis」、「neg_vis」、「pos_hid」、「neg_hid」をもとに、隠れ層のパラメータ「vis_hid」を更新する。

まず、「neg_hid」(100row x 16col、Transpose) と「neg_vis」(100row x 13col)を乗算する。
f:id:ichou1:20180409205330p:plain

これに、「pos_hid」(100row x 16col、Transpose) と「pos_vis(100row x 13col)」を乗算したものを足す。

加算結果

f:id:ichou1:20180409205919p:plain

さらに、「vis_hid」にlearning-rateとL2正則化パラメータを掛けたものを足す。

この結果を「vis_hid」に足しあわせたものが更新後のパラメータになる。

vis_hid

f:id:ichou1:20180409210909p:plain

f:id:ichou1:20180409210919p:plain