Tensorflow 如何进行单词嵌入以向RNN提供输入?

Tensorflow 如何进行单词嵌入以向RNN提供输入?,tensorflow,nlp,deep-learning,lstm,rnn,Tensorflow,Nlp,Deep Learning,Lstm,Rnn,我正在尝试使用基本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 =

我正在尝试使用基本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:Layer gru_cell_2需要1个输入,但它收到39个输入张量。我认为这个错误是由于嵌入,因为它没有给出一个可以输入到GRUCell的维度张量。那么,如何向GRU单元提供输入呢?

初始化X_输入的方式可能是错误的。这个额外的一维导致了这个问题。如果将其删除,则无需使用
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)
但是,如果您确实需要使用该维度,那么您需要在
取消堆栈
中进行一个小的修改。你把它沿着轴=1展开成张量的序列长度,这看起来又不对。这样做:

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)
最后,如果您真的需要在
序列\u length
张量数量中取消堆叠,则将
取消堆叠
替换为
tf.map\u 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)
警告:注意每个解决方案中
输出的形状。注意你想要什么样的形状

编辑:

要回答您关于何时使用何种输入的问题,请执行以下操作:

假设你有25个句子,每个句子有15个单词,你把它分成5批,每个5个大小。另外,假设您正在使用50维的单词嵌入(假设您正在使用word2vec),那么您的输入形状将是
(batch\u size=5,time\u step=15,features=50)
。在这种情况下,不需要使用取消堆叠或任何类型的映射


接下来,假设您有30个文档,每个文档有25个句子,每个句子有15个单词长,您将文档分为6批,每批大小为5个。同样,假设您使用50维的单词嵌入,那么您的输入形状现在有一个额外的维。这里的
batch\u size=5
time\u step=15
features=50
但是句子的数量呢?现在您的输入是
(批大小=5,句子数=25,时间步长=15,特征=50)
,这对于任何类型的
RNN
都是无效的形状。在这种情况下,您需要沿句子维度将其展开,以生成25个张量,每个张量的形状为(5,15,50)。为了实现这一点,我使用了
tf.map\u fn

tfWe的维度是多少?序列长度的值是多少?序列长度是列车数据的最大长度;我填充的序列小于训练数据的最大长度;tfWe是嵌入权重,并据此更正了上述代码是否有任何理由将
X\u输入初始化为
(无,序列长度,1)
和非
(无,序列长度)
?非常有用的解释!实际上,我对LSTM是新手,对输入的形状感到困惑;我知道形状应该是(批量大小、时间步长、数量特征)。所以我从形状开始(无,序列长度,1)-你能解释一下如何决定输入形状吗?我还发现了静态形状和动态形状,并观察到动态形状上不需要拆垛-你能解释一下吗?太棒了!。但我仍然面临一些挑战;我使用RNN进行实体提取,并使用带有标签的手动注释文件。我将它作为一系列单词传递给GRU单元;我期望输出应该是标签或类,但我得到的是标签序列的输出,我已经用行更新了输出代码;任何关于如何仅获取类标签作为输出的建议。谢谢首先,确保输出的形状
(无、序列长度、隐藏层大小)
。通常在最后一步执行时退出,所以执行
output=output[:,-1,:]
。现在您的输出具有shape
(无,隐藏层大小)
。将此输出通过完全连接的前馈网络,并为其中的权重矩阵和偏差提供适当的维数。输出是否等于dynamicRNN单元的最后状态?我们可以使用最后一个状态而不是输出吗?