7

ニューラル ネットで使用されるシグモイド関数を確認すると、https : //en.wikipedia.org/wiki/Softmax_function#Softmax_Normalization から次の式が見つかりました。

ここに画像の説明を入力

標準のシグモイド方程式とは異なります。

ここに画像の説明を入力

一番上の最初の方程式には平均値と標準偏差が含まれています(記号を間違って読んでいないことを願っています)が、2番目の方程式はマイナス平均を一般化し、標準偏差で割った定数です。これは、ベクトル内のすべての項で同じであるためです。 /マトリックス/テンソル。

したがって、方程式を実装すると、異なる結果が得られます。

2 番目の式 (標準のシグモイド関数) を使用すると、次のようになります。

def sigmoid(x):
    return 1. / (1 + np.exp(-x))

これらの出力が得られます:

>>> x = np.array([1,2,3])
>>> print sigmoid(x)
[ 0.73105858  0.88079708  0.95257413]

私は最初の関数が似ていることを期待していましたが、最初と2番目の要素の間のギャップはかなり広がっています(ただし、要素のランキングは残っています:

def get_statistics(x):
    n = float(len(x))
    m = x.sum() / n
    s2 = sum((x - m)**2) / (n-1.) 
    s = s2**0.5
    return m, s2, s

m, s, s2 = get_statistics(x)

sigmoid_x1 = 1 / (1 + np.exp(-(x[0] - m) / s2))
sigmoid_x2 = 1 / (1 + np.exp(-(x[1] - m) / s2))
sigmoid_x3 = 1 / (1 + np.exp(-(x[2] - m) / s2))
sigmoid_x1, sigmoid_x2, sigmoid_x3 

[アウト]:

(0.2689414213699951, 0.5, 0.7310585786300049)

おそらく、最初の方程式に何らかのソフトマックス正規化が含まれているという事実に関係している可能性がありますが、それが一般的なソフトマックスである場合、要素は合計して 1 になる必要があります。

def softmax(x):
    exp_x = np.exp(x)
    return exp_x / exp_x.sum()

[アウト]:

>>> x = np.array([1,2,3])
>>> print softmax(x)
[ 0.09003057  0.24472847  0.66524096]

しかし、最初の方程式からの出力は合計が 1 にならず、標準のシグモイド方程式と類似/同じではありません。質問は次のとおりです。

  • 式 1 の関数を間違って実装しましたか?
  • ウィキペディアの式 1 は間違っていますか? それとも、実際にはシグモイド/ロジスティック関数ではなく、何か他のものを参照していますか?
  • 1 番目と 2 番目の式に違いがあるのはなぜですか?
4

2 に答える 2

5

方程式を正しく実装しました。あなたの問題は、ソフトマックス関数とシグモイド関数の定義を混同していることです。

ソフトマックス関数は、外れ値を「あまり面白く」なくすることでデータを正規化する方法です。さらに、ベクトルの合計が 1 になるように、入力ベクトルを「押しつぶします」。

あなたの例:

> np.sum([ 0.09003057,  0.24472847,  0.66524096])
> 1.0

これは、間隔 (0, 1) 内のベクトルのすべての要素とその合計を 1.0 にするための「制約」を追加したロジスティック関数の単純な一般化です。

シグモイド関数は、ロジスティック関数のもう 1 つの特殊なケースです。これは、ベル型の実数値の微分可能な関数です。計算がかなり簡単で、非線形であり、負と正の境界があるため、ニューラルネットワークにとって興味深いものです。そのため、活性化は発散できず、「高すぎる」と飽和します。

ただし、シグモイド関数は、入力ベクトルの合計が 1.0 になることを保証していません。

ニューラル ネットワークでは、シグモイド関数は単一ニューロンの活性化関数として頻繁に使用されますが、シグモイド/ソフトマックス正規化関数はむしろ出力層で使用され、層全体の合計が 1 になるようにします。シグモイド関数を混同しただけです (単一ニューロンの場合) 対シグモイド/ソフトマックス正規化関数 (レイヤー全体の場合)。

編集:これを明確にするために、外れ値を使用した簡単な例を示します。これは、2つの異なる関数の動作を示しています。

シグモイド関数を実装しましょう。

import numpy as np

def s(x):
    return 1.0 / (1.0 + np.exp(-x))

そして、正規化されたバージョン (読みやすくするための小さなステップ):

def sn(x):
    numerator = x - np.mean(x)
    denominator = np.std(x)
    fraction = numerator / denominator

    return 1.0 / (1.0 + np.exp(-fraction))

ここで、大きな外れ値を持つもののいくつかの測定値を定義します。

measure = np.array([0.01, 0.2, 0.5, 0.6, 0.7, 1.0, 2.5, 5.0, 50.0, 5000.0])

s次に、 (シグモイド) とsn(正規化されたシグモイド) が与える結果を見てみましょう。

> s(measure)
> array([ 0.50249998,  0.549834  ,  0.62245933,  0.64565631,  0.66818777,
    0.73105858,  0.92414182,  0.99330715,  1.        ,  1.        ])

> sn(measure)
> array([ 0.41634425,  0.41637507,  0.41642373,  0.41643996,  0.41645618,
    0.41650485,  0.41674821,  0.41715391,  0.42447515,  0.9525677 ])

ご覧のとおりs、ロジスティック関数を介して値を「1 つずつ」変換するだけなので、外れ値は 0.999、1.0、1.0 で完全に飽和します。他の値の間の距離は異なります。

見てみるsnと、関数が実際に値を正規化したことがわかります。5000.0 であった 0.95 を除いて、すべてが非常に同一になりました。

これは何に役立ちますか、またはこれをどのように解釈しますか?

ニューラル ネットワークの出力層を考えてみてください。出力層の 1 つのクラスで 5000.0 の活性化 (他の小さな値と比較して) は、これが与えられた入力に対して「正しい」クラスであることをネットワークが本当に確信していることを意味します。そこで使用sした場合、最終的に 0.99、1.0、および 1.0 になり、どのクラスが入力の正しい推測であるかを区別できなくなります。

于 2016-04-27T22:54:46.377 に答える