Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright [2013-2014] eBay Software Foundation
   *  
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *  
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package ml.shifu.guagua.mapreduce.example.nn;

Weight is used to update NN weights according to propagation option. Which is also copied from Encog.

We'd like to reuse code from Encog but unfortunately the methods are private:(.

 
 public class Weight {
    
The zero tolerance to use.
 
     private static final double ZERO_TOLERANCE = 0.00000000000000001;
 
     private double learningRate;
 
     private String algorithm;
 
     // for quick propagation
     private double decay = 0.0001d;
     private double[] lastDelta = null;
     private double[] lastGradient = null;
     private double outputEpsilon = 0.35;
     private double eps = 0.0;
     private double shrink = 0.0;
 
     // for back propagation
     private double momentum = 0.0;
 
     // for resilient propagation
     private double[] updateValues = null;
     private static final double DEFAULT_INITIAL_UPDATE = 0.1;
     private static final double DEFAULT_MAX_STEP = 50;
 
     public Weight(int numWeightdouble numTrainSizedouble rateString algorithm) {
 
         this. = new double[numWeight];
         this. = new double[numWeight];
         this. = this. / numTrainSize;
         this. = rate / (1.0 + rate);
         this. = rate;
         this. = algorithm;
         this. = new double[numWeight];
 
         for(int i = 0; i < this..lengthi++) {
             this.[i] = ;
             this.[i] = 0;
         }
     }
 
     public double[] calculateWeights(double[] weightsdouble[] gradients) {
         for(int i = 0; i < gradients.lengthi++) {
             weights[i] += updateWeight(iweightsgradients);
         }
 
         return weights;
     }
 
     private double updateWeight(int indexdouble[] weightsdouble[] gradients) {
 
             return updateWeightBP(indexweightsgradients);
         } else if(this..equalsIgnoreCase(.)) {
             return updateWeightQBP(indexweightsgradients);
         } else if(this..equalsIgnoreCase(.)) {
             return updateWeightMHP(indexweightsgradients);
         } else if(this..equalsIgnoreCase(.)) {
             return updateWeightSCG(indexweightsgradients);
         } else if(this..equalsIgnoreCase(.)) {
             return updateWeightRLP(indexweightsgradients);
         }
 
         return 0.0;
 
     }
 
     private double updateWeightBP(int indexdouble[] weightsdouble[] gradients) {
         double delta = (gradients[index] * this.) + (this.[index] * this.);
         this.[index] = delta;
         return delta;
     }
 
     private double updateWeightQBP(int indexdouble[] weightsdouble[] gradients) {
 
        final double w = weights[index];
        final double d = this.[index];
        final double s = -gradients[index] + this. * w;
        final double p = -[index];
        double nextStep = 0.0;
        // The step must always be in direction opposite to the slope.
        if(d < 0.0) {
            // If last step was negative...
            if(s > 0.0) {
                // Add in linear term if current slope is still positive.
                nextStep -= this. * s;
            }
            // If current slope is close to or larger than prev slope...
            if(s >= (this. * p)) {
                // Take maximum size negative step.
                nextStep += this. * d;
            } else {
                // Else, use quadratic estimate.
                nextStep += d * s / (p - s);
            }
        } else if(d > 0.0) {
            // If last step was positive...
            if(s < 0.0) {
                // Add in linear term if current slope is still negative.
                nextStep -= this. * s;
            }
            // If current slope is close to or more neg than prev slope...
            if(s <= (this. * p)) {
                // Take maximum size negative step.
                nextStep += this. * d;
            } else {
                // Else, use quadratic estimate.
                nextStep += d * s / (p - s);
            }
        } else {
            // Last step was zero, so use only linear term.
            nextStep -= this. * s;
        }
        // update global data arrays
        this.[index] = nextStep;
        this.[index] = gradients[index];
        return nextStep;
    }
    private double updateWeightMHP(int indexdouble[] weightsdouble[] gradients) {
        if(Math.abs(gradients[index]) < ) {
            return 0;
        } else if(gradients[index] > 0) {
            return this.;
        } else {
            return -this.;
        }
    }
    private double updateWeightSCG(int indexdouble[] weightsdouble[] gradients) {
        // TODO
        return 0;
    }
    private double updateWeightRLP(int indexdouble[] weightsdouble[] gradients) {
        // multiply the current and previous gradient, and take the
        // sign. We want to see if the gradient has changed its sign.
        final int change = NNUtils.sign(gradients[index] * [index]);
        double weightChange = 0;
        // if the gradient has retained its sign, then we increase the
        // delta so that it will converge faster
        if(change > 0) {
            double delta = this.[index] * .;
            delta = Math.min(delta);
            weightChange = NNUtils.sign(gradients[index]) * delta;
            this.[index] = delta;
            [index] = gradients[index];
        } else if(change < 0) {
            // if change<0, then the sign has changed, and the last
            // delta was too big
            double delta = this.[index] * .;
            delta = Math.max(delta.);
            this.[index] = delta;
            weightChange = -this.[index];
            // set the previous gradent to zero so that there will be no
            // adjustment the next iteration
            [index] = 0;
        } else if(change == 0) {
            // if change==0 then there is no change to the delta
            final double delta = this.[index];
            weightChange = NNUtils.sign(gradients[index]) * delta;
            [index] = gradients[index];
        }
        this.[index] = weightChange;
        // apply the weight change, if any
        return weightChange;
    }
New to GrepCode? Check out our FAQ X