public void teach() throws NNException {
		int discrepancies = 0;
		double objectiveValue = objectiveFunction();
		while (true) {
			System.out.println("Objective value = " + objectiveValue);
			// Perform gradient descent optimization:
			for (Pattern<?,?> pattern : patterns) {
				performGradientDescent(pattern);
			}
			
			// Defensive checks:
			double newObjectiveValue = objectiveFunction();
			if (newObjectiveValue > objectiveValue) {
				discrepancies++;
			}
			if (Double.isInfinite(newObjectiveValue)) {
				System.out.println("Failed to teach due to objective value overflow.");
				break;
			}
			if (Math.abs(newObjectiveValue - objectiveValue) < minObjectiveDelta) {
				System.out.println("Finished teaching due to objective value unchanching.");
				break;
			}
			objectiveValue = newObjectiveValue;
			if (objectiveValue < minObjective) {
				System.out.println("Finished teaching due to objective value becoming low.");
				break;
			}
			if (discrepancies > maxDiscrepancies) {
				System.out.println("Failed to teach due to objective discrepancy.");
				break;
			}
		}
	}