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; }
@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; }
@Override public DoubleMatrix apply(DoubleMatrix matrix) { DoubleMatrix newInstance = newInstance(matrix); if (matrix.isSparse()) { // if we have a sparse matrix, it is more efficient to loop over the // sparse row vectors int[] rows = matrix.rowIndices(); for (int row : rows) { DoubleVector rowVector = matrix.getRowVector(row); if (rowVector.getLength() > 0) { DoubleVector apply = apply(rowVector); newInstance.setRowVector(row, apply); } } } 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, apply(matrix.get(i, j))); } } } return newInstance; }
/** * Computes dropout for the activations matrix. Each element for each row has * the similar probability p to be "dropped out" (set to 0) of the * computation. This way, the network does learn to not rely on other units * thus learning to detect more general features than drastically overfitting * the dataset. * * @param rnd the random number generator to consult. * @param activations activations of units per record on each column. * @param p dropout probability. */ public static void dropout(Random rnd, DoubleMatrix activations, double p) { for (int row = 0; row < activations.getRowCount(); row++) { for (int col = 0; col < activations.getColumnCount(); col++) { if (rnd.nextDouble() <= p) { activations.set(row, col, 0d); } } } }
/** * Unfolds a single vector into a single matrix by rows. * * @param vector the vector to split. * @param rows the number of rows the target matrix needs to have. * @param cols the number of columns the target matrix needs to have. * @return a matrix with the contents of the vector, row split. */ public static DoubleMatrix unfoldMatrix(DoubleVector vector, int rows, int cols) { DoubleMatrix mat = new DenseDoubleMatrix(rows, cols); int index = 0; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { mat.set(i, j, vector.get(index++)); } } return mat; }
@Override public DoubleMatrix subtract(DoubleMatrix other) { DoubleMatrix m = new DenseDoubleMatrix(this.numRows, this.numColumns); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { m.set(i, j, this.matrix[translate(i, j, numRows)] - other.get(i, j)); } } return m; }
@Override public DoubleMatrix add(DoubleMatrix other) { DoubleMatrix m = new DenseDoubleMatrix(this.numRows, this.numColumns); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { m.set(i, j, this.matrix[translate(i, j, numRows)] + other.get(i, j)); } } return m; }
/** * 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)); } } }
/** * Unfolds a vector into matrices by the rules defined in the sizeArray. The * sizeArray must have following format: in each row the row and column count * must be provided.<br/> * Example: sizeArray = {{2,3},{3,2}} will unfold into matrix 0 with 2 rows * and 3 columns and matrix 1 with 3 rows and 2 columns. */ public static DoubleMatrix[] unfoldMatrices(DoubleVector vector, int[][] sizeArray) { DoubleMatrix[] arr = new DoubleMatrix[sizeArray.length]; for (int i = 0; i < sizeArray.length; i++) { arr[i] = new DenseDoubleMatrix(sizeArray[i][0], sizeArray[i][1]); } int currentVectorIndex = 0; for (int i = 0; i < arr.length; i++) { final int numRows = sizeArray[i][0]; final int numColumns = sizeArray[i][1]; for (int col = 0; col < numColumns; col++) { for (int row = 0; row < numRows; row++) { arr[i].set(row, col, vector.get(currentVectorIndex++)); } } } return arr; }
@Override public DoubleMatrix divide(DoubleMatrix other) { DoubleMatrix m = new DenseDoubleMatrix(this.numRows, this.numColumns); for (int i = 0; i < numRows; i++) { for (int j = 0; j < numColumns; j++) { m.set(i, j, this.matrix[translate(i, j, numRows)] / other.get(i, j)); } } return m; }
@Override public DoubleMatrix multiply(double scalar) { DoubleMatrix result = new SparseDoubleRowMatrix(this); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterateNonZero = matrix.get(row) .iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement e = iterateNonZero.next(); result.set(row, e.getIndex(), get(row, e.getIndex()) * scalar); } } return result; }
@Override public DoubleMatrix subtract(double amount) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.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() - amount); } } return result; }
@Override public DoubleMatrix pow(double x) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.getColumnCount()); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterateNonZero = matrix.get(row) .iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement e = iterateNonZero.next(); if (x != 2d) { result.set(row, e.getIndex(), Math.pow(get(row, e.getIndex()), x)); } else { double res = get(row, e.getIndex()); result.set(row, e.getIndex(), res * res); } } } return result; }
@Override public DoubleMatrix divide(double scalar) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.getColumnCount()); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterateNonZero = matrix.get(row) .iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement e = iterateNonZero.next(); result.set(row, e.getIndex(), e.getValue() / scalar); } } return result; }
@Override public DoubleMatrix subtractBy(double amount) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.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(), amount - e.getValue()); } } return result; }
private void observe(DoubleVector document, DoubleVector outcome, int numDistinctClasses, int[] tokenPerClass, int[] numDocumentsPerClass) { int predictedClass = outcome.maxIndex(); if (numDistinctClasses == 2) { predictedClass = (int) outcome.get(0); } tokenPerClass[predictedClass] += document.getLength(); numDocumentsPerClass[predictedClass]++; Iterator<DoubleVectorElement> iterateNonZero = document.iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement next = iterateNonZero.next(); double currentCount = probabilityMatrix.get(predictedClass, next.getIndex()); probabilityMatrix.set(predictedClass, next.getIndex(), currentCount + next.getValue()); } }
@Override public DoubleMatrix divide(DoubleVector vec) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.getColumnCount()); for (int row : this.matrix.keys()) { SparseDoubleVector rowVector = matrix.get(row); Iterator<DoubleVectorElement> iterateNonZero = rowVector.iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement next = iterateNonZero.next(); result.set(row, next.getIndex(), next.getValue() / vec.get(row)); } } return result; }
@Override public DoubleMatrix multiplyElementWise(DoubleMatrix other) { DoubleMatrix result = new SparseDoubleRowMatrix(this.getRowCount(), this.getColumnCount()); for (int row : this.matrix.keys()) { Iterator<DoubleVectorElement> iterateNonZero = matrix.get(row) .iterateNonZero(); while (iterateNonZero.hasNext()) { DoubleVectorElement e = iterateNonZero.next(); result.set(row, e.getIndex(), get(row, e.getIndex()) * other.get(row, e.getIndex())); } } return result; }
@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; }
/** * Scales a matrix into the interval given by min and max. * * @param input the input value. * @param fromMin the lower bound of the input interval. * @param fromMax the upper bound of the input interval. * @param toMin the lower bound of the target interval. * @param toMax the upper bound of the target interval. * @return the new matrix with scaled values. */ public static DoubleMatrix minMaxScale(DoubleMatrix input, double fromMin, double fromMax, double toMin, double toMax) { DoubleMatrix newOne = new DenseDoubleMatrix(input.getRowCount(), input.getColumnCount()); double[][] array = input.toArray(); for (int row = 0; row < newOne.getRowCount(); row++) { for (int col = 0; col < newOne.getColumnCount(); col++) { newOne.set(row, col, minMaxScale(array[row][col], fromMin, fromMax, toMin, toMax)); } } return newOne; }