37

次のコードでソフトマックスを実装しようとしました(out_vecnumpyフロートのベクトルです):

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

追加した行の何が問題になっていますか? この特定のエラーを調べたところ、エラーを無視する方法に関する人々のアドバイスしか見つかりませんでした。コードでこのエラーが発生するたびに通常の結果が得られないため、単にエラーを無視しても役に立ちません。

4

4 に答える 4

36

問題は、配列内のNaNまたはInf要素が原因です。out_vecこの問題を回避するには、次のコードを使用できます。

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
于 2016-06-06T08:13:17.490 に答える
8

IMOより良い方法は、指数関数の合計のより数値的に安定した実装を使用することです。

from scipy.misc import logsumexp
out_vec = np.exp(out_vec - logsumexp(out_vec))
于 2016-12-28T11:00:36.807 に答える