/** * Calculates the AUC measurment. * * @param algorithm The optimisation algorithm with a NNTrainingProblem. * @return A Vector with the AUC for each NN output. */ @Override public Vector getValue(Algorithm algorithm) { Vector solution = (Vector) algorithm.getBestSolution().getPosition(); NNTrainingProblem problem = (NNTrainingProblem) algorithm.getOptimisationProblem(); StandardPatternDataTable generalisationSet = problem.getGeneralisationSet(); NeuralNetwork neuralNetwork = problem.getNeuralNetwork(); neuralNetwork.setWeights(solution); // Arrange outputs and target values into ArrayLists. ArrayList<ArrayList<Real>> targets = new ArrayList<ArrayList<Real>>(); ArrayList<ArrayList<Real>> outputs = new ArrayList<ArrayList<Real>>(); // case of multiple outputs if (generalisationSet.getRow(0).getTarget() instanceof Vector) { int size = ((Vector) generalisationSet.getRow(0).getTarget()).size(); for (int i = 0; i < size; ++i) { targets.add(new ArrayList<Real>()); outputs.add(new ArrayList<Real>()); } for (StandardPattern pattern : generalisationSet) { Vector target = (Vector) pattern.getTarget(); Vector output = neuralNetwork.evaluatePattern(pattern); for (int curOutput = 0; curOutput < target.size(); ++curOutput) { targets.get(curOutput).add((Real) target.get(curOutput)); outputs.get(curOutput).add((Real) output.get(curOutput)); } } } // case of single output else { targets.add(new ArrayList<Real>()); outputs.add(new ArrayList<Real>()); for (StandardPattern pattern : generalisationSet) { Real target = (Real) pattern.getTarget(); Vector output = neuralNetwork.evaluatePattern(pattern); targets.get(0).add(target); outputs.get(0).add((Real) output.get(0)); } } // Calculate the Vector of AUC values Vector results = Vector.of(); for (int curOutput = 0; curOutput < outputs.size(); ++curOutput) { results.add(Real.valueOf(areaUnderCurve(targets.get(curOutput), outputs.get(curOutput)))); } return results; }
/** Test the get row method. */ @Test public void testGetRow() { StandardPattern pattern = stringTargetPatterns.getRow(0); List<Type> row = typedData.getRow(0); for (int j = 0; j < row.size() - 1; j++) { Assert.assertEquals(row.get(j), pattern.getVector().get(j)); } Assert.assertEquals(row.get(row.size() - 1), pattern.getTarget()); pattern = vectorTargetPatterns.getRow(0); row = typedData.getRow(2); for (int j = 0; j < row.size() - 3; j++) { Assert.assertEquals(row.get(j), pattern.getVector().get(j)); } for (int j = row.size() - 3; j < row.size(); j++) { Assert.assertEquals(row.get(j), ((Vector) pattern.getTarget()).get(j - (row.size() - 3))); } }
@Test public void testRemoveRow() { StandardPattern removed = stringTargetPatterns.removeRow(0); List<Type> row = typedData.getRow(0); for (int j = 0; j < row.size() - 1; j++) { Assert.assertEquals(row.get(j), removed.getVector().get(j)); } Assert.assertEquals(row.get(row.size() - 1), removed.getTarget()); removed = vectorTargetPatterns.removeRow(1); row = typedData.getRow(3); for (int j = 0; j < row.size() - 3; j++) { Assert.assertEquals(row.get(j), removed.getVector().get(j)); } for (int j = row.size() - 3; j < row.size(); j++) { Assert.assertEquals(row.get(j), ((Vector) removed.getTarget()).get(j - (row.size() - 3))); } Assert.assertEquals(1, stringTargetPatterns.size()); Assert.assertEquals(1, vectorTargetPatterns.size()); }
/** * Performs a gradient decent backpropagation given the previous {@link StandardPattern} as input * as well as the weight updates after the previous execution of a backpropagation. If the * previous weight updates do not exist, the visitor will create them and initialize them to zero. * * @param architecture */ @Override public void visit(Architecture architecture) { List<Layer> layers = architecture.getLayers(); int numLayers = layers.size(); int currentLayerIdx = numLayers - 1; // skip input layer Layer currentLayer = layers.get(currentLayerIdx); int layerSize = currentLayer.size(); Layer nextLayer = null; int nextLayerSize = -1; Neuron currentNeuron; // setup delta storage layerWeightsDelta = new double[numLayers - 1][]; // not necessary for input layer // calculate output layer deltas layerWeightsDelta[currentLayerIdx - 1] = new double[layerSize]; for (int k = 0; k < layerSize; k++) { currentNeuron = currentLayer.get(k); double t_k = layerSize > 1 ? ((Vector) previousPattern.getTarget()).doubleValueOf(k) : ((Real) previousPattern.getTarget()).doubleValue(); double o_k = currentNeuron.getActivation(); layerWeightsDelta[currentLayerIdx - 1][k] = -1.0 * (t_k - o_k) * currentNeuron.getActivationFunction().getGradient(o_k); } // calculate deltas for all hidden layers for (currentLayerIdx = numLayers - 2; currentLayerIdx > 0; currentLayerIdx--) { currentLayer = layers.get(currentLayerIdx); layerSize = currentLayer.size(); layerSize = currentLayer.isBias() ? layerSize - 1 : layerSize; layerWeightsDelta[currentLayerIdx - 1] = new double[layerSize]; for (int j = 0; j < layerSize; j++) { layerWeightsDelta[currentLayerIdx - 1][j] = 0.0; nextLayer = layers.get(currentLayerIdx + 1); nextLayerSize = nextLayer.size(); nextLayerSize = nextLayer.isBias() ? nextLayerSize - 1 : nextLayerSize; for (int k = 0; k < nextLayerSize; k++) { double w_kj = nextLayer.get(k).getWeights().doubleValueOf(j); layerWeightsDelta[currentLayerIdx - 1][j] += w_kj * layerWeightsDelta[currentLayerIdx][k]; } currentNeuron = currentLayer.get(j); layerWeightsDelta[currentLayerIdx - 1][j] *= currentNeuron.getActivationFunction().getGradient(currentNeuron.getActivation()); } } // storage for the weight updates if (previousWeightUpdates == null) { previousWeightUpdates = new double[numLayers - 1][]; for (currentLayerIdx = numLayers - 1; currentLayerIdx > 0; currentLayerIdx--) { for (int k = 0; k < layerSize; k++) { currentLayer = layers.get(currentLayerIdx); layerSize = currentLayer.isBias() ? currentLayer.size() - 1 : currentLayer.size(); int previousLayerSize = layers.get(currentLayerIdx - 1).size(); previousWeightUpdates[currentLayerIdx - 1] = new double[layerSize * previousLayerSize + previousLayerSize + 1]; } } } ((ForwardingLayer) layers.get(0)).setSource(new PatternInputSource(previousPattern)); // updates output and all hidden layer weights for (currentLayerIdx = numLayers - 1; currentLayerIdx > 0; currentLayerIdx--) { // loop excludes input layer currentLayer = layers.get(currentLayerIdx); layerSize = currentLayer.isBias() ? currentLayer.size() - 1 : currentLayer.size(); int previousLayerSize = -1; Layer previousLayer = null; for (int k = 0; k < layerSize; k++) { currentNeuron = currentLayer.get(k); previousLayer = layers.get(currentLayerIdx - 1); previousLayerSize = previousLayer.size(); double tmp = (-1.0 * learningRate) * layerWeightsDelta[currentLayerIdx - 1][k]; for (int j = 0; j < previousLayerSize; j++) { double weight = currentNeuron.getWeights().doubleValueOf(j); double newWeightUpdate = tmp * previousLayer.getNeuralInput(j); double update = newWeightUpdate + momentum * previousWeightUpdates[currentLayerIdx - 1][k * previousLayerSize + j]; currentNeuron.getWeights().setReal(j, weight + update); previousWeightUpdates[currentLayerIdx - 1][k * previousLayerSize + j] = newWeightUpdate; } } } }