Reusing models#
In the past a colleague defined a graph that connected some data x with data y
[2]:
import numpy as np
import halerium.core as hal
ga = hal.Graph("ga")
with ga:
with inputs:
hal.Entity("e1")
with e1:
hal.Variable("x", shape=(10,), mean=0, variance=1)
with outputs:
hal.Entity("e2")
with e2:
hal.Variable("y", shape=(7,))
hal.regression.connect_via_regression("reg", inputs=inputs.e1.x, outputs=outputs.e2.y)
outputs.e2.y.variance = hal.exp(hal.StaticVariable("lnv", mean=-3, variance=1.))
# use this in the online platform to show the graph
#hal.show(ga)
The colleague had training data for x and y available and trained the graph accordingly
[3]:
# generating artificial data
np.random.seed(42)
real_xy_slope = np.random.randn(7,10)
real_xy_intercept = np.random.randn(7)
data_x = np.random.randn(74,10)
data_y = np.einsum("ij, nj -> ni", real_xy_slope, data_x) + real_xy_intercept
# normally these would of course be loaded from somewhere
posterior_model_a = hal.get_posterior_model(ga, data={ga.inputs.e1.x: data_x, ga.outputs.e2.y: data_y})
the trained model was converted back to a graph and saved as a JSON file
[4]:
posterior_graph_a = posterior_model_a.get_posterior_graph()
posterior_graph_a.dump_file("posterior_graph.json")
This was done in the past. Now lets clear the session and start over.
[5]:
%reset -f
Starting from there#
[6]:
import halerium.core as hal
import numpy as np
Our graph connects y and z.
[7]:
gb = hal.Graph("gb")
with gb:
with inputs:
hal.Entity("e2")
with e2:
hal.Variable("y", shape=(7,), mean=0, variance=1)
with outputs:
hal.Entity("e3")
with e3:
hal.Variable("z", shape=(5,))
hal.regression.connect_via_regression("reg", inputs=inputs.e2.y, outputs=outputs.e3.z)
outputs.e3.z.variance = hal.exp(hal.StaticVariable("lnv", mean=-3, variance=1.))
We have training data for y and z available, but not for x. We train our graph…
[8]:
# generating artificial data
np.random.seed(137)
real_yz_slope = np.random.randn(5,7)
real_yz_intercept = np.random.randn(5)
data_y = np.random.randn(63,7)
data_z = np.einsum("ij, nj -> ni", real_yz_slope, data_y) + real_yz_intercept
# normally these would of course be loaded from somewhere
posterior_model_b = hal.get_posterior_model(gb, data={gb.inputs.e2.y: data_y, gb.outputs.e3.z: data_z})
We can again extract the posterior graph
[9]:
posterior_graph_b = posterior_model_b.get_posterior_graph()
And load the work of our colleague from the hard drive
[10]:
posterior_graph_a = hal.Graph.from_specification(file="posterior_graph.json")
Now we can plug those two together in a big graph
[11]:
big_graph = hal.Graph("big_graph")
with big_graph:
posterior_graph_a.copy("ga")
posterior_graph_b.copy("gb")
hal.link(ga.outputs.e2, gb.inputs.e2)
With this graph we can now predict from x to z
[12]:
# test data
test_data_x = np.random.randn(100,10)
model_predict = hal.get_generative_model(big_graph, data={big_graph.ga.inputs.e1.x: test_data_x})
predicted_y, predicted_z = model_predict.get_means([big_graph.ga.outputs.e2.y, big_graph.gb.outputs.e3.z])