3

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;
}
4

1 に答える 1