首页 > 解决方案 > 神经元结果有点偏离

问题描述

嗨,我编写了一个神经元,根据学生 A、B 和 C 的分数来预测学生 D 的分数。

在用一些包含 3 个标记的历史数据以及他们为受试者 D 获得的实际分数训练我的神经元后,我输入了测试数据以查看预测标记与实际分数的匹配程度。下面是我的神经元课

public class Neuron
{
    double[] Weights = new double[3];

    public Neuron(double W1, double W2, double W3)
    {
        Weights[0] = W1;
        Weights[1] = W2;
        Weights[2] = W3;
    }

    public double FnetLinear(int Z1, int Z2, int Z3)
    {
        return (Z1*Weights[0] + Z2*Weights[1] + Z3*Weights[2]);
    }

    public void UpdateWeight(int i, double Wi)
    {
        Weights[i] = Wi;
    }
}

这是我的主要课程

public class Main
{
    public int t;
    public Neuron neuron;
    double LearningRate = 0.00001;
    public ArrayList<Marks> TrainingSet, TestSet;

    public static void main(String[] args) throws IOException
    {
      Main main = new Main();
        main.run();
    }

    public void run()
    {
        TrainingSet = ReadCSV("G:\\EVOS\\EVO_Assignemnt1\\resources\\Streamdata.csv");
        TestSet =  ReadCSV("G:\\EVOS\\EVO_Assignemnt1\\resources\\Test.csv");
        Random ran = new Random();
        neuron = new Neuron(ran.nextDouble(), ran.nextDouble(), ran.nextDouble());
        train();
        Test();
    }


    public void train()
    {
        t = 0;
        while(t<1000000)
        {
            for(Marks mark: TrainingSet)
            {
                for(int i=0; i<neuron.Weights.length; i++)
                {
                    double yp = neuron.FnetLinear(mark.marks[0] , mark.marks[1], mark.marks[2]);
                    double wi = neuron.Weights[i] - LearningRate*(-2*(mark.marks[3]-yp))*mark.marks[i];
                    neuron.UpdateWeight(i, wi);
                }
            }
            t++;
        }
    }

    public void Test()
    {
        System.out.println("Test Set results:");
        int count = 1;

        for(Marks mark: TestSet)
        {
            double fnet = neuron.FnetLinear(mark.marks[0] , mark.marks[1], mark.marks[2]);
            System.out.println("Mark " + count + ": " + fnet);
            count++;
        }
    }

    public static ArrayList<Marks> ReadCSV(String csv)
    {
        ArrayList<Marks> temp = new ArrayList<>();
        String line;
        BufferedReader br;
        try
        {
         br = new BufferedReader(new FileReader(csv));
            while((line=br.readLine()) != null)
            {
                String[] n = line.split(",");
                Marks stud = new Marks(Integer.valueOf(n[0]), Integer.valueOf(n[1]), Integer.valueOf(n[2]), Integer.valueOf(n[3]));
                temp.add(stud);
            }
        }
        catch (Exception e)
        {
            System.out.println("ERROR");
        }
        return temp;
    }
}

这是测试数据,最后一个数字是实际标记。 在此处输入图像描述

运行测试数据后,我得到了以下结果: 在此处输入图像描述

正如您所看到的,前 4 个分数的预测与实际分数相差甚远。我按照教科书对计算智能简介的解释(如果你好奇的话,第 2 章)。

但是我想知道我做错了什么。如何获得更准确的结果?

标签: javaneural-network

解决方案


神经网络是非常黑盒式的;正因为如此,很难准确地说出为什么你的分数结果很差。

话虽如此,这里有一些提高神经网络准确性的主要方法:

  • 调整层数和神经元;我注意到你只使用了一个神经元。神经网络中的单个神经元通常只是……不好。你永远不会得到这样的好结果。神经网络需要以分层和神经元计数的形式具有足够的复杂性,以便计算或预测你试图教它做什么。单个神经元本身真的无法学习任何有用的东西。这也可能是您的网络准确性如此糟糕的一个重要原因。

  • 训练更长时间;我注意到你只训练你的网络 100 万次;这并不总是足够的。作为参考,我上次训练神经网络时,使用了超过 3000 万组输入/输出。

  • 用不同的起始权重重新训练你的网络;随机的起始权重很棒,但有时你会得到一批糟糕的起始权重。在我使用 3000 万个输入/输出集的同一个项目中,我还在 15 个不同的节点和层布局中尝试了超过 25 种不同的初始起始权重配置。

  • 选择不同的激活函数;线性激活函数通常没那么有用。我通常默认使用 sigmoid 函数开始,除非有特定的其他函数可以满足我正在尝试训练的用例。

可能导致低准确率的常见陷阱是糟糕的训练数据;确保您使用的训练数据是正确的,并且在内部与您尝试教授的内容保持一致。

作为最后一点,我发现自己在理解你想要写出什么样的神经网络时遇到了一些麻烦。我假设这是对前馈、反向传播神经网络的某种尝试,其中只有一个神经元,但这里的大多数建议仍然适用。


推荐阅读