我有以下代码
# 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
我的问题是:
哪一行代码引起了警告?我猜cost
的行与log()
相同,但是为什么警告中提到了divide
?我唯一的divide
操作是最后一层的派生,但该行没有log()
。
关于invalid value in multiply
的警告的哪个部分来自:Y*np.log(A)
或(1-Y)*np.log(1-A)
?
警告是否使我的网络结果无效?
如何解决警告问题?
能请你帮忙吗?预先感谢。
我使用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,并且对网络进行了训练,而没有运行时警告。我根本不明白根本问题是什么。
答案 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.])