public static DoubleVertex logProbOutput(DoublePlaceholderVertex x, DoublePlaceholderVertex xMin, DoublePlaceholderVertex xMax, DoublePlaceholderVertex c) { final DoubleVertex range = xMax.minus(xMin); final DoubleVertex conditionalFirstHalf = x.toGreaterThanMask(xMin); final DoubleVertex conditionalSecondHalf = x.toLessThanMask(c); final DoubleVertex conditionalAnd = conditionalFirstHalf.times(conditionalSecondHalf); final DoubleVertex conditionalResult = range.reverseDiv(1.).times(2.).times(x.minus(xMin)).div(c.minus(xMin)); final DoubleVertex elseIfConditionalFirstHalf = x.toGreaterThanMask(c); final DoubleVertex elseIfConditionalSecondHalf = x.toLessThanOrEqualToMask(xMax); final DoubleVertex elseIfConditionalAnd = elseIfConditionalFirstHalf.times(elseIfConditionalSecondHalf); final DoubleVertex elseIfConditionalResult = range.reverseDiv(1.).times(2.).times(xMax.minus(x)).div(xMax.minus(c)); return (conditionalResult.times(conditionalAnd).plus(elseIfConditionalResult.times(elseIfConditionalAnd))).log(); }
@Test(expected = IllegalArgumentException.class) public void doesThrowOnLogProbDiffOnNonProbabilistic() { DoubleVertex A = ConstantVertex.of(5.0); DoubleVertex B = A.times(4); LogProbGradientCalculator calculator = new LogProbGradientCalculator(ImmutableList.of(B), ImmutableList.of(A)); calculator.getJointLogProbGradientWrtLatents(); }
public LinearRegressionGraph(long[] featureShape, Function<DoubleVertex, OutputVertices<OUTPUT>> outputTransform, DoubleVertex interceptVertex, DoubleVertex weightsVertex) { long featureCount = featureShape[1]; Preconditions.checkArgument(TensorShape.isLengthOne(interceptVertex.getShape())); TensorShapeValidation.checkShapesMatch(weightsVertex.getShape(), new long[]{featureCount, 1}); this.weightsVertex = weightsVertex; this.interceptVertex = interceptVertex; xVertex = new ConstantDoubleVertex(DoubleTensor.zeros(featureShape)); OutputVertices<OUTPUT> outputVertices = outputTransform.apply( TensorShape.isLengthOne(weightsVertex.getShape()) ? weightsVertex.times(xVertex).plus(interceptVertex) : xVertex.matrixMultiply(weightsVertex).plus(interceptVertex) ); yVertex = outputVertices.outputVertex; yObservationVertex = outputVertices.observedVertex; bayesianNetwork = new BayesianNetwork(yVertex.getConnectedGraph()); }
public static void main(String[] args) { //%%SNIPPET_START%% Overview DoubleVertex x = new UniformVertex(1, 2); DoubleVertex y = x.times(2); DoubleVertex observedY = new UniformVertex(new long[]{1, 2}, y, y.plus(0.5)); observedY.observe(new double[]{4.0, 4.49}); //%%SNIPPET_END%% Overview } }
public static DoubleVertex logProbOutput(DoublePlaceholderVertex x, IntegerPlaceHolderVertex k) { final DoubleVertex halfK = k.toDouble().div(2.); final DoubleVertex numerator = halfK.minus(1.).times(x.log()).minus(x.div(2.)); final DoubleVertex denominator = halfK.times(LOG_TWO).plus(halfK.logGamma()); return numerator.minus(denominator); }
@Test public void canDoSumAutoDiffWhenWrtIsScalar() { UniformVertex a = new UniformVertex(0, 10); a.setValue(2); DoubleVertex d = a.sum(); DoubleVertex e = new UniformVertex(0, 10); e.setValue(new double[]{1, 2, 3}); MultiplicationVertex f = d.times(e); DoubleTensor dfdaForward = Differentiator.forwardModeAutoDiff(a, f).of(f); PartialsOf dfdx = Differentiator.reverseModeAutoDiff(f, a); DoubleTensor dfdaReverse = dfdx.withRespectTo(a); DoubleTensor expectedDfda = DoubleTensor.create(1, 2, 3); assertThat(dfdaForward, equalTo(expectedDfda)); assertThat(dfdaReverse, equalTo(expectedDfda)); }
public static DoubleVertex logProbGraph(DoublePlaceholderVertex x, DoublePlaceholderVertex mu, DoublePlaceholderVertex covariance) { final long dimensions = numberOfDimensions(mu.getShape()); final double kLog2Pi = dimensions * LOG_2_PI; final DoubleVertex logCovDet = covariance.matrixDeterminant().log(); DoubleVertex xMinusMu = x.minus(mu); DoubleVertex xMinusMuT = xMinusMu.permute(1, 0); DoubleVertex covInv = covariance.matrixInverse(); DoubleVertex scalar = isUnivariate(dimensions) ? covInv.times(xMinusMu).times(xMinusMuT).slice(0, 0): xMinusMuT.matrixMultiply(covInv.matrixMultiply(xMinusMu)).slice(0, 0); return scalar.plus(kLog2Pi).plus(logCovDet).times(-0.5).slice(0, 0); }
@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 static DoubleVertex logProbOutput(DoublePlaceholderVertex t, IntegerPlaceHolderVertex v) { DoubleVertex vAsDouble = v.toDouble(); DoubleVertex halfVPlusOne = vAsDouble.plus(1.).div(2.); DoubleVertex logGammaHalfVPlusOne = halfVPlusOne.logGamma(); DoubleVertex logGammaHalfV = vAsDouble.div(2.).logGamma(); DoubleVertex halfLogV = vAsDouble.log().div(2.); return logGammaHalfVPlusOne .minus(halfLogV) .minus(HALF_LOG_PI) .minus(logGammaHalfV) .minus( halfVPlusOne.times( t.pow(2.).div(vAsDouble).plus(1.).log() ) ); }
@Test public void canReverseAutoDiffOfMultiplicationAndLogWithSingleOutputWithRespectToMany() { DoubleVertex A = new GaussianVertex(0, 1); A.setValue(3.0); DoubleVertex B = new GaussianVertex(0, 1); B.setValue(5.0); DoubleVertex C = A.times(B); DoubleVertex E = C.times(2); DoubleVertex Y = E.log(); PartialsOf dY = Differentiator.reverseModeAutoDiff(Y, ImmutableSet.of(A, B)); DoubleTensor dYdA = dY.withRespectTo(A); DoubleTensor dYdB = dY.withRespectTo(B); assertEquals(A.getValue().reciprocal().scalar(), dYdA.scalar(), 1e-5); assertEquals(B.getValue().reciprocal().scalar(), dYdB.scalar(), 1e-5); }
@Test public void diffWrtScalarOverMultipleMultiplies() { DoubleVertex A = new UniformVertex(0, 1); A.setValue(2); DoubleVertex prod = A.times(ConstantVertex.of(new double[]{1, 2, 3, 4})); DoubleVertex sum = prod.plus(ConstantVertex.of(new double[]{2, 4, 6, 8})); DoubleVertex prod2 = sum.times(ConstantVertex.of(new double[]{2, 4, 6, 8})); MultiplicationVertex output = prod2.plus(5).times(2); DoubleTensor wrtA = Differentiator.reverseModeAutoDiff(output, A).withRespectTo(A); DoubleTensor expectedWrt = DoubleTensor.create(4, 16, 36, 64); assertArrayEquals(expectedWrt.asFlatDoubleArray(), wrtA.asFlatDoubleArray(), 0.0); assertArrayEquals(expectedWrt.getShape(), wrtA.getShape()); }
@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 canReverseAutoDiffOfMultiplicationWithSingleOutputWithRespectToMany() { DoubleVertex A = new GaussianVertex(0, 1); DoubleVertex B = new GaussianVertex(0, 1); DoubleVertex C = A.times(B); PartialsOf dC = Differentiator.reverseModeAutoDiff(C, ImmutableSet.of(A, B)); DoubleTensor dCdA = dC.withRespectTo(A); DoubleTensor dCdB = dC.withRespectTo(B); assertEquals(A.getValue().scalar(), dCdB.scalar(), 1e-5); assertEquals(B.getValue().scalar(), dCdA.scalar(), 1e-5); }
private BayesianNetwork createComplexNet() { DoubleVertex A = new GaussianVertex(new long[]{2, 2}, 0, 1).setLabel(INPUT_NAME); A.setValue(DoubleTensor.create(3.0, new long[]{2, 2})); DoubleVertex B = new GaussianVertex(new long[]{2, 2}, 0, 1); B.setValue(DoubleTensor.create(5.0, new long[]{2, 2})); DoubleVertex D = A.times(B); DoubleVertex C = A.sin(); DoubleVertex E = C.times(D); DoubleVertex G = E.log(); DoubleVertex F = D.plus(B); BooleanVertex predicate = ConstantVertex.of(BooleanTensor.create(new boolean[]{true, false, true, false}, new long[]{2, 2})); DoubleVertex H = If.isTrue(predicate).then(G).orElse(F).setLabel(OUTPUT_NAME); return new BayesianNetwork(H.getConnectedGraph()); }
@Test public void valuesAreBeingWrittenOut() throws IOException { DoubleVertex unobservedGaussianVertex = new GaussianVertex(0, 1); DoubleVertex observedGammaVertex = new GammaVertex(2, 3); observedGammaVertex.observe(2.5); DoubleVertex gammaMultipliedVertex = observedGammaVertex.times(new ConstantDoubleVertex(4)); Vertex resultVertex = gammaMultipliedVertex.plus(unobservedGaussianVertex); gammaMultipliedVertex.setLabel("Gamma Multiplied"); DotSaver dotSaver = new DotSaver(new BayesianNetwork(resultVertex.getConnectedGraph())); dotSaver.save(outputWriter, true); String expectedOutputWithValues = readFileToString(OUTPUT_WITH_VALUES_FILENAME); checkDotFilesMatch(outputWriter.toString(), expectedOutputWithValues); }
private static void tensorFinal() { //%%SNIPPET_START%% TensorFinal DoubleVertex muA = ConstantVertex.of(new double[]{0.5, 1.5}); DoubleVertex A = new GaussianVertex(new long[]{1, 2}, muA, 1); DoubleVertex B = ConstantVertex.of(new double[]{3, 4}); DoubleVertex C = A.times(B); DoubleVertex CObservation = new GaussianVertex(C, 1); CObservation.observe(new double[]{6, 12}); //Use algorithm to find MAP or posterior samples for A and/or B Optimizer optimizer = KeanuOptimizer.of(new BayesianNetwork(A.getConnectedGraph())); optimizer.maxAPosteriori(); //Retrieve the most likely estimate using MAP estimation DoubleTensor mostLikelyEstimate = A.getValue(); //approximately [2, 3] //%%SNIPPET_END%% TensorFinal }
@Test public void diffWrtVectorOverMultipleMultiplies() { DoubleVertex A = new UniformVertex(new long[]{1, 4}, 0, 1); A.setValue(new double[]{-1, 3, 5, -2}); DoubleVertex prod = A.times(ConstantVertex.of(new double[]{1, 2, 3, 4})); DoubleVertex sum = prod.plus(ConstantVertex.of(new double[]{2, 4, 6, 8})); DoubleVertex prod2 = sum.times(ConstantVertex.of(new double[]{2, 4, 6, 8})); MultiplicationVertex output = prod2.plus(5).times(2); DoubleTensor wrtA = Differentiator.reverseModeAutoDiff(output, A).withRespectTo(A); DoubleTensor expectedWrt = DoubleTensor.create(new double[]{4, 16, 36, 64}) .diag() .reshape(TensorShape.concat(A.getShape(), A.getShape())); assertArrayEquals(expectedWrt.asFlatDoubleArray(), wrtA.asFlatDoubleArray(), 0.0); assertArrayEquals(expectedWrt.getShape(), wrtA.getShape()); }
@Test public void canRunEvalOnTheOutputsToRecalculateTheModel() { 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); inputToModel.setValue(10.0); shouldIBringUmbrella.eval(); Assert.assertEquals(20.0, shouldIBringUmbrella.getValue().scalar(), 1e-6); inputToModel.setValue(20.0); shouldIBringUmbrella.eval(); Assert.assertEquals(80.0, shouldIBringUmbrella.getValue().scalar(), 1e-6); }
@Test public void canRunEvalOnTheOutputsToRecalculateTheModel() { 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); inputToModel.setValue(10.0); shouldIBringUmbrella.eval(); Assert.assertEquals(20.0, shouldIBringUmbrella.getValue().scalar(), 1e-6); inputToModel.setValue(20.0); shouldIBringUmbrella.eval(); Assert.assertEquals(80.0, shouldIBringUmbrella.getValue().scalar(), 1e-6); }
@Ignore public void doesSimpleTensorInferenceExample() { //%%SNIPPET_START%% TensorExample DoubleVertex muA = ConstantVertex.of(new double[]{0.5, 1.5}); DoubleVertex A = new GaussianVertex(new long[]{1, 2}, muA, 1); DoubleVertex B = ConstantVertex.of(new double[]{3, 4}); DoubleVertex C = A.times(B); DoubleVertex CObservation = new GaussianVertex(C, 1); CObservation.observe(new double[]{6, 12}); //Use algorithm to find MAP or posterior samples for A and/or B Optimizer optimizer = KeanuOptimizer.of(new BayesianNetwork(A.getConnectedGraph())); optimizer.maxLikelihood(); //%%SNIPPET_END%% TensorExample assertArrayEquals(new double[]{2.0, 3.0}, A.getValue().asFlatDoubleArray(), 1e-2); }