1
  1. full code

      the full code of the neuron. am trying to code a radial basis                    neuron network but i can figure out where and getting an NaN error
    

    import java.util.ArrayList; import java.util.List; import java.util.Random;

    public class Neurons {
    
        static Random rand =new Random();
        instance variables
    
    
        private float m_neuronOutput;
        private float alpha=0.4f;
        private  float  m_gradient;
        private int neuronIndex;
        public  float eta;
        public float sigma=22.5f;
        public List<Connection> neuronWeights= new ArrayList<Connection>();
        //public List<Center> neuronCenter= new ArrayList<Center>();
        NetWork net=new NetWork();
        public Neurons(){
            //  sigma=22.5f;
            eta=0.5f;
    
        }
        //neuron constructor
        public Neurons(int outputNum, int m_neuronIndex){
            neuronIndex=m_neuronIndex;
    
            add connection weights
            for (int connect = 0; connect < outputNum; connect++) {
                neuronWeights.add(new Connection());
    
    
            }
    
    
        }
    
        public  void SetOutputValue(float value){
            m_neuronOutput = value;
    
        }
        public float GetOutputValue(){
            return m_neuronOutput;
        }
        ## feed the layer with the input ##
    
  2. feed the layers

        public void FeedForward(Layer previousLayer, int n){
            float sum = 0;
            //weightsum the inputs of the last layer, including bias
            //System.out.println(n);
            m_neuronOutput= previousLayer.neuron.get(n).GetOutputValue () ;
            //System.out.println(m_neuronOutput);
        }
    
  3. set the value of the hidden layer

        public void FeedHidden(Layer previousLayer, int j ){
    
            //      for(int i=0;i<center.length;i++)
            //          System.out.println(center[i]);
            float distance= 0;
            //System.out.println(n+" "+hiddenLayer.neuron.get(n).neuronCenter.get(n).center);
            //weightsum the inputs of the last layer, including bias
            for (int n = 0; n <previousLayer.neuron.size(); n++) {
                distance += (float) Math.pow(previousLayer.neuron.get(n).GetOutputValue ()-previousLayer.neuronCenter.get(j).center,2);
                //System.out.println(previousLayer.neuronCenter.get(j).center);
            }
    
         ## where am calling phi(Gaussian function) ##                  m_neuronOutput =  phi (distance);
            //System.out.println(m_neuronOutput);
        }
            private float phi( float distance){
    
            //System.out.println(sigma);
            return (float) Math.exp(- distance/(2*Math.pow(sigma, 2)));
        }
    
  4. calculate output

        public void setOutput(Layer hidden){
            float output=0;
            for(int i=0;i<hidden.neuron.size();i++){
                output+=hidden.neuron.get(i).GetOutputValue()*hidden.neuron.get(i).neuronWeights.get(neuronIndex).weight;
                // System.out.println(hidden.neuron.get(i).GetOutputValue());
                // System.out.println(hidden.neuron.get(i).neuronWeights.get(neuronIndex).weight);
            }
            m_neuronOutput=output;
            //System.out.println(hidden.neuron.get(i).neuronWeights.get(neuronIndex).weight);
    
        }
    
  5. gradient at the output layer

        public void CalcOutputGradients( float targetValue,float output){
            // System.out.println(output);
            float delta = targetValue -output;
    
    
            m_gradient = delta;
            //System.out.println( output);
    
        }   
    
        public void UpdateInputWeights(Layer previousLayer,float eta){
            //System.out.println(phi);
            the weights to be updated are in the connection container
            in the neurons in the preceding layer
            int numNeuronas = previousLayer.neuron.size();
            for (int n = 0; n < numNeuronas; n++) {//for every previous layer neuron
                Neurons neu = previousLayer.neuron.get(n);//getting the previous layer neuron
                //System.out.println(neu.neuronCenter.get(neuronIndex).center );
                float phi=previousLayer.neuron.get(n).GetOutputValue ();
                //double oldDeltaW = neu.neuronWeights.get(neuronIndex).deltaweight;
                double deltaWeight=
                        //Individual input magnified by the gradient and trainrate
                        eta *phi*m_gradient;
                also add momentum = a fraction of the previos delta weight
                +oldDeltaW;
                neu.neuronWeights.get(neuronIndex).deltaweight = deltaWeight;
                neu.neuronWeights.get(neuronIndex).weight+= deltaWeight;
    
                //System.out.println(m_gradient +" delta");
    
            }
        }
    ## my method to update the center but yet to call it in my network  work class ##
        public void updateCenter( Layer previousLayer,float[] input, float eta){
            int numNeuronas = previousLayer.neuron.size();
    
            for (int n = 0; n < numNeuronas-1; n++) {//for every previous layer neuron
                Neurons neu = previousLayer.neuron.get(n);//getting the previous layer neuro
                Center neu1 = previousLayer.neuronCenter.get(n);
                float phi=previousLayer.neuron.get(n).GetOutputValue ();
                double oldcenter = neu1.center;
    
                double weight= neu.neuronWeights.get(neuronIndex).weight;
                double deltaC=
                        //Individual input magnified by the gradient and trainrate
                        eta *phi*((m_gradient*weight)/Math.pow(sigma, 2))*(input[n]-oldcenter);
                //also add momentum = a fraction of the previos delta weight
                //+oldcenter;
    
    
                neu1.center+= deltaC;
    
                //System.out.println(gredient+" delta");
    
            }
    
    
    
        }
    

    update sigma

        public void updateSigma(Layer previousLayer, float[] center, float[] input, float eta){
            float distance= 0;
            //weightsum the inputs of the last layer, including bias
            for (int n = 0; n < center.length; n++) {
                distance+= Math.pow(previousLayer.neuron.get(n).GetOutputValue () -center[n],2);
                //System.out.println(distance);
            }
            float phi=(float) phi(distance);
            float sigma1=0;
            for(int i=0;i<center.length;i++){
                double w =previousLayer.neuron.get(i).neuronWeights.get(neuronIndex).weight;
                sigma1=(float) (sigma+(eta*((m_gradient*w)/Math.pow(sigma, 3))*phi*Math.pow(input[i]-center[i],2)));
            }
            sigma=sigma1;
        }
        get the current learning rate
        public  float updateLearningRate(float epoch){  
            //search the converge algorithm
    
            return (float) (eta/((epoch)/500));
    
        }
    
        set the learning rate
        public  void  setLearningRate(float rate){  
    
            eta=rate;
    
        }
    
        update the learining rate
        public  float getLearningRate(){
            return eta;
    
        }
    
    
    
    
    }
    

    looking for word to your help. Thanks

shan
  • 11
  • 3
  • 2
    please add the full stacktrace – XtremeBaumer Nov 14 '16 at 11:29
  • Can't remember if this return `NaN` or `Can't divide by 0` but this could be the reason `(float) Math.exp(- distance/(2*Math.pow(sigma, 2)));`might be equals to 0/0 – AxelH Nov 14 '16 at 11:33
  • Possible duplicate of [In Java, what does NaN mean?](http://stackoverflow.com/questions/2618059/in-java-what-does-nan-mean) – AxelH Nov 14 '16 at 11:36
  • 2
    I suggest you step through the code in your debugger to see which line produced the NaN and what the inputs where which created it. – Peter Lawrey Nov 14 '16 at 11:44
  • 1
    It is not possible to explain what is going on here. You are calling methods that are not shown, and (apparently) some of the methods that are shown are not called; e.g. `phi(...)` – Stephen C Nov 14 '16 at 11:53
  • Please update your code to show us the **relevant** portions. As it is right now, the code that is present wouldn't show the problematic behaviour (i.e. it doesn't call `phi(float distance)` which is the only place a `NaN` could occur) – QBrute Nov 14 '16 at 12:08
  • eta *phi*m_gradient; – shan Nov 14 '16 at 12:29
  • neu.neuronWeights.get(neuronIndex).weight+= deltaWeight //this the line of code that is causing the problem but i can't figure out why – shan Nov 15 '16 at 01:43

1 Answers1

2
return (float) Math.exp(- distance/(2*Math.pow(sigma, 2)));

in the above line, when sigma and distance are 0, you execute Math.exp(-0/0) which is NaN.

NaN stands for Not a Number which occurs e.g. when you divide by 0 or take a square root of a negative number.

NaN is defined by IEE 754 and stands for a double which isn't actually numeric value.

And as a side remark, as I believe you will read, please always add the stacktrace to the question. Always add all important information about the problem.

xenteros
  • 15,586
  • 12
  • 56
  • 91
  • @StephenC I made an experiment and Math.exp(0/0) is NaN – xenteros Nov 14 '16 at 11:54
  • @StephenC of course you can. You were right. At the moment I believe there is a good answer. – xenteros Nov 14 '16 at 11:57
  • 1
    Yes, if is was called with distance zero and sigma zero, that would lead to a NaN. (You got that right now). However, the `phi` method is not even called in the code that the OP showed us! So, on the face of it, there is no evidence that the NaN comes from the `phi` call at all. – Stephen C Nov 14 '16 at 11:57
  • the distance that am passing to method phi() is never 0 and for testing purpose and i set assign sigma to a constant value. so there is no possibility of 0/0 in method phi() – shan Nov 15 '16 at 01:31