gpt4 book ai didi

c++ - 反向传播不适用于 XOR

转载 作者:搜寻专家 更新时间:2023-10-31 02:14:40 26 4
gpt4 key购买 nike

过去两周我一直在学习反向传播,做了它背后的数学计算,并认为我对这个主题的理解足够好,可以自己实现(没有任何线性代数包等)。显然,我错了。您可以在下面找到我能想到的最简单的示例网络:2 个隐藏单元和 1 个输出单元。我尝试学习 XOR 函数。但是,这根本不起作用。预测始终在 0.5 左右。我不确定我在哪里搞砸了。也许有人可以提供帮助?

float sigmoid(float pX) {
return 1.0f/(1.0f+exp(-1.0f*pX));
}

int main(int argc, char const *argv[]) {
// DEFINE XOR problem
float examples[4][2] = { {0,0} , {0,1}, {1,0}, {1,1}};
float labels[4] = {0, 1, 1, 0};

/* I want to use a network with two hidden neurons and 1 output neuron
*/

// Weights from input to hidden neurons
float WInput[2][2];
float WInputBias[2];

// Weights from hidden to output neuron
float WOutput[2];
float WOutputBias;

// output of hidden layer to output neuron
float hidden[2];

// error for hidden layer
float error[2];

//output of network
float yPred;

// randomly init weights
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<float> d(0, 0.1);
WInput[0][0] = d(gen); WInput[0][1] = d(gen);
WInput[1][0] = d(gen); WInput[1][1] = d(gen);
WInputBias[0] = d(gen); WInputBias[1] = d(gen);
WOutput[0] = d(gen); WOutput[1] = d(gen); WOutputBias = d(gen);

// do the learning
for(unsigned int i = 0; i < 1000; ++i) {
for (unsigned int k = 0; k < 4; ++k) {
float * input = &examples[k][0];
float label = labels[k];

// Compute forward pass
hidden[0] = sigmoid(WInput[0][0]*input[0] + WInput[1][0]*input[1] + WInputBias[0]);
hidden[1] = sigmoid(WInput[0][1]*input[0] + WInput[1][1]*input[1] + WInputBias[1]);
yPred = sigmoid(WOutput[0]*hidden[0] + WOutput[1]*hidden[1] + WOutputBias);

std :: cout << "Target / Prediction: " << label << " / " << yPred << std :: endl;

// Backward pass with alpha = 0.1
float outputError = -(label - yPred)*yPred*(1-yPred);
WOutput[0] = WOutput[0] - 0.1f*outputError*hidden[0]; //hidden equals input from this layer
WOutput[1] = WOutput[1] - 0.1f*outputError*hidden[1];
WOutputBias = WOutputBias - 0.1f*outputError;

error[0] = (WOutput[0]*outputError)*hidden[0]*(1-hidden[0]);
error[1] = (WOutput[1]*outputError)*hidden[1]*(1-hidden[1]);

WInput[0][0] = WInput[0][0] - 0.1f*error[0]*input[0];
WInput[1][0] = WInput[1][0] - 0.1f*error[0]*input[1];
WInput[0][1] = WInput[0][1] - 0.1f*error[1]*input[0];
WInput[1][1] = WInput[1][1] - 0.1f*error[1]*input[1];
WInputBias[0] = WInputBias[0] - 0.1f*error[0];
WInputBias[1] = WInputBias[1] - 0.1f*error[1];

}
std :: cout << std :: endl;
// getch();
}
}

最佳答案

我又看了一遍代码,并尝试了一些参数,结果证明所有代码实际上都是正确的。

问题是,只有 2 个隐藏节点,这个问题很难学习,你使用的训练周期数 (1000) 与你使用的学习率 (0.1) 相结合意味着它还没有收敛。

尝试让它训练大约 4000-6000 个时期(或者,最好是,直到误差的绝对值降至某个阈值以下),并尝试将权重更新乘以 1.0 而不是 0.1。那么你应该会得到更好的结果。

它也可能有助于随机初始化权重位于 [-0.1, 0.1] 而不是 [0.0, 0.1]。不过,这应该不会有太大的不同。

关于c++ - 反向传播不适用于 XOR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39663730/

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