前馈神经网络训练
Feedforward Neural Network Training
我正在尝试编写前馈 NN,我正在测试它以使用粒子群优化来学习 x*y 函数来学习(PSO 算法正在运行),但它甚至无法接近学习该函数.我已经检查了我的代码很多次,所以我不知道我是否对 NN 算法中的任何明显错误视而不见!
架构是一个 int[],因此 {No'Inputs,No'Hidden neurons,No'outputs}
所以这里我使用 {2,3,1} 作为 x*y。
注意 - 添加神经元 0 用于输入层和隐藏层中的偏差。激活函数为tanh()
//takes in array of inputs, and weight vector w
public 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 输出是无界的,普通 MLP 不适合学习此类函数。充其量,它只能近似于 x*y 的某个固定范围,给定正确归一化的数据 2)。要正确学习乘法,应该将数字表示为二进制(每个输入神经元一个数字)。有关使用 NN 进行算术运算的进一步讨论,请参阅 this paper。
结论:x*y 对于调试新实现的神经网络来说是一个非常糟糕的选择。考虑改用 AND、OR、XOR 等逻辑门。
我正在尝试编写前馈 NN,我正在测试它以使用粒子群优化来学习 x*y 函数来学习(PSO 算法正在运行),但它甚至无法接近学习该函数.我已经检查了我的代码很多次,所以我不知道我是否对 NN 算法中的任何明显错误视而不见!
架构是一个 int[],因此 {No'Inputs,No'Hidden neurons,No'outputs} 所以这里我使用 {2,3,1} 作为 x*y。
注意 - 添加神经元 0 用于输入层和隐藏层中的偏差。激活函数为tanh()
//takes in array of inputs, and weight vector w
public 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 输出是无界的,普通 MLP 不适合学习此类函数。充其量,它只能近似于 x*y 的某个固定范围,给定正确归一化的数据 2)。要正确学习乘法,应该将数字表示为二进制(每个输入神经元一个数字)。有关使用 NN 进行算术运算的进一步讨论,请参阅 this paper。
结论:x*y 对于调试新实现的神经网络来说是一个非常糟糕的选择。考虑改用 AND、OR、XOR 等逻辑门。