Skip to content

Commit f952705

Browse files
committed
add note about numerical instability
1 parent bb2f046 commit f952705

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

code/ch12/ch12.ipynb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,21 @@
706706
" term1 = -y_enc * (np.log(output))\n",
707707
" term2 = (1. - y_enc) * np.log(1. - output)\n",
708708
" cost = np.sum(term1 - term2) + L2_term\n",
709+
" \n",
710+
" # If you are applying this cost function to other\n",
711+
" # datasets where activation\n",
712+
" # values maybe become more extreme (closer to zero or 1)\n",
713+
" # you may encounter \"ZeroDivisionError\"s due to numerical\n",
714+
" # instabilities in Python & NumPy for the current implementation.\n",
715+
" # I.e., the code tries to evaluate log(0), which is undefined.\n",
716+
" # To address this issue, you could add a small constant to the\n",
717+
" # activation values that are passed to the log function.\n",
718+
" #\n",
719+
" # For example:\n",
720+
" #\n",
721+
" # term1 = -y_enc * (np.log(output + 1e-5))\n",
722+
" # term2 = (1. - y_enc) * np.log(1. - output + 1e-5)\n",
723+
" \n",
709724
" return cost\n",
710725
"\n",
711726
" def predict(self, X):\n",

code/ch12/ch12.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,21 @@ def _compute_cost(self, y_enc, output):
331331
term1 = -y_enc * (np.log(output))
332332
term2 = (1. - y_enc) * np.log(1. - output)
333333
cost = np.sum(term1 - term2) + L2_term
334+
335+
# If you are applying this cost function to other
336+
# datasets where activation
337+
# values maybe become more extreme (closer to zero or 1)
338+
# you may encounter "ZeroDivisionError"s due to numerical
339+
# instabilities in Python & NumPy for the current implementation.
340+
# I.e., the code tries to evaluate log(0), which is undefined.
341+
# To address this issue, you could add a small constant to the
342+
# activation values that are passed to the log function.
343+
#
344+
# For example:
345+
#
346+
# term1 = -y_enc * (np.log(output + 1e-5))
347+
# term2 = (1. - y_enc) * np.log(1. - output + 1e-5)
348+
334349
return cost
335350

336351
def predict(self, X):

code/ch12/neuralnet.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,21 @@ def _compute_cost(self, y_enc, output):
109109
term1 = -y_enc * (np.log(output))
110110
term2 = (1. - y_enc) * np.log(1. - output)
111111
cost = np.sum(term1 - term2) + L2_term
112+
113+
# If you are applying this cost function to other
114+
# datasets where activation
115+
# values maybe become more extreme (closer to zero or 1)
116+
# you may encounter "ZeroDivisionError"s due to numerical
117+
# instabilities in Python & NumPy for the current implementation.
118+
# I.e., the code tries to evaluate log(0), which is undefined.
119+
# To address this issue, you could add a small constant to the
120+
# activation values that are passed to the log function.
121+
#
122+
# For example:
123+
#
124+
# term1 = -y_enc * (np.log(output + 1e-5))
125+
# term2 = (1. - y_enc) * np.log(1. - output + 1e-5)
126+
112127
return cost
113128

114129
def predict(self, X):

0 commit comments

Comments
 (0)