1

ニューラルネットワーククラスについて、次のドラフトがあります。このニューラルネットワークはTDラムダで学習する必要があります。これは、getRating()関数を呼び出すことによって開始されます。

ただし、残念ながら、次の行で約1000回の反復を行った後、EInvalidOp(無効な読み込みポイント操作)エラーが発生します。

neuronsHidden[j] := neuronsHidden[j]+neuronsInput[t][i]*weightsInput[i][j]; // input -> hidden

weightsHidden[j][k] := weightsHidden[j][k]+LEARNING_RATE_HIDDEN*tdError[k]*eligibilityTraceOutput[j][k]; // adjust hidden->output weights according to TD-lambda

このエラーはなぜですか?コードに間違いが見つかりません:(助けてくれませんか?よろしくお願いします!

learningMode: Boolean; // does the network learn and change its weights?
neuronsInput: Array[1..MAX_TIMESTEPS] of Array[1..NEURONS_INPUT] of Extended;
neuronsHidden: Array[1..NEURONS_HIDDEN] of Extended;
neuronsOutput: Array[1..NEURONS_OUTPUT] of Extended;
weightsInput: Array[1..NEURONS_INPUT] of Array[1..NEURONS_HIDDEN] of Extended;
weightsHidden: Array[1..NEURONS_HIDDEN] of Array[1..NEURONS_OUTPUT] of Extended;

[...]

function HyperbolicTangent;
begin
  if x > 5500 then // prevent overflow
    result := 1
  else
    result := (Exp(2*x)-1)/(Exp(2*x)+1);
end;
[...]
4

3 に答える 3

2

答えではなく、単なる提案です。表示している2行のコードには、乗算と加算、非常に単純な操作のみが含まれています。失敗時に値をログに記録するのはどうですか。おそらく、何かを理解できる値を確認してください。

例外で停止する際の最も厄介な問題は、その例外に関係する変数を検査できないことです。この制限を回避するために、面倒な操作をtry-exceptブロックでラップし、exceptハンドラーにブレークポイントを設定することがあります。Delphiは最初に例外で停止し、実行を押してから、ブレークポイントで停止します。ブレークポイントでは、エラー生成ステートメントで使用されているすべての変数を自由に検査できるため、何が問題なのかを把握できます。

// In place of:
neuronsHidden[j] := neuronsHidden[j]+neuronsInput[t][i]*weightsInput[i][j];

var saveNerusonsHidden: Double;
try
  saveNeuronsHidden := neuronsHidden[j]; // saved, to be sure I can inspect the original value
  neuronsHidden[j] := neuronsHidden[j]+neuronsInput[t][i]*weightsInput[i][j];
except on E:EInvalidOp do
  begin
    // Breakpoint here, so you can inspect the values of neuronsInput[t][i], wightsInput[i][j] and saveNeuronsHidden
    raise;
  end;
end;
于 2011-02-17T07:10:42.517 に答える
1

エラーの最も可能性の高い理由は、アキュムレータneuronsHiddenまたはweightsHidden. 私はニューラル ネットワークについて何も知らないので、なぜそうなのかについて説明することはできません。

副次的な問題として、Extended浮動小数点変数の使用について疑問があります。通常、これは単純にパフォーマンスが非常に遅くなり、 を使用する場合よりもはるかに遅くなりますDouble。多数の場合にヘッドルームが増えると思うかもしれませんが、実際には、これが私が疑う性質の暴走的なオーバーフローである場合、 を使用してExtendedも決して救われることはありません。

UPDATE OP は、オーバーフローによって別の例外クラスが発生することを指摘しています。したがって、EInvalidOp平方根または三角関数の失敗またはそのようなものが疑われます。またはおそらくシグナリングNaNですが、初期化されていないデータを明らかに使用していないため、それを追求しません。

Embarcadero のTanh. これは、Delphi の古いバージョン (D6 など) では完全に機能していましたが、最近壊れました。使用するバージョンは、大きな負の入力にはまったく適しておらずExp、1 つで十分な場合に 2 つの呼び出しを使用します。私はこのバージョンを使用します:

const
  MaxTanhDomain = 5678.22249441322; // Ln(MaxExtended)/2

function Tanh(const X: Extended): Extended;
begin
  if X>MaxTanhDomain then begin
    Result := 1.0
  end else if X<-MaxTanhDomain then begin
    Result := -1.0
  end else begin
    Result := Exp(X);
    Result := Result*Result;
    Result := (Result-1.0)/(Result+1.0);
  end;
end;
于 2011-02-16T06:48:50.597 に答える
0

非常に大きな数または非常に小さな数を計算すると、EInvalidOp を取得できます。

このエラーが発生した場合、配列内の値をデバッグ/表示し、ウォッチ リストで部分的な計算を行うことができますか?

于 2011-02-16T07:21:32.227 に答える