首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >故障感知器

故障感知器
EN

Stack Overflow用户
提问于 2015-04-27 00:57:28
回答 1查看 367关注 0票数 0

我是一个机器学习的新手,在进入多层网络之前,我一直在尝试基本的感知技术。

我遇到的问题是下面的代码。我有一个训练数据生成器,它使用一组权重来生成真值表。

我遇到的问题是,当训练数据用集合'A‘生成,而不是用集合'B’生成时,感知器能够解决/确定权重集。当给定用集合'B‘生成的训练数据时,它在一个无限循环中继续,试图确定权重(这是一个局部最小问题吗?)

我不明白为何会出现这种情况。如有任何帮助或建议,我们将不胜感激。

提前谢谢。

代码语言:javascript
复制
// 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;

    }
}

输出的样本:

8lpv4&ithint=file%2crtf

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-29 20:51:33

将学习率改为0.075解决了这一问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29885530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档