public void learn(
      List<DoubleMatrix> trainingSet,
      List<DoubleMatrix> resultSet,
      double learningFactor,
      double momentum,
      int epochCount,
      EvaluationContext evalCtx) {

    if (trainingSet.size() != resultSet.size()) {
      throw new IllegalArgumentException("trainingSet and resultSet should have the same size");
    }

    if (learningFactor >= 1 || learningFactor <= 0) {
      throw new IllegalArgumentException("learningFactor should be in the range (0, 1)");
    }

    if (epochCount < 1) {
      throw new IllegalArgumentException("epoch count should be the positive number!");
    }

    List<DoubleMatrix> previousModifications = new ArrayList<DoubleMatrix>();
    for (int i = 1; i < getLayers().size(); i++) {
      Layer l = getLayers().get(i);
      DoubleMatrix m = new DoubleMatrix(l.getWeights().rows, l.getWeights().columns);
      m.fill(0.0);
      previousModifications.add(m);
    }

    for (int i = 0; i < epochCount; i++) {
      learn(
          trainingSet,
          resultSet,
          Math.max(MIN_LEARNING_FACTOR, learningFactor * ((epochCount - i) * 1.0 / epochCount)),
          momentum,
          previousModifications,
          evalCtx);
    }
  }