関連する論文を読み直し、教科書を調べた後、encog のドキュメントは現時点では正しくないと思います。ソースコードにマイナス記号を一時的に追加して試してみませんか? ドキュメントが正しければ、同じ初期重みを使用すると、まったく同じ結果が得られるはずです。しかし、最終的には weightUpdate 変数をどのように使用するかが重要です。ドキュメントの作成者が weightUpdate を追加するのではなく、重みから削除することに慣れている場合、これは機能します。
編集:元の回答の勾配計算に関する部分を再訪しました。
まず、出力レイヤーの重みのグラデーションをどのように想像できるかについて簡単に説明します。まず、出力と目標値の間の誤差を計算します。
あなたが今やろうとしていることは、アクティブだった前の層のニューロンを「責める」ことです。出力ニューロンが「ここでエラーが発生しました。責任者は誰ですか?」と言っていると想像してください。責任があるのは、前の層のニューロンです。ターゲット値と比較して出力が小さすぎるか大きすぎるかによって、前のレイヤーの各ニューロンの重みが増減されます。
x は隠れ層のニューロンの活性化です。
o は出力ニューロンの活性化です。
φ は出力ニューロンの活性化関数であり、φ' はその導関数です。
Edit2 : 以下の部分を修正しました。バックプロパゲーションの行列スタイルの計算が追加されました。
各出力ニューロン j での誤差は次のとおりです。
(1) δアウト、j = φ'(o j )(t - o j )
非表示ニューロン i と出力ニューロン j を接続する重みの勾配:
(2) 勾配i, j = x i * δ out, j
重み w を使用した各隠れニューロン i での逆伝播誤差:
(3) δ hid, i = φ'(x)*∑w i, j * δ out, j
式 2 と 3 を繰り返し適用することで、入力層まで逆伝播できます。
1 つのトレーニング サンプルに関して、 loopsで記述します。
各出力ニューロン j での誤差は次のとおりです。
for(int j=0; j < numOutNeurons; j++) {
errorOut[j] = activationDerivative(o[j])*(t[j] - o[j]);
}
非表示ニューロン i と出力ニューロン j を接続する重みの勾配:
for(int i=0; i < numHidNeurons; i++) {
for(int j=0; j < numOutNeurons; j++) {
grad[i][j] = x[i] * errorOut[j]
}
}
各隠れニューロン i での逆伝播誤差:
for(int i=0; i < numHidNeurons; i++) {
for(int j=0; j < numOutNeurons; j++) {
errorHid[i] = activationDerivative(x[i]) * weights[i][j] * errorOut[j]
}
}
畳み込みなどのない完全に接続された多層パーセプトロンでは、標準の行列演算を使用できます。これははるかに高速です。
各サンプルが入力行列の行であり、列がその属性であると仮定すると、次のようにネットワークを介して入力を伝播できます。
activations[0] = input;
for(int i=0; i < numWeightMatrices; i++){
activations[i+1] = activations[i].dot(weightMatrices[i]);
activations[i+1] = activationFunction(activations[i+1]);
}
バックプロパゲーションは次のようになります。
n = numWeightMatrices;
error = activationDerivative(activations[n]) * (target - activations[n]);
for (int l=n-1; l >= 0; l--){
gradient[l] = activations[l].transposed().dot(error);
if (l > 0) {
error = error.dot(weightMatrices[l].transposed());
error = activationDerivative(activations[l])*error;
}
}
上記の説明では、バイアス ニューロンを省略しました。文献では、常に 1.0 である各活性化行列の追加の列としてバイアス ニューロンをモデル化することが推奨されています。いくつかのスライス割り当てを処理する必要があります。行列逆伝播ループを使用する場合は、各ステップの前にバイアスの位置の誤差を 0 に設定することを忘れないでください!