神经元结果略有下降

时间:2018-07-30 20:54:01

标签: java neural-network

您好,我对单个神经元进行了编码,以根据他们在科目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;
    }
}

这是测试数据,最后一个数字是实际标记。 enter image description here

运行测试数据后,我得到以下结果: enter image description here

如您所见,前4个标记的预测与实际标记相差甚远。 我遵循了教科书对计算智能的介绍(如果您好奇的话,请参阅第2章)。

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

1 个答案:

答案 0 :(得分:1)

神经网络是非常黑盒式的。因此,很难确切说明您的成绩差强人意的原因。

话虽这么说,以下是提高神经网络准确性的一些主要方法:

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

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

  • 以不同的起始权重训练网络;随机的初始权重很好,但是有时候您得到的起始权重很差。在使用3000万个输入/输出集的同一项目中,我还尝试了15种不同的节点和层布局中的25种不同的初始起始权重配置。

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

会导致准确性降低的常见陷阱是不良的训练数据;确保您使用的训练数据正确,并且与您要教的内容在内部保持一致。

最后一点,我发现自己在理解您要精确编写的神经网络方面遇到一些麻烦;我已经假设这是对其中具有单个神经元的前馈,反向传播神经网络的某种尝试,但此处的大多数建议仍应适用。