gpt4 book ai didi

neural-network - 教授神经网络 : Bipolar XOR

转载 作者:行者123 更新时间:2023-12-04 06:41:26 24 4
gpt4 key购买 nike

我正在尝试教授 2 个输入、4 个隐藏节点(都在同一层)和 1 个输出节点的神经网络。二进制表示工作正常,但我对双极有问题。我不知道为什么,但总误差有时会收敛到 2.xx 附近的相同数字。我的 sigmoid 是 2/(1+ exp(-x)) - 1。也许我在错误的地方使用了 sigmoid。例如,要计算输出误差,我应该将 sigmoided 输出与期望值还是与 sigmoided 期望值进行比较?

我在这里关注这个网站:http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html ,但他们使用不同的功能然后我被指示使用。即使我确实尝试实现他们的功能,我仍然遇到了同样的问题。无论哪种方式,我都有一半的时间卡在相同的数字上(不同的实现有不同的数字)。请告诉我我的代码是否在某处犯了错误,或者这是否正常(我不知道这是怎么回事)。动量设置为 0。这是一个常见的 0 动量问题吗?我们应该使用的误差函数是:

如果 ui 是输出单元
Error(i) = (Ci - ui ) * f'(Si )
如果 ui 是隐藏单元
Error(i) = Error(Output) * weight(i to output) * f'(Si)

public double sigmoid( double x ) {
double fBipolar, fBinary, temp;
temp = (1 + Math.exp(-x));
fBipolar = (2 / temp) - 1;
fBinary = 1 / temp;
if(bipolar){
return fBipolar;
}else{
return fBinary;
}

}

// Initialize the weights to random values.
private void initializeWeights(double neg, double pos) {
for(int i = 0; i < numInputs + 1; i++){
for(int j = 0; j < numHiddenNeurons; j++){
inputWeights[i][j] = Math.random() - pos;
if(inputWeights[i][j] < neg || inputWeights[i][j] > pos){
print("ERROR ");
print(inputWeights[i][j]);
}
}
}
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenWeights[i] = Math.random() - pos;
if(hiddenWeights[i] < neg || hiddenWeights[i] > pos){
print("ERROR ");
print(hiddenWeights[i]);
}
}
}

// Computes output of the NN without training. I.e. a forward pass
public double outputFor ( double[] argInputVector ) {
for(int i = 0; i < numInputs; i++){
inputs[i] = argInputVector[i];
}
double weightedSum = 0;
for(int i = 0; i < numHiddenNeurons; i++){
weightedSum = 0;
for(int j = 0; j < numInputs + 1; j++){
weightedSum += inputWeights[j][i] * inputs[j];
}
hiddenActivation[i] = sigmoid(weightedSum);
}

weightedSum = 0;
for(int j = 0; j < numHiddenNeurons + 1; j++){
weightedSum += (hiddenActivation[j] * hiddenWeights[j]);
}

return sigmoid(weightedSum);
}

//Computes the derivative of f
public static double fPrime(double u){
double fBipolar, fBinary;
fBipolar = 0.5 * (1 - Math.pow(u,2));
fBinary = u * (1 - u);
if(bipolar){
return fBipolar;
}else{
return fBinary;
}
}

// This method is used to update the weights of the neural net.
public double train ( double [] argInputVector, double argTargetOutput ){
double output = outputFor(argInputVector);
double lastDelta;

double outputError = (argTargetOutput - output) * fPrime(output);

if(outputError != 0){
for(int i = 0; i < numHiddenNeurons + 1; i++){
hiddenError[i] = hiddenWeights[i] * outputError * fPrime(hiddenActivation[i]);
deltaHiddenWeights[i] = learningRate * outputError * hiddenActivation[i] + (momentum * lastDelta);
hiddenWeights[i] += deltaHiddenWeights[i];
}

for(int in = 0; in < numInputs + 1; in++){
for(int hid = 0; hid < numHiddenNeurons; hid++){
lastDelta = deltaInputWeights[in][hid];
deltaInputWeights[in][hid] = learningRate * hiddenError[hid] * inputs[in] + (momentum * lastDelta);
inputWeights[in][hid] += deltaInputWeights[in][hid];
}
}
}

return 0.5 * (argTargetOutput - output) * (argTargetOutput - output);
}

最佳答案

一般编码注释:

initializeWeights(-1.0, 1.0);

实际上可能无法获得您期望的初始值。

initializeWeights 应该有:
inputWeights[i][j] = Math.random() * (pos - neg) + neg;
// ...
hiddenWeights[i] = (Math.random() * (pos - neg)) + neg;

代替:
Math.random() - pos;

这样就可以了:
initializeWeights(0.0, 1.0);

并为您提供介于 0.0 和 1.0 之间而不是介于 -1.0 和 0.0 之间的初始值。
lastDelta在声明之前使用:
deltaHiddenWeights[i] = learningRate * outputError * hiddenActivation[i] + (momentum * lastDelta);

我不确定 + 1numInputs + 1numHiddenNeurons + 1是必要的。

记住要注意整数的舍入:5/2 = 2,而不是 2.5!
请改用 5.0/2.0。通常,当输出应该是 double 时,在代码中添加 .0。

最重要的是,你对 NeuralNet 的训练时间够长了吗?

尝试使用 numInputs = 2、numHiddenNeurons = 4、learningRate = 0.9 和 运行它训练 1,000 或 10,000 次。

使用 numHiddenNeurons = 2 有时会在尝试解决 XOR 问题时“卡住”。

另见 XOR problem - simulation

关于neural-network - 教授神经网络 : Bipolar XOR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4190494/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com