Tensorflow serving variable file - tensorflow

I'm about to do tensorflow serving.
pb file and variable folder are created.
but No file was created under the variable folder.
like this
└── variables
├── variables.data-00000-of-00001
└── variables.index
After further experimentation, I found that the file only occurs when output is output to tf.Variable.
for example
1) z = tf.Variable(3,dtype=tf.float32)
2) z = tf.constant(3,dtype=tf.float32)
1) is created the file but 2) is not created file
z is output variable
signature_def_map= {
"serving_default": tf.saved_model.signature_def_utils.predict_signature_def(
inputs= {"egg": x, "bacon":y},
outputs= {"spam": z})
})
Is it right that I found out?
The above explanation is a test result as a simple example.
This is what I really want to do
sIdSorted = tf.gather(sId, indices[::-1])[0:5]
sess=tf.Session()
print sess.run(sIdSorted,feed_dict={userLat:37.12,userLon:127.2})
As a result of printing, it was output as follows.
['s7' 's1' 's2' 's3' 's4']
However, in this way, nothing is displayed in the variable folder.....
So I tried to output to tf.variable.
sIdSorted = tf.Variable(tf.gather(sId, indices[::-1])[0:5])
but This will output an error to the following.
initial_value must have a shape specified: Tensor("strided_slice_1:0", dtype=string)
so I tried it as follows.
sIdSorted = tf.Variable(tf.constant(tf.gather(sId, indices[::-1])[0:5],shape=[5]))
but This will output an error to the following.
List of Tensors when single Tensor expected
I need your help. Thank you for reading.
**tensorflow version :1.3.0 python 2.x

That is correct: only tf.Variables result in variable files being exported. Those files contain the actual values of the variables. The graph structure itself is stored in the saved_model.pb. That's where your gather (and any other ops) are. You should be able to serve the model.

Related

Data augmentation with tf.keras throwing "no such file or directory" error at for loop with .flow()

I am currently writing a script to augment a dataset for me using tf.keras (code given below). I'm pretty new to tf and data augmentation so I've been following a tutorial (https://blog.devgenius.io/data-augmentation-programming-e9a4703198be) pretty religiously. Despite this, I've been running into a lot of errors when I try to actually apply the ImageDataGenerator object to the image I'm loading. Specifically, I keep getting this error:
Exception has occurred: FileNotFoundError
[Errno 2] No such file or directory: '/home/kai/SURF22/yolov5/data/sc_google_aug/aug_0_3413.png'
File "/home/kai/SURF22/yolov5/data_augmentation", line 45, in <module>
for batch in idg.flow(aug_array,
It seems like tf can't find the image I want it to augment but I have no idea why because I load the image and input it as an array like the tutorial does. I tried inputting the absolute file path to the image instead one time but then I got a "string to float" error. Basically, I have no idea what is wrong and no one else seems to be getting this error when applying a for loop to .flow(). If anyone has advice on what could be going wrong I'd really appreciate it!
# images folder directory
folder_dir = "/home/kai/SURF22/yolov5/data/"
# initialize count
i = 0
for image in os.listdir(folder_dir + "prelim_data/sc_google_trans"):
# open the image
img = Image.open(folder_dir + "prelim_data/sc_google_trans/" + image)
# make copy of image to augment
# want to preserve original image
aug_img = img.copy()
# define an ImageDataGenerator object
idg = ImageDataGenerator(horizontal_flip=True,
vertical_flip=True,
rotation_range=360,
brightness_range=[0.2, 1.0],
shear_range=45)
# aug_img = load_img(folder_dir + "prelim_data/sc_google_trans/0.png")
# reshape image to a 4D array to be used with keras flow function
aug_array = img_to_array(aug_img)
aug_array = aug_array.reshape((1,) + aug_array.shape)
# augment image
for batch in idg.flow(aug_array,
batch_size=1,
save_to_dir='/home/kai/SURF22/yolov5/data/sc_google_aug',
save_prefix='aug',
save_format='png'):
i += 1
if i > 3:
break

tf.train.latest_checkpoint returning none when passing checkpoint path

When I am trying to load checkpoint after training ENet model for prediction using tf.train.latest_checkpoint(), it's returning "None" though I am passing the correct checkpoint path.
Here is my code:
image_dir = './dataset/test/'
images_list = sorted([os.path.join(image_dir, file) for file in
os.listdir(image_dir) if file.endswith('.png')])
checkpoint_dir = "./checkpoint_mk"
listi = os.listdir(checkpoint_dir)
print(listi)
checkpoint = tf.train.latest_checkpoint("./log/original/check")
print(checkpoint,'---------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++')
It returns None.
I am passing absolute path of checkpoint as they store in some other Dir.
Here are my checkpoint folder.
EDIT ---------------
model_checkpoint_path: "model.ckpt-400"
all_model_checkpoint_paths: "model.ckpt-0"
all_model_checkpoint_paths: "model.ckpt-400"
The tf.train.latest_checkpoint path argument needs to be relative to your current directory (from which Python script is executed). If it is a complex structure (i.e. data set is stored in a different folder or on a HDD) you can simply use absolute path to the folder. That is why tf.train.latest_checkpoint("/home/nikhil_m/TensorFlow-ENet/log/original") works in this case.
Try tf.train.latest_checkpoint(os.path.dirname('your_checkpoint_path'))

How can I reroute the training input pipeline to test pipeline in tensorflow using tf.contrib.graph_editor?

Suppose now I have a training input pipeline which finally generate train_x and train_y using tf.train.shuffle_batch. I export meta graph and re-import the graph in another code file. Now I want to detach the input pipeline, i.e., the train_x and train_y, and connect a new test_x and test_y. How can I make accomplish this using tf.contrib.graph_editor?
EDIT: As suggested by #iga, I change my input directory using input_map
filenames = tf.train.match_filenames_once(FLAGS.data_dir + '*', name='matching_filenames')
if FLAGS.ckpt != '':
latest = FLAGS.log_dir + FLAGS.ckpt
else:
latest = tf.train.latest_checkpoint(FLAGS.log_dir)
if not latest or not os.path.exists(latest+'.meta'):
print("checkpoint " + latest + " does not exist")
sys.exit(1)
saver = tf.train.import_meta_graph(latest+'.meta',
input_map={'matching_filenames:0':filenames},
import_scope='import')
g = tf.get_default_graph()
but I get the following error:
ValueError: graph_def is invalid at node u'matching_filenames/Assign':
Input tensor 'matching_filenames:0' Cannot convert a tensor of type
string to an input of type string_ref.
Are there any elegant way to resolve this?
For this task, you should be able to just use input_map argument to https://www.tensorflow.org/api_docs/python/tf/import_graph_def. If you are using import_meta_graph, you can pass the input_map into its kwargs and it will get passed down to import_graph_def.
RESPONSE TO EDIT: I am assuming that your original graph (the one you are deserializing) had the same matching_filenames variable. Quite confusingly, the tensor name "matching_filenames:0" actually refers to the tensor going from the VariableV2 op to the Assign op. The type of this edge is string_ref and you don't really want to break that edge.
The output from a variable typically goes through an identity op called matching_filenames/read. This is what you want to use as the key in your input_map. For the value, you want the same tensor in your new filenames. So, your call should probably look like:
tf.train.import_meta_graph(latest+'.meta',
input_map={'matching_filenames/read': filenames.read_value()},
import_scope='import')
In general, variables are fairly complicated. If this does not work, you can use some placeholder op and feed the names into it manually.

Accessing learned weights of a DNN in CNTK

How can one access to the learned weights of a DNN saved as following:
lstm_network_output.save(model_path)
The weights/parameters of a network can be accessed by calling ‘lstm_network_output.parameters’ which returns a list of ‘Parameter’ variable objects. The value of a Parameter can be obtained using ‘value’ property of the Parameter object in the form of a numpy array. The value of the Parameter can be updated by ‘.value = ’.
If you used name= properties in creating your model, you can also identify layers by name. For example:
model = Sequential([Embedding(300, name='embed'), Recurrence(LSTM(500)), Dense(10)])
E = model.embed.E # accesses the embedding matrix of the embed layer
To know that the parameter is .E, please consult the docstring of the respective function (e.g. help(Embedding)). (In Dense and Convolution, the parameters would be .W and .b.)
The pattern above is for named layers, which are created using as_block(). You can also name intermediate variables, and access them in the same way. E.g.:
W = Parameter((13,42), init=0, name='W')
x = Input(13)
y = times(x, W, name='times1')
W_recovered = y.times1.W
# e.g. check the shape to see that they are the same
W_recovered.shape # --> (13, 42)
W.shape # --> (13, 42)
Technically, this will search all parameters that feed y. In case of a more complex network, you may end up having multiple parameters of the same name. Then an error will be thrown due to the ambiguity. In that case, you must work the .parameters tuple mentioned in Anna's response.
This python code worked for me to visualize some weights:
import numpy as np
import cntk as C
dnnFile = C.cntk_py.Function.load('Models\ConvNet_MNIST_5.dnn') # load model from MS example
layer8 = dnnFile.parameters()[8].value()
filter_num = 0
sliced = layer8.asarray()[ filter_num ][ 0 ] # shows filter works on input image
print(sliced)

How to "append" Op at the beginning of a TensorFlow graph?

I have a GraphDef proto file which I am importing using tf.import_graph_def. Ops can be added at the end of the graph like this:
final_tensor = tf.import_graph_def(graph_def, name='', return_elements=['final_tensor'])
new_tensor = some_op(final_tensor)
But I want to add Ops at the beginning of the graph, so essentially the first Op in the graph_def needs to take the output of my Op as input, how do I do it?
Finally found a way to do this. I am sure the function Yarolsav mentioned in the comments does something similar internally.
new_input = graph_def.node.add()
new_input.op = 'new_op_name' # eg: 'Const', 'Placeholder', 'Add' etc
new_input.name = 'some_new_name'
# set any attributes you want for new_input here
old_input.input[0] = 'some_new_name' # must match with the name above
For details about how to set the attributes, see this file.
The script #Priyatham gives in the link is a good example how to add node in tf graph_def. name, op, input, attr are 4 required elements. name and op could be assigned, whereas input should use extend and attr should use CopyFrom method for assignment, like:
new_node = graph_def.node.add()
new_node.op = "Cast"
new_node.name = "To_Float"
new_node.input.extend(["To_Float"])
new_node.attr["DstT"].CopyFrom(attr_value_pb2.AttrValue(type=types_pb2.DT_FLOAT))
new_node.attr["SrcT"].CopyFrom(attr_value_pb2.AttrValue(type=types_pb2.DT_FLOAT))
new_node.attr["Truncate"].CopyFrom(attr_value_pb2.AttrValue(b=True))