RuntimeWarning:在日志中除以零,在乘法中除以无效​​值

时间:2019-04-19 01:07:08

标签: python numpy conv-neural-network

我有以下代码

# weighted input:
Z = np.array(...) 

# activation for hidden layer:                
A = np.where(Z > 0, Z, Z * 0.01) 

# activation for last layer:
A = 1.0 / (1.0 + np.exp(-Z)) 

# cost function for the output at last layer:    
cost =  np.sum(np.nan_to_num(-Y*np.log(A)-(1-Y)*np.log(1-A)))

# derivative of cost function:
dA = (A - Y) / A * (1 - A)  

# derivative of hidden layer:
dZ = np.ones_like(cache)
dZ[cache < 0] = 0.01

# derivative of last layer:
dZ = np.exp(-Z)/(1 + np.exp(-Z))**2

当我训练神经网络时,具有一定的学习率(0.1或0.5,但当学习率= 0.01时不是),在某些迭代中收到以下警告:

D:\Users\jason\AppData\Local\Continuum\Anaconda3\lib\site-packages\ipykernel_launcher.py:21: RuntimeWarning: divide by zero encountered in log
D:\Users\jason\AppData\Local\Continuum\Anaconda3\lib\site-packages\ipykernel_launcher.py:21: RuntimeWarning: invalid value encountered in multiply

我的问题是:

  1. 哪一行代码引起了警告?我猜cost的行与log()相同,但是为什么警告中提到了divide?我唯一的divide操作是最后一层的派生,但该行没有log()

  2. 关于invalid value in multiply的警告的哪个部分来自:Y*np.log(A)(1-Y)*np.log(1-A)

  3. 警告是否使我的网络结果无效?

  4. 如何解决警告问题?

能请你帮忙吗?预先感谢。

我使用expit(Z)尝试了kmario23的建议,但仍然得到以下信息:

Cost after iteration 0: 0.954719
Cost after iteration 100: 0.321576
Cost after iteration 200: 0.291157
D:\Users\jason\AppData\Local\Continuum\Anaconda3\lib\site-packages\ipykernel_launcher.py:21: RuntimeWarning: divide by zero encountered in log
D:\Users\jason\AppData\Local\Continuum\Anaconda3\lib\site-packages\ipykernel_launcher.py:21: RuntimeWarning: invalid value encountered in multiply
Cost after iteration 300: inf
Cost after iteration 400: inf
Cost after iteration 500: inf
Cost after iteration 600: inf
Cost after iteration 700: inf
Cost after iteration 800: inf

新信息: 我在原始代码中添加了几行以确保AL永远不会为0或1:

min_nonzero = np.min(AL[np.nonzero(AL)])
AL[AL == 0] = min_nonzero
AL[AL == 1] = 0.999
cost =  np.sum(np.nan_to_num(-Y*np.log(AL)-(1-Y)*np.log(1-AL)))

然后我遇到了以下错误

~\AppData\Local\Continuum\Anaconda3\lib\site-packages\numpy\core\fromnumeric.py in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs)
     84                 return reduction(axis=axis, out=out, **passkwargs)
     85 
---> 86     return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
     87 
     88 

ValueError: zero-size array to reduction operation minimum which has no identity

这是否有助于找出divide by zero in log原始问题的根本原因?

更新 我将所有内容恢复为原始代码,但将学习率从0.01更改为0.009,并且对网络进行了训练,而没有运行时警告。我根本不明白根本问题是什么。

1 个答案:

答案 0 :(得分:1)

据我所知,罪魁祸首是如何以数值不稳定的方式计算A的方式,问题可能出现在以下行中:

A = 1.0 / (1.0 + np.exp(-Z)) 

所以,我建议您用更稳定的SciPy's expit funciton代替上一行。

from scipy.special import expit 
A = expit(Z)

并且比使用NumPy手动实现它要快得多。

expit产生的值范围为[0, 1]-封闭间隔。

例如:非常高的+ ve值将近似为1,而非常高的-ve值将近似为0。

expit([-np.inf, -1.5,  0,   1.5,   np.inf])
array([ 0.   ,  0.182, 0.5, 0.817, 1.])