2015-04-27 4 views
0

Я новичок в обучении машинам и экспериментирую с основными персептронами, прежде чем переходить к многослойным сетям.Неисправный персептрон

Проблема у меня есть с кодом ниже. У меня есть генератор данных обучения, который использует набор весов для генерации таблицы истинности.

Проблема заключается в том, что персептрон способен решать/определять набор весов, когда данные обучения были сгенерированы с помощью набора «А», но не с установкой «В». Когда дается подготовка данных, который был сгенерирован с набором «B», она продолжается в бесконечном цикле пытается определить веса (это локальный минимум вопрос?)

Я не понимаю, почему именно это происходит. Любая помощь или совет оценен.

Заранее спасибо.

// Calling function 
public static void TestPerceptron() 
    { 
     // Problem: 
     // When training data is generated using the 'A' set of weights, the perceptron is able to determine the correct weights based on the given training data. 
     // When training data is generated using the 'B' set of weights, the perceptron never completes training and is stuck in an infinite loop 

     double[] weights = new double[] { 
      //3,2,2,3 // A 
      3,2,1,3,1 // B 
     }; 

     double bias = 0.0; 

     var trainingData = PerceptronHelper.GenerateDataSetUsingWeights (weights, bias); 
     var perceptron = new Perceptron(); 
     perceptron.Train (trainingData, null, null); 

     //perceptron.Train (trainingData, weights, bias); 
    } 


public class Perceptron 
{ 
    private static Random r = new Random(); 
    protected double _bias = r.NextDouble(); 
    protected double[] _weights; 

    protected virtual double ComputeOutput(double[] weights, double[] inputs, double bias) 
    { 
     var total = 0.0; 

     for (var index = 0; index < inputs.Length-1; index++) 
     { 
      total += weights [index] * inputs [index]; 
     } 

     return total + (1 * bias); 
    } 

    protected virtual void SetWeights(ref double[] weights, double[] inputs, double error, double learningRate, ref double bias) 
    { 
     for (var index = 0; index < inputs.Length-1; index++) 
     { 
      weights[index] = weights [index] + (learningRate * error * inputs [index]); 
     } 

     bias += learningRate * error * 1; 
    } 

    public virtual void Train(double[][] trainingData, double[] idealWeights, double? idealBias) 
    { 
     var learningRate = 1.0; 
     var totalError = 1.0; 
     var targetError = 0.0; 
     var epochs = 0.0; 
     var bias = _bias; 
     var weights = new double[trainingData[0].Length-1]; 

     if (idealBias.HasValue) 
      bias = idealBias.Value; 

     if (idealWeights != null) 
      weights = idealWeights; 

     while (totalError > targetError) 
     { 
      totalError = 0.0; 

      for (var index = 0; index < trainingData.Length; index++) 
      { 
       var inputs = trainingData [index]; 

       // get target 
       var target = inputs [inputs.Length - 1]; 

       // compute output 
       var computed = ComputeOutput (weights, inputs, bias); 

       // pass computed through activation 
       var output = PerceptronHelper.Activation (computed); 

       // determine error 
       var error = (target - output); 

       // adjust weights 
       SetWeights (ref weights, inputs, error, learningRate, ref bias); 

       totalError += Math.Abs(error); 

       var weightsMsg = "Weights: "; 

       foreach(var weight in weights) 
       { 
        weightsMsg += weight + "|"; 
       } 

       Console.WriteLine (String.Format ("error: {0} weights: {1} bias: {2}", totalError, weightsMsg, bias)); 
      } 

      epochs++; 
     } 

     _bias = bias; 
     _weights = weights; 
    } 

    public void Predict(double[] inputs) 
    { 
     var sum = 0.0; 

     for (var index = 0; index < inputs.Length; index++) 
     { 
      sum += inputs [index] * _weights [index] + 1 * _bias; 

      Console.WriteLine (String.Format("input: {0} weight: {1} bias: {2}", inputs[index], _weights[index], _bias)); 
     } 

     var output = PerceptronHelper.Activation (sum); 
     Console.WriteLine ("Output:{0}", output); 
    } 
} 


public static class PerceptronHelper 
{ 
    // generate training data based on given weights - the number of inputs = number of weights 
    public static double[][] GenerateDataSetUsingWeights(double[] idealWeights, double bias) 
    { 
     var weights = idealWeights; 
     var inputs = new double[weights.Length]; 
     var numInputCombinations = Math.Pow(2,inputs.Length); 
     var trainData = new double[(int)numInputCombinations][]; 
     int inputValue = 0; 

     // generate training data 
     for (var index = 0; index < numInputCombinations; index++) 
     { 
      var sum = 0.0; 

      // last item in array is expected output 
      var trainDataLine = new double[weights.Length+1]; 

      var binary = Convert.ToString (inputValue, 2); 
      binary = binary.PadLeft (weights.Length, '0'); 

      // create training data line 
      for (var wIndex = 0; wIndex < weights.Length; wIndex++) 
      { 
       inputs [wIndex] = double.Parse(binary[wIndex].ToString()); 
       trainDataLine [wIndex] = inputs [wIndex]; 
       sum += inputs [wIndex] * weights [wIndex]; 
      } 

      sum += (1 * bias); 

      var output = Activation (sum); 

      // store the expected result in the last item of the array 
      trainDataLine [weights.Length] = output; 

      // add the line to the data 
      trainData[index] = trainDataLine; 

      inputValue++; 
     } 

     return trainData; 
    } 

    public static double Activation (double sum) 
    { 
     Console.WriteLine (String.Format("evaluating :{0}", sum)); 
     return Math.Abs(sum) >= 5 ? 1 : 0; 

    } 
} 

Образец продукции:

https://onedrive.live.com/redir?resid=8a0ad995f81066db!176&authkey=!AGgY8Iy4g_8lpv4&ithint=file%2crtf

+0

Можете ли вы отлаживать и проверять, что именно происходит с весами в B. Какое значение имеет (оно близко к правильному значению) и почему условие остановки никогда не срабатывает? – slabofguinness

+0

Спасибо за ваш ответ, я обновил сообщение с образцом вывода. Глядя на результат, проблема представляет собой общую ошибку, которая вызывает бесконечный цикл. – noobie

ответ

0

Изменение скорости обучения до 0,075 исправили проблему.

Смежные вопросы