我无法对 tensorflow 中的数据进行标准化,这会导致 np.nan
和 np.inf
出现损失,从而破坏训练。
我的图像位于[-1, +1]
范围内。我想计算二元交叉熵损失
_bce = -1 * tf.reduce_sum(tf.mul(img1_n, img2_n)) + tf.mul((1 - img1_n),tf.log(1 - img2_n)), 0)
bce_loss = tf.reduce_mean(_bce)
在计算损失之前,我将图像标准化为:
img1_n = (img1 + 1)/2 - 1e-8 #to prevent NaN and inf
img2_n = np.flip(img1_n)
这样,tf.log()
就可以从 (0,1)
中获取不包含在内的值。
我这样捕获错误:
if np.isnan(bce_loss) or np.isinf(bce_loss):
foo = (img1 + 1)/2 - 1e-8
goo = (img1 + 1)/2
hoo = ((1 - 2 * 1e-8) * g + 1 - 2 * 1e-8)/2 # scaled to get [0 + 1e-8, 1 - 1e-8] ~= (0, 1)
print np.min(img1), np.max(img1) #img1 ~ [-1, 1] # -0.998874 1.0
print np.min(img1_n), np.max(img1_n) #img1_n ~ (0, 1) # 0.000563224 1.0
print np.min(foo), np.max(foo) # 0.000563234 1.0
print np.min(goo) - 1e-8, np.max(goo) - 1e-8 # 0.000563224090805 0.99999999
print np.min(hoo), np.max(hoo) # 0.000563234 1.0
由于存在 np.log(1 - x)
操作,因此发生 np.inf
错误。为什么这些值没有缩放?我无法减去 1e-8 值。人们还能如何进行标准化?
如果我使用 epsilon 作为 1e-4
而不是 1e-8
,则缩放有效。考虑到 numpy float 是 64 位,为什么 1e-8
没有被计算?我也尝试用 0.00000001
替换 1e-8
,但同样的错误。
最佳答案
TensorFlow默认的浮点精度为float32
,分辨率为1e-6
。您可以像这样检查 numpy 中类型的分辨率:
In [5]: np.finfo(np.float32)
Out[5]: finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32)
关于python - tensorflow 中的数据标准化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44779851/