Resilient Propagation を正しく実装するのに苦労しています。ニューラル ネットワークをトレーニングするためにバックプロパゲーション アルゴリズムを既に実装しました。これは XOR-Net で期待どおりに機能します。つまり、エラーを 1% 未満に下げるには約 600 エポックが必要です。今、同じ問題に対して Resilient Propagation ( http://en.wikipedia.org/wiki/Rprop ) を実装しようとしましたが、最初のいくつかのエポックではエラーが 23% まで急速に低下しましたが、その後 50% まで上昇し、そこにとどまりました。http://www.heatonresearch.com/book/introduction-neural-network-math.html
の説明に従って正確に実装しました、しかし、それは不可解です 説明: それは、ウィキペディアの Rprop-Page とは異なり、また、私が知る限り、本と同じ著者によって書かれた encog の実装とも異なります。また、さまざまなソースからさまざまな実装を既に試しましたが、何も機能しませんでした。
さまざまなソース間の違いの一部:
- 重みの変化の計算に、signum(currentPartialDerivative * previousPartialDerivative) の代わりに signum(currentPartialDerivative) を使用する
- 新しい重み変更の新しい更新値の代わりに、最後の重み変更を使用する
- 最初に重みの変化を計算し、次に新しい更新値を計算します
これを実装する正しい方法は何ですか? その後、本によると実装:
public ResilientPropagation() {
initialUpdateValue = 0.01;
deltaMaximum = 50;
deltaMinimum = 0.000001;
negativeEta = 0.5;
positiveEta = 1.2;
double zeroTolerance = 0.0000000000000001;
signum = new Signum(zeroTolerance);
init();
}
@Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
if (!synapseValues.containsKey(synapse)){
double initialPartialDerivative = 0;
synapseValues.put(synapse, new SynapseValues(initialUpdateValue, initialPartialDerivative));
}
SynapseValues values = synapseValues.get(synapse);
double signChange = signum.value(values.lastPartialDerivative * partialDerivative);
values.lastPartialDerivative = partialDerivative;
double weightChange = 0;
if (signChange > 0){
newUpdateValue = Math.min(positiveEta * values.updateValue, deltaMaximum);
weightChange = -1*newUpdateValue;
} else if (signChange < 0){
newUpdateValue = Math.max(negativeEta * values.updateValue, deltaMinimum);
weightChange = newUpdateValue;
} else {
newUpdateValue = values.updateValue;
double weightChange = 0;
}
values.updateValue = newUpdateValue;
return weightChange;
}
通常のバックプロパゲーションの同じメソッドが正常に機能します。
@Override
public double calculateWeightChange(Synapse synapse, double partialDerivative) {
double previousChange = previousWeightChange.get(synapse) != null ? previousWeightChange.get(synapse) : 0;
double weightChange = learningRate * partialDerivative + momentum * previousChange;
previousWeightChange.put(synapse, weightChange);
return weightChange;
}