Вопрос или проблема
надеюсь, у вас все хорошо!
Я работаю над автоматическим распознаванием речи с Python и набором данных LibriSpeech.
После предварительной обработки аудиоданных и применения “MFCC признаков” я добавляю все в список и получаю форму (14174,)
. Зная, что каждая выборка имеет разную длину, но одинаковое количество признаков, например:
print(X[0].shape)
print(X[12000].shape)
>> (615, 13)
>> (301, 13)
Теперь, когда я подаю данные в свою сеть с определенным входным слоем как
input_data = Input(name="the_input", shape=(None, input_dim)) # с input_dim = 13 MFCC признаков
я получаю следующую ошибку
ValueError: Error when checking input: expected the_input to have 3 dimensions, but got array with shape (14174, 1)
Я пробовал изменить форму с разными параметрами, но все еще сталкиваюсь с трудностями.
Это модель
def final_model(input_dim, units, output_dim=29):
""" Построить двунаправленную рекуррентную сеть для речи
"""
# Основной акустический вход
input_data = Input(name="the_input", shape=(None, input_dim))
# =============== 1-й слой =============== #
# Добавить двунаправленный рекуррентный слой
bidirectional_rnn = Bidirectional(GRU(units, activation=None,return_sequences=True, implementation=2, name="bidir_rnn"))(input_data)
# Добавить пакетную нормализацию
batch_normalization = BatchNormalization(name = "batch_normalization_bidirectional_rnn")(bidirectional_rnn)
# Добавить функцию активации
activation = Activation('relu')(batch_normalization)
# Добавить Dropout
#drop = Dropout(rate = 0.1)(activation)
# =============== 2-й слой =============== #
# Добавить двунаправленный рекуррентный слой
bidirectional_rnn = Bidirectional(GRU(units, activation=None,return_sequences=True, implementation=2, name="bidir_rnn"))(activation)
# Добавить пакетную нормализацию
batch_normalization = BatchNormalization(name = "bn_bidir_rnn_2")(bidirectional_rnn)
# Добавить функцию активации
activation = Activation('relu')(batch_normalization)
# Добавить Dropout
#drop = Dropout(rate = 0.1)(activation)
# =============== 3-й слой =============== #
# Добавить слой TimeDistributed(Dense(output_dim))
time_dense = TimeDistributed(Dense(output_dim))(activation)
# Добавить слой с активацией softmax
y_pred = Activation('softmax', name="softmax")(time_dense)
# Указать модель
model = Model(inputs=input_data, outputs=y_pred)
model.output_length = lambda x: x
print(model.summary())
return model
Спасибо
Ваши ввода имеют разную длину, поэтому, как предложил @skrrrt, вам следует дополнить ваши данные и применить маскирование в вашей модели.
Следующее дополняет все ваши ввода значениями 0.
, чтобы все последовательности имели одинаковую длину.
from tensorflow.keras.preprocessing.sequence import pad_sequences
padded_inputs = pad_sequences(X, padding="post", dtype="float")
Вы можете выбрать, какое значение использовать для дополнения, с параметром value=0.0
(документация)
Затем добавьте слой маскировки сразу после вашего входного слоя в вашей модели.
# Основной акустический вход
input_data = Input(name="the_input", shape=(None, input_dim))
masked_input = Masking(mask_value=0.0)(input_data)
bidirectional_rnn = Bidirectional(GRU(units, activation=None,return_sequences=True, implementation=2, name="bidir_rnn"))(masked_input)
Обратитесь к этому учебнику для получения дополнительной информации.
Ответ или решение
Ваша проблема связана с несоответствием ожидаемых и фактических размеров входных данных в вашей модели автоматического распознавания речи на языке Python с использованием набора данных LibriSpeech. Ошибка ValueError: Error when checking input: expected the_input to have 3 dimensions, but got array with shape (14174, 1)
указывает на то, что ваша модель ожидает данные с тремя измерениями, однако получает массив с двумя.
Причины возникновения ошибки
-
Неправильная форма входных данных: Ваша модель ожидает входы формы
(None, input_dim)
, что эквивалентно (длина последовательности, количество признаков). Однако после обработки MFCC, ваши данные имеют нефиксированную длину для каждого примера. Выходит, что ваши данные неправильно упакованы и воспринимаются как двумерный массив с одной строкой и одной колонкой. -
Неоднородная длина последовательностей: Разные длины сигналов после извлечения признаков MFCC требуют приведения их к общему формату перед подачей в нейросеть.
Решение проблемы
1. Пакетное выравнивание данных
Учитывая разнообразие длины ваших входных данных, вам необходимо выровнять последовательности. Это делается посредством padding:
from tensorflow.keras.preprocessing.sequence import pad_sequences
# Выровняем последовательности с добавлением нулей в конце (padding='post')
padded_inputs = pad_sequences(X, padding="post", dtype="float")
Используйте pad_sequences()
для того, чтобы ваши входные данные имели одинаковую длину и формат (samples, time_steps, features)
. Для этого введите параметр padding='post'
, который добавит нули в конец более коротких последовательностей, а параметр dtype="float"
обеспечит совместимость типов данных.
2. Добавление Masking слоя в архитектуру модели
После выравнивания данных полезно использовать маскирование, чтобы избежать влияния padding значений на обучение модели:
from tensorflow.keras.layers import Masking
# Добавляем слой Masking после входного слоя
input_data = Input(name="the_input", shape=(None, input_dim))
masked_input = Masking(mask_value=0.0)(input_data)
# Далее продолжайте с первоначальной архитектурой
bidirectional_rnn = Bidirectional(GRU(units, activation=None, return_sequences=True, implementation=2, name="bidir_rnn"))(masked_input)
Используя Masking
, вы отключаете нулевые значения в padded последовательностях, позволяя модели игнорировать эти позиции при обучении.
Преимущества подхода
-
Оптимизация: Выравнивание и маскирование позволяют вашему нейросетевому решению быть более эффективным и точным в обработке различной длины входных данных.
-
Универсальность: Эти изменения делают ваш код более устойчивым и масштабируемым для работы с произвольными длинами входных данных без дополнительных манипуляций с данными.
-
Улучшение точности: Исключение влияния padding значений позволяет модели концентрироваться исключительно на значимой информации, повышая точность предсказаний.
Следуя вышеперечисленным рекомендациям, вы сможете устранить возникшую ошибку, подать данные в нужном формате и улучшить производительность вашей модели.