This article is a part of a series of articles that show you how to save a Keras model and use it for predictions in a Visual Studio C program.
This article will guide you in creating a simple Keras model and then exporting it a Keras graph. It is part of a tutorial on Using a Keras Model For inference in C.
Lets start by creating a simple model in Keras that predicts if a series of numbers is increasing or decreasing. For example, the series 1,2,3,4,5 is increasing, while the series 5,4,3,2,1 is decreasing.
Dataset
We’ll use slope-lownoise.txt. Each row in this text file is a series of numbers. The first number in each row is the class (0: decreasing or 1: increasing). The other 21 numbers are the numbers in the series. Download here.
Preamble
Lets import the things we need, load the data into our python program program, and normalize it.
| # imports | |
| import pandas as pd | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| # Load the data | |
| df = pd.read_csv("slope-lownoise.txt", sep='\t', header=None) | |
| labels = np.asarray(df[0]).reshape((len(df[0]),-1)) | |
| data = np.asarray(df.iloc[:,1:]) | |
| # Check data | |
| print(labels.shape) | |
| print(data.shape) | |
| # Normalize segments | |
| normdata = np.empty_like(data).astype('float64') | |
| for row in range(len(data)): | |
| normdata[row] = (data[row] - min(data[row])) / (max(data[row]) - min(data[row])) |
Here’s an example of the second sample after normalization that was visualized using the command plt.plot(normdata[1]). label[1] = 1 (since it it a rising series).

Create the network
Lets create a simple sequential model in Keras train it on the dataset. I like importing modules when I need them rather than at the start of code. This helps me remember and understand what I need and why I need it.
| import keras | |
| from keras.models import Sequential | |
| from keras.layers import Dense, Dropout, Flatten, Reshape | |
| from keras.layers import Conv1D, MaxPooling1D | |
| from keras.utils import np_utils | |
| TIME_PERIODS = 21 # Number of steps in a time series sample | |
| model = Sequential() | |
| model.add(Dense(100, activation='relu', input_shape=(21,))) | |
| model.add(Dense(1, activation='sigmoid')) | |
| print(model.summary()) | |
| model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) | |
| BATCH_SIZE = 100 | |
| EPOCHS = 5 | |
| history = model.fit(normdata, | |
| labels, | |
| batch_size=BATCH_SIZE, | |
| epochs=EPOCHS, | |
| validation_split=0.8, | |
| verbose=1) |
Freeze the model to a TF graph
We’re almost at the home stretch. We’re going to take this model (with it’s weights) and freeze them to a TF graph in a .pb file. For this, we’re going to get the TF session from the Keras backend, use a function to convert this to a frozen TF graph, then save this TF graph to a file.
| # Define a function that takes a tensorflow session as input and freezes its model. | |
| # Function from https://www.dlology.com/blog/how-to-convert-trained-keras-model-to-tensorflow-and-make-prediction/ | |
| def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True): | |
| """ | |
| Freezes the state of a session into a pruned computation graph. | |
| Creates a new computation graph where variable nodes are replaced by | |
| constants taking their current value in the session. The new graph will be | |
| pruned so subgraphs that are not necessary to compute the requested | |
| outputs are removed. | |
| @param session The TensorFlow session to be frozen. | |
| @param keep_var_names A list of variable names that should not be frozen, | |
| or None to freeze all the variables in the graph. | |
| @param output_names Names of the relevant graph outputs. | |
| @param clear_devices Remove the device directives from the graph for better portability. | |
| @return The frozen graph definition. | |
| """ | |
| graph = session.graph | |
| with graph.as_default(): | |
| freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or [])) | |
| output_names = output_names or [] | |
| output_names += [v.op.name for v in tf.global_variables()] | |
| input_graph_def = graph.as_graph_def() | |
| if clear_devices: | |
| for node in input_graph_def.node: | |
| node.device = "" | |
| frozen_graph = tf.graph_util.convert_variables_to_constants( | |
| session, input_graph_def, output_names, freeze_var_names) | |
| return frozen_graph |
Now save the graph to a file
| from keras import backend as K | |
| import tensorflow as tf | |
| frozen_graph = freeze_session(K.get_session(), | |
| output_names=[out.op.name for out in model.outputs]) | |
| tf.train.write_graph(frozen_graph, "slopemodel", "slopemodel.pb", as_text=False) |
And that’s it! We’re now ready to use this frozen graph and run inference (predictions) using Tensorflow. We’ll first test it in python, and then test it using libTensorflow in C.