2016-03-23 18 views
0

Son iki haftada NN hakkında çok fazla şey okudum, sanırım her bir net "XOR" net öğretme öğreticisini gördüm. Ama kendi işimi kendim yapamamıştım. Basit bir "OR" nöron yaklaşımıyla başladım. İyi sonuç vermek. Sorunumun geri yayılma uygulamasında olduğunu düşünüyorum. Bir nesne yaklaşımı yaptım, bu yüzden ana hatlar.Yapay Sinir ağı kötü yakınsama

üç sınıfı: (FeedForwardLayers içeren) (nöronlar içeren)

Neuron

public class Neuron { 

/* 
* Attributes 
*/ 

double[] inputs; 
double[] weights; 

double output; 
double error; 

double delta; 
double deltaWeight; 

/* 
* Constructors 
*/ 

public Neuron(int nInputs) 
{ 
    inputs = new double[nInputs + 1]; 
    inputs[inputs.length - 1] = 1; // bias 
    weights = new double[nInputs + 1]; 
} 

/* 
* Methods 
*/ 

/** 
* Reset all weights of the neuron to random values between -1 and 1 
*/ 
public void reset() 
{  
    Random random = new Random(); 
    for (int i = 0; i < weights.length; i++) 
     weights[i] = (random.nextDouble() * ((0.5d - (-0.5d))) + (-0.5d)); 
} 

/** 
* Compute output for given inputs 
* @param inputs 
*/ 
public void computeOutput(double inputs[]) 
{ 
    setInputs(inputs); 
    output = Sigmoid.activation(getDotProduct()); 
} 

/** 
* Compute error for given ideal 
* @param ideal 
*/ 
public void computeError(double ideal) 
{ 
    error = ideal - output; 
    delta = error; 
} 

/** 
* Compute error for hidden neurons 
*/ 
public void computeError(FeedForwardLayer previousLayer, int position) 
{ 
    double sum = 0; 
    for (int i = 0; i < previousLayer.neurons.length; i++) 
     sum += (previousLayer.neurons[i].delta * previousLayer.neurons[i].weights[position]); 

    delta = Sigmoid.derivative(getDotProduct()) * sum; 
    error = delta; 
} 

/** 
* Adjust every weight of the neuron 
*/ 
public void adjustWeights(double lambda, double momentum) 
{ 
    for (int i = 0; i < weights.length; i++) 
    { 
     double lastDeltaWeight = deltaWeight; 
     deltaWeight = lambda * (delta * inputs[i]) + momentum * lastDeltaWeight; 
     weights[i] += deltaWeight; 
    } 
} 

@Override 
public String toString() 
{ 
    String str = ""; 
    for (int i = 0; i < weights.length; i++) 
     str = str.concat(String.format("IN|W --> %.6f | %.6f \n", (float) inputs[i], (float) weights[i])); 

    str = str.concat("Output = " + output + "\n"); 
    str = str.concat("Error = " + error + "\n"); 
    return str; 
} 

/* 
* Getters & Setters 
*/ 

/** 
* @return weights * inputs + bias 
*/ 
public double getDotProduct() 
{ 
    double sum = 0; 
    for (int i = 0; i < inputs.length; i++) 
     sum += (weights[i] * inputs[i]); 

    return sum; 
} 

/** 
* Set inputs (keep bias input) 
* @param inputs 
*/ 
public void setInputs(double[] inputs) 
{ 
    for (int i = 0; i < inputs.length; i++) 
     this.inputs[i] = inputs[i]; 
} 

/** 
* Set every weight to a single value 
* @param weight 
*/ 
public void setWeights(double weight) 
{ 
    for (int i = 0; i < weights.length; i++) 
     this.weights[i] = weight; 
} 
} 

FeedForwardLayer

public class FeedForwardLayer { 

/* 
* Attributes 
*/ 

Neuron[] neurons; 
LayerTypes type; 

/* 
* Constructors 
*/ 

/** 
* First layer constructor 
* @param nNeurons 
*/ 
public FeedForwardLayer(int nInputs, int nNeurons, LayerTypes type) 
{ 
    neurons = new Neuron[nNeurons]; 
    for (int i = 0; i < neurons.length; i++) 
     neurons[i] = new Neuron(nInputs); 

    this.type = type; 
} 

/* 
* Methods 
*/ 

/** 
* Reset all weights of the layer's neurons to random values between -1 and 1 
*/ 
public void reset() 
{ 
    for (Neuron neuron : neurons) 
     neuron.reset(); 
} 

/** 
* Compute output, if layer isn't input one, you can pass null into parameter 
* @param inputs 
*/ 
public void computeOutputs(double[] inputs) 
{ 
    for (int i = 0; i < neurons.length; i++) 
     neurons[i].computeOutput(inputs); 
} 

/** 
* Compute error, if layer is output one 
* @param ideals 
*/ 
public void computeErrors(double[] ideals) 
{ 
    for (int i = 0; i < neurons.length; i++) 
     neurons[i].computeError(ideals[i]); 
} 

/** 
* Compute error, if layer isn't output one 
* @param layer n+1 
*/ 
public void computeErrors(FeedForwardLayer next) 
{ 
    for (int i = 0; i < neurons.length; i++) 
     neurons[i].computeError(next, i); 
} 

/** 
* Adjust weights for every neurons 
*/ 
public void adjustWeights(double lambda, double momentum) 
{ 
    for (Neuron neuron : neurons) 
     neuron.adjustWeights(lambda, momentum); 
} 

@Override 
public String toString() 
{ 
    String str = ""; 
    for (int i = 0; i < neurons.length; i++) 
     str = str.concat("Neuron " + i + "\n" + neurons[i]); 
    return str; 
} 

/* 
* Getters - Setters 
*/ 

/** 
* @return true if layer is input, false otherwise 
*/ 
public boolean isInput() 
{ 
    if (type == LayerTypes.INPUT) 
     return true; 

    return false; 
} 

/** 
* @return true if layer is input, false otherwise 
*/ 
public boolean isOutput() 
{ 
    if (type == LayerTypes.OUTPUT) 
     return true; 

    return false; 
} 

/** 
* @return an array of layer's outputs 
*/ 
public double[] getOutputs() 
{ 
    double[] outputs = new double[neurons.length]; 

    for (int i = 0; i < neurons.length; i++) 
     outputs[i] = neurons[i].output; 

    return outputs; 
} 

/** 
* @return array of layer's errors 
*/ 
public double[] getErrors() 
{ 
    double[] errors = new double[neurons.length]; 

    for (int i = 0; i < neurons.length; i++) 
     errors[i] = neurons[i].error; 

    return errors; 
} 

/** 
* Set all the weights of the layer to given weight 
* @param weight 
*/ 
public void setWeights(double weight) 
{ 
    for (int i = 0; i < neurons.length; i++) 
     neurons[i].setWeights(weight); 
} 
} 

FeedForwardNetwork

public class FeedForwardNetwork { 

static final double lambda = 0.1; 
static final double momentum = 0; 

/* 
* Attributes 
*/ 

private ArrayList<FeedForwardLayer> layers; 

/* 
* Constructors 
*/ 

public FeedForwardNetwork() 
{ 
    layers = new ArrayList<FeedForwardLayer>(); 
} 

/* 
* Methods 
*/ 

/** 
* Init all the weights to random values 
*/ 
public void reset() 
{  
    for (int i = 0; i < layers.size(); i++) 
     layers.get(i).reset();; 
} 

/** 
* Compute output for all the neurons of all the layers for given inputs 
* @param inputs 
*/ 
public void feedForward(double[] inputs) 
{ 
    //System.err.println("FeedForwardNetwork.feedForward(" + inputs[0] + ", " + inputs[1] +")"); 
    for (int i = 0; i < layers.size(); i++) 
    { 
     //System.err.println("\n*** COMPUTING OUTPUT FOR LAYER " + i + "***\n"); 
     if (layers.get(i).isInput()) 
      layers.get(i).computeOutputs(inputs); 
     else 
      layers.get(i).computeOutputs(layers.get(i - 1).getOutputs()); 
    } 
} 

/** 
* Compute errors for all the neurons of all the layers starting by output layer 
* @param ideals 
*/ 
public void feedBackward(double[] ideals) 
{ 
    //System.err.println("FeedForwardNetwork.feedBackward(" + ideals[0] + ")"); 
    // For each layers starting by output one 
    for (int i = layers.size() - 1; i > 0; i--) 
    { 
     //System.err.println("*** COMPUTING ERROR FOR LAYER " + i + "***"); 
     if (layers.get(i).isOutput()) 
      layers.get(i).computeErrors(ideals); 
     else 
      layers.get(i).computeErrors(layers.get(i + 1)); 
    } 
} 

/** 
* Adjust weights of every layer 
*/ 
public void adjustWeights() 
{ 
    for (FeedForwardLayer feedForwardLayer : layers) 
     feedForwardLayer.adjustWeights(lambda, momentum); 
} 

/** 
* Train the nn with given inputs and outputs 
* @param inputs 
* @param outputs 
*/ 
public void train(double[] inputs, double... outputs) 
{ 
    feedForward(inputs); 
    feedBackward(outputs); 
    adjustWeights(); 
} 

/** 
* Add a layer to the network 
* @param layer 
*/ 
public void addLayer(FeedForwardLayer layer) 
{ 
    layers.add(layer); 
} 

@Override 
public String toString() 
{ 
    String str = ""; 
    for (int i = 0; i < layers.size(); i++) 
     str = str.concat("Layer " + LayerTypes.values()[i] + "\n" + layers.get(i)); 

    str = str.concat("\n"); 
    str = str.concat("OUTPUT = " + getOutputs()[0] + "\n"); 
    str = str.concat("ERROR = " + getError(false) + "\n"); 
    return str; 
} 
/* 
* Getters & Setters 
*/ 

public FeedForwardLayer getInputLayer() 
{ 
    return layers.get(0); 
} 

public FeedForwardLayer getOutputLayer() 
{ 
    return layers.get(layers.size() - 1); 
} 

public FeedForwardLayer getLayer(int index) 
{ 
    return layers.get(index); 
} 

public double getError(boolean abs) 
{ 
    if (abs) 
     return Math.abs(getOutputLayer().neurons[0].error); 

    return getOutputLayer().neurons[0].error; 
} 

public double[] getOutputs() 
{ 
    return getOutputLayer().getOutputs(); 
} 
} 

Yani ben ağ binlerce yaklaşık 0.5 Epoch'tan edecektir çıktı sonra XOR masayı xor tablonun o

X | Y | S 
0 0 0 
0 1 1 
0 1 1 
0 0 0 

çağı vererek ağını eğitmek ... İlginç bir gerçektir Eğer bir AND tablosu, bir OR tablosu veya bir NAND tablosu ile eğitim setini değiştirirseniz, nn, sayısını S sütununda tr aining set .. (AND ve NAND tablosu için 0.25 ve OR tablosu için 0,75 çıktı)

Sadece uygulamamın işe yaramaya yetecek kadar iyi olup olmadığını bilmek istiyorum, Ty!

+0

Bu soruyu programcılar grubunda denemeliydi. –

cevap

0

Bazı araştırmalardan sonra, giriş katmanımın nasıl çalıştığını anlamadığım dışında, uygulamamın iyi olduğunu anladım. Öyleyse, giriş katmanı In = Out

İlgili konular