【问题标题】:Java Back-propagation ANN output valuesJava 反向传播 ANN 输出值
【发布时间】:2015-01-13 04:05:54
【问题描述】:

我正在尝试用 Java 编写一个简单的反向传播 ANN 实现,但我得到了非常奇怪的输出。 ANN 有一个带有两个节点的输入层(一个用于输入向量中的每个值),一个带有 4 个节点的单个隐藏层(我已经尝试过更多但无济于事)和一个带有 3 个节点的输出层。三个输出节点代表数据的三种可能分类,采用“one-hot”编码。

ANN 的一些输入格式如下:

0.020055 0.40759 2
0.020117 0.14934 3
0.020117 0.25128 3
0.020262 1.6068 1

2 个小数作为 2 个输入,整数是所需的分类 (1-3)。

在使用列表中每个可能的数据组合训练 ANN 之后,我得到的所有输出看起来都像这样,小数点作为三个输出节点的输出

0.11237534579646044   0.15172262242962917   0.7906017313009316   2
0.13686775670201043   0.1774606939461421   0.7656339988150088   3
0.13554918638846133   0.1761024282314506   0.766924262279491   3
0.06185317503169881   0.09410559150503017   0.8516964148498476   1

按照我写的方式,每一行应该显示一个“高”值(由于 sigmoidal 函数,接近 0.95),其余的应该是“低”(接近 0.05)。

下面是我写的计算最终输出值的方法:

public static double [] testANN(double [] input, List<BPNode> hiddenLayer, List <BPNode> outputLayer){
    double [] outInputs = new double[hiddenLayer.size()];
    double [] results = new double[outputLayer.size()];
    for(int i = 0; i<hiddenLayer.size(); i++){
        BPNode node = hiddenLayer.get(i);
        node.inputs = input.clone();
        outInputs[i] = node.getOutput();
    }
    for(int i = 0; i<outputLayer.size(); i++){
        BPNode node = outputLayer.get(i);
        node.inputs = outInputs.clone();
        results[i] = node.getOutput();
    }

    return results;
}

下面是使用反向传播算法训练 ANN 的方法:

public static void trainANN(double [] input, int desired, List<BPNode> hiddenLayer, List <BPNode> outputLayer){
   double [] d = new double[outputLayer.size()];
   d[0] = desired==1 ? 0.95 :0.05;
   d[1] = desired==2 ? 0.95 :0.05;
   d[2] = desired==3 ? 0.95 :0.05;
   double [] [] weights = new double[outputLayer.size()][hiddenLayer.size()];
   double [] output = testANN(input,hiddenLayer,outputLayer);
   double [] del = new double[outputLayer.size()];
   for(int i = 0; i<outputLayer.size(); i++){
       del[i] = (d[i]-output[i])*output[i]*(1-output[i]);
       for (int j = 0; j<outputLayer.get(i).weights.length; j++){
           weights[i][j] = outputLayer.get(i).weights[j];
           outputLayer.get(i).weights[j]+=0.2*del[i]*outputLayer.get(i).inputs[j];
       }
   }
   for(int i = 0; i<hiddenLayer.size(); i++){
       double hiddenDel = 0.0;
       for(int j = 0; j<outputLayer.size(); j++){
           hiddenDel+=(del[j]*weights[j][i]*hiddenLayer.get(i).getOutput()*(1-hiddenLayer.get(i).getOutput()));
       }
       for(int j = 0; j<hiddenLayer.get(i).weights.length; j++){
           hiddenLayer.get(i).weights[j]+=0.2*hiddenDel*input[j];
       }
   }

}

最后,这是我用来实现 ANN 的 Node 类:

public class BPNode {

public double [] inputs = new double[10];
public double [] weights = new double[10];

public BPNode(double [] w){
    weights = w;
}

public double getOutput() {
    double a = 0;
    for(int j = 0; j<inputs.length; j++){
        a += (inputs[j] * weights[j]);
    }
    return sigmoid(a,10.0);
}

private static double sigmoid(double x, double m)
{
    return 1 / (1 + Math.exp(-x*m));
}

}

所有的权重都被初始化为 0.1,并且节点已经被放置在 Array Lists 中。非常感谢您的帮助。

【问题讨论】:

    标签: java neural-network backpropagation


    【解决方案1】:

    对于任何想知道我如何解决这个问题的人,我尝试在 0 和 1 之间随机改变权重。这表现得稍微好一些,但是一旦我尝试在 1 和 -1 之间改变权重,ANN 就能够对 85% 的数据正确。

    【讨论】:

      猜你喜欢
      • 2013-07-06
      • 2017-03-13
      • 1970-01-01
      • 2016-02-16
      • 2013-02-05
      • 2013-08-05
      • 1970-01-01
      • 2018-10-24
      • 1970-01-01
      相关资源
      最近更新 更多