CTC модель не учится

Я пытаюсь запрограммировать модель Keras для транскрипции звука, используя временную классификацию соединений. Используя в основном работающую модель покадровой классификации и пример OCR, я придумал модель, приведенную ниже, которую я хочу обучить отображению кратковременного преобразования Фурье немецких предложений в их фонетическую транскрипцию.

Мои тренировочные данные на самом деле содержат информацию о времени, поэтому я могу использовать ее для обучения по рамочной модели без CTC. Модель прогнозирования по кадрам без потери CTC работает прилично (точность обучения 80%, точность проверки 50%). Тем не менее, существует гораздо больше потенциальных учебных данных без информации о времени, поэтому я действительно хочу сменить CTC. Чтобы проверить это, я удалил синхронизацию из данных, увеличил размер вывода на единицу для класса NULL и добавил функцию потери CTC.

Эта модель CTC, кажется, не учиться. В целом, потери не уменьшаются (они уменьшились с 2000 до 180 в дюжине эпох по 80 предложений каждое, но затем вернулись к 430), и максимальный выход правдоподобия, который он производит, колеблется вокруг [nh каждое из всех предложений, которые обычно имеют около шести слов и транскрипций, таких как [foːɐmʔɛsndʰaɪnəhɛndəvaʃn] - [] являются частью последовательности, представляющей паузу в начале и конце аудио.

Мне трудно найти хорошие объяснения КТК в Керасе, поэтому, возможно, я сделал что-то глупое. Я испортил модель, перепутав где-то порядок аргументов? Должен ли я быть более осторожным в обучении модели, начиная с аудио-фрагментов с одним, двумя или, может быть, тремя звуками, прежде чем дать модели законченные предложения? Короче,

Как мне научиться этой модели 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 ответ

Он полностью невидим в приведенном здесь коде, но в других местах OP дает ссылки на их репозиторий Github. Ошибка на самом деле заключается в подготовке данных:

Данные являются логограммами спектрограмм. Они ненормализованы и в основном крайне негативны. Функция 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
Другие вопросы по тегам