私は soft-max を次のコードで実装しようとしました(out_vec
はfloatのnumpy
ベクトルです):
numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator
ただし、np.exp(out_vec)
が原因でオーバーフローエラーが発生しました。したがって、np.exp()
の上限を(手動で)チェックし、np.exp(709)
が数値であることがわかりましたが、np.exp(710)
はnp.inf
と見なされます。したがって、オーバーフローエラーを回避するために、コードを次のように変更しました。
out_vec[out_vec > 709] = 709 #prevent np.exp overflow
numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator
今、私は別のエラーが発生します:
RuntimeWarning: invalid value encountered in greater out_vec[out_vec > 709] = 709
追加した行の何が問題になっていますか?私はこの特定のエラーを調べましたが、私が見つけたのは、エラーを無視する方法に関する人々のアドバイスだけです。エラーを無視するだけでは役に立ちません。コードでこのエラーが発生するたびに通常の結果が得られないためです。
問題は、out_vec
配列のNaN
またはInf
要素が原因です。この問題を回避するには、次のコードを使用できます。
if np.isnan(np.sum(out_vec)):
out_vec = out_vec[~numpy.isnan(out_vec)] # just remove nan elements from vector
out_vec[out_vec > 709] = 709
...
または、次のコードを使用して、配列にNaN
値を残すことができます。
out_vec[ np.array([e > 709 if ~np.isnan(e) else False for e in out_vec], dtype=bool) ] = 709
私の場合、比較の前にこれを呼び出すと警告が表示されませんでした(比較されるNaN値がありました)
np.warnings.filterwarnings('ignore')
IMOのより良い方法は、指数の和の数値的に安定した実装を使用することです。
from scipy.misc import logsumexp
out_vec = np.exp(out_vec - logsumexp(out_vec))