我正在关注this tutorial以了解NLP中的CNN . 尽管我面前有代码,但仍有一些事情我不明白 . 我希望有人能在这里澄清一些事情 .
第一个相当小的事情是 TextCNN
对象的 sequence_length
参数 . 在github的例子中,这只是 56
,我认为是训练数据中所有句子的最大长度 . 这意味着 self.input_x
是一个56维向量,它只包含每个单词的句子字典中的索引 .
此列表进入 tf.nn.embedding_lookup(W, self.intput_x)
,它将返回一个矩阵,该矩阵由 self.input_x
给出的那些单词的嵌入字组成 . 根据this answer,此操作类似于使用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] .
这是否意味着我们实际上在这里学习嵌入这个词?该教程在开头说明:
我们不会使用预先训练过的word2vec向量进行单词嵌入 . 相反,我们从头开始学习嵌入 .
但我没有看到实际发生这种情况的代码行 . code of the embedding layer看起来好像没有任何训练或学习的东西 - 所以它在哪里发生?
1 回答
对问题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是嵌入矩阵,默认情况下,在tensorflowtrainable=TRUE
中为变量 . 因此,W也将是一个学习参数 . 要使用预先训练的模型,请设置trainable = False
.有关代码的详细说明,您可以关注博客:https://agarnitin86.github.io/blog/2016/12/23/text-classification-cnn