gpt4 book ai didi

java - 具有线性层的简单神经网络未生成预期输出

转载 作者:行者123 更新时间:2023-11-29 05:32:29 25 4
gpt4 key购买 nike

我一直在网上关注 jeff heaton 指南,我来到了这一点,我试图创建一个简单的神经网络,它有三个输入神经元和一个输出神经元,没有隐藏层,三个权重与这三个输入神经元相关联。

神经网络从总共 6 个二进制组合中识别出两个 3 位的二进制组合。

代码如下:

class neural{
double weight1=1.0,weight2=1.0,weight3=1.0;
double learningRate = 0.000001;
public double getOutput(double i1,double i2,double i3,double ideals){
double u = weight1*i1 + weight2*i2 + weight3*i3;
double error = 0.0;
error = ideals -u;
weight1 += error * learningRate * i1;
weight2 += error * learningRate * i2 ;
weight3 += error * learningRate * i3 ;

return u;
}


}

public class pattern{
public static void main(String argz[]){
neural a = new neural();
for(int i = 0; i < 2000; i++){
a.getOutput(0.0, 0.0, 0.0,0.0);
a.getOutput(0.0, 0.0, 1.0,1.0);
a.getOutput(0.0, 1.0, 0.0,1.0);
a.getOutput(0.0, 1.0, 1.0,0.0);
a.getOutput(1.0, 1.0, 0.0,0.0);
a.getOutput(1.0, 1.0, 1.0,1.0);

}

}
}

正如@Widdershins 指出的那样,我尝试了低至 0.000001 的学习率

高于 0.5 的为 1,低于 0.5 的为 0。因此输出为 000101 而不是 011001

最佳答案

所以,让我们在脑海中解决这个问题。

u 是您使用输入和给定权重获得的结果。

ideals 是您希望实现的输出。

error 就是 u 出错的数量;它应该是 from uideals 的距离。也就是说,它应该是ideals - u。这似乎是正确的。

不过,您的学习值似乎相当高。将这些值设置得太高可能导致振荡而不是收敛,特别是对于高度规则的输入。您是否检查过在学习循环接近尾声的连续运行之间您的体重值是什么样的?您是否尝试过降低学习率?

免责声明:我不是神经网络专家,您应该将我所做的任何断言视为推测,但这是我的理解。

编辑:我尝试使用少得多的学习值(在 0.25 和 0.01 之间)运行您的代码,少至 200 次并获得了所需的输出。对于一个如此简单的网络,您不需要 将近 两万个循环,并且记住保持您的学习率足够低以避免出现奇怪的结果:有了大约 200 个学习循环,网络将开始输出一旦学习率达到大约 0.7 的临界值,错误的 000101 而不是 001010。较低的学习率,即使是非常低的学习率,也会产生更好的结果。


现在我们正在研究 sigmoid 函数:

import java.util.Random;
import java.util.Arrays;

public class NeuralNet {
static final Random rand = new Random();


static final double[][] teach = new double[][]
{ {0d, 0d, 0d, 0d},
{0d, 0d, 1d, 0d},
{0d, 1d, 0d, 1d},
{0d, 1d, 1d, 0d},
{1d, 1d, 0d, 1d},
{1d, 1d, 1d, 0d} };


public static void main(String[] args) {
Neural a = new Neural();
for(int i = 0; i < 2000; i++){
int t = rand.nextInt(teach.length);
a.learn(teach[t][0], teach[t][1], teach[t][2], teach[t][3]);
}

System.out.println(a);
for (int t = 0; t < teach.length; t++) {
System.out.println(a.react(teach[t][0], teach[t][1], teach[t][2]));
}
}

public static double sigmoid(double u) {
return 1 / (1 + Math.exp(-u));
}

static class Neural {
static final double INIT_WEIGHT_RANGE = 1 / Math.sqrt(3);
final double LEARNING_RATE = 0.1;

double offset = (rand.nextDouble() * 2 - 1) * INIT_WEIGHT_RANGE,
weight1 = (rand.nextDouble() * 2 - 1) * INIT_WEIGHT_RANGE,
weight2 = (rand.nextDouble() * 2 - 1) * INIT_WEIGHT_RANGE,
weight3 = (rand.nextDouble() * 2 - 1) * INIT_WEIGHT_RANGE;

public double learn(double i1, double i2, double i3, double ideals) {
double u =
offset +
weight1 * i1 +
weight2 * i2 +
weight3 * i3;
u = sigmoid(u);
double correction = (ideals - u) * LEARNING_RATE;

offset += correction;
weight1 += correction * i1;
weight2 += correction * i2;
weight3 += correction * i3;

return u;
}

public double react(double i1, double i2, double i3) {
double u =
offset +
weight1 * i1 +
weight2 * i2 +
weight3 * i3;
return sigmoid(u);
}

public String toString() {
// how lazy!
return Arrays.toString(new double[] {offset, weight1, weight2, weight3});
}
}
}

我刚才已经阅读了一些关于我们应该拥有什么样的反向传播函数的资料,但是像这样让它保持线性似乎效果很好。 For all I can tell这可能是正确的。有了足够多的 epoch,这几乎可以学习从 0 到 1 的任何值。

关于java - 具有线性层的简单神经网络未生成预期输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20647294/

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