对于神经网络类,我有以下草案。这个神经网络应该学习TD-lambda。它通过调用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;
[...]
最佳答案
错误的最可能原因是累加器neuronsHidden
或weightsHidden
。我对神经网络一无所知,因此无法提供任何解释。
作为附带问题,我质疑Extended
浮点变量的使用。通常,这只会导致性能极慢,比使用Double
时要慢得多。您可能会认为它为大量用户提供了更大的扩展空间,但实际上,如果这是我怀疑的性质的失控溢出,那么使用Extended
永远无法挽救您。
UPDATE OP指出溢出会导致不同的异常类。因此,对于EInvalidOp
,我怀疑是某些平方根或Trig失败或类似的事情。也许是一个信号NaN,但是由于您显然不使用未初始化的数据,因此我不建议这样做。
我现在可以看到,您已经受到Embarcadero中断其Tanh
实施的奇怪决定的影响。过去,该代码可以在旧版的Delphi(例如D6)上完美运行,但最近已被破坏。您使用的版本不太适合用于较大的负输入,并且在满足条件的情况下使用两个对Exp
的调用。我使用这个版本:
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;
关于delphi - Delphi:神经网络类(TD-lambda)中的EInvalidOp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5010871/