I have created a neural net model for a process that achieves over 80% R2 on a test group predicting performance of a final test from upstream data. The boss was impressed, but asked if a Bokeh interactive slider plot could be created that showed visually the effects of each input on the output. I started with the famous sine wave “slider.py” example and modified the code to try to create this. The code below creates the initial graph okay, but does not update when the sliders are moved. Just for fun, I created a simple arithmetic model using the same slider outputs, and that works (see commented out alternate code in code below). So, what am I missing? I have attached the .h5 model above. Thanks in advance.
-- coding: utf-8 --
“”"
Created on Fri Apr 20 13:15:46 2018
@author: steve.olsen
“”"
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import row, widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import figure
from keras.models import load_model
from sklearn.preprocessing import StandardScaler
scale = StandardScaler()
#Get neural net model
my_model = load_model(‘C:\Temp\nets\18bfs_iter_b.h5’)
#Set beginning levels of input factors
a=1.55
b=34
c=0.255
d=73.6
e=0.2
f=0.185
g=23.5
h=40
i=2.19
Set up data
x = np.array([0.9999, 1, 1.0001])
y_1 = np.array([a, b, c, d, e, f, g, h, i])
y_2 = np.transpose(y_1.reshape(-1, 1))
norm_y = scale.fit_transform(y_2)
pred_y = x*my_model.predict(norm_y)
y = np.transpose(pred_y).reshape(3,)
source = ColumnDataSource(data=dict(x=x, y=y))
#below is alternate simple code
‘’'x = np.array([0.9999, 1, 1.0001])
y = x*(d+h+i-a-b-c-e-f-g)
source = ColumnDataSource(data=dict(x=x, y=y))’’’
Set up plot
plot = figure(plot_height=400, plot_width=400, title=“my sine wave”,
tools=“crosshair,pan,reset,save,wheel_zoom”,
x_range=[0.999, 1.001], y_range=[40, 80])
plot.line(‘x’, ‘y’, source=source, line_width=3, line_alpha=0.6)
Set up widgets
text = TextInput(title=“title”, value=‘BERT value’)
#initialize AlO2 slider
slider_a = Slider(title=“AlO2 assy”, value=1.55, start=1.35, end=1.75, step=.01)
#initialize Cu slider
slider_b = Slider(title=“Cu”, value=34, start=33, end=35, step=.01)
#initialize FrbltyLoss slider
slider_c = Slider(title=“FrbltyLoss”, value=0.255, start=0.01, end=0.5, step=.001)
#initialize Insoluble slider
slider_d = Slider(title=“Insoluble”, value=73.6, start=72, end=75.2, step=.01)
#initialize MOIST slider
slider_e = Slider(title=“MOIST”, value=0.2, start=0.1, end=0.3, step=.001)
#initialize MOIST_PWD slider
slider_f = Slider(title=“MOIST_PWD”, value=0.185, start=0.01, end=0.36, step=.001)
#initialize REL_HUMD slider
slider_g = Slider(title=“REL_HUMD”, value=23.5, start=7, end=40, step=.01)
#initialize TAB_Cr slider
slider_h = Slider(title=“TAB_Cr”, value=40, start=32, end=48, step=.01)
#initialize TAB_DEN slider
slider_i = Slider(title=“TAB_DEN”, value=2.19, start=2.14, end=2.25, step=.001)
Set up callbacks
def update_title(attrname, old, new):
plot.title.text = text.value
text.on_change(‘value’, update_title)
def update_data(attrname, old, new):
Get the current slider values
a = slider_a.value
b = slider_b.value
c = slider_c.value
d = slider_d.value
e = slider_e.value
f = slider_f.value
g = slider_g.value
h = slider_h.value
i = slider_i.value
Generate the new curve
x = np.array([0.9999, 1, 1.0001])
y_1 = np.array([a, b, c, d, e, f, g, h, i])
y_2 = np.transpose(y_1.reshape(-1, 1))
norm_y = scale.fit_transform(y_2)
pred_y = x*my_model.predict(norm_y)
y = np.transpose(pred_y).reshape(3,)
source.data = dict(x=x, y=y)
#below is alternate simple code
‘’’ x = np.array([0.9999, 1, 1.0001])
y = x*(d+h+i-a-b-c-e-f-g)
source.data = dict(x=x, y=y)’’’
for w in [slider_a, slider_b, slider_c, slider_d, slider_e, slider_f, slider_g, slider_h, slider_i]:
w.on_change(‘value’, update_data)
Set up layouts and add to document
inputs = widgetbox(text, slider_a, slider_b, slider_c, slider_d, slider_e, slider_f, slider_g, slider_h, slider_i)
curdoc().add_root(row(inputs, plot, width=800))
curdoc().title = “BERT”
18bfs_iter_b.h5 (286 KB)