Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make predictions using a tensorflow graph from a keras model

I have a model trained using Keras with Tensorflow as my backend, but now I need to turn my model into a tensorflow graph for a certain application. I attempted to do this and make predictions to insure that it is working correctly, but when comparing to the results gathered from model.predict() I get very different values. For instance:

from keras.models import load_model import tensorflow as tf  model = load_model('model_file.h5')  x_placeholder = tf.placeholder(tf.float32, shape=(None,7214,1)) y = model(x_placeholder)  x = np.ones((1,7214,1))   with tf.Session() as sess:     sess.run(tf.global_variables_initializer())     print("Predictions from:\ntf graph:      "+str(sess.run(y, feed_dict={x_placeholder:x})))     print("keras predict: "+str(model.predict(x))) 

returns:

Predictions from: tf graph:      [[-0.1015993   0.07432419  0.0592984 ]] keras predict: [[ 0.39339241  0.57949686 -3.67846966]] 

The values from keras predict are correct, but the tf graph results are not.

If it helps to know the final intended application, I am creating a jacobian matrix with the tf.gradients() function, but currently it does not return the correct results when comparing to theano's jacobian function, which gives the correct jacobian. Here is my tensorflow jacobian code:

x = tf.placeholder(tf.float32, shape=(None,7214,1)) y = tf.reshape(model(x)[0],[-1]) y_list = tf.unstack(y)  jacobian_list = [tf.gradients(y_, x)[0] for y_ in y_list] jacobian = tf.stack(jacobian_list) 

EDIT: Model code

import numpy as np  from keras.models import Sequential from keras.layers import Dense, InputLayer, Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D from keras.optimizers import Adam from keras.callbacks import EarlyStopping, ReduceLROnPlateau  # activation function used following every layer except for the output layers activation = 'relu'  # model weight initializer initializer = 'he_normal'  # shape of input data that is fed into the input layer input_shape = (None,7214,1)  # number of filters used in the convolutional layers num_filters = [4,16]  # length of the filters in the convolutional layers filter_length = 8  # length of the maxpooling window  pool_length = 4  # number of nodes in each of the hidden fully connected layers num_hidden_nodes = [256,128]  # number of samples fed into model at once during training batch_size = 64  # maximum number of interations for model training max_epochs = 30  # initial learning rate for optimization algorithm lr = 0.0007  # exponential decay rate for the 1st moment estimates for optimization algorithm beta_1 = 0.9  # exponential decay rate for the 2nd moment estimates for optimization algorithm beta_2 = 0.999  # a small constant for numerical stability for optimization algorithm optimizer_epsilon = 1e-08  model = Sequential([      InputLayer(batch_input_shape=input_shape),      Conv1D(kernel_initializer=initializer, activation=activation, padding="same", filters=num_filters[0], kernel_size=filter_length),      Conv1D(kernel_initializer=initializer, activation=activation, padding="same", filters=num_filters[1], kernel_size=filter_length),      MaxPooling1D(pool_size=pool_length),      Flatten(),      Dense(units=num_hidden_nodes[0], kernel_initializer=initializer, activation=activation),      Dense(units=num_hidden_nodes[1], kernel_initializer=initializer, activation=activation),      Dense(units=3, activation="linear", input_dim=num_hidden_nodes[1]), ])   # compile model loss_function = mean squared error early_stopping_min_delta = 0.0001 early_stopping_patience = 4 reduce_lr_factor = 0.5 reuce_lr_epsilon = 0.0009 reduce_lr_patience = 2 reduce_lr_min = 0.00008  optimizer = Adam(lr=lr, beta_1=beta_1, beta_2=beta_2, epsilon=optimizer_epsilon, decay=0.0)  early_stopping = EarlyStopping(monitor='val_loss',     min_delta=early_stopping_min_delta,                                     patience=early_stopping_patience, verbose=2, mode='min')  reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.5, epsilon=reuce_lr_epsilon,                                patience=reduce_lr_patience,     min_lr=reduce_lr_min, mode='min', verbose=2)  model.compile(optimizer=optimizer, loss=loss_function)  model.fit(train_x, train_y, validation_data=(cv_x, cv_y),       epochs=max_epochs, batch_size=batch_size, verbose=2,       callbacks=[reduce_lr,early_stopping])  model.save('model_file.h5') 
like image 731
Starnetter Avatar asked May 31 '17 02:05

Starnetter


People also ask

How do you predict using TensorFlow model?

Just pull on node y and you'll have what you want. This applies to just about any model you create - you'll have computed the prediction probabilities as one of the last steps before computing the loss.

How do you connect model input data with predictions for machine learning?

To give inputs to a machine learning model, you have to create a NumPy array, where you have to input the values of the features you used to train your machine learning model. Then we can use that array in the model. predict() method, and at the end, it will give the predicted value as an output based on the inputs.


1 Answers

@frankyjuang linked me to here

https://github.com/amir-abdi/keras_to_tensorflow

and combining this with code from

https://github.com/metaflow-ai/blog/blob/master/tf-freeze/load.py

and

https://github.com/tensorflow/tensorflow/issues/675

I have found a solution to both predicting using a tf graph and creating the jacobian function:

import tensorflow as tf import numpy as np  # Create function to convert saved keras model to tensorflow graph def convert_to_pb(weight_file,input_fld='',output_fld=''):      import os     import os.path as osp     from tensorflow.python.framework import graph_util     from tensorflow.python.framework import graph_io     from keras.models import load_model     from keras import backend as K       # weight_file is a .h5 keras model file     output_node_names_of_input_network = ["pred0"]      output_node_names_of_final_network = 'output_node'      # change filename to a .pb tensorflow file     output_graph_name = weight_file[:-2]+'pb'     weight_file_path = osp.join(input_fld, weight_file)      net_model = load_model(weight_file_path)      num_output = len(output_node_names_of_input_network)     pred = [None]*num_output     pred_node_names = [None]*num_output      for i in range(num_output):         pred_node_names[i] = output_node_names_of_final_network+str(i)         pred[i] = tf.identity(net_model.output[i], name=pred_node_names[i])      sess = K.get_session()      constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), pred_node_names)     graph_io.write_graph(constant_graph, output_fld, output_graph_name, as_text=False)     print('saved the constant graph (ready for inference) at: ', osp.join(output_fld, output_graph_name))      return output_fld+output_graph_name 

Call:

tf_model_path = convert_to_pb('model_file.h5','/model_dir/','/model_dir/') 

Create function to load the tf model as a graph:

def load_graph(frozen_graph_filename):     # We load the protobuf file from the disk and parse it to retrieve the      # unserialized graph_def     with tf.gfile.GFile(frozen_graph_filename, "rb") as f:         graph_def = tf.GraphDef()         graph_def.ParseFromString(f.read())      # Then, we can use again a convenient built-in function to import a graph_def into the      # current default Graph     with tf.Graph().as_default() as graph:         tf.import_graph_def(             graph_def,              input_map=None,              return_elements=None,              name="prefix",              op_dict=None,              producer_op_list=None         )      input_name = graph.get_operations()[0].name+':0'     output_name = graph.get_operations()[-1].name+':0'      return graph, input_name, output_name 

Create a function to make model predictions using the tf graph

def predict(model_path, input_data):     # load tf graph     tf_model,tf_input,tf_output = load_graph(model_path)      # Create tensors for model input and output     x = tf_model.get_tensor_by_name(tf_input)     y = tf_model.get_tensor_by_name(tf_output)       # Number of model outputs     num_outputs = y.shape.as_list()[0]     predictions = np.zeros((input_data.shape[0],num_outputs))     for i in range(input_data.shape[0]):                 with tf.Session(graph=tf_model) as sess:             y_out = sess.run(y, feed_dict={x: input_data[i:i+1]})             predictions[i] = y_out      return predictions 

Make predictions:

tf_predictions = predict(tf_model_path,test_data) 

Jacobian function:

def compute_jacobian(model_path,input_data):      tf_model,tf_input,tf_output = load_graph(model_path)          x = tf_model.get_tensor_by_name(tf_input)     y = tf_model.get_tensor_by_name(tf_output)     y_list = tf.unstack(y)     num_outputs = y.shape.as_list()[0]     jacobian = np.zeros((num_outputs,input_data.shape[0],input_data.shape[1]))     for i in range(input_data.shape[0]):         with tf.Session(graph=tf_model) as sess:             y_out = sess.run([tf.gradients(y_, x)[0] for y_ in y_list], feed_dict={x: input_data[i:i+1]})             jac_temp = np.asarray(y_out)         jacobian[:,i:i+1,:]=jac_temp[:,:,:,0]     return jacobian 

Compute Jacobian Matrix:

jacobians = compute_jacobian(tf_model_path,test_data) 
like image 109
Starnetter Avatar answered Sep 20 '22 02:09

Starnetter