【问题标题】:Normalized output of keras layerkeras层的归一化输出
【发布时间】:2018-12-29 03:14:38
【问题描述】:

我想创建一个带有 Tensorflow 背景的 Keras 模型,它返回一个范数为 1 的向量。为此,模型以下一层结束:

main_network = Lambda(lambda t: K.l2_normalize(t, axis=1))(x)

我还创建了一个测试,其中我只创建模型,并且在没有训练的情况下进行随机预测以检查输出是否具有范数 1。但测试失败:

AssertionError: 0.37070954 != 1 within 0.1 delta

因此 Lambda 层无法正常工作,因为它没有对输出进行标准化。我为轴参数尝试了不同的值,并且使用所有可能的值,测试失败。但我失踪了吗?

【问题讨论】:

  • 你是怎么做出这个断言的?
  • self.assertAlmostEqual(np.linalg.norm(vector), 1, delta=0.1) 其中vector是预测的结果。
  • @RodrigoSernaPérez np.linalg.norm 返回 l2-norm 而不是“l2-normalize”。根据我在答案中的示例,对于列表 [3, 1, 4, 3, 1] np.linalg.norm reutrn 6.
  • linalg.norm 应该返回batch_size。所以出了点问题,但它可能在代码中的其他地方。

标签: python keras neural-network


【解决方案1】:

好的,我解决了这个问题。出于同样的原因,K.l2_normalize 不适用于非常小的数字,所以我只是将这一行改为:

main_network = Lambda(lambda t: K.l2_normalize(1000*t, axis=1))(x)

现在测试正常了!!

【讨论】:

  • 这是因为你不能除以零。有一个常数K.epsilon(),通常是1e-7,它被添加到分母中,以避免(可能)在 Keras 中具有除法的每个函数中被零除。
【解决方案2】:

L2 normalize 公式为:

       x
---------------
sqrt(sum(x**2))

例如,对于输入[3, 1, 4, 3, 1][3/6, 1/6, 4/6, 3/6, 1/6]=12/6,这表明L2-normalize 的输出不必是。如果您需要将输出归一化为总和 1 的东西,您可能需要 Softmax

这是一个例子,你可以检查 softmax 的输出是 1:

import tensorflow as tf
from tensorflow.python.keras import backend as K
from tensorflow.python.keras.layers import Lambda

x = tf.keras.layers.Input(tensor=tf.constant([[1, 2, 3, 4, 5]], dtype=tf.float32))
n_layer = Lambda(lambda t: K.softmax(t, axis=-1))(x)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(n_layer.eval())

【讨论】:

  • 我相信您发布了 l2“规范”的公式,而不是“规范化”。应该是x / ||x||
  • Softmax 只会导致元素之和为 1,这与范数 1 不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2017-07-14
  • 2017-06-02
  • 2020-04-23
  • 2018-09-06
  • 1970-01-01
相关资源
最近更新 更多