public ConditionalLikelihoodCostFunction(DoubleMatrix features, DoubleMatrix outcome) { this.features = features; this.outcome = outcome; this.m = outcome.getRowCount(); this.classes = outcome.getColumnCount() == 1 ? 2 : outcome.getColumnCount(); }
static DoubleMatrix binarize(Random r, DoubleMatrix hiddenActivations) { for (int i = 0; i < hiddenActivations.getRowCount(); i++) { for (int j = 0; j < hiddenActivations.getColumnCount(); j++) { hiddenActivations.set(i, j, hiddenActivations.get(i, j) > r.nextDouble() ? 1d : 0d); } } return hiddenActivations; }
protected DoubleMatrix newInstance(DoubleMatrix mat) { if (mat.isSparse()) { return new SparseDoubleRowMatrix(mat.getRowCount(), mat.getColumnCount()); } else { return new DenseDoubleMatrix(mat.getRowCount(), mat.getColumnCount()); } }
/** * Folds a single matrix into a single vector by rows. */ public static DoubleVector foldMatrix(DoubleMatrix mat) { DoubleVector vec = new DenseDoubleVector(mat.getRowCount() * mat.getColumnCount()); int index = 0; for (int i = 0; i < mat.getRowCount(); i++) { for (int j = 0; j < mat.getColumnCount(); j++) { vec.set(index++, mat.get(i, j)); } } return vec; }
/** * Row-copies the given matrix to this sparse implementation. * * @param mat the matrix to copy. */ public SparseDoubleRowMatrix(DoubleMatrix mat) { this(mat.getRowCount(), mat.getColumnCount()); for (int i = 0; i < numColumns; i++) { setRowVector(i, mat.getRowVector(i)); } }
/** * Sets the weights in the whole matrix uniformly between -eInit and eInit * (eInit is the standard deviation) with zero mean. */ private void setWeightsUniformly(RandomDataImpl rnd, double eInit) { for (int i = 0; i < weights.getColumnCount(); i++) { for (int j = 0; j < weights.getRowCount(); j++) { weights.set(j, i, rnd.nextUniform(-eInit, eInit)); } } }
/** * Folds the given matrices column-wise into a single vector. */ public static DoubleVector foldMatrices(DoubleMatrix... matrices) { int length = 0; for (DoubleMatrix matrix : matrices) { length += matrix.getRowCount() * matrix.getColumnCount(); } DenseDoubleVector v = new DenseDoubleVector(length); int index = 0; for (DoubleMatrix matrix : matrices) { for (int j = 0; j < matrix.getColumnCount(); j++) { for (int i = 0; i < matrix.getRowCount(); i++) { v.set(index++, matrix.get(i, j)); } } } return v; }
@Override public double calculateLoss(DoubleMatrix y, DoubleMatrix hypothesis) { double sum = 0d; for (int col = 0; col < y.getColumnCount(); col++) { for (int row = 0; row < y.getRowCount(); row++) { double diff = y.get(row, col) - hypothesis.get(row, col); sum += (diff * diff); } } return sum / y.getRowCount(); }
public static double calculateRegularization(DoubleMatrix[] thetas, final int m, NetworkConfiguration conf) { double regularization = 0d; // only calculate the regularization term if lambda is not 0 if (conf.lambda != 0d) { for (DoubleMatrix theta : thetas) { regularization += (theta.slice(0, theta.getRowCount(), 1, theta.getColumnCount())).pow(2).sum(); } regularization = (conf.lambda / (2.0d * m)) * regularization; } return regularization; }
/** * Creates a new matrix with the given vector into the first column and the * other matrix to the other columns. This is usually used in machine learning * algorithms that add a bias on the zero-index column. * * @param first the new first column. * @param otherMatrix the other matrix to set on from the second column. */ public SparseDoubleRowMatrix(DenseDoubleVector first, DoubleMatrix otherMatrix) { this(otherMatrix.getRowCount(), otherMatrix.getColumnCount() + 1); setColumnVector(0, first); for (int i = 1; i < numColumns; i++) { setColumnVector(i, otherMatrix.getColumnVector(i - 1)); } }
@Override public DoubleMatrix multiply(DoubleMatrix other) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), other.getColumnCount()); for (int row = 0; row < getRowCount(); row++) { for (int col = 0; col < other.getColumnCount(); col++) { double sum = 0; Iterator<DoubleVectorElement> kIterator = getRowVector(row) .iterateNonZero(); while (kIterator.hasNext()) { DoubleVectorElement k = kIterator.next(); double val = other.get(k.getIndex(), col); if (val != 0d) { sum += k.getValue() * val; } } result.set(row, col, sum); } } return result; }
@Override public double calculateLoss(DoubleMatrix y, DoubleMatrix hypothesis) { double sum = 0d; for (int col = 0; col < y.getColumnCount(); col++) { for (int row = 0; row < y.getRowCount(); row++) { sum += FastMath.abs(y.get(row, col) - hypothesis.get(row, col)); } } return sum / y.getRowCount(); }
/** * Creates a new matrix with the given vector into the first column and the * other matrix to the other columns. This is usually used in machine learning * algorithms that add a bias on the zero-index column. * * @param first the new first column. * @param otherMatrix the other matrix to set on from the second column. */ public DenseDoubleMatrix(DenseDoubleVector first, DoubleMatrix otherMatrix) { this(otherMatrix.getRowCount(), otherMatrix.getColumnCount() + 1); // copy the first column System.arraycopy(first.toArray(), 0, matrix, 0, first.getDimension()); int offset = first.getDimension(); for (int col : otherMatrix.columnIndices()) { double[] clv = otherMatrix.getColumnVector(col).toArray(); System.arraycopy(clv, 0, matrix, offset, clv.length); offset += clv.length; } }
@Override public DoubleMatrix multiply(DoubleMatrix other) { int m = this.numRows; int n = this.numColumns; int p = other.getColumnCount(); DenseDoubleMatrix matrix = new DenseDoubleMatrix(m, p); for (int k = 0; k < n; k++) { for (int i = 0; i < m; i++) { for (int j = 0; j < p; j++) { matrix.set(i, j, matrix.get(i, j) + get(i, k) * other.get(k, j)); } } } return matrix; }
@Override public DoubleMatrix subtract(DoubleMatrix other) { SparseDoubleRowMatrix result = new SparseDoubleRowMatrix( other.getRowCount(), other.getColumnCount()); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterate = matrix.get(row).iterate(); while (iterate.hasNext()) { DoubleVectorElement e = iterate.next(); result.set(row, e.getIndex(), e.getValue() - other.get(row, e.getIndex())); } } return result; }
@Override public DoubleMatrix add(DoubleMatrix other) { SparseDoubleRowMatrix result = new SparseDoubleRowMatrix( other.getRowCount(), other.getColumnCount()); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterate = matrix.get(row).iterate(); while (iterate.hasNext()) { DoubleVectorElement e = iterate.next(); result.set(row, e.getIndex(), e.getValue() + other.get(row, e.getIndex())); } } return result; }
public static DoubleMatrix[] backwardPropagate(DoubleMatrix y, DoubleMatrix[] thetas, DoubleMatrix[] ax, DoubleMatrix[] zx, NetworkConfiguration conf) { // now backpropagate the error backwards by calculating the deltas. // also here we are following the math equations and nulling out the 0th // entry. DoubleMatrix[] deltaX = new DoubleMatrix[conf.layerSizes.length]; // set the last delta to the difference of outcome and prediction deltaX[deltaX.length - 1] = ax[conf.layerSizes.length - 1].subtract(y); // compute the deltas onto the input layer for (int i = (conf.layerSizes.length - 2); i > 0; i--) { DoubleMatrix slice = thetas[i].slice(0, thetas[i].getRowCount(), 1, thetas[i].getColumnCount()); deltaX[i] = multiply(deltaX[i + 1], slice, false, false, conf); // apply the gradient of the activations deltaX[i] = deltaX[i].multiplyElementWise(conf.activations[i] .gradient(zx[i])); } return deltaX; }
/** * Creates a weight matrix that can be used for unsupervised weight * initialization in the {@link MultilayerPerceptron}. * * @param outputLayerSize the size of the classification layer on top of this * RBM. * @return the {@link WeightMatrix} that maps layers to the weights. */ public WeightMatrix[] getNeuralNetworkWeights(int outputLayerSize) { WeightMatrix[] toReturn = new WeightMatrix[this.weights.length + 1]; // translate the matrices for (int i = 0; i < weights.length; i++) { toReturn[i] = new WeightMatrix(this.weights[i].slice(1, weights[i].getRowCount(), 0, weights[i].getColumnCount())); } // add a last layer on top of it toReturn[toReturn.length - 1] = new WeightMatrix( toReturn[toReturn.length - 2].getWeights().getRowCount(), outputLayerSize); return toReturn; }
/** * @return a log'd matrix that was guarded against edge cases of the * logarithm. */ public static DoubleMatrix logMatrix(DoubleMatrix input) { DenseDoubleMatrix log = new DenseDoubleMatrix(input.getRowCount(), input.getColumnCount()); for (int row = 0; row < log.getRowCount(); row++) { for (int col = 0; col < log.getColumnCount(); col++) { double d = input.get(row, col); log.set(row, col, guardedLogarithm(d)); } } return log; }
@Override public DoubleMatrix gradient(DoubleMatrix matrix) { DoubleMatrix newInstance = newInstance(matrix); if (matrix.isSparse()) { // if we have a sparse matrix, it is more efficient to loop over the // sparse column vectors int[] columnIndices = matrix.columnIndices(); for (int col : columnIndices) { newInstance.setColumnVector(col, gradient(matrix.getColumnVector(col))); } } else { // on dense matrices we can be faster by directly looping over the items for (int i = 0; i < matrix.getRowCount(); i++) { for (int j = 0; j < matrix.getColumnCount(); j++) { newInstance.set(i, j, gradient(matrix.get(i, j))); } } } return newInstance; }