I'm following a tutorial from codelabs. They use this script to optimize the model
python -m tensorflow.python.tools.optimize_for_inference \
--input=tf_files/retrained_graph.pb \
--output=tf_files/optimized_graph.pb \
--input_names="input" \
--output_names="final_result"
they verify the optimized_graph.pb using this script
python -m scripts.label_image \
--graph=tf_files/optimized_graph.pb \
--image=tf_files/flower_photos/daisy/3475870145_685a19116d.jpg
The problem is I try to use optimize_for_inference to my own code which is not for image classification.
Previously, before optimizing, I use this script to verify my model by test it to a sample data:
import tensorflow as tf
from tensorflow.contrib import predictor
from tensorflow.python.platform import gfile
import numpy as np
def load_graph(frozen_graph_filename):
with tf.gfile.GFile(frozen_graph_filename, "rb") as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
tf.import_graph_def(graph_def, name="prefix")
input_name = graph.get_operations()[0].name+':0'
output_name = graph.get_operations()[-1].name+':0'
return graph, input_name, output_name
def predict(model_path, input_data):
# load tf graph
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)
model_input = tf.train.Example(
features=tf.train.Features(feature={
"thisisinput": tf.train.Feature(float_list=tf.train.FloatList(value=input_data)),
}))
model_input = model_input.SerializeToString()
num_outputs = 3
predictions = np.zeros(num_outputs)
with tf.Session(graph=tf_model) as sess:
y_out = sess.run(y, feed_dict={x: [model_input]})
predictions = y_out
return predictions
if __name__=="__main__":
input_data = [4.7,3.2,1.6,0.2] # my model recieve 4 inputs
print(np.argmax(predict("not_optimized_model.pb",x)))
but after optimizing the model, my testing script doesn't work. It raises an error:
ValueError: Input 0 of node import/ParseExample/ParseExample was
passed float from import/inputtensors:0 incompatible with expected
string.
So my question is how to verify my model after optimizing the model? I can't use --image command like the tutorial.
I've solved the error by changing the placeholder's type with tf.float32 when exporting the model:
def my_serving_input_fn():
input_data = {
"featurename" : tf.placeholder(tf.float32, [None, 4], name='inputtensors')
}
return tf.estimator.export.ServingInputReceiver(input_data, input_data)
and then change the prediction function above to:
def predict(model_path, input_data):
# load tf graph
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)
num_outputs = 3
predictions = np.zeros(num_outputs)
with tf.Session(graph=tf_model) as sess:
y_out = sess.run(y, feed_dict={x: [input_data]})
predictions = y_out
return predictions
After freezing the model, the prediction code above will be work. But unfortunately it raises another error when trying to load pb directly after exporting the model.
Related
After converting a model from tf1 to tf2, I cannot use the tf2 model with tf.GradientTape().
Some useful information:
The model uses tfa.seq2seq layers, which are most likely the source of the error (e.g. replacing the content of the function network below with a single tf.compat.v1.layers.Dense works fine)
tensorflow 2.9.1
Python 3.9
Here are 2 snippets to reproduce the error:
First run this snippet to create/save the model
import functools
import tensorflow as tf
import tensorflow_addons as tfa
MODEL_FOLDER = "model"
LSTM_UNITS = 3
def network(input):
attention_mechanism = tfa.seq2seq.BahdanauAttention(
1, input, memory_sequence_length=None
)
cell = tf.compat.v1.nn.rnn_cell.LSTMCell(
LSTM_UNITS,
)
attention_cell = tfa.seq2seq.AttentionWrapper(
cell, attention_mechanism, output_attention=False
)
embedding_fn = functools.partial(tf.compat.v1.one_hot, depth=10)
output_layer = tf.compat.v1.layers.Dense(
10,
)
train_helper = tfa.seq2seq.GreedyEmbeddingSampler(embedding_fn)
decoder = tfa.seq2seq.BasicDecoder(
cell=attention_cell, sampler=train_helper, output_layer=output_layer
)
init_kwargs = {}
init_kwargs["start_tokens"] = tf.compat.v1.fill([1], 1)
init_kwargs["end_token"] = 2
init_kwargs["initial_state"] = attention_cell.get_initial_state(
batch_size=1, dtype=tf.compat.v1.float32
)
outputs, _, output_lengths = tfa.seq2seq.dynamic_decode(
decoder=decoder,
output_time_major=False,
impute_finished=False,
maximum_iterations=1,
decoder_init_kwargs=init_kwargs,
)
return outputs
def main(_):
input = tf.compat.v1.placeholder(dtype=tf.compat.v1.float32, shape=[1, 1, LSTM_UNITS])
fetches = {
"output": network(input).rnn_output,
}
with tf.compat.v1.Session() as sess:
builder = tf.compat.v1.saved_model.Builder(MODEL_FOLDER)
sess.run(
[
tf.compat.v1.global_variables_initializer(),
tf.compat.v1.local_variables_initializer(),
tf.compat.v1.tables_initializer(),
]
)
sig_def = tf.compat.v1.saved_model.predict_signature_def(
inputs={"input": input}, outputs=fetches
)
builder.add_meta_graph_and_variables(
sess,
tags=["serve"],
signature_def_map={
tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY: sig_def
},
)
builder.save()
if __name__ == "__main__":
# Save model
tf.compat.v1.disable_eager_execution()
tf.compat.v1.disable_v2_behavior()
tf.compat.v1.app.run()
Then run this snippet to load/use the model
import tensorflow as tf
MODEL_FOLDER = "model"
LSTM_UNITS = 3
if __name__ == "__main__":
# Load model and use it
input = tf.ones((1, 1, LSTM_UNITS))
model = tf.saved_model.load(
MODEL_FOLDER, tags="serve"
).signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
print(model(input)) # this works
with tf.GradientTape():
model(input) # AttributeError: 'NoneType' object has no attribute 'outer_context'
If anyone could help me that would be great, thank you!
I am doing a simple cyberbullying detection model using BERT embeddings and TensorFlow. My dataset has two columns (label and text). It is a binary classification problem since 0 means a tweet is harassing and 1 is neutral.
You can find the altered_data dataset that I am using here. The original dataset can be found here.
Following the TensorFlow documentation for fine-tuning BERT, I have built the following model:
!git clone --depth 1 -b v2.3.0 https://github.com/tensorflow/models.git
!pip install -Uqr models/official/requirements.txt
After this, a runtime restart is required. Then the following code is executed.
import sys
sys.path.append('models')
import tensorflow as tf
import tensorflow_hub as tf_hub
import numpy as np
import pandas as pd
import sklearn
from official.nlp.data import classifier_data_lib
from official.nlp.bert import tokenization
from official.nlp import optimization
from sklearn.model_selection import train_test_split
df = pd.read_csv('altered_data.csv', encoding='utf-8')
train_df, remaining = train_test_split(df, random_state=42, train_size=0.90, stratify=df.sentiment.values)
valid_df, _ = train_test_split(remaining, random_state=42, train_size=0.90, stratify=remaining.sentiment.values)
train_df.shape, valid_df.shape
with tf.device('/cpu:0'):
train_data = tf.data.Dataset.from_tensor_slices((train_df['sentiment'].values, train_df['tweet'].values))
valid_data = tf.data.Dataset.from_tensor_slices((valid_df.sentiment.values, valid_df.tweet.values))
for label, text in train_data.take(1):
print(label)
print(text)
for label, text in valid_data.take(1):
print(label)
print(text)
label_list = [0, 1]
max_seq_length = 128
train_batch_size = 32
bert_layer = tf_hub.KerasLayer("https://tfhub.dev/tensorflow/bert_en_uncased_L-12_H-768_A-12/2", trainable=True)
vocab_file = bert_layer.resolved_object.vocab_file.asset_path.numpy()
do_lower_case = bert_layer.resolved_object.do_lower_case.numpy()
tokenizer = tokenization.FullTokenizer(vocab_file, do_lower_case)
def to_feature(text, label, label_list=label_list, max_seq_length=max_seq_length, tokenizer=tokenizer):
example = classifier_data_lib.InputExample(guid=None,
text_a = text.numpy(),
text_b = None,
label = label.numpy())
feature = classifier_data_lib.convert_single_example(0, example, label_list, max_seq_length, tokenizer)
return (feature.input_ids, feature.input_mask, feature.segment_ids, feature.label_id)
def to_feature_map(label, text):
input_ids, input_mask, segment_ids, label_id = tf.py_function(to_feature, inp=[label, text],
Tout=[tf.int32, tf.int32, tf.int32, tf.int32])
input_ids.set_shape([max_seq_length])
input_mask.set_shape([max_seq_length])
segment_ids.set_shape([max_seq_length])
label_id.set_shape([])
x = {
'input_word_ids': input_ids,
'input_mask': input_mask,
'input_type_ids': segment_ids
}
return (label, x)
with tf.device('/cpu:0'):
train_data = (train_data.map(to_feature_map,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
.shuffle(1000)
.batch(32, drop_remainder=True)
.prefetch(tf.data.experimental.AUTOTUNE))
valid_data = (valid_data.map(to_feature_map,
num_parallel_calls=tf.data.experimental.AUTOTUNE)
.batch(32, drop_remainder=True)
.prefetch(tf.data.experimental.AUTOTUNE))
Train Data tensor spec
train_data.element_spec
Create model code:
def create_model():
input_word_ids = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32,
name="input_word_ids")
input_mask = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32,
name="input_mask")
input_type_ids = tf.keras.layers.Input(shape=(max_seq_length,), dtype=tf.int32,
name="input_type_ids")
pooled_output, sequence_output = bert_layer([input_word_ids, input_mask, input_type_ids])
drop = tf.keras.layers.Dropout(0.4)(pooled_output)
output = tf.keras.layers.Dense(1, activation='sigmoid', name="output")(drop)
model = tf.keras.Model(
inputs={
'input_word_ids': input_word_ids,
'input_mask': input_mask,
'input_type_ids': input_type_ids
}, outputs=output)
return model
model = create_model()
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=2e-5),
loss=tf.keras.losses.BinaryCrossentropy(),
metrics=[tf.keras.metrics.BinaryAccuracy()])
model.summary()
epoch = 4
history = model.fit(train_data,
validation_data=valid_data,
epochs=epoch,
verbose=1)
Raises the following error:
I am still a beginner in TensorFlow. To my understanding, there is a problem between the dropout and dense layers, while getting the inputs. However, I can't figure out what needs to be done in order to fix this. Any help would be appreciated!
When I run my code ,it just stay in the line image_batch, label_batch = sess.run([test_images, test_labels]) without any error prompt. It just stays here and can't move.
Here is my code:
# coding=utf-8
from color_1 import read_and_decode, get_batch, get_test_batch
import color_inference
import cv2
import os
import time
import numpy as np
import tensorflow as tf
import color_train
import math
batch_size=128
num_examples = 10000
crop_size=56
def evaluate():
image_holder = tf.placeholder(tf.float32, [batch_size, 56, 56, 3], name='x-input')
label_holder = tf.placeholder(tf.int32, [batch_size], name='y-input')
test_image, test_label = read_and_decode('val.tfrecords')
test_images, test_labels = get_test_batch(test_image, test_label, batch_size, crop_size)
y=color_inference.inference(image_holder)
num_iter = int(math.ceil(num_examples / batch_size))
true_count = 0
total_sample_count = num_iter * batch_size
top_k_op = tf.nn.in_top_k(y, label_holder, 1)
saver = tf.train.Saver()
with tf.Session() as sess:
ckpt=tf.train.get_checkpoint_state(color_train.MODEL_SAVE_PATH)
if ckpt and ckpt.model_checkpoint_path:
ckpt_name = os.path.basename(ckpt.model_checkpoint_path)
global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
saver.restore(sess, os.path.join(color_train.MODEL_SAVE_PATH, ckpt_name))
print('Loading success, global_step is %s' % global_step)
image_batch, label_batch = sess.run([test_images, test_labels])
predictions = sess.run([top_k_op], feed_dict={image_holder: image_batch,
label_holder: label_batch})
true_count += np.sum(predictions)
print("Count is:%g" % true_count)
precision = true_count * 1.0 / total_sample_count
print("After %s training step,the prediction is :%g",global_step,precision)
else:
print('No checkpoint file found')
return
def main(argv=None):
evaluate()
if __name__=='__main__':
tf.app.run()
My last question is similar with this ,but the code is litter different with this, maybe you can get something in last question.
Seems like you are not starting the queue-runners / initializing the variables properly. I have seen similar behavior with my models when i forgot to to that.
When this is the case you most likely get stuck at the line
image_batch, label_batch = sess.run([test_images, test_labels])
because the threads that pull data from the tfrecords have not been started.
Before you initialize your session setup an op for initializing the variables and a thread-coordinator:
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
coord = tf.train.Coordinator()
then at the very start of your session, before pulling any data from the tfrecords you run the op and start the queue runners:
sess.run(init_op)
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
# main loop goes here, like training and evaluating
import tensorflow as tf
import numpy as np
#import matplotlib.pyplot as plt
def add_layer(inputs,in_size,out_size,activation_function=None):
with tf.name_scope('layer'):
with tf.name_scope('weight'):
Weights = tf.Variable(tf.random_normal([in_size,out_size]),name='W')
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1,out_size])+0.1,name='b')
with tf.name_scope('Wx_plus_b'):
Wx_plus_b = tf.matmul(inputs,Weights)+biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
x_data = np.linspace(-1,1,300)[:,np.newaxis]
noise = np.random.normal(0,0.05,x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
#define the placeholder for input
with tf.name_scope('inputs'):
xs = tf.placeholder(tf.float32,[None,1],name='x_input')
ys = tf.placeholder(tf.float32,[None,1],name='y_input')
#add hidden layer
l1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
#add output layer
prediction = add_layer(l1,10,1,activation_function=None)
# error between prediction and real data
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-prediction),
reduction_indices=[1]),name='loss')
with tf.name_scope('train'):
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
init = tf.global_variables_initializer()
sess = tf.Session()
writer = tf.train.SummaryWrite("C:\\Users\\duke\\Desktop\\tensorflow example\\",sess.graph)
sess.run(init)
#fig = plt.figure()
#ax = fig.add_subplot(1,1,1)
#ax.scatter(x_data,y_data)
#plt.ion()
#plt.show()
#training step
for i in range (1000):
sess.run(train_step, feed_dict={xs:x_data,ys:y_data})
if i % 50 ==0:
# print(sess.run(loss,feed_dict={xs:x_data,ys:y_data}))
try:
ax.lines.remove(lines[0])
except Exception:
pass
prediction_value = sess.run(prediction,feed_dict={xs:x_data})
lines = ax.plot(x_data,prediction_value,'r-',lw=5)
plt.pause(0.1)
sess.close()
I currently use tensorflow to build a simple 3 layers NN, and I want to use tensorboard to show the gragh. but when I run the module, it shows: AttributeError: module 'tensorflow.python.training.training' has no attribute 'SummaryWrite'. I am really confused....
As commented by #Neal, SummaryWriter is no longer exported into the train module, as it was deprecated.See here.
Instead use tf.summary.FileWriter
I am trying to load a tensorflow model from disk and predicting the values.
Code
def get_value(row):
print("**********************************************")
graph = tf.Graph()
rowkey = row[0]
checkpoint_file = "/home/sahil/Desktop/Relation_Extraction/data/1485336002/checkpoints/model-300"
print("Loading model................................")
with graph.as_default():
session_conf = tf.ConfigProto(
allow_soft_placement=allow_soft_placement,
log_device_placement=log_device_placement)
sess = tf.Session(config=session_conf)
with sess.as_default():
# Load the saved meta graph and restore variables
saver = tf.train.import_meta_graph("{}.meta".format(checkpoint_file))
saver.restore(sess, checkpoint_file)
input_x = graph.get_operation_by_name("X_train").outputs[0]
dropout_keep_prob = graph.get_operation_by_name("dropout_keep_prob").outputs[0]
predictions = graph.get_operation_by_name("output/predictions").outputs[0]
batch_predictions = sess.run(predictions, {input_x: [row[1]], dropout_keep_prob: 1.0})
print(batch_predictions)
return (rowkey, batch_predictions)
I have a RDD which consists of a tuple (rowkey, input_vector). I want to use the loaded model to predict the score/class of the input.
Code to call get_value()
result = data_rdd.map(lambda iter: get_value(iter))
result.foreach(print)
The problem is every time I call the map, the model is loaded everytime for each tuple and it takes a lot of time.
I am thinking of loading the model using mapPartitions and then use map to call get_value function.
I have no clue as how to convert the code to a mapPartition where I load the tensorflow model only once per parition and reduce the running time.
Thanks in advance.
I am not sure if I get your question correctly, but we can optimise your code a bit here.
graph = tf.Graph()
checkpoint_file = "/home/sahil/Desktop/Relation_Extraction/data/1485336002/checkpoints/model-300"
with graph.as_default():
session_conf = tf.ConfigProto(
allow_soft_placement=allow_soft_placement,
log_device_placement=log_device_placement)
sess = tf.Session(config=session_conf)
s = sess.as_default()
saver = tf.train.import_meta_graph("{}.meta".format(checkpoint_file))
saver.restore(sess, checkpoint_file)
input_x = graph.get_operation_by_name("X_train").outputs[0]
dropout_keep_prob = graph.get_operation_by_name("dropout_keep_prob").outputs[0]
predictions = graph.get_operation_by_name("output/predictions").outputs[0]
session_pickle = cPickle.dumps(sess)
def get_value(key, vector, session_pickle):
sess = cPickle.loads(session_pickle)
rowkey = key
batch_predictions = sess.run(predictions, {input_x: [vector], dropout_keep_prob: 1.0})
print(batch_predictions)
return (rowkey, batch_predictions
result = data_rdd.map(lambda (key, row): get_value(key=key, vector = row , session_pickle = session_pickle))
result.foreach(print)
So you can serialize your tensorflow session. Though I haven't tested your code here. Run this and leave a comment.
I guess that the below code is a huge improvement as it uses mapPartitions.
Code
def predict(rows):
graph = tf.Graph()
checkpoint_file = "/home/sahil/Desktop/Relation_Extraction/data/1485336002/checkpoints/model-300"
print("Loading model................................")
with graph.as_default():
session_conf = tf.ConfigProto(
allow_soft_placement=allow_soft_placement,
log_device_placement=log_device_placement)
sess = tf.Session(config=session_conf)
with sess.as_default():
# Load the saved meta graph and restore variables
saver = tf.train.import_meta_graph("{}.meta".format(checkpoint_file))
saver.restore(sess, checkpoint_file)
print("**********************************************")
# Get the placeholders from the graph by name
input_x = graph.get_operation_by_name("X_train").outputs[0]
dropout_keep_prob = graph.get_operation_by_name("dropout_keep_prob").outputs[0]
# Tensors we want to evaluate
predictions = graph.get_operation_by_name("output/predictions").outputs[0]
# Generate batches for one epoch
for row in rows:
X_test = [row[1]]
batch_predictions = sess.run(predictions, {input_x: X_test, dropout_keep_prob:
yield (row[0], batch_predictions)
result = data_rdd.mapPartitions(lambda iter: predict(iter))
result.foreach(print)