Я строю сеть RNN LSTM для классификации текстов по возрасту авторов (бинарная классификация - молодые/взрослые).
Похоже, сеть не учится и вдруг начинает переобучать:
Красный: обучение
Синий: проверка
Одной из возможностей может быть недостаточное представление данных. Я просто отсортировал уникальные слова по их частоте и дал им индексы. Например.:
unknown -> 0
the -> 1
a -> 2
. -> 3
to -> 4
Поэтому я пытаюсь заменить это встраиванием слов. Я видел пару примеров, но я не могу реализовать это в своем коде. Большинство примеров выглядят так:
embedding = tf.Variable(tf.random_uniform([vocab_size, hidden_size], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, input_data)
Означает ли это, что мы создаем слой, который изучает встраивание? Я подумал, что нужно скачать какой-нибудь Word2Vec или Glove и просто использовать его.
В любом случае, скажем, я хочу создать этот слой внедрения...
Если я использую эти 2 строки в своем коде, я получаю сообщение об ошибке:
TypeError: значение, переданное параметру «индексы», имеет DataType float32, которого нет в списке допустимых значений: int32, int64
Так что я думаю, мне нужно изменить тип input_data
на int32
. Итак, я делаю это (в конце концов, это все индексы), и я получаю следующее:
TypeError: входы должны быть последовательностью
Я попытался обернуть inputs
(аргумент tf.contrib.rnn.static_rnn
) списком: [inputs]
, как это было предложено в этом ответе, но это привело к другой ошибке:
ValueError: Размер входных данных (размерность 0 входных данных) должен быть доступен через вывод формы, но видел значение None.
Обновление:
Я распаковывал тензор x
, прежде чем передать его embedding_lookup
. Я перенес распаковку после встраивания.
Обновленный код:
MIN_TOKENS = 10
MAX_TOKENS = 30
x = tf.placeholder("int32", [None, MAX_TOKENS, 1])
y = tf.placeholder("float", [None, N_CLASSES]) # 0.0 / 1.0
...
seqlen = tf.placeholder(tf.int32, [None]) #list of each sequence length*
embedding = tf.Variable(tf.random_uniform([VOCAB_SIZE, HIDDEN_SIZE], -1, 1))
inputs = tf.nn.embedding_lookup(embedding, x) #x is the text after converting to indices
inputs = tf.unstack(inputs, MAX_POST_LENGTH, 1)
outputs, states = tf.contrib.rnn.static_rnn(lstm_cell, inputs, dtype=tf.float32, sequence_length=seqlen) #---> Produces error
*seqlen: я дополнил последовательности нулями, чтобы все они имели одинаковый размер списка, но, поскольку фактические размеры различаются, я подготовил список, описывающий длину без заполнения.
Новая ошибка:
ValueError: Вход 0 слоя basic_lstm_cell_1 несовместим со слоем: ожидается ndim=2, найдено ndim=3. Получена полная форма: [Нет, 1, 64]
64 – размер каждого скрытого слоя.
Очевидно, что у меня проблема с размерами... Как сделать так, чтобы входы соответствовали сети после встраивания?