Как сделать встраивание слов, чтобы обеспечить ввод в RNN? - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь сделать предсказание слов, используя базовый RNN. Мне нужно предоставить вход в ячейку RNN; Я пытаюсь следующий код

X_input = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))
Y_target = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))

tfWe = tf.Variable(tf.random_uniform((V, embedding_dim)))
W1 = tf.Variable(np.random.randn(hidden_layer_size, label).astype(np.float32))
b = tf.Variable(np.zeros(label).astype(np.float32))
rnn = GRUCell(num_units = hidden_layer_size, activation = tf.nn.relu)

x = tf.nn.embedding_lookup(tfWe, X_input)
x = tf.unstack(x, sequence_length, 1)
output, states = tf.nn.dynamic_rnn(rnn, x, dtype = tf.float32)
output = tf.transpose(output, (1,0,2))
output = tf.reshape(output, (sequence_length*num_samples,hidden_layer_size))

Я получаю ошибку ValueError: Слой gru_cell_2 ожидает 1 вход, но он получил 39 входных тензоров . Я думаю, что эта ошибка связана с встраиванием, поскольку оно не дает тензор размерности, который может быть введен в GRUCell. Итак, как обеспечить ввод в ячейку GRU?

1 Ответ

0 голосов
/ 13 сентября 2018

Способ инициализации X_input, вероятно, неверен.Это дополнительное измерение вызывает проблему.Если вы удалите это, тогда нет необходимости использовать unstack.Этот следующий код будет работать.

X_input = tf.placeholder(tf.int32, shape = (None, sequence_length))
Y_target = tf.placeholder(tf.int32, shape = (None, sequence_length))

tfWe = tf.Variable(tf.random_uniform((V, embedding_dim)))
W1 = tf.Variable(np.random.randn(hidden_layer_size, label).astype(np.float32))
b = tf.Variable(np.zeros(label).astype(np.float32))
rnn = tf.contrib.rnn.GRUCell(num_units = hidden_layer_size, activation = tf.nn.relu)

x = tf.nn.embedding_lookup(tfWe, X_input)
output, states = tf.nn.dynamic_rnn(rnn, x, dtype = tf.float32)
##shape of output here is (None,sequence_length,hidden_layer_size)

Но если вам действительно нужно использовать это измерение, вам нужно внести небольшую модификацию в unstack.Вы распаковываете его вдоль axis=1 в sequence_length число тензоров, что опять-таки не кажется правильным.Так что сделайте это:

X_input = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))
Y_target = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))

tfWe = tf.Variable(tf.random_uniform((V, embedding_dim)))
W1 = tf.Variable(np.random.randn(hidden_layer_size, label).astype(np.float32))
b = tf.Variable(np.zeros(label).astype(np.float32))
rnn = tf.contrib.rnn.GRUCell(num_units = hidden_layer_size, activation = tf.nn.relu)

x = tf.nn.embedding_lookup(tfWe, X_input)
x = tf.unstack(x, 1, 2)
output, states = tf.nn.dynamic_rnn(rnn, x[0], dtype = tf.float32)
##shape of output here is again same (None,sequence_length,hidden_layer_size)

Наконец, если вам действительно нужно разложить его в sequence_length количестве тензоров, замените unstack на tf.map_fn() и сделайте это:

X_input = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))
Y_target = tf.placeholder(tf.int32, shape = (None, sequence_length, 1))

tfWe = tf.Variable(tf.random_uniform((V, embedding_dim)))
W1 = tf.Variable(np.random.randn(hidden_layer_size, label).astype(np.float32))
b = tf.Variable(np.zeros(label).astype(np.float32))
rnn = tf.contrib.rnn.GRUCell(num_units = hidden_layer_size, activation = tf.nn.relu)

x = tf.nn.embedding_lookup(tfWe, X_input)
x = tf.transpose(x,[1,0,2,3])
##tf.map_fn unstacks a tensor along the first dimension only so we need to make seq_len as first dimension by taking transpose

output,states = tf.map_fn(lambda x: tf.nn.dynamic_rnn(rnn,x,dtype=tf.float32),x,dtype=(tf.float32, tf.float32))
##shape of output here is (sequence_length,None,1,hidden_layer_size)

Предупреждение: обратите внимание на форму output в каждом решении.будьте осторожны с тем, какой тип фигуры вы хотите.

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

Чтобы ответить на ваш вопрос о том, когда использовать какие типы входов:

Предположим,у вас есть 25 предложений, у каждого есть 15 слов, и вы разделили его на 5 партий размером 5 каждое.Кроме того, предположим, что вы используете вложение слов из 50 измерений (допустим, вы используете word2vec), тогда ваша форма ввода будет (batch_size=5,time_step=15, features=50).В этом случае вам не нужно использовать распаковку или какое-либо отображение.

Далее, предположим, у вас есть 30 документов, у каждого есть 25 предложений, каждое предложение по 15 слов, и вы разделили документы на 6 пакетовразмером 5 каждый.Снова, предположим, что вы используете вложение слов из 50 измерений, тогда у вашей входной фигуры теперь есть одно дополнительное измерение.Здесь batch_size=5, time_step=15 и features=50 но как насчет количества предложений?Теперь вы вводите (batch_size=5,num_sentences=25,time_step=15, features=50), что является недопустимой формой для любого типа RNNs.В этом случае вам нужно разложить его по размеру предложения, чтобы получить 25 тензоров, каждый из которых будет иметь форму (5,15,50).Чтобы заставить это работать, я использовал tf.map_fn.

...