Простая нейронная сеть, использующая только один класс - PullRequest
0 голосов
/ 26 апреля 2018

Я реализовал простую нейронную сеть на Java, которая должна решить проблему XOR (http://www.mind.ilstu.edu/curriculum/artificial_neural_net/xor_problem_and_solution.php).

Мне было интересно, для чего вам нужны классы Neuron, NeuronLayer и т. Д., Поэтому я решил попытаться заставить его работать, используя только один класс.

К сожалению, после некоторых эпох он достигает состояния, когда ошибка имеет одно из двух значений: 0,5 или -0,5.

Я пытался ограничить диапазон, из которого выбираются стартовые веса, но это ничего не изменило.

Может быть, некоторые из вас могут помочь мне обнаружить ошибку или улучшить сеть. Заранее спасибо!

Вот мой код:

int inCount = 2;
int hidCount = 3;
int outCount = 1;

float learningRate = 0.01;

float[] inputs = new float[inCount];
float[] hidden = new float[hidCount];
float[] outputs = new float[outCount];

float[][] IHweights = new float[inCount][hidCount];
float[][] HOweights = new float[hidCount][outCount];

void setup ()
{
  for (int i = 0; i < IHweights.length; i++)
  {
    for (int e = 0; e < IHweights[i].length; e++)
    {
      float newWeight = random(-1,1);
      while(newWeight > -0.5 && newWeight < 0.5)
      {
        newWeight = random(-1,1);
      }
      IHweights[i][e] = newWeight;
      println(IHweights[i][e]+"\n");
    }
  }

  for (int i = 0; i < HOweights.length; i++)
  {
    for (int e = 0; e < HOweights[i].length; e++)
    {
      float newWeight = random(-1,1);
      while(newWeight > -0.5 && newWeight < 0.5)
      {
        newWeight = random(-1,1);
      }
      HOweights[i][e] = newWeight;
    }
  }
}

void draw ()
{
  float[] inData = {round(random(1)),round(random(1))};
  println(inData[0]+"   "+inData[1]);
  float[] expResult = {(int) inData[0]^(int) inData[1]};
  println("  ->  "+expResult[0]);
  feedForward(inData,expResult);
}

public float sigmoid (float x)
{
  if (x>10)
  {
    return 1;
  }
  if (x<-10)
  {
    return 0;
  }
  return 1/(1+exp(-x));
}

public void feedForward (float[] input, float[] expOut)
{
  inputs = input;

  for (int i = 0; i < hidCount; i++)
  {
    float var = 0;
    for (int e = 0; e < inCount; e++)
    {
      var += inputs[e] * IHweights[e][i];
    }
    hidden[i] = sigmoid(var);
  }

  for (int i = 0; i < outCount; i++)
  {
    float var = 0;
    for (int e = 0; e < hidCount; e++)
    {
      var += hidden[e] * HOweights[e][i];
    }
    outputs[i] = sigmoid(var);
  }

  float[] error = new float[outCount];
  float[] deltaOut = new float[outCount];

  for (int i = 0; i < outCount; i++)
  {
    error[i] = expOut[i] - outputs[i];
    deltaOut[i] = outputs[i] * (1-outputs[i]) * error[i];
  }

  float[] deltaHid = new float[hidCount];

  for (int i = 0; i < hidCount; i++)
  {
    deltaHid[i] = hidden[i] * (1-hidden[i]);
    for (int e = 0; e < outCount; e++)
    {
      deltaHid[i] += HOweights[i][e] * outputs[e];
    }
  }

  for (int i = 0; i < inCount; i++)
  {
    for (int e = 0; e < hidCount; e++)
    {
      IHweights[i][e] += inputs[i] * deltaHid[e] * learningRate;
    }
  }

  for (int i = 0; i < hidCount; i++)
  {
    for (int e = 0; e < outCount; e++)
    {
      HOweights[i][e] += hidden[i] * deltaOut[e] * learningRate;
    }
  }

  println(error[0]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...