この行:delta3[range(num_examples), y] -= 1
はの一部である私は、私は(私の自宅のPCを含む)を実行しようとしたどこにでもエラーを得ていましたソフトマックス損失関数の勾配を計算する。私はこの損失関数がどのように定式化されているか、その背後にある直感の詳細について、あなたにこの素晴らしいリンクを紹介します:http://peterroelants.github.io/posts/neural_network_implementation_intermezzo02/。
さらに、私はsoftmax損失の勾配がどのように導出されるかを示す数学的スタックエクスチェンジに関するこの記事を参照してください:https://math.stackexchange.com/questions/945871/derivative-of-softmax-loss-function。最初のリンクを深いダイビングとして考えてください。一方、2番目のリンクは最初のリンクのtl;dr
です。
ソフトマックス損失関数の勾配は、出力レイヤーがバックプロパゲーションアルゴリズムを続行する前に、レイヤーに逆方向に伝播する必要がある出力レイヤーの勾配です。
上記のリンクをまとめたので、訓練例のsoftmaxの勾配の勾配を計算すると、各クラスの損失の勾配は単純にそのクラスで評価されたsoftmaxの値になります。さらに、実際のトレーニングサンプルが属するクラスの損失値を1つ減算する必要があります。 i
の例の勾配は、p_i - y_i
に等しく、ここで、p_i
は、例のクラスi
のsoftmaxスコアであり、y_i
は、ワンホットエンコーディングスキームを使用する分類ラベルです。具体的には、y_i = 0
の場合、i
は例の真のクラスではない場合はy_i = 1
です。 delta3
には、ミニバッチの例ごとにsoftmax loss関数の勾配が含まれています。具体的には、行の総数が訓練例の数と等しい2次元行列、または列の数がクラスの総数である場合はnum_examples
です。
まず、各トレーニング例と各クラスのsoftmaxスコアを計算します。次に、グラディエントの各行について、例が属する真のクラスに対応する列の位置を決定し、スコアを1だけ引きます。0
からnum_examples - 1
にリストを生成し、y
には例ごとの真のクラスラベルが含まれます。したがって、range(num_examples)
とy
の各ペアに対して、右の行と列の位置にアクセスして1を引いて、損失関数の勾配を確定します。
数学スタックエクスチェンジのポストとあなたの理解では、グラデーションはdelta3 = probs - y
です。これはy
はprobs
と同じサイズを有し、y
の行ごとに、それが1に設定されている適切なクラスが含まれている列インデックスの除くすべてゼロであることを意味し、y
はワンホット符号化行列であることを前提としていしたがって、正しく考えると、行列y
を生成した場合、各行に対して、その例が属するクラス番号を除いて列がすべて0になる場合は、各行の右の列にアクセスしてスコアを減算することと同等です
MATLABでは、この減算を容易にするために線形インデックスを作成する必要があります。具体的には、あなたは、線形インデックスにこれらの行と列の位置を変換するsub2ind
を使用する必要があり、我々は勾配マトリックスにアクセスし、そこで1
て値を減算することができる:Pythonのチュートリアルで
ind = sub2ind(size(delta3), 1 : num_examples, y + 1);
delta3(ind) = delta3(ind) - 1;
あなたクラスラベルは0
からN-1
までと仮定され、ここでN
はクラスの総数です。 1
から始まる配列のインデックス付けをMATLABで開始する必要がありますので、0
の代わりに1
でラベルが始まるように、上記のコードで1
をy
に追加しました。 ind
には、アクセスする必要がある行と列の位置の線形インデックスが含まれているため、これらのインデックスを使用して減算を完了します。あなたがあなたの編集から得た知識を使って、これを策定した場合
、あなたの代わりにこれを行うだろう:
ymatrix = full(sparse(1 : num_examples, y + 1, 1, size(delta3, 1), size(delta3, 2));
delta3 = probs - ymatrix;
ymatrix
は、私は、各行が全てで例に対応する場所について話しましたマトリックスが含まれています例が属しているクラスに関連する列を除いて0です。これまでに見たことがないものは、sparse
とfull
です。 sparse
を使用すると、ゼロ行列を作成することができます。また、ゼロ以外の行と列の位置と、これらの位置のそれぞれが使用する値を指定することができます。この例では、行ごとに1つの要素にアクセスし、例のクラスIDを使用して列にアクセスし、これらの場所のそれぞれを1に設定しています。また、クラスを想定しているので、これはsparse
の行列なので、sparse
という形式で表現するのではなく、数値の行列を与えるためにfull
に変換します。したがって、このコードは、私が示した前のコードスニペットと同じです。ただし、勾配計算を容易にするために追加の行列を作成しないので、最初の方法で行う方が効率的です。その代わりにグラデーションを修正しています。追記として
、sklearn
はscikit-learn Pythonの機械学習パッケージである、とNameError
は、インストール実際のパッケージを持っていないに言及しています。
pip install sklearn
か:しかし
easy_install sklearn
、scikitあなたのコマンドラインで、それはのように簡単ですので、それをインストールするには、....お使いのコンピュータにPythonパッケージをインストールするpip
またはeasy_install
を使用上記の減算コードを実行するには、-learnは必須ではありません。あなたはNumPyが必要ですが、そのパッケージがインストールされていることを確認してください。 pip
については
:
pip install numpy
...とeasy_install
用:
easy_install numpy
'delta3'は何ですか? 'NameError'は' sklearn'が見つからないことを意味していますので、正しく 'import'しなかったでしょう。 –