我正在关注this tutorial以了解NLP中的CNN。尽管我面前有代码,但仍有一些事情我不明白。我希望有人能在这里澄清一些事情。
第一个相当小的事情是sequence_length
对象的TextCNN
参数。在github上的示例中,这只是56
,我认为是训练数据中所有句子的最大长度。这意味着self.input_x
是一个56维向量,它只包含每个单词的句子字典中的索引。
此列表进入tf.nn.embedding_lookup(W, self.intput_x)
,它将返回一个矩阵,该矩阵由self.input_x
给出的那些词的嵌入字组成。根据{{3}},此操作类似于使用numpy索引:
matrix = np.random.random([1024, 64])
ids = np.array([0, 5, 17, 33])
print matrix[ids]
但问题是self.input_x
大部分时间都是[1 3 44 25 64 0 0 0 0 0 0 0 .. 0 0]
。如果我假设tf.nn.embedding_lookup
忽略值0,那么我是否正确?
我没有得到的另一件事是tf.nn.embedding_lookup
如何在这里工作:
# Embedding layer
with tf.device('/cpu:0'), tf.name_scope("embedding"):
W = tf.Variable(
tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),
name="W")
self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x)
self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1)
我假设,taht self.embedded_chars
是矩阵,它是CNN的实际输入,其中每行代表一个字的嵌入字。但tf.nn.embedding_lookup
如何self.input_x
了解W
给出的指数?
我在这里不明白的最后一件事是
tf.nn.embedding_lookup
是我们在培训期间学习的嵌入矩阵。我们使用随机均匀分布对其进行初始化。[None, sequence_length, embedding_size]
创建实际的嵌入操作。嵌入操作的结果是形状Instrumentation.sendPointerSync(motionEvent);
的三维张量。
这是否意味着我们实际在这里学习
我们不会将预先训练过的word2vec向量用于我们的单词嵌入。相反,我们从头开始学习嵌入。
但我没有看到实际发生这种情况的代码行。 this answer看起来好像没有任何训练或学习的东西 - 那么它在哪里发生?
答案 0 :(得分:3)
回答问题1(如果我假设tf.nn.embedding_lookup忽略值0,那么我是否正确):
输入向量中的0是词汇表中第0个符号的索引,即PAD符号。我认为执行查找时不会忽略它。将返回嵌入矩阵的第0行。
对问题2的回答(但是tf.nn.embedding_lookup如何知道self.input_x给出的那些索引?):
嵌入矩阵的大小是[V * E],其中是词汇量的大小,E是嵌入向量的维度。矩阵的第0行是词汇的第0个元素的嵌入向量,矩阵的第1行是词汇的第1个元素的嵌入向量。 从输入向量x,我们得到词汇表中的单词索引,用于索引嵌入矩阵。
对问题3的回答(这是否意味着我们实际上在这里学习嵌入这个词?)。
是的,我们实际上正在学习嵌入矩阵。
在嵌入层中,在行W = tf.Variable( tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0),name="W")
中,W是嵌入矩阵,默认情况下,在变量的tensorflow trainable=TRUE
中。因此,W也将是一个学习参数。要使用预先训练的模型,请设置trainable = False
。
有关代码的详细说明,您可以关注博客:https://agarnitin86.github.io/blog/2016/12/23/text-classification-cnn