我正在尝试使用连接主义时间分类为音频转录编写 Keras 模型。使用主要工作的逐帧分类模型和OCR 示例,我想出了下面给出的模型,我想训练该模型将德语句子的短时傅里叶变换映射到它们的音标。
我的训练数据实际上确实有时间信息,所以我可以用它来训练没有 CTC 的逐帧模型。没有 CTC 损失的逐帧预测模型运行良好(训练准确率 80%,验证准确率 50%)。然而,在没有时间信息的情况下,还有更多潜在的训练数据可用,所以我真的很想换一个 CTC。为了测试这一点,我从数据中删除了时间,将 NULL 类的输出大小增加了一倍,并添加了 CTC 损失函数。
这个 CTC 模型似乎没有学习。总体而言,损失并没有下降(在每个 80 个句子的十几个 epoch 中,它从 2000 下降到 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 示例。