CTC模型不学习

时间:2018-12-06 02:36:31

标签: python machine-learning keras ctc

我正在尝试使用连接主义的时间分类对Keras模型进行音频转录编程。使用一个工作效率最高的框架分类模型和OCR example,我想到了下面给出的模型,我想训练该模型来将德语句子的短时傅立叶变换映射到其语音转录。

我的训练数据实际上具有时序信息,因此我可以使用它来训练没有CTC的逐帧模型。没有CTC损失的逐帧预测模型工作得很好(训练精度为80%,验证精度为50%)。 但是,在没有计时信息的情况下,还有更多潜在的训练数据可用,因此我真的想切换CTC。为了测试这一点,我从数据中删除了时序,将NULL类的输出大小增加了一个,并添加了CTC损失函数。

此CTC模型似乎无法学习。总体而言,损失并没有减少(从2000年的80个句子的十几个时期减少到180个,然后又增加到430个),并且它产生的最大似然输出都在[nh周围爬行通常包含大约六个单词的句子中的[foːɐmʔɛsndʰaɪnəhɛndəvaʃn][]等转录是序列的一部分,表示音频开始和结束处的停顿。

我发现很难在Keras中找到关于CTC的很好的解释,所以可能我做了一些愚蠢的事情。我是否弄乱了模型,在某个地方混淆了参数的顺序?在给模型完整的句子之前,我是否需要更加谨慎地训练模型,可能从音频片段开始,每个片段具有一种,两种或三种声音。简而言之,

我如何学习该CTC模型?

connector = inputs
for l in [100, 100, 150]:
    lstmf, lstmb = Bidirectional(
        LSTM(
            units=l,
            dropout=0.1,
            return_sequences=True,
        ), merge_mode=None)(connector)

    connector = keras.layers.Concatenate(axis=-1)([lstmf, lstmb])

output = Dense(
    units=len(dataset.SEGMENTS)+1,
    activation=softmax)(connector)

loss_out = Lambda(
    ctc_lambda_func, output_shape=(1,),
    name='ctc')([output, labels, input_length, label_length])

ctc_model = Model(
    inputs=[inputs, labels, input_length, label_length],
    outputs=[loss_out])
ctc_model.compile(loss={'ctc': lambda y_true, y_pred: y_pred},
                  optimizer=SGD(
                      lr=0.02,
                      decay=1e-6,
                      momentum=0.9,
                      nesterov=True,
                      clipnorm=5))

ctc_lambda_function和根据预测生成序列的代码来自OCR示例。

1 个答案:

答案 0 :(得分:0)

从这里给出的代码中完全看不到它,但是在其他地方,OP提供了指向其Github repository的链接。错误实际上在于数据准备:

数据是对数频谱图。他们是不规范的,而且大多是负面的。 CTC功能获取标签的一般分布的速度比LSTM层适应其输入偏差和输入权重的速度快得多,因此输入中的所有变化都可以被压平。当尚未假定标签的边缘化分布时,则损失的局部最小值可能来自纪元。

解决方案是缩放输入频谱图,使其包含正值和负值:

for i, file in enumerate(files):
    sg = numpy.load(file.with_suffix(".npy").open("rb"))
    spectrograms[i][:len(sg)] = 2 * (sg-sg.min())/(sg.max()-sg.min()) - 1
相关问题