感知器故障(Malfunctioning perceptron)
我是机器学习的新手,在进入多层网络之前一直在尝试基本的感知器。
我遇到的问题是下面的代码。 我有一个训练数据生成器,它使用一组权重来生成真值表。
我遇到的问题是感知器能够在使用设置'A'而不是设置'B'生成训练数据时解决/确定权重集。 当给定使用集合'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; } }
输出样本:
I am a newbie to machine learning and have been experimenting with basic perceptrons before moving on to multilayer networks.
The problem I have is with the code below. I have a training data generator which uses a set of weights to generate a truth table.
The problem I have is the perceptron is able to solve/determine the set of weights when the training data was generated with set 'A' but not with set 'B'. When given training data that was generated with set 'B', it continues in an infinite loop trying to determine the weights (is this a local minimum issue?)
I do not understand exactly why this is happening. Any help or advice is appreciated.
Thanks in advance.
// 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; } }
A sample of the output:
原文:https://stackoverflow.com/questions/29885530