DBN+DNN的结构问题(含bottleneck)

假期之前遇到一个问题一直在困扰着我,先用DBN做pretrain的时候,那么DNN的层数以及每层的结构该怎么设计呢?匆匆忙忙的三四天假期结束了,先解决一下这个问题。

先来看一下,之前做的一个wsj的一个demo,用的原始的配置:

  hidlayers=2
  hiddims=512
  #训练dbn的脚本,两层的RBM 隐层维数是512
  steps/nnet/pretrain_dbn.sh --rbm-iter 3 --nn-depth $hidlayers --hid-dim $hiddims \
    data/fmllr_${gmmname}/train_data $dir
  #训练dnn的脚本,用的上面pretrain生成的feature_transform 和 dbn, 注意:--hid-layers 0,也没有hidden_dim的参数
  steps/nnet/train.sh --feature-transform $feature_transform --dbn $dbn --hid-layers 0 --learn-rate 0.004 data/fmllr_${gmmname}/train_data data/fmllr_${gmmname}/test_data data/lang ${ali}_train \ ${ali}_test $dir || exit 1;

下面分别看一下生成的网络拓扑图:

#1.rbm.proto
<Rbm> <InputDim> 462 <OutputDim> 512 <VisibleType> gauss <HiddenType> bern <ParamStddev> 0.1
#2.rbm.proto
<Rbm> <InputDim> 512 <OutputDim> 512 <VisibleType> bern <HiddenType> bern <ParamStddev> 0.1 <VisibleBiasCmvnFilename> exp/pretrain_lstm_2_512_recurrent/2.cmvn
#nnet.proto, 这里用的lstm,AffineTransform是输出层
<NnetProto>
<LstmProjectedStreams> <InputDim> 462 <OutputDim> 512 <CellDim> 800 <ParamScale> 0.010000 <ClipGradient> 5.000000
<LstmProjectedStreams> <InputDim> 512 <OutputDim> 512 <CellDim> 800 <ParamScale> 0.010000 <ClipGradient> 5.000000
<AffineTransform> <InputDim> 512 <OutputDim> 1979 <BiasMean> 0.0 <BiasRange> 0.0 <ParamStddev> 0.040000
<Softmax> <InputDim> 1979 <OutputDim> 1979
NnetProto>

初步总结一下结论(不确定,具体问一下作者再来补充): dnn隐层的个数等于dbn的层数,并且前两层的维数保持与之前dbn的结构一致(不设置隐层维数参数)。

但是现在我们需要加bottleneck layer:
dnn_hidden_layer=0
scripts/train.sh –splice 5 –dbn dbnfeaturetransformfeature_transform –hid-layers dnnhiddenlayerbndimbn_dim
–learn-rate 0.004 12 34 $5 || exit 1;

#command: /home/zjm/kaldi/src/nnetbin/nnet-info exp/train_0_512/nnet_dbn_dnn.init
#results:
num-components 11
input-dim 286
output-dim 48
number-of-parameters 0.828464 millions
component 1 : <AffineTransform>, input-dim 286, output-dim 512, 
  linearity ( min -1.00076, max 1.05867, mean -0.000582807, stddev 0.0549108, skewness 1.95299, kurtosis 34.2073 ) , lr-coef 1, max-norm 0
  bias ( min -5.15176, max 3.76015, mean -2.61085, stddev 1.22834, skewness 0.860572, kurtosis 1.58346 ) , lr-coef 1
component 2 : <Sigmoid>, input-dim 512, output-dim 512, 
component 3 : <AffineTransform>, input-dim 512, output-dim 512, 
  linearity ( min -2.07009, max 2.73179, mean -0.0121263, stddev 0.133941, skewness 1.1626, kurtosis 18.9128 ) , lr-coef 1, max-norm 0
  bias ( min -26.1294, max 18.4352, mean -3.11283, stddev 3.36512, skewness -2.40273, kurtosis 16.4141 ) , lr-coef 1
component 4 : <Sigmoid>, input-dim 512, output-dim 512, 
component 5 : <AffineTransform>, input-dim 512, output-dim 512, 
  linearity ( min -1.85442, max 2.6435, mean -0.0147206, stddev 0.137383, skewness 1.64592, kurtosis 23.7388 ) , lr-coef 1, max-norm 0
  bias ( min -5.55276, max 1.51492, mean -2.62382, stddev 0.815517, skewness -0.163322, kurtosis 2.72185 ) , lr-coef 1
component 6 : <Sigmoid>, input-dim 512, output-dim 512, 
component 7 : <LinearTransform>, input-dim 512, output-dim 128, 
  linearity ( min -0.588584, max 0.635746, mean 0.000682702, stddev 0.147005, skewness 0.00623861, kurtosis -0.00738311 ) , lr-coef 0.1
component 8 : <AffineTransform>, input-dim 128, output-dim 512, 
  linearity ( min -0.571826, max 0.64164, mean -0.000542065, stddev 0.146909, skewness 0.00927952, kurtosis 0.00426197 ) , lr-coef 0.1, max-norm 0
  bias ( min -3.98881, max -0.00461864, mean -1.98305, stddev 1.12245, skewness -0.0044525, kurtosis -1.14907 ) , lr-coef 0.1
component 9 : <Sigmoid>, input-dim 512, output-dim 512, 
component 10 : <AffineTransform>, input-dim 512, output-dim 48, 
  linearity ( min -0.926078, max 0.86341, mean 0.0022525, stddev 0.209632, skewness -0.00951353, kurtosis 0.0446613 ) , lr-coef 1, max-norm 0
  bias ( min 0, max 0, mean 0, stddev 0, skewness -nan, kurtosis -nan ) , lr-coef 0.1
component 11 : <Softmax>, input-dim 48, output-dim 48, 

注意:这里的nnet.proto只有bottleneck layer + affinetransform + softmax. 并不是最后生成的网络拓扑图。因为train.sh中进行了:
nnet-concat “dbn"nnet_init_old $nnet_init
将dbn 和 nnet.proto 共同生成了 nnet_init(exp/train_0_512/nnet_dbn_dnn.init), 所以我们上面的结论是正确的,想知道具体的信息还得去看train.sh。

---》 补充
经过一段时间的使用,可以发现在总层数确定的情况下,DBN的层数不一定越多越好。 Kaldi默认是BN层是在输出层的前边的全联接层的前边,并且通过train.sh添加的DNN层数在BN的前边,所以整体结构是这样的:
“n层DBN + m层DNN + BN + 全连接层(48*1024 +sigmoid) + output(1024 * 600 + softmax)”
我们假设的BN层是固定的48位,输出层的lables是600个
还有一个DBN生成的结构跟DNN是一样的夜市输出+sigmoid激活层(核函数)
NOTE: 综上不要去加 remove-last-compnents 参数,除非你想用deep feature.
嗯嗯,核函数,是个好问题,可以去知乎学习一下

你可能感兴趣的:(ASR,kaldi)