예제 #1
0
  /**
   * Get a vector orthogonal to the instance.
   *
   * <p>There are an infinite number of normalized vectors orthogonal to the instance. This method
   * picks up one of them almost arbitrarily. It is useful when one needs to compute a reference
   * frame with one of the axes in a predefined direction. The following example shows how to build
   * a frame having the k axis aligned with the known vector u :
   *
   * <pre><code>
   *   Vector3D k = u.normalize();
   *   Vector3D i = k.orthogonal();
   *   Vector3D j = Vector3D.crossProduct(k, i);
   * </code></pre>
   *
   * @return a new normalized vector orthogonal to the instance
   * @exception ArithmeticException if the norm of the instance is null
   */
  public Vector3D orthogonal() {

    double threshold = 0.6 * getNorm();
    if (threshold == 0) {
      throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_NORM);
    }

    if ((x >= -threshold) && (x <= threshold)) {
      double inverse = 1 / FastMath.sqrt(y * y + z * z);
      return new Vector3D(0, inverse * z, -inverse * y);
    } else if ((y >= -threshold) && (y <= threshold)) {
      double inverse = 1 / FastMath.sqrt(x * x + z * z);
      return new Vector3D(-inverse * z, 0, inverse * x);
    }
    double inverse = 1 / FastMath.sqrt(x * x + y * y);
    return new Vector3D(inverse * y, -inverse * x, 0);
  }
예제 #2
0
 /**
  * Returns the next pseudorandom, Gaussian ("normally") distributed {@code double} value with mean
  * {@code 0.0} and standard deviation {@code 1.0} from this random number generator's sequence.
  *
  * <p>The default implementation uses the <em>Polar Method</em> due to G.E.P. Box, M.E. Muller and
  * G. Marsaglia, as described in D. Knuth, <u>The Art of Computer Programming</u>, 3.4.1C.
  *
  * <p>The algorithm generates a pair of independent random values. One of these is cached for
  * reuse, so the full algorithm is not executed on each activation. Implementations that do not
  * override this method should make sure to call {@link #clear} to clear the cached value in the
  * implementation of {@link #setSeed(long)}.
  *
  * @return the next pseudorandom, Gaussian ("normally") distributed {@code double} value with mean
  *     {@code 0.0} and standard deviation {@code 1.0} from this random number generator's sequence
  */
 public double nextGaussian() {
   if (!Double.isNaN(cachedNormalDeviate)) {
     double dev = cachedNormalDeviate;
     cachedNormalDeviate = Double.NaN;
     return dev;
   }
   double v1 = 0;
   double v2 = 0;
   double s = 1;
   while (s >= 1) {
     v1 = 2 * nextDouble() - 1;
     v2 = 2 * nextDouble() - 1;
     s = v1 * v1 + v2 * v2;
   }
   if (s != 0) {
     s = FastMath.sqrt(-2 * FastMath.log(s) / s);
   }
   cachedNormalDeviate = v2 * s;
   return v1 * s;
 }
예제 #3
0
 /**
  * Compute the distance between two vectors according to the L<sub>2</sub> norm.
  *
  * <p>Calling this method is equivalent to calling: <code>v1.subtract(v2).getNorm()</code> except
  * that no intermediate vector is built
  *
  * @param v1 first vector
  * @param v2 second vector
  * @return the distance between v1 and v2 according to the L<sub>2</sub> norm
  */
 public static double distance(Vector3D v1, Vector3D v2) {
   final double dx = v2.x - v1.x;
   final double dy = v2.y - v1.y;
   final double dz = v2.z - v1.z;
   return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
 }
예제 #4
0
 /**
  * Get the L<sub>2</sub> norm for the vector.
  *
  * @return euclidian norm for the vector
  */
 public double getNorm() {
   return FastMath.sqrt(x * x + y * y + z * z);
 }
예제 #5
0
public class DenseFeatureMatrix {
  int inputSize;
  int outputSize;
  INDArray features;
  INDArray featuresT;
  GradientStore gradientStore = new GradientStore();
  double l2 = GlobalParameters.l2regularizerLambdaDefault;
  double learningRate = GlobalParameters.learningRateDefault;

  // adagrad vars
  boolean useAdagrad = GlobalParameters.useAdagradDefault;
  INDArray adagradQuotient;
  double adagradEps = 0.001;
  double adagradMax = 10;

  // gaussian noise
  double noiseVar = GlobalParameters.noiseDevDefault;
  double noiseVarSqrt = FastMath.sqrt(noiseVar);;
  HashMap<Integer, INDArray> currentNoise = new HashMap<Integer, INDArray>();

  // momentum vars
  boolean useMomentum = GlobalParameters.useMomentumDefault;
  INDArray momentumPrevUpdate;
  double momentum = GlobalParameters.momentumDefault;

  // adadelta vars
  boolean useAdadelta = GlobalParameters.useAdadeltaDefault;
  INDArray adadeltaRMSGradient;
  INDArray adadeltaRMSUpdate;
  double adadeltaMomentum = GlobalParameters.adadeltaMomentumDefault;
  double adadeltaEps = GlobalParameters.adadeltaEpsDefault;

  // commit
  int commitMethod = GlobalParameters.commitMethodDefault;

  public DenseFeatureMatrix(
      int inputSize, int outputSize, boolean useAdagrad, boolean useMomentum, boolean useAdadelta) {
    if (inputSize == 1) {
      throw new RuntimeException("input size = 1: use vector instead");
    }
    this.inputSize = inputSize;
    this.outputSize = outputSize;
    this.useAdadelta = useAdadelta;
    this.useAdagrad = useAdagrad;
    this.useMomentum = useMomentum;
    if (useAdagrad) {
      adagradQuotient = Nd4j.zeros(inputSize, outputSize);
      adagradQuotient.addi(adagradEps);
    }
    if (useMomentum) {
      momentumPrevUpdate = Nd4j.zeros(inputSize, outputSize);
    }
    if (useAdadelta) {
      adadeltaRMSGradient = Nd4j.zeros(inputSize, outputSize);
      adadeltaRMSUpdate = Nd4j.zeros(inputSize, outputSize);
    }
  }

  public DenseFeatureMatrix(int inputSize, int outputSize) {
    if (inputSize == 1) {
      throw new RuntimeException("input size = 1: use vector instead");
    }
    this.inputSize = inputSize;
    this.outputSize = outputSize;
    if (useAdagrad) {
      adagradQuotient = Nd4j.zeros(inputSize, outputSize);
      adagradQuotient.addi(adagradEps);
    }
    if (useMomentum) {
      momentumPrevUpdate = Nd4j.zeros(inputSize, outputSize);
    }
    if (useAdadelta) {
      adadeltaRMSGradient = Nd4j.zeros(inputSize, outputSize);
      adadeltaRMSUpdate = Nd4j.zeros(inputSize, outputSize);
    }
  }

  public void initialize(double[][] vals) {
    features = Nd4j.create(vals);
    featuresT = features.transpose();
  }

  public void initializeUniform(double min, double max) {
    double[][] featuresMatrixStub = new double[inputSize][outputSize];
    RandomUtils.initializeRandomMatrix(featuresMatrixStub, min, max, 1);
    features = Nd4j.create(featuresMatrixStub);
    featuresT = features.transpose();
  }

  public void normalizedInitializationHtan(int fanin, int fanout) {
    double max = Math.sqrt(6.0d / (fanout + fanin));
    double[][] featuresMatrixStub = new double[inputSize][outputSize];
    RandomUtils.initializeRandomMatrix(featuresMatrixStub, -max, max, 1);

    features = Nd4j.create(featuresMatrixStub);
    featuresT = features.transpose();
  }

  public void normalizedInitializationSigmoid(int fanin, int fanout) {
    double max = 4 * Math.sqrt(6.0d / (fanin + fanout));
    double[][] featuresMatrixStub = new double[inputSize][outputSize];
    RandomUtils.initializeRandomMatrix(featuresMatrixStub, -max, max, 1);
    features = Nd4j.create(featuresMatrixStub);
    featuresT = features.transpose();
  }

  public INDArray getWeights() {
    return features;
  }

  public INDArray getTranspose() {
    return featuresT;
  }

  public void storeGradients(int processId, INDArray gradient) {
    gradientStore.addGradient(processId, gradient);
  }

  public void storeInputsAndOutputs(int id, INDArray x, INDArray yGrad) {
    gradientStore.addInputAndOutput(id, x, yGrad);
  }

  public void checkinGradients(int id) {
    gradientStore.computeGradientAndAdd(id);
  }

  public void update() {
    INDArray gradient = null;
    if (commitMethod == 0) {
      gradient = gradientStore.getGradientAvg();
    } else {
      gradient = gradientStore.getGradientSum();
    }
    if (gradient == null) return;
    INDArray gradientL2 = gradient.sub(features.mul(l2));
    if (useAdagrad) {
      getAdagradGradient(gradientL2);
      features.addi(gradientL2.mul(learningRate));
    } else if (useMomentum) {
      getMomentumGradient(gradientL2);
      features.addi(gradientL2.mul(learningRate));
    } else if (useAdadelta) {
      getAdadeltaGradient(gradientL2);
      features.addi(gradientL2);
    } else {
      features.addi(gradientL2.mul(learningRate));
    }
    capValues(GlobalParameters.maxVal);
    featuresT = features.transpose();
    gradientStore.init();
  }

  protected void getAdagradGradient(INDArray gradient) {
    adagradQuotient.addi(gradient.mul(gradient));
    for (int i = 0; i < inputSize; i++) {
      for (int j = 0; j < outputSize; j++) {
        double adagradQ = adagradQuotient.getDouble(i, j);
        if (adagradMax < adagradQ) {
          adagradQuotient.putScalar(new int[] {i, j}, adagradMax);
          adagradQ = adagradMax;
        }
        gradient.putScalar(new int[] {i, j}, gradient.getDouble(i, j) / Math.sqrt(adagradQ));
      }
    }
  }

  protected void getAdadeltaGradient(INDArray gradient) {
    adadeltaRMSGradient =
        adadeltaRMSGradient
            .mul(adadeltaMomentum)
            .add(gradient.mul(gradient).mul(1 - adadeltaMomentum));
    gradient.muli(
        Transforms.sqrt(adadeltaRMSUpdate.add(adadeltaEps))
            .div(Transforms.sqrt(adadeltaRMSGradient.add(adadeltaEps))));
    adadeltaRMSUpdate.mul(adadeltaMomentum).add(gradient.mul(gradient).mul(1 - adadeltaMomentum));
  }

  protected void getMomentumGradient(INDArray gradient) {
    INDArray momemtumUpdate = momentumPrevUpdate.mul(momentum);
    gradient.addi(momemtumUpdate);
    momentumPrevUpdate = gradient.dup();
  }

  public INDArray genGaussianNoise(int id) {
    if (!currentNoise.containsKey(id)) {
      INDArray zeroMean = Nd4j.zeros(inputSize, outputSize);

      currentNoise.put(id, Sampling.normal(RandomUtils.getRandomGenerator(id), zeroMean, noiseVar));
    } else {
      RealDistribution reals =
          new NormalDistribution(
              RandomUtils.getRandomGenerator(id),
              0,
              noiseVarSqrt,
              NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
      INDArrayUtils.shiftLeft(
          currentNoise.get(id),
          inputSize,
          outputSize,
          RandomUtils.getRandomGenerator(id).nextInt(inputSize * outputSize),
          reals.sample());
    }

    //		currentNoise = Sampling.normal(RandomUtils.getRandomGenerator(id), zeroMean, noiseVar);

    return currentNoise.get(id);
  }

  public void capValues(double max) {
    INDArray linear = features.linearView();
    for (int i = 0; i < linear.size(0); i++) {
      linear.putScalar(i, Math.max(-max, Math.min(max, linear.getDouble(i))));
    }
  }

  public void save(PrintStream out) {
    out.println(inputSize);
    out.println(outputSize);
    out.println(useAdagrad);
    out.println(adagradEps);
    out.println(adagradMax);
    out.println(noiseVar);
    out.println(useMomentum);
    out.println(momentum);
    out.println(useAdadelta);
    out.println(adadeltaEps);
    out.println(adadeltaMomentum);
    saveMatrix(features, out);
    if (useAdagrad) {
      saveMatrix(adagradQuotient, out);
    }
    if (useMomentum) {
      saveMatrix(momentumPrevUpdate, out);
    }
    if (useAdadelta) {
      saveMatrix(adadeltaRMSGradient, out);
      saveMatrix(adadeltaRMSUpdate, out);
    }
  }

  public void saveMatrix(INDArray matrix, PrintStream out) {
    for (int row = 0; row < inputSize; row++) {
      for (int col = 0; col < outputSize; col++) {
        double val = matrix.getDouble(row, col);
        if (col < outputSize - 1) {
          out.print(val + " ");
        } else {
          out.println(val);
        }
      }
    }
  }

  public static DenseFeatureMatrix load(BufferedReader in) {
    try {
      int inputSize = Integer.parseInt(in.readLine());
      int outputSize = Integer.parseInt(in.readLine());
      DenseFeatureMatrix matrix = new DenseFeatureMatrix(inputSize, outputSize);
      matrix.useAdagrad = Boolean.parseBoolean(in.readLine());
      matrix.adagradEps = Double.parseDouble(in.readLine());
      matrix.adagradMax = Double.parseDouble(in.readLine());
      matrix.noiseVar = Double.parseDouble(in.readLine());
      matrix.useMomentum = Boolean.parseBoolean(in.readLine());
      matrix.momentum = Double.parseDouble(in.readLine());
      matrix.useAdadelta = Boolean.parseBoolean(in.readLine());
      matrix.adadeltaEps = Double.parseDouble(in.readLine());
      matrix.adadeltaMomentum = Double.parseDouble(in.readLine());
      matrix.features = loadMatrix(in, inputSize, outputSize);
      if (matrix.useAdagrad) {
        matrix.adagradQuotient = loadMatrix(in, inputSize, outputSize);
      }
      if (matrix.useMomentum) {
        matrix.momentumPrevUpdate = loadMatrix(in, inputSize, outputSize);
      }
      if (matrix.useAdadelta) {
        matrix.adadeltaRMSGradient = loadMatrix(in, inputSize, outputSize);
        matrix.adadeltaRMSUpdate = loadMatrix(in, inputSize, outputSize);
      }
      matrix.featuresT = matrix.features.transpose();
      return matrix;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public static INDArray loadMatrix(BufferedReader in, int inputSize, int outputSize)
      throws IOException {
    INDArray matrix = Nd4j.create(inputSize, outputSize);
    for (int row = 0; row < inputSize; row++) {
      String[] vals = in.readLine().split("\\s+");
      for (int col = 0; col < outputSize; col++) {
        matrix.putScalar(new int[] {row, col}, Double.parseDouble(vals[col]));
      }
    }
    return matrix;
  }

  public void setL2(double l2) {
    this.l2 = l2;
  }

  public static void main(String[] args) {
    DenseFeatureMatrix matrix = new DenseFeatureMatrix(1, 5);
    matrix.initializeUniform(-0.1, 0.1);
    matrix.save(IOUtils.getPrintStream("/tmp/file"));

    DenseFeatureMatrix.load(IOUtils.getReader("/tmp/file")).save(System.err);
  }

  public void normalize() {
    features.divi(features.sum(0).getDouble(0) * inputSize);
    featuresT = features.transpose();
  }
}