Тренируйте только некоторые вложения слов (Керас)

В моей модели я использую предварительно обученные вложения GloVe. Я хочу, чтобы они не тренировались, чтобы уменьшить количество параметров модели и избежать переобучения. Однако у меня есть специальный символ, вложение которого я хочу обучить.

Используя предоставленный Уровень Вложения, я могу использовать только параметр "обучаемый", чтобы установить обучаемость всех вложений следующим образом:

embedding_layer = Embedding(voc_size,
                        emb_dim,
                        weights=[embedding_matrix],
                        input_length=MAX_LEN,
                        trainable=False)

Есть ли решение на уровне Keras для обучения только подмножеству вложений?

Пожалуйста, обратите внимание:

  1. Недостаточно данных для создания новых вложений для всех слов.
  2. Эти ответы относятся только к нативному TensorFlow.

2 ответа

Решение

Найден хороший обходной путь, вдохновленный двумя слоями вложений Кейта.

Смысл:

Назначьте специальные токены (и OOV) с самыми высокими идентификаторами. Создайте "предложение", содержащее только специальные токены, дополненные нулями в других местах. Затем примените необучаемые вложения к "нормальному" предложению и обучаемые вложения к специальным токенам. Наконец, добавьте оба.

Работает нормально для меня.

    # Normal embs - '+2' for empty token and OOV token
    embedding_matrix = np.zeros((vocab_len + 2, emb_dim))
    # Special embs
    special_embedding_matrix = np.zeros((special_tokens_len + 2, emb_dim))

    # Here we may apply pre-trained embeddings to embedding_matrix

    embedding_layer = Embedding(vocab_len + 2,
                        emb_dim,
                        mask_zero = True,
                        weights = [embedding_matrix],
                        input_length = MAX_SENT_LEN,
                        trainable = False)

    special_embedding_layer = Embedding(special_tokens_len + 2,
                            emb_dim,
                            mask_zero = True,
                            weights = [special_embedding_matrix],
                            input_length = MAX_SENT_LEN,
                            trainable = True)

    valid_words = vocab_len - special_tokens_len

    sentence_input = Input(shape=(MAX_SENT_LEN,), dtype='int32')

    # Create a vector of special tokens, e.g: [0,0,1,0,3,0,0]
    special_tokens_input = Lambda(lambda x: x - valid_words)(sentence_input)
    special_tokens_input = Activation('relu')(special_tokens_input)

    # Apply both 'normal' embeddings and special token embeddings
    embedded_sequences = embedding_layer(sentence_input)
    embedded_special = special_embedding_layer(special_tokens_input)

    # Add the matrices
    embedded_sequences = Add()([embedded_sequences, embedded_special])

Я не нашел хорошего решения, как маска для слоя Embedding. Но вот что я хотел попробовать:

  • Два встраиваемых слоя - один обучаемый, а другой нет
  • Не обучаемый имеет все вложения Glove для слов in-vocab и нулевых векторов для других
  • Обучаемый только наносит на карту слова OOV и специальные символы
  • Вывод этих двух слоев добавлен (я думал об этом как ResNet)
  • Conv/LSTM/etc ниже встраивания неизменен

Это даст вам решение с небольшим количеством свободных параметров, выделенных для этих вложений.

Другие вопросы по тегам