def naive_sigmoid_loss(x, t): y = 1 / (1 + np.exp(-x)) return -np.sum(t * np.log(y) + (1 - t) * np.log(1 - y)) / y.shape[0]
我们给出一个温和的例子:
a = np.random.rand(10) b = a > 0.5 print a print b print naive_sigmoid_loss(a,b) [ 0.39962673 0.04308825 0.18672843 0.05445796 0.82770513 0.16295996 0.18544111 0.57409273 0.63078192 0.62763516] [False False False False True False False True True True] 0.63712381656
下面自然是一个暴力的例子:
a = np.random.rand(10)* 1000 b = a > 500 print a print b print naive_sigmoid_loss(a,b) [ 63.20798359 958.94378279 250.75385942 895.49371345 965.62635077 81.1217712 423.36466749 532.20604694 333.45425951 185.72621262] [False True False True True False False True False False] nan
果然不出所料,我们的程序又一次溢出了。
那怎么办呢?这里节省点笔墨,直接照搬老司机的推导过程:(侵删,我就自己推一遍了……)
于是,代码变成了:
def high_level_sigmoid_loss(x, t): first = (t - (x > 0)) * x second = np.log(1 + np.exp(x - 2 * x * (x > 0))) return -np.sum(first - second) / x.shape[0]
举一个例子:
a = np.random.rand(10)* 1000 - 500 b = a > 0 print a print b print high_level_sigmoid_loss(a,b) [-173.48716596 462.06216262 -417.78666769 6.10480948 340.13986055 23.64615392 256.33358957 -332.46689674 416.88593348 -246.51402684] [False True False True True True True False True False] 0.000222961919658
这样一来数值的问题也就解决了!
就剩一句话了
计算中遇到Exp要小心溢出!