예제 #1
0
  /**
   * Convert data to probability co-occurrences (aka calculating the kernel)
   *
   * @param d the data to convert
   * @param u the perplexity of the model
   * @return the probabilities of co-occurrence
   */
  public INDArray computeGaussianPerplexity(final INDArray d, double u) {
    int n = d.rows();
    final INDArray p = zeros(n, n);
    final INDArray beta = ones(n, 1);
    final double logU = Math.log(u);

    log.info("Calculating probabilities of data similarities..");
    for (int i = 0; i < n; i++) {
      if (i % 500 == 0 && i > 0) log.info("Handled " + i + " records");

      double betaMin = Double.NEGATIVE_INFINITY;
      double betaMax = Double.POSITIVE_INFINITY;
      int[] vals = Ints.concat(ArrayUtil.range(0, i), ArrayUtil.range(i + 1, d.columns()));
      INDArrayIndex[] range = new INDArrayIndex[] {new NDArrayIndex(vals)};

      INDArray row = d.slice(i).get(range);
      Pair<INDArray, INDArray> pair = hBeta(row, beta.getDouble(i));
      INDArray hDiff = pair.getFirst().sub(logU);
      int tries = 0;

      // while hdiff > tolerance
      while (BooleanIndexing.and(abs(hDiff), Conditions.greaterThan(tolerance)) && tries < 50) {
        // if hdiff > 0
        if (BooleanIndexing.and(hDiff, Conditions.greaterThan(0))) {
          if (Double.isInfinite(betaMax)) beta.putScalar(i, beta.getDouble(i) * 2.0);
          else beta.putScalar(i, (beta.getDouble(i) + betaMax) / 2.0);
          betaMin = beta.getDouble(i);
        } else {
          if (Double.isInfinite(betaMin)) beta.putScalar(i, beta.getDouble(i) / 2.0);
          else beta.putScalar(i, (beta.getDouble(i) + betaMin) / 2.0);
          betaMax = beta.getDouble(i);
        }

        pair = hBeta(row, beta.getDouble(i));
        hDiff = pair.getFirst().subi(logU);
        tries++;
      }

      p.slice(i).put(range, pair.getSecond());
    }

    // dont need data in memory after
    log.info("Mean value of sigma " + sqrt(beta.rdiv(1)).mean(Integer.MAX_VALUE));
    BooleanIndexing.applyWhere(p, Conditions.isNan(), new Value(realMin));

    // set 0 along the diagonal
    INDArray permute = p.transpose();

    INDArray pOut = p.add(permute);

    pOut.divi(pOut.sum(Integer.MAX_VALUE));
    BooleanIndexing.applyWhere(
        pOut, Conditions.lessThan(Nd4j.EPS_THRESHOLD), new Value(Nd4j.EPS_THRESHOLD));
    // ensure no nans
    return pOut;
  }
예제 #2
0
  /**
   * @param X
   * @param nDims
   * @param perplexity
   */
  public INDArray calculate(INDArray X, int nDims, double perplexity) {
    if (usePca) X = PCA.pca(X, Math.min(50, X.columns()), normalize);
    // normalization (don't normalize again after pca)
    if (normalize) {
      X.subi(X.min(Integer.MAX_VALUE));
      X = X.divi(X.max(Integer.MAX_VALUE));
      X = X.subiRowVector(X.mean(0));
    }

    if (nDims > X.columns()) nDims = X.columns();

    INDArray sumX = pow(X, 2).sum(1);

    INDArray D = X.mmul(X.transpose()).muli(-2).addRowVector(sumX).transpose().addRowVector(sumX);

    // output
    if (y == null) y = randn(X.rows(), nDims, Nd4j.getRandom()).muli(1e-3f);

    INDArray p = computeGaussianPerplexity(D, perplexity);

    // lie for better local minima
    p.muli(4);

    // init adagrad where needed
    if (useAdaGrad) {
      if (adaGrad == null) {
        adaGrad = new AdaGrad(y.shape());
        adaGrad.setMasterStepSize(learningRate);
      }
    }

    for (int i = 0; i < maxIter; i++) {
      step(p, i);

      if (i == switchMomentumIteration) momentum = finalMomentum;
      if (i == stopLyingIteration) p.divi(4);

      if (iterationListener != null) iterationListener.iterationDone(null, i);
    }

    return y;
  }