Я строю сеть RNN LSTM для классификации текстов по возрасту писателей (двоичная классификация - молодые / взрослые).
Похоже, что сеть не учится и внезапно начинает переоснащаться:
Красный: поезд
Синий: проверка
Одной из возможностей может быть то, что представление данных недостаточно хорошее. Я просто отсортировал уникальные слова по частоте и дал им индексы. E.g.:
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: Значение, переданное параметру 'indexes', имеет тип DataType float32, отсутствующий в списке допустимых значений: int32, int64
Итак, я думаю, мне нужно изменить тип input_data
на int32
. Так что я делаю это (в конце концов, это все индексы), и я получаю это:
TypeError: входные данные должны быть последовательностью
Я попытался обернуть inputs
(аргумент tf.contrib.rnn.static_rnn
) списком: [inputs]
, как предложено в этого ответа , но это привело к другой ошибке:
ValueError: Размер ввода (размер 0 входов) должен быть доступен через
вывод формы, но значение пилы отсутствует.
Обновление:
Я распаковывал тензор 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 - размер каждого скрытого слоя.
Очевидно, что у меня проблема с размерами ... Как сделать так, чтобы входы соответствовали сети после встраивания?