Проблемы с объединением вложенных категориальных и числовых переменных для использования в LSTM

Вопрос или проблема

Я новичок здесь и в глубоких обучения, поэтому заранее прошу прощения за неправильно форматированный код или формулировки. У меня есть набор данных, где я отслеживаю 4 переменные с 2 категориальными и 3 числовыми полями на 4 временных этапах.

Мне удалось построить фрейм данных следующим образом:

входное описание изображения здесь

  1. cat1 – переменные с закодированными метками SckitLearn
  2. cat2 – временные этапы с закодированными метками SckitLearn
  3. num1 : num3 – нормализованные переменные SckitLearn

Я смог преобразовать это в список массивов numpy следующим образом:

входное описание изображения здесь

Я хочу внедрить и объединить все эти поля перед подачей в LSTM в Keras, используя эту функцию:

def build_concat(df):
  global inputs
  inputs = []
  global embeddings
  embeddings = []
  cat_cols = df.filter(like="cat")
  num_cols = df.filter(like="num")
  for cat_col in cat_cols:
    cat_input = Input(shape=(4,4), name=cat_col)
    unique_cat = cat_cols[cat_col].nunique()
    embedding_size = min(np.ceil((unique_cat)/2), 20)
    embedding_size = int(embedding_size)
    cat_dim = unique_cat + 1
    inputs.append(cat_input)
    embeddings.append(Embedding(cat_dim, embedding_size, input_length = (4,4),
        name=str(cat_col) + "_emb")(cat_input))
  for num_col in num_cols:
    num_input = Input(shape=(4,4), name=num_col)
    inputs.append(num_input)
    embeddings.append(num_input)

Но я получаю эту ошибку :

ValueError: Shape must be rank 3 but is rank 2 for ‘{{node so2_model/concat/concat}} = ConcatV2[N=5, T=DT_FLOAT, Tidx=DT_INT32](so2_model/cat1_emb/embedding_lookup/Identity_1, so2_model/cat2_emb/embedding_lookup/Identity_1, IteratorGetNext:2, IteratorGetNext:3, IteratorGetNext:4, so2_model/concat/concat/axis)’ with input shapes: [2,4,2], [2,4,2], [2,4], [2,4], [2,4], [].

Это мой список внедрений :

[<KerasTensor: shape=(None, 4, 4, 2) dtype=float32 (созданный слоем ‘cat1_emb’)>, <KerasTensor: shape=(None, 4, 4, 2) dtype=float32 (созданный слоем ‘cat2_emb’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num1’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num2’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num3’)>]

Это мой список входных данных перед внедрением :

[<KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘cat1’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘cat2’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num1’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num2’)>, <KerasTensor: shape=(None, 4, 4) dtype=float32 (созданный слоем ‘num3’)>]

Спасибо за вашу помощь!

Вам следует изменить форму ваших числовых слоев так, чтобы они имели форму (None,4,4,1). Для конкатенации вам нужно, чтобы все, кроме одной оси, были равны.

Если вы использовали:

tf.keras.layers.Reshape((4,4,1))(num_input)

это должно сработать.

Ответ или решение

При работе с набором данных, содержащим как категориальные, так и численные переменные, для использования в LSTM (Long Short-Term Memory) моделях часто возникают проблемы с конкатенацией этих переменных. Давайте подробно проанализируем основные трудности, которые могут возникнуть в этом контексте, а также предложим возможные решения.

Проблема конкатенации переменных

В вашем случае вы имеете дело с двумя категориальными переменными и тремя числовыми полями, за которыми вы следите в течение четырех временных диапазонов. Проблема, с которой вы столкнулись, связана с несовпадением форматов данных при попытке конкатенировать результирующие тензоры перед подачей их в модель LSTM.

Из сообщения об ошибке:

ValueError: Shape must be rank 3 but is rank 2 for '{{node so2_model/concat/concat}}...

выявляется, что проблема заключается в несоответствии размерностей тензоров. Чтобы конкатенировать тензоры, нужно, чтобы все, кроме одной оси (в данном случае это может быть ось временного компонента), имели одинаковую размерность.

Описание источников проблемы

  1. Размерность тензоров:

    • Ваша ошибка указывает на наличие тензоров с различными размерностями. Для категориальных переменных (после применения слоя Embedding) вы получаете тензоры размерности (None, 4, 4, 2), что служит корректным представлением для категориальных признаков. Но для числовых переменных у вас тензоры размерности (None, 4, 4), что не позволяет выполнить конкатенацию.
  2. Форма для числовых данных:

    • Как было правильно замечено, для числовых переменных необходимо изменить размерность с (None, 4, 4) на (None, 4, 4, 1). Это можно сделать с помощью слоя Reshape: tf.keras.layers.Reshape((4, 4, 1))(num_input). Это приведет к тому, что все входные данные будут иметь согласованную размерность для выполнения конкатенации.

Решение проблемы

Для того чтобы корректно конкатенировать ваши тензоры, рекомендуется внести следующие изменения в ваш код:

for num_col in num_cols:
    num_input = Input(shape=(4, 4), name=num_col)
    num_input_reshaped = tf.keras.layers.Reshape((4, 4, 1))(num_input)  # Изменение размерности
    inputs.append(num_input)
    embeddings.append(num_input_reshaped)

Таким образом, после этих изменений все тензоры в embeddings будут иметь размерности (None, 4, 4, X), что позволит вам выполнить конкатенацию без возникновения ошибок.

Заключение

Ключ к решению проблем с конкатенацией категориальных и числовых переменных для их дальнейшего использования в LSTM моделях заключается в согласовании размерностей тензоров. Убедитесь, что все тензоры имеют совместимую размерность, что позволяет избежать проблем, связанных с терминами и формами входных данных. С этими изменениями ваш код должен успешно выполнять конкатенацию и подготавливаться к дальнейшему обучению модели.

Надеюсь, эта информация была полезной для вас. Если у вас есть дополнительные вопросы или вам нужна дальнейшая помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...