![](/img/trans.png)
[英]what is the difference between using softmax as a sequential layer in tf.keras and softmax as an activation function for a dense layer?
[英]What is the difference between an Embedding Layer and a Dense Layer?
Keras 中嵌入层的文档说:
将正整数(索引)转换为固定大小的密集向量。 例如。
[[4], [20]]
->[[0.25, 0.1], [0.6, -0.2]]
我相信这也可以通过将输入编码为长度为vocabulary_size
的单热向量并将它们输入到Dense Layer中来实现。
嵌入层仅仅是这个两步过程的便利,还是在引擎盖下发生了一些更有趣的事情?
嵌入层更快,因为它本质上等同于简化假设的密集层。
想象一个具有这些权重的词嵌入层:
w = [[0.1, 0.2, 0.3, 0.4],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
Dense
层会将这些视为执行矩阵乘法的实际权重。 嵌入层将简单地将这些权重视为向量列表,每个向量代表一个词; 词汇表中的第 0 个单词是w[0]
,第一个是w[1]
,等等。
例如,使用上面的权重和这句话:
[0, 2, 1, 2]
一个朴素的基于Dense
的网络需要将该句子转换为 1-hot 编码
[[1, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 0, 1]]
然后做一个矩阵乘法
[[1 * 0.1 + 0 * 0.5 + 0 * 0.9, 1 * 0.2 + 0 * 0.6 + 0 * 0.0, 1 * 0.3 + 0 * 0.7 + 0 * 0.1, 1 * 0.4 + 0 * 0.8 + 0 * 0.2],
[0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2],
[0 * 0.1 + 1 * 0.5 + 0 * 0.9, 0 * 0.2 + 1 * 0.6 + 0 * 0.0, 0 * 0.3 + 1 * 0.7 + 0 * 0.1, 0 * 0.4 + 1 * 0.8 + 0 * 0.2],
[0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2]]
=
[[0.1, 0.2, 0.3, 0.4],
[0.9, 0.0, 0.1, 0.2],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
然而, Embedding
层只是查看[0, 2, 1, 2]
并在索引 0、2、1 和 2 处获取层的权重以立即得到
[w[0],
w[2],
w[1],
w[2]]
=
[[0.1, 0.2, 0.3, 0.4],
[0.9, 0.0, 0.1, 0.2],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
所以这是相同的结果,只是以一种希望更快的方式获得。
Embedding
层确实有限制:
但是,如果您只想将整数编码的单词转换为嵌入,那么这些限制都无关紧要。
从数学上讲,区别在于:
嵌入层执行选择操作。 在 keras 中,这一层相当于:
K.gather(self.embeddings, inputs) # just one matrix
一个密集层执行点积运算,加上一个可选的激活:
outputs = matmul(inputs, self.kernel) # a kernel matrix outputs = bias_add(outputs, self.bias) # a bias vector return self.activation(outputs) # an activation function
您可以通过 one-hot 编码模拟具有完全连接层的嵌入层,但密集嵌入的重点是避免one-hot 表示。 在 NLP 中,单词词汇量可以达到 100k 的量级(有时甚至是一百万)。 最重要的是,通常需要批量处理单词序列。 处理一批单词索引序列将比处理一批 one-hot 向量序列更有效。 此外,无论是前向还是后向传播, gather
操作本身都比矩阵点积更快。
在这里,我想通过提供更多详细信息来改进投票答案:
当我们使用嵌入层时,通常是将 one-hot 输入向量(稀疏)减少为更密集的表示。
嵌入层很像一个表格查找。 当桌子很小时,它很快。
当表很大时,表查找要慢得多。 在实践中,我们将使用密集层作为降维器来减少单热输入,而不是在这种情况下嵌入层。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.