Iri*_*nen 5 python numpy keras tensorflow
我想在带有 tensorflow 后端的 keras 张量上执行类似于 np.where 的操作。这意味着可以说我有两个张量:diff 和 sum。我将这些向量划分为:
rel_dev = diff / sum
Run Code Online (Sandbox Code Playgroud)
对于 np.arrays 我会写:
rel_dev = np.where((diff == 0.0) & (sum == 0.0), 0.0, rel_dev)
Run Code Online (Sandbox Code Playgroud)
rel_dev = np.where((diff != 0.0) & (sum == 0.0), np.sign(diff), rel_dev)
Run Code Online (Sandbox Code Playgroud)
也就是说,例如,如果我在 diff 和 sum 中都有零,我希望我不会得到 np.Inf,而是将 rel_dev 设置为零。现在在带有张量的 keras 中它不起作用。我尝试过 K.switch、K.set_value 等。据我所知,它适用于整个张量,但不适用于单独的部分,对吗?虽然它没有设置这些条件就可以工作,但我不知道实际发生了什么。我还没有成功调试它。
你能告诉我如何在 Keras 中为 rel_dev 写两个条件吗?
你可以在 Keras 中这样做:
import keras.backend as K
diff = K.constant([0, 1, 2, -2, 3, 0])
sum = K.constant([2, 4, 1, 0, 5, 0])
rel_dev = diff / sum
d0 = K.equal(diff, 0)
s0 = K.equal(sum, 0)
rel_dev = K.switch(d0 & s0, K.zeros_like(rel_dev), rel_dev)
rel_dev = K.switch(~d0 & s0, K.sign(diff), rel_dev)
print(K.eval(rel_dev))
# [ 0. 0.25 2. -1. 0.6 0. ]
Run Code Online (Sandbox Code Playgroud)
编辑:上面的公式有一个潜在的问题,即即使结果是正确的,nan值也会通过梯度传播回(即因为除以零给出infor nan,乘以inf或nan为零给出nan)。事实上,如果你检查梯度:
gd, gs = K.gradients(rel_dev, (diff, sum))
print(K.eval(gd))
# [0.5 0.25 1. nan 0.2 nan]
print(K.eval(gs))
# [-0. -0.0625 -2. nan -0.12 nan]
Run Code Online (Sandbox Code Playgroud)
您可以用来避免这种情况的技巧是以sum不影响结果但阻止nan值的方式更改除法,例如像这样:
import keras.backend as K
diff = K.constant([0, 1, 2, -2, 3, 0])
sum = K.constant([2, 4, 1, 0, 5, 0])
d0 = K.equal(diff, 0)
s0 = K.equal(sum, 0)
# sum zeros are replaced by ones on division
rel_dev = diff / K.switch(s0, K.ones_like(sum), sum)
rel_dev = K.switch(d0 & s0, K.zeros_like(rel_dev), rel_dev)
rel_dev = K.switch(~d0 & s0, K.sign(diff), rel_dev)
print(K.eval(rel_dev))
# [ 0. 0.25 2. -1. 0.6 0. ]
gd, gs = K.gradients(rel_dev, (diff, sum))
print(K.eval(gd))
# [0.5 0.25 1. 0. 0.2 0. ]
print(K.eval(gs))
# [-0. -0.0625 -2. 0. -0.12 0. ]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
563 次 |
| 最近记录: |