Как тренироваться с входами переменного размера?

Этот вопрос довольно абстрактен и не обязательно связан с тензорным потоком или керасом. Скажем, вы хотите обучить языковую модель и хотите использовать входные данные разного размера для своих LSTM. В частности, я слежу за этой статьей: https://www.researchgate.net/publication/317379370_A_Neural_Language_Model_for_Query_Auto-Completion.

Авторы используют, среди прочего, встраивание слов и горячее кодирование символов. Скорее всего, размеры каждого из этих входов разные. Теперь, чтобы передать это в сеть, я вижу несколько альтернатив, но я уверен, что что-то упускаю, и я хотел бы знать, как это должно быть сделано.

  • Создайте трехмерный тензор формы (экземпляры, 2, макс (вложения, символы)). То есть заполнение меньшего ввода 0 с.
  • Создайте трехмерный тензор формы (экземпляры, вложения + символы, 1)). То есть объединение входных данных.

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


РЕДАКТИРОВАТЬ

Вот более подробная информация. Назовем эти входные данные X (ввод на уровне символов) и E (ввод на уровне слов). Для каждого символа последовательности (текста) я вычисляю метку x, e и y.

  • x: однократное кодирование символов. Мой индекс символов имеет размер 38, так что это вектор, заполненный 37 нулями и одной единицей.
  • e: предварительно вычисленное вложение слова размером 200. Если символ является пробелом, я извлекаю вложение слова предыдущего слова в последовательности. В противном случае я назначаю вектор для неполного слова (INC, также размером 200). Реальный пример с последовательностью "красная машина": r>INC, e>INC, d>INC, _>embeddings["red"], c>INC, a>INC, r>INC.
  • y: предсказуемая метка, которая является следующим символом, закодированным в горячем режиме. Этот вывод имеет ту же размерность, что и x, потому что он использует тот же индекс символов. В приведенном выше примере для «r» y является однократным кодированием «e».

person Johy    schedule 12.09.2017    source источник
comment
Кажется, что E также является последовательностью символов, а не последовательностью слов, можете ли вы это прояснить?   -  person Daniel Möller    schedule 13.09.2017
comment
Нет, e — это встраивание слова для символа, читаемого во время обучения. Точнее, для каждого слова в словаре это вектор или 200 чисел с плавающей запятой, обученных с помощью Word2Vec. Но поскольку у меня нет полного слова до символа пробела, этот вектор заполняется случайным образом 200 числами с плавающей запятой. Когда читается символ пробела, e является вложением предыдущего слова в последовательность. Это яснее?   -  person Johy    schedule 13.09.2017
comment
Работайте только со словами, этот подход создаст в модели много ненужных и вводящих в заблуждение данных.   -  person Daniel Möller    schedule 13.09.2017
comment
Одно встраивание символов в качестве одного ввода и одно вложение слов в качестве параллельного ввода.   -  person Daniel Möller    schedule 13.09.2017
comment
Ясно, и оба вложения одинакового размера, наверное?   -  person Johy    schedule 13.09.2017
comment
Не обязательно... вложения символов, вероятно, должны быть намного меньше, в конце концов, всего 26 (или 52) символов плюс несколько дополнительных. Вы можете иметь оба вложения и объединять их на последней оси: >один пример того, как создавать параллельные слои, в этом случае вы должны определить два входных тензора, каждый из которых переходит к другому встраиванию, и после встраивания вы объединяете их.   -  person Daniel Möller    schedule 13.09.2017
comment
Это именно то, что я хотел сделать, за исключением того, что я не мог подобрать слов, чтобы прояснить это. Большое вам спасибо за то, что помогли мне, ссылка, которую вы разместили, идеальна, а ваши объяснения кристально ясны.   -  person Johy    schedule 13.09.2017


Ответы (1)


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

Вам просто нужно позаботиться о том, чтобы не приписать нулевое значение какому-либо другому символу, даже пробелам или неизвестным словам.

Слой встраивания предназначен не только для маскирования (маскирование — это просто опция слоя встраивания).

Слой внедрения преобразует целочисленные значения из словаря слов/символов в фактические векторы определенной формы.

Предположим, у вас есть этот словарь:

1: hey
2: ,
3: I'm
4: here
5: not

И вы формируете такие предложения, как

[1,2,3,4,0] -> this is "hey, I'm here"
[1,2,3,5,4] -> this is "hey, I'm not here"
[1,2,1,2,1] -> this is "hey, hey, hey"

Слой внедрения преобразует каждое из этих целых чисел в векторы определенного размера. Это делает две хорошие вещи одновременно:

  • Преобразует слова в векторы, потому что нейронные сети могут обрабатывать только векторы или интенсивности. Список индексов не может быть обработан нейронной сетью напрямую, между индексами и словами нет логической связи

  • Создает вектор, который будет «значимым» набором признаков для каждого слова.

А после обучения они становятся «осмысленными» векторами. Каждый элемент начинает представлять определенную характеристику слова, хотя эта особенность непонятна людям. Возможно, что вложение будет способно обнаруживать слова, которые являются глаголами, существительными, женским, мужским родом и т. Д., Все, что закодировано в комбинации числовых значений (наличие/отсутствие/интенсивность признаков).


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

person Daniel Möller    schedule 12.09.2017
comment
Большое спасибо за то, что помогли мне очистить мой разум! :-) Дело в том, что я уже использую обученное встраивание слов. Таким образом, у меня есть это вложение размером 200 и этот другой вход (одно горячее кодирование) размера 38. Как бы вы передали эти 2 входа в слой встраивания? - person Johy; 12.09.2017
comment
Встраивание не принимает входные данные, закодированные one_hot, оно должно принимать целые числа. Можете ли вы рассказать режиму о другом входе? Что это такое? - person Daniel Möller; 12.09.2017