web-dev-qa-db-ja.com

numpy:softmax関数の導関数を計算します

backpropagationを使用した単純な3層ニューラルネットワークでMNISTを理解しようとしています。

weightsbiasを持つ入力レイヤーがあります。ラベルはMNISTなので、10クラスベクトルです。

2番目のレイヤーはlinear tranformです。 3番目の層は、出力を確率として取得するsoftmax activationです。

Backpropagationは各ステップで導関数を計算し、これを勾配と呼びます。

前のレイヤーは、globalまたはpreviousグラデーションをlocal gradientに追加します。 softmaxlocal gradientの計算に問題があります

オンラインでいくつかのリソースがsoftmaxとその派生物の説明を通過し、softmax自体のコードサンプルを提供します。

def softmax(x):
    """Compute the softmax of vector x."""
    exps = np.exp(x)
    return exps / np.sum(exps)

派生物は、いつi = jおよびi != jに関して説明されます。これは、私が思いついた簡単なコードスニペットであり、私の理解を確認したいと考えていました。

def softmax(self, x):
    """Compute the softmax of vector x."""
    exps = np.exp(x)
    return exps / np.sum(exps)

def forward(self):
    # self.input is a vector of length 10
    # and is the output of 
    # (w * x) + b
    self.value = self.softmax(self.input)

def backward(self):
    for i in range(len(self.value)):
        for j in range(len(self.input)):
            if i == j:
                self.gradient[i] = self.value[i] * (1-self.input[i))
            else: 
                 self.gradient[i] = -self.value[i]*self.input[j]

self.gradientは、ベクトルであるlocal gradientです。これは正しいです?これを書くより良い方法はありますか?

10
Sam Hammamy

W1b1 forが入力レイヤーから非表示レイヤーへの線形変換に関連付けられ、W2b2が関連付けられた3レイヤーNNがあると仮定しています隠れ層から出力層への線形変換。 Z1およびZ2は、非表示層および出力層への入力ベクトルです。 a1およびa2は、非表示層および出力層の出力を表します。 a2は予測出力です。 delta3delta2はエラー(逆伝播)であり、モデルパラメーターに関する損失関数の勾配を確認できます。

enter image description hereenter image description here

これは、3層NN(入力層、1つの非表示層と1つの出力層のみ)の一般的なシナリオです。上記の手順に従って、簡単に計算できる勾配を計算できます!この投稿への別の答えはすでにあなたのコードの問題を指しているので、私は同じことを繰り返していません。

16
Wasi Ahmad

先ほど言ったように、あなたは_n^2_偏微分を持っています。

計算すると、_dSM[i]/dx[k]_がSM[i] * (dx[i]/dx[k] - SM[i])であることがわかります。

_if i == j:
    self.gradient[i,j] = self.value[i] * (1-self.value[i])
else: 
    self.gradient[i,j] = -self.value[i] * self.value[j]
_

の代わりに

_if i == j:
    self.gradient[i] = self.value[i] * (1-self.input[i])
else: 
     self.gradient[i] = -self.value[i]*self.input[j]
_

ちなみに、これは(ベクトル化された)より簡潔に計算できます:

_SM = self.value.reshape((-1,1))
jac = np.diagflat(self.value) - np.dot(SM, SM.T)
_
9
Julien

np.expにはInfがあるため安定していません。したがって、xの最大値を減算する必要があります。

def softmax(x):
    """Compute the softmax of vector x."""
    exps = np.exp(x - x.max())
    return exps / np.sum(exps)

Xが行列の場合、このノートブックのsoftmax関数を確認してください( https://github.com/rickiepark/ml-learn/blob/master/notebooks/5.%20multi-layer%20perceptron.ipynb =)

6
Haesun Park