This is an automated email from the ASF dual-hosted git repository. mawiesne pushed a commit to branch OPENNLP-1472_Fix_flaky_GradientDescentUtilsTest_in_sandbox_component_nlp-utils in repository https://gitbox.apache.org/repos/asf/opennlp-sandbox.git
commit 8e4f82a1a98481999f1c2d97c93fabc9c92fbd93 Author: Martin Wiesner <[email protected]> AuthorDate: Thu Feb 23 15:50:00 2023 +0100 OPENNLP-1472 Fix flaky (sub-) test of GradientDescentUtilsTest in sandbox component 'nlp-utils' - adjusts parameter alpha in GradientDescentUtilsTest from `0.00002` to `0.00001` - aforementioned param change results in stable convergence, checked via RepeatedTest (JUnit) - optimizes how random values are obtained in `GradientDescentUtils` - fixes a potentially unpredictable BigDecimal value in `AnomalyDetectionUtils` (see JavaDoc of that constructor) --- .../utils/anomalydetection/AnomalyDetectionUtils.java | 2 +- .../opennlp/utils/regression/GradientDescentUtils.java | 16 ++++++++-------- .../utils/regression/GradientDescentUtilsTest.java | 15 +++++++++++---- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/nlp-utils/src/main/java/org/apache/opennlp/utils/anomalydetection/AnomalyDetectionUtils.java b/nlp-utils/src/main/java/org/apache/opennlp/utils/anomalydetection/AnomalyDetectionUtils.java index 009441f..0f38415 100644 --- a/nlp-utils/src/main/java/org/apache/opennlp/utils/anomalydetection/AnomalyDetectionUtils.java +++ b/nlp-utils/src/main/java/org/apache/opennlp/utils/anomalydetection/AnomalyDetectionUtils.java @@ -96,7 +96,7 @@ public class AnomalyDetectionUtils { private static double calculateGaussianProbability(TrainingExample x, double[] mus, double[] sigmas) { assert mus.length == sigmas.length : "parameters not aligned"; - BigDecimal px = new BigDecimal(1d); + BigDecimal px = new BigDecimal("1"); for (int i = 0; i < mus.length; i++) { BigDecimal firstTerm = BigDecimal.ONE.divide(BigDecimal.valueOf(Math.sqrt(2d * Math.PI * sigmas[i])), RoundingMode.CEILING); BigDecimal secondTerm = BigDecimal.valueOf(Math.exp(-1 * (Math.pow(x.getInputs()[i] - mus[i], 2) / (2 * Math.pow(sigmas[i], 2))))); diff --git a/nlp-utils/src/main/java/org/apache/opennlp/utils/regression/GradientDescentUtils.java b/nlp-utils/src/main/java/org/apache/opennlp/utils/regression/GradientDescentUtils.java index 67613b5..ce99ebb 100644 --- a/nlp-utils/src/main/java/org/apache/opennlp/utils/regression/GradientDescentUtils.java +++ b/nlp-utils/src/main/java/org/apache/opennlp/utils/regression/GradientDescentUtils.java @@ -18,8 +18,6 @@ */ package org.apache.opennlp.utils.regression; -import java.util.Arrays; -import java.util.Random; import org.apache.opennlp.utils.TrainingSet; /** @@ -31,10 +29,13 @@ public class GradientDescentUtils { private static final int MAX_ITERATIONS = 100000; /** - * Calculates batch gradient descent on the give hypothesis, training set and learning rate alpha. - * The algorithms iteratively adjusts the hypothesis parameters + * Calculates batch gradient descent on a {@link Hypothesis}, {@link TrainingSet} and + * learning rate {@code alpha}. The algorithms iteratively adjusts the hypothesis parameters * - * @param trainingSet the training set used to fit the parameters + * <p> + * Note: This implementation uses {@link LinearCombinationHypothesis} as hypothesis. + * + * @param trainingSet the {@link TrainingSet} used to fit the parameters * @param alpha the learning rate alpha used to define how big the descent steps are */ public static void batchGradientDescent(TrainingSet trainingSet, double alpha) { @@ -52,7 +53,7 @@ public class GradientDescentUtils { if (newCost > cost) { throw new RuntimeException("failed to converge at iteration " + iterations + " with cost going from " + cost + " to " + newCost); } else if (cost == newCost || newCost < THRESHOLD || iterations > MAX_ITERATIONS) { - System.out.println(cost + " with parameters " + Arrays.toString(parameters) + "(" + iterations + " iterations)"); + // System.out.println(cost + " with parameters " + Arrays.toString(parameters) + "(" + iterations + " iterations)"); break; } @@ -72,8 +73,7 @@ public class GradientDescentUtils { private static double[] initializeRandomWeights(int size) { double[] doubles = new double[size]; for (int i = 0; i < doubles.length; i++) { - Random rand = new Random(); - doubles[i] = rand.nextDouble() * 0.1d; + doubles[i] = Math.random() * 0.1d; } return doubles; } diff --git a/nlp-utils/src/test/java/org/apache/opennlp/utils/regression/GradientDescentUtilsTest.java b/nlp-utils/src/test/java/org/apache/opennlp/utils/regression/GradientDescentUtilsTest.java index 258985f..a551a5d 100644 --- a/nlp-utils/src/test/java/org/apache/opennlp/utils/regression/GradientDescentUtilsTest.java +++ b/nlp-utils/src/test/java/org/apache/opennlp/utils/regression/GradientDescentUtilsTest.java @@ -20,6 +20,7 @@ package org.apache.opennlp.utils.regression; import org.apache.opennlp.utils.TestUtils; import org.apache.opennlp.utils.TrainingSet; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** @@ -27,11 +28,17 @@ import org.junit.jupiter.api.Test; */ class GradientDescentUtilsTest { - @Test - void testConvergence() { - TrainingSet trainingSet = new TrainingSet(); + private TrainingSet trainingSet; + + @BeforeEach + public void setup() { + trainingSet = new TrainingSet(); TestUtils.fillTrainingSet(trainingSet, 100, 5); - GradientDescentUtils.batchGradientDescent(trainingSet, 0.00002); + } + + @Test // @RepeatedTest(1000) + void testConvergence() { + GradientDescentUtils.batchGradientDescent(trainingSet, 0.00001); } }
