Java中的XOR神经网络

我正在尝试用Java中的XOR函数实现和训练具有反向传播的五神经元神经网络。 我的代码(请原谅它的丑陋):

public class XORBackProp { private static final int MAX_EPOCHS = 500; //weights private static double w13, w23, w14, w24, w35, w45; private static double theta3, theta4, theta5; //neuron outputs private static double gamma3, gamma4, gamma5; //neuron error gradients private static double delta3, delta4, delta5; //weight corrections private static double dw13, dw14, dw23, dw24, dw35, dw45, dt3, dt4, dt5; //learning rate private static double alpha = 0.1; private static double error; private static double sumSqrError; private static int epochs = 0; private static boolean loop = true; private static double sigmoid(double exponent) { return (1.0/(1 + Math.pow(Math.E, (-1) * exponent))); } private static void activateNeuron(int x1, int x2, int gd5) { gamma3 = sigmoid(x1*w13 + x2*w23 - theta3); gamma4 = sigmoid(x1*w14 + x2*w24 - theta4); gamma5 = sigmoid(gamma3*w35 + gamma4*w45 - theta5); error = gd5 - gamma5; weightTraining(x1, x2); } private static void weightTraining(int x1, int x2) { delta5 = gamma5 * (1 - gamma5) * error; dw35 = alpha * gamma3 * delta5; dw45 = alpha * gamma4 * delta5; dt5 = alpha * (-1) * delta5; delta3 = gamma3 * (1 - gamma3) * delta5 * w35; delta4 = gamma4 * (1 - gamma4) * delta5 * w45; dw13 = alpha * x1 * delta3; dw23 = alpha * x2 * delta3; dt3 = alpha * (-1) * delta3; dw14 = alpha * x1 * delta4; dw24 = alpha * x2 * delta4; dt4 = alpha * (-1) * delta4; w13 = w13 + dw13; w14 = w14 + dw14; w23 = w23 + dw23; w24 = w24 + dw24; w35 = w35 + dw35; w45 = w45 + dw45; theta3 = theta3 + dt3; theta4 = theta4 + dt4; theta5 = theta5 + dt5; } public static void main(String[] args) { w13 = 0.5; w14 = 0.9; w23 = 0.4; w24 = 1.0; w35 = -1.2; w45 = 1.1; theta3 = 0.8; theta4 = -0.1; theta5 = 0.3; System.out.println("XOR Neural Network"); while(loop) { activateNeuron(1,1,0); sumSqrError = error * error; activateNeuron(0,1,1); sumSqrError += error * error; activateNeuron(1,0,1); sumSqrError += error * error; activateNeuron(0,0,0); sumSqrError += error * error; epochs++; if(epochs >= MAX_EPOCHS) { System.out.println("Learning will take more than " + MAX_EPOCHS + " epochs, so program has terminated."); System.exit(0); } System.out.println(epochs + " " + sumSqrError); if (sumSqrError < 0.001) { loop = false; } } } } 

如果它有帮助,这是一个网络图 。

所有权重的初始值和学习率直接来自我的教科书中的一个例子。 目标是训练网络,直到平方误差的总和小于.001。 教科书还给出了第一次迭代(1,1,0)后所有权重的值,并且我测试了我的代码,其结果完全符合教科书的结果。 但根据这本书,这应该只需要224个时代汇聚。 但是当我运行它时,它总是达到MAX_EPOCHS,除非它设置为几千。 我究竟做错了什么?

  //Add this in the constants declaration section. private static double alpha = 3.8, g34 = 0.13, g5 = 0.21; // Add this in activate neuron gamma3 = sigmoid(x1 * w13 + x2 * w23 - theta3); gamma4 = sigmoid(x1 * w14 + x2 * w24 - theta4); if (gamma3 > 1 - g34 ) {gamma3 = 1;} if (gamma3 < g34) {gamma3 = 0;} if (gamma4 > 1- g34) {gamma4 = 1;} if (gamma4 < g34) {gamma4 = 0;} gamma5 = sigmoid(gamma3 * w35 + gamma4 * w45 - theta5); if (gamma5 > 1 - g5) {gamma5 = 1;} if (gamma5 < g5) {gamma5 = 0;} 

ANN应该在66次迭代中学习,但是处于分歧的边缘。

尝试在激活阶段对gamma3,gamma4,gamma5进行舍入:

 if (gamma3 > 0.7) gamma3 = 1; if (gamma3 < 0.3) gamma3 = 0; 

并上升一点学习变量(alpha)

 alpha = 0.2; 

学习在466个时代结束。

当然,如果你做出更大的舍入和更高的alpha设置,你可以获得比224更好的结果。

这个网络的重点是展示如何处理分组不是基于“top = yes,bottom = no”的情况,而是有一条中心线(通过点(0,1)和(1) ,0)在这种情况下)如果值接近该行,则回答为“是”,而如果它是远,则回答为“否”。 您不能仅使用一个层来集群此类系统。 但是两层就足够了。