Java-based Neural Network — how zur Umsetzung RÜCKFÜHRUNG

Baue ich einen test neuronalen Netzwerk und es ist definitiv nicht arbeiten. Mein Hauptproblem ist backpropagation. Aus meiner Forschung weiß ich, dass es einfach zu bedienen ist die sigmoid-Funktion. Also, ich update jedes Gewicht von (1-Ausgang)(Ausgang)(Ziel-Output), aber das problem mit diesem ist, was ist, wenn mein Ausgang ist 1, aber mein Ziel ist es nicht? Wenn es einem dann irgendwann das Gewicht update wird immer 0 sein...Für jetzt bin ich einfach nur zu versuchen, um das verflixte Ding zu fügen Sie die Eingänge von 2 input-Neuronen, so dass die optimalen GEWICHTE sollte nur 1 sein, da das output-neuron fügt einfach die Eingänge. Ich bin mir sicher, dass ich Durcheinander gebracht wurden diese in vielen Orten, aber hier ist mein code:

    public class Main {

        public static void main(String[] args) {
            Double[] inputs = {1.0, 2.0};
            ArrayList<Double> answers = new ArrayList<Double>();
            answers.add(3.0);

            net myNeuralNet = new net(2, 1, answers);

            for(int i=0; i<200; i++){

                myNeuralNet.setInputs(inputs);
                myNeuralNet.start();
                myNeuralNet.backpropagation();
                myNeuralNet.printOutput();
                System.out.println("*****");
                for(int j=0; j<myNeuralNet.getOutputs().size(); j++){
                    myNeuralNet.getOutputs().get(j).resetInput();
                    myNeuralNet.getOutputs().get(j).resetOutput();
                    myNeuralNet.getOutputs().get(j).resetNumCalled();
                }
            }
        }

    }


    package myneuralnet;
    import java.util.ArrayList;

    public class net {

    private ArrayList<neuron> inputLayer;
    private ArrayList<neuron> outputLayer;
    private ArrayList<Double> answers;

    public net(Integer numInput, Integer numOut, ArrayList<Double> answers){
        inputLayer = new ArrayList<neuron>();
        outputLayer = new ArrayList<neuron>();
        this.answers = answers;

        for(int i=0; i<numOut; i++){
            outputLayer.add(new neuron(true));
        }

        for(int i=0; i<numInput; i++){
            ArrayList<Double> randomWeights = createRandomWeights(numInput);
            inputLayer.add(new neuron(outputLayer, randomWeights, -100.00, true));
        }

        for(int i=0; i<numOut; i++){
            outputLayer.get(i).setBackConn(inputLayer);
        }
    }

    public ArrayList<neuron> getOutputs(){
        return outputLayer;
    }

    public void backpropagation(){
        for(int i=0; i<answers.size(); i++){
            neuron iOut = outputLayer.get(i);
            ArrayList<neuron> iOutBack = iOut.getBackConn();
            Double iSigDeriv = (1-iOut.getOutput())*iOut.getOutput();
            Double iError = (answers.get(i) - iOut.getOutput());

            System.out.println("Answer: "+answers.get(i) + " iOut: "+iOut.getOutput()+" Error: "+iError+" Sigmoid: "+iSigDeriv);

            for(int j=0; j<iOutBack.size(); j++){
                neuron jNeuron = iOutBack.get(j);
                Double ijWeight = jNeuron.getWeight(i);

                System.out.println("ijWeight: "+ijWeight);
                System.out.println("jNeuronOut: "+jNeuron.getOutput());

                jNeuron.setWeight(i, ijWeight+(iSigDeriv*iError*jNeuron.getOutput()));
            }
        }

        for(int i=0; i<inputLayer.size(); i++){
            inputLayer.get(i).resetInput();
            inputLayer.get(i).resetOutput();
        }
    }

    public ArrayList<Double> createRandomWeights(Integer size){
        ArrayList<Double> iWeight = new ArrayList<Double>();

        for(int i=0; i<size; i++){
            Double randNum = (2*Math.random())-1;
            iWeight.add(randNum);
        }

        return iWeight;
    }

    public void setInputs(Double[] is){
        for(int i=0; i<is.length; i++){
            inputLayer.get(i).setInput(is[i]);
        }
        for(int i=0; i<outputLayer.size(); i++){
            outputLayer.get(i).resetInput();
        }
    }

    public void start(){
        for(int i=0; i<inputLayer.size(); i++){
            inputLayer.get(i).fire();
        }
    }

    public void printOutput(){
        for(int i=0; i<outputLayer.size(); i++){
            System.out.println(outputLayer.get(i).getOutput().toString());
        }
    }

}

package myneuralnet;
import java.util.ArrayList;

public class neuron {

    private ArrayList<neuron> connections;
    private ArrayList<neuron> backconns;
    private ArrayList<Double> weights;
    private Double threshold;
    private Double input;
    private Boolean isOutput = false;
    private Boolean isInput = false;
    private Double totalSignal;
    private Integer numCalled;
    private Double myOutput;

    public neuron(ArrayList<neuron> conns, ArrayList<Double> weights, Double threshold){
        this.connections = conns;
        this.weights = weights;
        this.threshold = threshold;
        this.totalSignal = 0.00;
        this.numCalled = 0;
        this.backconns = new ArrayList<neuron>();
        this.input = 0.00;
    }

    public neuron(ArrayList<neuron> conns, ArrayList<Double> weights, Double threshold, Boolean isin){
        this.connections = conns;
        this.weights = weights;
        this.threshold = threshold;
        this.totalSignal = 0.00;
        this.numCalled = 0;
        this.backconns = new ArrayList<neuron>();
        this.input = 0.00;
        this.isInput = isin;
    }

    public neuron(Boolean tf){
        this.connections = new ArrayList<neuron>();
        this.weights = new ArrayList<Double>();
        this.threshold = 0.00;
        this.totalSignal = 0.00;
        this.numCalled = 0;
        this.isOutput = tf;
        this.backconns = new ArrayList<neuron>();
        this.input = 0.00;
    }

    public void setInput(Double input){
        this.input = input;
    }

    public void setOut(Boolean tf){
        this.isOutput = tf;
    }

    public void resetNumCalled(){
        numCalled = 0;
    }

    public void setBackConn(ArrayList<neuron> backs){
        this.backconns = backs;
    }

    public Double getOutput(){
        return myOutput;
    }

    public Double getInput(){
        return totalSignal;
    }

    public Double getRealInput(){
        return input;
    }

    public ArrayList<Double> getWeights(){
        return weights;
    }

    public ArrayList<neuron> getBackConn(){
        return backconns;
    }

    public Double getWeight(Integer i){
        return weights.get(i);
    }

    public void setWeight(Integer i, Double d){
        weights.set(i, d);
    }

    public void setOutput(Double d){
        myOutput = d;
    }

    public void activation(Double myInput){
        numCalled++;
        totalSignal += myInput;

        if(numCalled==backconns.size() && isOutput){
            System.out.println("Total Sig: "+totalSignal);
            setInput(totalSignal);
            setOutput(totalSignal);
        }
    }

    public void activation(){
        Double activationValue = 1 /(1 + Math.exp(input));
        setInput(activationValue);
        fire();
    }

    public void fire(){
        for(int i=0; i<connections.size(); i++){
            Double iWeight = weights.get(i);
            neuron iConn = connections.get(i);
            myOutput = (1/(1+(Math.exp(-input))))*iWeight;
            iConn.activation(myOutput);
        }
    }

    public void resetInput(){
        input = 0.00;
        totalSignal = 0.00;
    }

    public void resetOutput(){
        myOutput = 0.00;
    }
}

OK also das ist eine Menge code, so lassen Sie mich erklären. Das Netz ist einfach für jetzt, nur ein input-layer und einem output layer - - - - ich möchte hinzufügen, eine versteckte Schicht später, aber ich mache baby-Schritte für jetzt. Jede Ebene ist eine arraylist von Neuronen. Input-Neuronen sind geladen mit den Eingängen 1 und 2 in diesem Beispiel. Diese Neuronen feuern, berechnet die Sigma der Eingänge und Ausgänge, die sich auf die output-Neuronen, welche fügt Sie hinzu und speichert den Wert. Dann net backpropagates, indem die (Antwort-Ausgang)(output)(1-Ausgang)(Ausgang von spezifischen input-neuron) und aktualisiert die GEWICHTE entsprechend. Eine Menge Zeit, es durchläuft und ich bekomme unendlich, das scheint zu korrelieren mit negativen gewichten oder sigmoid. Wenn das nicht passiert, wird es konvergiert gegen 1, und da (1-Ausgabe der 1) ist 0, meine GEWICHTE nicht mehr aktualisiert.

Den numCalled und totalSignal Werte sind also nur der Algorithmus wartet für alle neuron-Eingänge, bevor Sie fortfahren. Ich weiß, ich bin dabei eine seltsame Weise, aber die neuron-Klasse hat eine arraylist mit Neuronen genannt, verbindungen zu halten, die Neuronen, es ist vorne angeschlossen. Eine weitere arraylist namens backconns hält die rückwärts gerichtete verbindungen. Ich sollte updaten, die richtigen GEWICHTE so gut, da bin ich immer alle wieder verbindungen zwischen den Neuronen i und j, sondern alle Neuronen j (der Schicht oberhalb i) ich bin nur ziehen Sie Gewicht ich. Ich entschuldige mich für die Unordnung --- ich habe versucht, viele Dinge, für die Stunden nach Stunden jetzt und kann immer noch nicht herausfinden. Jede Hilfe wird sehr geschätzt!

Schreibe einen Kommentar