【问题标题】:Limited range for TensorFlow Universal Sentence Encoder Lite embeddings?TensorFlow Universal Sentence Encoder Lite 嵌入的范围有限?
【发布时间】:2019-08-18 17:50:33
【问题描述】:

从 TensorFlow.js 中的 universal-sentence-encoder 开始,我注意到嵌入中的数字范围不是我所期望的。我期待在 [0-1] 或 [-1,1] 之间有一些分布,但没有看到其中任何一个。

对于句子“猫很棒!”这是一个可视化,其中每个维度都投影到 [-0.5, 0.5] 的比例上:

这是“我想知道这个句子的嵌入是什么”的相同类型的可视化(我尝试的前 10 个句子的模式相似):

为了调试,我查看了demo Colab notebook中是否出现了同样的事情,似乎是这样。如果我看到这两个句子的嵌入范围,这就是我看到的:

# NEW: added this, with different messages
messages = ["cats are great!", "sometimes models are confusing"]
values, indices, dense_shape = process_to_IDs_in_sparse_format(sp, messages)

with tf.Session() as session:
  session.run([tf.global_variables_initializer(), tf.tables_initializer()])
  message_embeddings = session.run(
      encodings,
      feed_dict={input_placeholder.values: values,
                input_placeholder.indices: indices,
                input_placeholder.dense_shape: dense_shape})

  for i, message_embedding in enumerate(np.array(message_embeddings).tolist()):
    print("Message: {}".format(messages[i]))
    print("Embedding size: {}".format(len(message_embedding)))
    message_embedding_snippet = ", ".join(
        (str(x) for x in message_embedding[:3]))
    print("Embedding: [{}, ...]\n".format(message_embedding_snippet))
    # NEW: added this, to show the range of the embedding output
    print("Embedding range: [{}, {}]".format(min(message_embedding), max(message_embedding)))

输出显示:

Message: cats are great!
Embedding range: [-0.05904272198677063, 0.05903803929686546]

Message: sometimes models are confusing
Embedding range: [-0.060731519013643265, 0.06075377017259598]

所以这又不是我所期待的 - 范围比我预期的要窄。我认为这可能是我错过的 TF 约定,但在 TFHub pageguide to text embeddingspaper 中看不到它,所以如果不深入研究培训代码,我不确定在哪里可以查看。

colab notebook 示例代码有一个例句:

Universal Sentence Encoder 嵌入还支持短段落。 段落的长度没有硬性限制。大致上, 嵌入越“稀释”的时间越长。

但是对于 colab 中的所有其他示例,甚至是一个单词示例,嵌入的范围大致相同。

我假设这个范围不仅是任意的,而且范围以零为中心并且很小对我来说确实有意义,但我试图了解这个比例是如何形成的。

【问题讨论】:

    标签: tensorflow word-embedding tensorflow.js tensorflowjs-converter


    【解决方案1】:

    通用句子编码器的输出是一个长度为 512 的向量,其 L2 范数(大约)为 1.0。您可以通过计算内积来检查这一点

    ip = 0
    for i in range(512):
      ip +=  message_embeddings[0][i] * message_embeddings[0][i]
    
    print(ip)
    
    > 1.0000000807544893
    

    含义是:

    • 大多数值可能位于以零为中心的狭窄范围内
    • 向量中最大可能的单个值是 1.0 - 只有当所有其他值都恰好为 0 时才会发生这种情况。
    • 同样,可能的最小值是 -1。
    • 如果我们采用长度为 512 且值均匀分布的随机向量,然后将其归一化为单位幅度,我们希望看到的值范围与您看到的相似。
    rand_uniform = np.random.uniform(-1, 1, 512)
    l2 = np.linalg.norm(rand_uniform)
    plt.plot(rand_uniform / l2, 'b.')
    axes = plt.gca()
    axes.set_ylim([-0.5, 0.5])
    

    从视觉上看,激发的分布看起来并不均匀,而是偏向极端。

    【讨论】:

    • 这非常有用,谢谢! :) 我仍然想知道 为什么 这是这样的。我可以看到关于范数向量方法的一般信息,并且像 L2 这样的一些东西在计算上更简单,但我有兴趣更具体地了解为什么这对文本嵌入很重要。我的理解是,这是因为有额外的操作或属性只能在以特定方式规范的空间中证明是正确的。特别是,这似乎与保证 L2 范数空间中余弦相似度的输出有关?
    • 对于算法设计者选择 L2 归一化的问题为什么,我不确定是否有一个简短而封闭的答案。一些有助于指导他们选择的可能观点可能包括:1. 具有恒定 L2 范数的输出允许对任何两个嵌入之间的内积进行约束,因此可以说:“这两个输入是相似的,因为它们的嵌入在点积意义上很接近”2. 很容易计算和执行
    • 知道了,感谢您帮助了解更多信息!其他发现此问题的人的相关问题:stackoverflow.com/questions/32276391/…
    猜你喜欢
    • 2019-03-28
    • 2022-07-23
    • 2020-11-19
    • 2020-01-30
    • 2020-05-26
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多