public OUTPUT predict(DoubleTensor input) { xVertex.setAndCascade(input); return yVertex.getValue(); }
@Test public void doesNotDoUnnecessaryOperationsOnCascade() { AtomicInteger n = new AtomicInteger(0); AtomicInteger m = new AtomicInteger(0); DoubleVertex start = new GaussianVertex(0, 1); int links = 20; DoubleVertex end = addLinks(start, n, m, links); start.setAndCascade(2.0); //Calculates the correct answer assertEquals(Math.pow(2, links + 1), end.getValue().scalar(), 0.0); //Does the right amount of work assertEquals(3 * links, n.get()); }
@Test public void coefficientOfDeterminationIs1HighForSimilarData() { DoubleVertex input = new UniformVertex(new long[]{1, 1000}, -1000, 1000); DoubleVertex noisy = new GaussianVertex(input, 50); DoubleTensor inputSample = input.sample(); input.setAndCascade(inputSample); assertThat(ModelScoring.coefficientOfDetermination(inputSample, noisy.sample()), greaterThan(0.9)); } }
@Test public void doesNotPropagateThroughProbabilisticVerticesOnCascade() { AtomicInteger n = new AtomicInteger(0); AtomicInteger m = new AtomicInteger(0); DoubleVertex start = new GaussianVertex(0, 1); DoubleVertex end = addLinks(start, n, m, 1); DoubleVertex nextLayerStart = new GaussianVertex(end, 1); DoubleVertex secondLayerEnd = addLinks(nextLayerStart, n, m, 1); start.setAndCascade(3.0); //Calculates the correct answer assertEquals(6.0, end.getValue().scalar(), 0.0); //Does the right amount of work assertEquals(3, n.get()); }
@Test public void canSetAndCascadeArrayOfValues() { DoubleVertex gaussianVertex = new GaussianVertex(0, 1); double[] values = new double[]{1, 2, 3}; gaussianVertex.setAndCascade(values); assertArrayEquals(values, gaussianVertex.getValue().asFlatDoubleArray(), 0.0); }
@Test public void canSetAndCascadeAsScalarOnNonScalarVertex() { DoubleVertex gaussianVertex = new GaussianVertex(new long[]{1, 2}, 0, 1); gaussianVertex.setAndCascade(2); assertArrayEquals(new double[]{2}, gaussianVertex.getValue().asFlatDoubleArray(), 0.0); }
@Test public void canTakeValue() { DoubleVertex gaussianVertex = new GaussianVertex(0, 1); double[] values = new double[]{1, 2, 3}; gaussianVertex.setAndCascade(values); assertEquals(1, gaussianVertex.take(0).getValue().scalar(), 0.0); }
static TestData generateTwoFeatureData(int numSamples) { DoubleVertex x1Generator = new UniformVertex(new long[]{numSamples, 1}, 0, 10); DoubleVertex x2Generator = new UniformVertex(new long[]{numSamples, 1}, 50, 100); DoubleVertex yGenerator = new GaussianVertex( x1Generator.multiply(EXPECTED_W1).plus(x2Generator.multiply(EXPECTED_W2)).plus(EXPECTED_B), 1.0 ); DoubleTensor x1Data = x1Generator.sample(); x1Generator.setAndCascade(x1Data); DoubleTensor x2Data = x1Generator.sample(); x2Generator.setAndCascade(x2Data); DoubleTensor yData = yGenerator.sample(); return new TestData(DoubleTensor.create(EXPECTED_W1, EXPECTED_W2), EXPECTED_B, DoubleTensor.concat(1, x1Data, x2Data), yData); }
@Test public void canRunAModelInAModelWithDifferentOutputTypes() { weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); ModelVertex model = LambdaModelVertex.createFromProcess(inputs, COMMAND, weatherModel::updateValuesMultipleTypes); IntegerVertex suggestedFactorSuncream = model.getIntegerModelOutputVertex(new VertexLabel("suggestedFactorSuncream")); BooleanVertex isSunny = model.getBooleanModelOutputVertex(new VertexLabel("isSunny")); double inputValue = 20.0; inputToModel.setAndCascade(inputValue); Assert.assertEquals(suggestedFactorSuncream.getValue().scalar(), new Integer(2)); Assert.assertEquals(isSunny.getValue().scalar(), false); }
@Test public void canRunAModelInAModelWithDifferentOutputTypes() { weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); ModelVertex model = new LambdaModelVertex(inputs, weatherModel::modelExecution, weatherModel::updateValuesMultipleTypes); IntegerVertex suggestedFactorSuncream = model.getIntegerModelOutputVertex(new VertexLabel("suggestedFactorSuncream")); BooleanVertex isSunny = model.getBooleanModelOutputVertex(new VertexLabel("isSunny")); double inputValue = 20.0; inputToModel.setAndCascade(inputValue); Assert.assertEquals(suggestedFactorSuncream.getValue().scalar(), new Integer(2)); Assert.assertEquals(isSunny.getValue().scalar(), false); }
private void assertCanCalculateMaxLikelihood(Function<BayesianNetwork, Optimizer> optimizerMapper) { DoubleVertex A = new GaussianVertex(20.0, 1.0); DoubleVertex B = new GaussianVertex(20.0, 1.0); A.setValue(20.0); B.setAndCascade(20.0); DoubleVertex Cobserved = new GaussianVertex(A.plus(B), 1.0); Cobserved.observe(44.0); BayesianNetwork bayesNet = new BayesianNetwork(Arrays.asList(A, B, Cobserved)); Optimizer optimizer = optimizerMapper.apply(bayesNet); optimizer.maxLikelihood(); double maxA = A.getValue().scalar(); double maxB = B.getValue().scalar(); assertEquals(44, maxA + maxB, 0.1); }
static TestData generateSingleFeatureData(int numSamples) { DoubleVertex xGenerator = new UniformVertex(new long[]{numSamples, 1}, 0, 10); DoubleVertex mu = xGenerator.multiply(EXPECTED_W1).plus(EXPECTED_B); DoubleVertex yGenerator = new GaussianVertex(mu, 1.0); DoubleTensor xData = xGenerator.sample(); xGenerator.setAndCascade(xData); DoubleTensor yData = yGenerator.sample(); return new TestData(DoubleTensor.scalar(EXPECTED_W1), EXPECTED_B, xData, yData); }
@Test public void canReshape() { DoubleVertex gaussianVertex = new GaussianVertex(0, 1); gaussianVertex.setAndCascade(DoubleTensor.ones(2, 2)); assertArrayEquals(gaussianVertex.getShape(), new long[]{2, 2}); DoubleVertex reshaped = gaussianVertex.reshape(4, 1); assertArrayEquals(reshaped.getShape(), new long[]{4, 1}); }
static TestData generateThreeFeatureDataWithOneUncorrelatedFeature() { DoubleVertex x1Generator = new UniformVertex(new long[]{N, 1}, 0, 10); DoubleVertex x2Generator = new UniformVertex(new long[]{N, 1}, 50, 100); DoubleVertex x3Generator = new UniformVertex(new long[]{N, 1}, 50, 100); DoubleVertex yGenerator = new GaussianVertex( x1Generator.multiply(EXPECTED_W1).plus(x2Generator.multiply(EXPECTED_W2)).plus(EXPECTED_B), 1.0 ); DoubleTensor x1Data = x1Generator.sample(); x1Generator.setAndCascade(x1Data); DoubleTensor x2Data = x1Generator.sample(); x2Generator.setAndCascade(x2Data); DoubleTensor yData = yGenerator.sample(); return new TestData(DoubleTensor.create(EXPECTED_W1, EXPECTED_W2), EXPECTED_B, DoubleTensor.concat(1, x1Data, x2Data, x3Generator.sample()), yData); }
@Test public void canRunAModelInAModel() { weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); ModelVertex model = new LambdaModelVertex(inputs, weatherModel::modelExecution, weatherModel::updateValues); DoubleVertex chanceOfRain = model.getDoubleModelOutputVertex(new VertexLabel("ChanceOfRain")); DoubleVertex humidity = model.getDoubleModelOutputVertex(new VertexLabel("Humidity")); DoubleVertex shouldIBringUmbrella = chanceOfRain.times(humidity); double inputValue = 10.0; inputToModel.setAndCascade(inputValue); Assert.assertEquals(shouldIBringUmbrella.getValue().scalar(), 20.0, 1e-6); }
public void assertCanCalculateMaxAPosteriori(Function<BayesianNetwork, Optimizer> optimizerMapper) { DoubleVertex A = new GaussianVertex(20.0, 1.0); DoubleVertex B = new GaussianVertex(20.0, 1.0); A.setValue(21.5); B.setAndCascade(21.5); DoubleVertex Cobserved = new GaussianVertex(A.plus(B), 1.0); Cobserved.observe(46.0); BayesianNetwork bayesNet = new BayesianNetwork(Arrays.asList(A, B, Cobserved)); Optimizer optimizer = optimizerMapper.apply(bayesNet); optimizer.maxAPosteriori(); double maxA = A.getValue().scalar(); double maxB = B.getValue().scalar(); assertEquals(22, maxA, 0.1); assertEquals(22, maxB, 0.1); }
@Test public void canUseGradientBasedSamplingWithAssertVertex() { DoubleVertex A = new GaussianVertex(20.0, 1.0); DoubleVertex B = new GaussianVertex(20.0, 1.0); A.setValue(21.5); B.setAndCascade(21.5); A.greaterThan(new ConstantDoubleVertex(20)).assertTrue(); B.greaterThan(new ConstantDoubleVertex(20)).assertTrue(); DoubleVertex Cobserved = new GaussianVertex(A.plus(B), 1.0); Cobserved.observe(46.0); KeanuProbabilisticModel bayesNet = new KeanuProbabilisticModel(Arrays.asList(A, B, Cobserved)); PosteriorSamplingAlgorithm samplingAlgorithm = Keanu.Sampling.MCMC.withDefaultConfigFor(bayesNet); assertThat(samplingAlgorithm, instanceOf(NUTS.class)); }
@Test public void canRunAModelInAModel() { weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); // An example of what running a real Python model would look like String command = formatCommandForExecution(inputs, "python ./src/test/resources/model.py {Temperature}"); ModelVertex model = LambdaModelVertex.createFromProcess(inputs, command, weatherModel::updateValues); DoubleVertex chanceOfRain = model.getDoubleModelOutputVertex(new VertexLabel("ChanceOfRain")); DoubleVertex humidity = model.getDoubleModelOutputVertex(new VertexLabel("Humidity")); DoubleVertex shouldIBringUmbrella = chanceOfRain.times(humidity); double inputValue = 10.0; inputToModel.setAndCascade(inputValue); Assert.assertEquals(shouldIBringUmbrella.getValue().scalar(), 20.0, 1e-6); }
@Test public void modelInsideVertexIsRecalculatedOnEachParentSample() { int numSamples = 50; weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); ModelVertex model = new LambdaModelVertex(inputs, weatherModel::modelExecution, weatherModel::updateValues); DoubleVertex chanceOfRain = model.getDoubleModelOutputVertex(new VertexLabel("ChanceOfRain")); DoubleVertex humidity = model.getDoubleModelOutputVertex(new VertexLabel("Humidity")); DoubleVertex shouldIBringUmbrella = chanceOfRain.times(humidity); for (int i = 0; i < numSamples; i++) { double inputValue = inputToModel.sample(random).scalar(); inputToModel.setAndCascade(inputValue); double expectedValue = (inputValue * 0.1) * (inputValue * 2); Assert.assertEquals(expectedValue, shouldIBringUmbrella.getValue().scalar(), 1e-6); } }
@Category(Slow.class) @Test public void modelInsideVertexIsRecalculatedOnEachParentSample() { int numSamples = 50; weatherModel.setInputToModel(inputToModel); Map<VertexLabel, Vertex<? extends Tensor>> inputs = ImmutableMap.of(new VertexLabel("Temperature"), inputToModel); ModelVertex model = LambdaModelVertex.createFromProcess(inputs, COMMAND, weatherModel::updateValues); DoubleVertex chanceOfRain = model.getDoubleModelOutputVertex(new VertexLabel("ChanceOfRain")); DoubleVertex humidity = model.getDoubleModelOutputVertex(new VertexLabel("Humidity")); DoubleVertex shouldIBringUmbrella = chanceOfRain.times(humidity); for (int i = 0; i < numSamples; i++) { double inputValue = inputToModel.sample().scalar(); inputToModel.setAndCascade(inputValue); double expectedValue = (inputValue * 0.1) * (inputValue * 2); Assert.assertEquals(expectedValue, shouldIBringUmbrella.getValue().scalar(), 1e-6); } }