2017-05-31 32 views
14

Mam model przeszkolony za pomocą Keras z Tensorflow jako moim zapleczem, ale teraz muszę przekształcić mój model w wykres tensorflow dla pewnej aplikacji. Próbowałem to zrobić i przewidzieć, aby upewnić się, że działa poprawnie, ale w porównaniu do wyników uzyskanych z metody model.predict() otrzymuję bardzo różne wartości. Na przykład:Twórz prognozy za pomocą wykresu tensorflow z modelu keras

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))) 

Powroty:

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

Wartości z Keras przewidywania są poprawne, ale wyniki nie są wykres TF.

Jeśli pomaga poznać ostateczną zamierzoną aplikację, tworzę macierz jacobian z funkcją tf.gradients(), ale obecnie nie zwraca poprawnych wyników w porównaniu z funkcją jacobian theano, która daje poprawną odpowiedź jacobian . Oto moja tensorflow kod Jacobiego:

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 Kod

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') 
+0

Naprawdę nie rozumiem twojego kodu. czy możesz bardziej szczegółowo opisać, w jaki sposób ładujesz i eksportujesz swój kod? co robi 'load_model'? gdzie jest zdefiniowany "model"? także myślę, że jest to niebezpieczne przy użyciu 'global_variables_initializer', czy możesz bardziej szczegółowo opisać sposób tworzenia swojego modelu tensorflow? – maxymoo

+0

@maxymoo Dzięki za komentarz dodałem kod służący do utworzenia modelu tensorflow i poprawiłem poprzedni kod, aby poprawnie zdefiniować zmienną modelu.Zgadzam się, że używanie 'global_variables_initializer' jest nieco niepokojące, ale gdy nie otrzymuję błędu, pojawia się komunikat' FailedPreconditionError: Próba użycia niezainicjowanej wartości dense_14/bias'. Wszelkie pomysły na rozwiązanie tego problemu? – Starnetter

+0

Czy jesteś pewien, że został przeszkolony w TF? – frankyjuang

Odpowiedz

8

@frankyjuang powiązany mi tutaj

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

i łącząc to z kodem z

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

i

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

znalazłem rozwiązanie zarówno przewidywania za pomocą wykresu TF i tworzenie funkcji Jacobiego:

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/') 

Tworzenie funkcji załadować model TF jako wykres:

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 

utworzyć funkcję Marka Model przewidywania za pomocą wykresu TF

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 

dokonać prognozy:

tf_predictions = predict(tf_model_path,test_data) 

Jacobiego funkcji:

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 Jacobiego Matrix:

jacobians = compute_jacobian(tf_model_path,test_data) 
+0

czy w jakiś sposób możemy poprawić czas przewidywania, zapisując krotkę zwróconą przez funkcję load_graph(), a może nawet zapisać wartości tensora x i y. Chcę tylko, żeby przewidywania były szybkie, aby móc przewidzieć werdykt tylko dla jednej próbki. – Mohsin