Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java实现神经网络:训练和反向传播问题_Java_Neural Network_Backpropagation_Feed Forward - Fatal编程技术网

用Java实现神经网络:训练和反向传播问题

用Java实现神经网络:训练和反向传播问题,java,neural-network,backpropagation,feed-forward,Java,Neural Network,Backpropagation,Feed Forward,我正试图用Java实现一个前馈神经网络。 我创建了三个类NNeuron、NLayer和NNetwork。“简单”的计算似乎很好(我得到了正确的总和/激活/输出),但在培训过程中,我似乎没有得到正确的结果。谁能告诉我我做错了什么吗? NNetwork类的整个代码相当长,因此我将发布导致问题的部分: [编辑]:这实际上是几乎所有的网络类 import java.util.ArrayList; 导入java.util.array; 导入java.util.List; 公共类网络 { 公共静态最终双默认

我正试图用Java实现一个前馈神经网络。 我创建了三个类NNeuron、NLayer和NNetwork。“简单”的计算似乎很好(我得到了正确的总和/激活/输出),但在培训过程中,我似乎没有得到正确的结果。谁能告诉我我做错了什么吗? NNetwork类的整个代码相当长,因此我将发布导致问题的部分: [编辑]:这实际上是几乎所有的网络类

import java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共类网络
{
公共静态最终双默认学习率=0.4;
公共静态最终双违约动量=0.8;
私有n层输入层;
私有数组列表隐藏层;
私有n层输出层;
私有数组列表层;
private double momentum=NNetwork1.defaultMomentum;//alpha:momentum,默认值!0.3
私人ArrayList学习率;
公共网络(整数输入、整数输出、整数…神经元SperhidEndLayer)
{
这(nInputs、noutput、array.asList(neurosperhiddenlayer));
}
公共网络(整数输入、整数输出、列表输出层)
{
//到目前为止最后一层构建的神经元数量(即下一层每个神经元的输入数量)
int prvOuts=1;
this.layers=新的ArrayList();
//输入层
this.inputLayer=新的NLayer(nInputs、prvOuts、this);
这个.inputLayer.SetAllWeights为(1.0);
此.inputLayer.SetAllBiaseTo(0.0);
this.inputLayer.useSigmaForOutput(false);
prvOuts=nInputs;
this.layers.add(this.inputLayer);
//隐藏层
this.hiddenLayers=new ArrayList();

对于(inti=0;i我试着检查您的代码,但正如您所说的,它相当长

以下是我的建议:

  • 要验证您的网络是否正常学习,请尝试训练一个简单的网络,例如识别XOR运算符的网络。这不需要花那么长时间
  • 使用最简单的反向传播算法。随机反向传播(在每次训练输入呈现后更新权重)是最简单的。最初在不使用动量项的情况下,以恒定的学习速率(即,不要从自适应学习速率开始)实现该算法。一旦你对算法的运行感到满意,你就可以引入动量项。同时做太多的事情会增加不止一件事情出错的可能性。这会让你更难看出哪里出了错
  • 如果你想看一些代码,你可以查看一些;你想看的。我基本上实现了带有动量项的随机反向传播算法。我还有一个例子,我在这里快速解释了我的反向传播算法的实现

希望这会有所帮助!

这里是一个非常简单的java实现,在主方法中进行了测试:

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

public class MLP {

 public static class MLPLayer {

  float[] output;
  float[] input;
  float[] weights;
  float[] dweights;
  boolean isSigmoid = true;

  public MLPLayer(int inputSize, int outputSize, Random r) {
   output = new float[outputSize];
   input = new float[inputSize + 1];
   weights = new float[(1 + inputSize) * outputSize];
   dweights = new float[weights.length];
   initWeights(r);
  }

  public void setIsSigmoid(boolean isSigmoid) {
   this.isSigmoid = isSigmoid;
  }

  public void initWeights(Random r) {
   for (int i = 0; i < weights.length; i++) {
    weights[i] = (r.nextFloat() - 0.5f) * 4f;
   }
  }

  public float[] run(float[] in) {
   System.arraycopy(in, 0, input, 0, in.length);
   input[input.length - 1] = 1;
   int offs = 0;
   Arrays.fill(output, 0);
   for (int i = 0; i < output.length; i++) {
    for (int j = 0; j < input.length; j++) {
     output[i] += weights[offs + j] * input[j];
    }
    if (isSigmoid) {
     output[i] = (float) (1 / (1 + Math.exp(-output[i])));
    }
    offs += input.length;
   }
   return Arrays.copyOf(output, output.length);
  }

  public float[] train(float[] error, float learningRate, float momentum) {
   int offs = 0;
   float[] nextError = new float[input.length];
   for (int i = 0; i < output.length; i++) {
    float d = error[i];
    if (isSigmoid) {
     d *= output[i] * (1 - output[i]);
    }
    for (int j = 0; j < input.length; j++) {
     int idx = offs + j;
     nextError[j] += weights[idx] * d;
     float dw = input[j] * d * learningRate;
     weights[idx] += dweights[idx] * momentum + dw;
     dweights[idx] = dw;
    }
    offs += input.length;
   }
   return nextError;
  }
 }
 MLPLayer[] layers;

 public MLP(int inputSize, int[] layersSize) {
  layers = new MLPLayer[layersSize.length];
  Random r = new Random(1234);
  for (int i = 0; i < layersSize.length; i++) {
   int inSize = i == 0 ? inputSize : layersSize[i - 1];
   layers[i] = new MLPLayer(inSize, layersSize[i], r);
  }
 }

 public MLPLayer getLayer(int idx) {
  return layers[idx];
 }

 public float[] run(float[] input) {
  float[] actIn = input;
  for (int i = 0; i < layers.length; i++) {
   actIn = layers[i].run(actIn);
  }
  return actIn;
 }

 public void train(float[] input, float[] targetOutput, float learningRate, float momentum) {
  float[] calcOut = run(input);
  float[] error = new float[calcOut.length];
  for (int i = 0; i < error.length; i++) {
   error[i] = targetOutput[i] - calcOut[i]; // negative error
  }
  for (int i = layers.length - 1; i >= 0; i--) {
   error = layers[i].train(error, learningRate, momentum);
  }
 }

 public static void main(String[] args) throws Exception {
  float[][] train = new float[][]{new float[]{0, 0}, new float[]{0, 1}, new float[]{1, 0}, new float[]{1, 1}};
  float[][] res = new float[][]{new float[]{0}, new float[]{1}, new float[]{1}, new float[]{0}};
  MLP mlp = new MLP(2, new int[]{2, 1});
  mlp.getLayer(1).setIsSigmoid(false);
  Random r = new Random();
  int en = 500;
  for (int e = 0; e < en; e++) {

   for (int i = 0; i < res.length; i++) {
    int idx = r.nextInt(res.length);
    mlp.train(train[idx], res[idx], 0.3f, 0.6f);
   }

   if ((e + 1) % 100 == 0) {
    System.out.println();
    for (int i = 0; i < res.length; i++) {
     float[] t = train[i];
     System.out.printf("%d epoch\n", e + 1);
     System.out.printf("%.1f, %.1f --> %.3f\n", t[0], t[1], mlp.run(t)[0]);
    }
   }
  }
 }
}
导入java.util.array;
导入java.util.Random;
公共类MLP{
公共静态类MLPLayer{
浮点输出;
浮点[]输入;
浮动[]砝码;
浮动[]重量;
布尔isSigmoid=true;
公共MLPLayer(int-inputSize、int-outputSize、Random r){
输出=新浮点[outputSize];
输入=新浮点[inputSize+1];
权重=新浮点[(1+输入大小)*输出大小];
dweights=新浮动[重量.长度];
初始权重(r);
}
public void setIsSigmoid(布尔isSigmoid){
this.isSigmoid=isSigmoid;
}
公共权重(随机r){
对于(int i=0;i=0;i--){
错误=层[i]。训练(错误、学习率、动量);
}
}
公共静态void main(字符串[]args)引发异常{
float[][]train=newfloat[][{newfloat[]{0,0},newfloat[]{0,1},newfloat[]{1,0},newfloat[]{1,1};
float[][]res=新的float[][{n