2016-07-09 1 views
1

Вот код.Мой одиночный персептрон не работает

public class Adaline 
{ 
    private int _layer; 
    public int Layer { get { return _layer; } } 
    private int _epoch; 
    public int Epoch { get { return _epoch; } } 
    private double _error; 
    public double Error { get { return _error; } } 

    private double[] _weights; 

    public Adaline(int layer) 
    { 
     _layer = layer; 
     _weights = new double[layer]; 
     Reset(); 
    } 

    public void Reset() 
    { 
     Random r = new Random(); 
     for (int i = 0; i < _layer; i++) 
      _weights[i] = r.NextDouble() - 0.5; 
     _error = 1; 
    } 

    public void Train(BasicTrainSet<double> trainset, double learnRate) 
    { 
     double ers = 0; 
     for(int p = 0; p < trainset.DataCount; p++) 
     { 
      double result = Compute(trainset.Input[p], true); 
      double error = trainset.Output[p] - result; 

      for (int i = 0; i < _weights.Length; i++) 
      { 
       _weights[i] += error * trainset.Input[p][i] * learnRate; 
      } 

      ers += Math.Abs(error); 
     } 
     _epoch++; 
     _error = ers; 
    } 

    public double Compute(double[] input, bool quan) 
    { 
     double result = 0; 
     for (int i = 0; i < _layer; i++) 
      result += Math.Tanh(_weights[i] * input[i]); 
     //double result = _weights.Zip(input, (a, b) => Math.Tanh(a * b)).Sum(); 
     return quan ? (result >= 0 ? 1 : 0) : result; 
    } 
} 

Когда я пытался тренироваться и воротился, как это, он работает так. Up four results are from this code Это довольно странно, потому что нет проблем с алгоритмом. Вес становится все больше и больше. Где я ошибся?

+0

Можете ли вы показать, как вы тренируете свой персептрон? Я имею в виду код, который выполняет вашу логику обучения. – serhiyb

+0

Вы наносите tanh после каждой операции накопления. Сначала нужно накапливать THEN, затем наносить tanh. – rayryeng

+0

@rayryeng спасибо, теперь работает очень хорошо. :) – phillyai

ответ

1

В вашем коде для вычисления выхода каждого нейрона вы не применяете функцию активации правильно. Вам нужно найти точечный продукт между весами и входами в каждый нейрон , затем применить функцию активации после. Вы применяете функцию активации после каждого взвешенного накопления, что неверно.

накапливались, а затем применить функцию активации:

public double Compute(double[] input, bool quan) 
{ 
    double result = 0; 
    for (int i = 0; i < _layer; i++) 
     result += _weights[i] * input[i]; // Change - accumulate first 
    result = Math.Tanh(result); // Change - now apply activation function 

    return quan ? (result >= 0 ? 1 : 0) : result; 
} 
+1

Я использовал linq для более короткого кода. 'double result = Sigmoid.LogSigmoid (_weights.Zip (input, (a, b) => (a * b)). Sum() + _biasWeight);' – phillyai

+0

Это лучше. Благодаря! Я скоро отредактирую. – rayryeng