Fitting with a neural network

This notebook is available at arjunsavel/cortecs

Fitting with a neural network#

In the Quickstart tutorial, we worked through how to use the PCA-based approach implemented in cortecs. Now, let’s walk through how to use the neural network-based approach.

Setting up the objects#

[1]:
import numpy as np

import cortecs
from cortecs.opac.opac import *
from cortecs.fit.fit import *
from cortecs.eval.eval import *

We’ll be using the same Opac object as in the Quickstart.

[2]:
T_filename = "temperatures.npy"
P_filename = "pressures.npy"
wl_filename = "wavelengths.npy"

cross_sec_filename = "absorb_coeffs_C2H4.npy"

load_kwargs = {
    "T_filename": T_filename,
    "P_filename": P_filename,
    "wl_filename": wl_filename,
}
opac_obj = Opac(cross_sec_filename, loader="platon", load_kwargs=load_kwargs)

This time, we specify that we’d like to fit the object with the neural_net method.

[3]:
fitter = Fitter(opac_obj, method="neural_net")
fitter
[3]:
<cortecs.fit.fit.Fitter at 0x29217e950>

We won’t actually fit the entire opacity, though—that would take about 15 hours on a laptop. Instead, let’s just fit a single one using a lower-level API.

[4]:
res = cortecs.fit.fit_neural_net.fit_neural_net(
    fitter.opac.cross_section[:, :, -2],
    fitter.opac.T,
    fitter.opac.P,
    None,
    n_layers=3,
    n_neurons=8,
    activation="sigmoid",
    learn_rate=0.04,
    loss="mean_squared_error",
    epochs=4000,
    verbose=0,
    sequential_model=None,
    plot=True,
)
../../_images/pages_fitting_nn_9_0.png

This code shouldn’t take more than 15 seconds or so to run.

The above plot tells us how the model performs as it iterates on its weights.

[5]:
history, neural_network = res
[6]:
P_unraveled = unravel_data(fitter.opac.P, fitter.opac.T, None, tileboth=True)
T_unraveled = unravel_data(fitter.opac.T, fitter.opac.P, None, tileboth=False)
input_array = np.column_stack([T_unraveled, P_unraveled])

npres = len(fitter.opac.P)
ntemp = len(fitter.opac.T)

predictions = neural_network.predict(input_array)
plt.imshow(
    100
    * (predictions.reshape(ntemp, npres) - fitter.opac.cross_section[:, :, -1])
    / predictions.reshape(ntemp, npres)
)
plt.colorbar()
13/13 [==============================] - 0s 571us/step
[6]:
<matplotlib.colorbar.Colorbar at 0x29e981660>
../../_images/pages_fitting_nn_12_2.png

Awesome! Looks like we have accuracy at better than ~5%. We can tune the architecture of the neural network to achieve greater accuracy, but keep in mind that a larger network means more memory — that is, less efficient compression.

We can save the weights for this individual neural network with the built-in API.

[7]:
save_neural_net(neural_network, "test_nn.pkl")

Great! We’ve saved our network to the disk. Let’s make sure that evaluating this on the fly (without the neural network API — just the weights and the biases) works out.

First, we load in the weights and the biases.

[8]:
with open("test_nn.pkl", "rb") as f:
    all_weights, all_biases = pickle.load(f)

Next, we call the eval_neural_net method to evaluate the neural net with those weights and biases.

[9]:
n_layers = len(all_weights)
eval_neural_net(100, 1e-4, n_layers, all_weights, all_biases)
[9]:
Array([-49.47523], dtype=float32)

Great! And let’s check that this matches the prediction we made earlier with the same neural net.

[10]:
predictions[0]
[10]:
array([-49.475227], dtype=float32)

Finally, let’s do a speed test.

[11]:
%%timeit
eval_neural_net(2000, 1e-4, n_layers, all_weights, all_biases)
214 µs ± 1.96 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

Again, this is slower than simply accessing the array. This is a trade-off you’ll have to make depending on your architecture (CPU vs. GPU), desired accuracy, and desired memory performance.

This tutorial has walked through how to use the neural network-based approach to fitting opacity data. We did so using a single neural network architecture — i.e., we only used n_layers=3, n_neurons=8, etc. These model “hyperparameters” in principle have an optimal value for a given dataset, given constraints on model size. We will explore this idea further in the Optimizing Fits tutorial.