我正在尝试编写前馈神经网络,并使用粒子群优化算法来学习x*y函数(PSO算法是有效的),但它甚至无法接近学习这个函数。我已经多次检查我的代码,所以我不知道是否已经对神经网络算法中的任何明显错误视而不见了!
架构是一个整数数组,如下所示 {输入数量, 隐藏层神经元数量, 输出数量},所以在这里我使用 {2,3,1} 来表示x*y。
注意 – 在输入层和隐藏层中添加了神经元0作为偏置。激活函数是tanh()。
//takes in array of inputs, and weight vector wpublic float[] solve(float[] input, float[] w){ int max_neurons = 0; for(int i =0; i<this.architecture.length; i++){ max_neurons = this.architecture[i]>max_neurons? this.architecture[i]:max_neurons; } //layer output arrays float[] output = new float[max_neurons+1]; //+1 for bias neuron 0 float[] output_l = new float[max_neurons+1]; output[0] = 1; //set bias output_l[0] = 1; //set bias //setup from input for(int i = 0; i<architecture[0]; i++){ output[i+1] = input[i]; } //iterate through hidden layers int hidden_layers = architecture.length-2; int vector_index = 0; float av = 0; for(int l = 1; l<=hidden_layers; l++){ for(int n = 1; n<=architecture[l]; n++){ av = 0; for(int k = 0; k<=architecture[l-1]; k++){ av += output[k]*w[vector_index]; vector_index++; } output_l[n] = af.activation(av); } output = Arrays.copyOf(output_l, output_l.length); } //output layer no activation function int l = architecture.length-1; for(int n = 0; n<architecture[l]; n++){ av = 0; for(int k = 0; k<=architecture[l-1]; k++){ av += output[k]*w[vector_index]; vector_index++; } output_l[n] = av; } return Arrays.copyOf(output_l, output_l.length);}
回答:
首先也是最重要的一点是,无论你如何编写代码,前馈多层神经网络都无法学习x*y,特别是当数据以两个连续输入的形式呈现时。原因有:1)x * y的输出是无界的,普通的多层感知器不适合学习这样的函数。充其量,它只能在给定适当归一化的数据下近似x*y的某个固定范围。2)要正确学习乘法,应该将数字表示为二进制(每个输入神经元一个数字)。有关使用神经网络进行算术运算的进一步讨论,请参见这篇论文。
结论:x*y对于调试新实现的神经网络来说是一个非常糟糕的选择。考虑使用逻辑门如AND、OR、XOR来代替。