Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions examples/keras_multiple_inputs_saved_model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use tensorflow::{SessionRunArgs, Graph, SessionOptions, Tensor, SavedModelBundle};

fn main() {
// In this file test_in_input is being used while in the python script,
// that generates the saved model from Keras model it has a name "test_in".
// For multiple inputs _input is not being appended to the op name.
let input_1_op_name = "test_in1";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't op names, they're signature input (or output) parameter names. I know this sounds like nitpicking, but this can be confusing, so it's important to make a clear distinction, so readers don't think they're the same thing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable is renamed now.

let input_2_op_name = "test_in2";
let output_op_name = "test_out";
let save_dir = "examples/keras_multiple_inputs_saved_model";
let v1: Vec<f32> = vec![0.1, 0.2, 0.3, 0.4, 0.5];
let v2 = vec![0.6, 0.7, 0.8, 0.9, 0.1];
let tensor1 = vector_to_tensor(&v1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified to:

let tensor1 = Tensor::from(&[0.1, 0.2, 0.3, 0.4, 0.5][..]);

no Vec or vector_to_tensor needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function is removed.

let tensor2 = vector_to_tensor(&v2);
let mut graph = Graph::new();

let bundle = SavedModelBundle::load(
&SessionOptions::new(),
&["serve"],
&mut graph,
save_dir,
).expect("Can't load saved model");

let session = &bundle.session;

let signature = bundle.meta_graph_def().get_signature("serving_default").unwrap();
let input_info1 = signature.get_input(input_1_op_name).unwrap();
let input_info2 = signature.get_input(input_2_op_name).unwrap();
let output_info = signature.get_output(output_op_name).unwrap();

let input_op1 = graph.operation_by_name_required(&input_info1.name().name).unwrap();
let input_op2 = graph.operation_by_name_required(&input_info2.name().name).unwrap();
let output_op = graph.operation_by_name_required(&output_info.name().name).unwrap();
let mut args = SessionRunArgs::new();
args.add_feed(&input_op1, 0, &tensor1);
args.add_feed(&input_op2, 0, &tensor2);
let out = args.request_fetch(&output_op, 0);

let result = session.run(&mut args);
if result.is_err() {
panic!("Error occured during calculations: {:?}", result);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified to:

session.run(&mut args).expect("Error occurred during calculations");

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplification has been performed.

let out_res:f32 = args.fetch(out).unwrap()[0];
println!("Results: {:?}", out_res);
}

pub fn vector_to_tensor(v: &Vec<f32>) -> Tensor<f32> {
let dimension = v.len();
let tensor = Tensor::new(&[1, dimension as u64]).with_values(&v[..]).unwrap();
return tensor;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import tensorflow as tf;
from tensorflow.python import keras
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Concatenate
from tensorflow.keras import Model
import numpy as np


input = Input((5))
x = Flatten()(input)
x = Dense(3,'relu')(x)
dense = Model(input, x)

input1 = Input((5), name='test_in1')
input2 = Input((5), name='test_in2')

dense1 = dense(input1)
dense2 = dense(input2)

merge_layer = Concatenate()([dense1, dense2])
dense_layer = Dense(1, activation="sigmoid", name='test_out')(merge_layer)

model = Model(inputs=[input1, input2], outputs=dense_layer)

v1 = np.array([[0.1, 0.2, 0.3, 0.4, 0.5]])
v2 = np.array([[0.6, 0.7, 0.8, 0.9, 0.1]])
print(v1.shape)
x1, x2 = np.random.randn(100, 5), np.random.randn(100, 5)
print(x1.shape)
y = np.random.randn(100, 1)
# print(v1.shape)
# print(v2.shape)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were these commented-out lines intended to be removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Obsolete lines have been removed.

outputs = np.array([1.0]);
model.compile(optimizer ='adam',loss='binary_crossentropy', metrics = ['accuracy'])
model.fit([v1, v2], outputs, epochs=1, batch_size=1)
model.save('examples/keras_multiple_inputs_saved_model', save_format='tf')
Binary file not shown.
Binary file not shown.
Binary file not shown.
45 changes: 45 additions & 0 deletions examples/keras_signle_input_saved_model.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use tensorflow::{SessionRunArgs, Graph, SessionOptions, Tensor, SavedModelBundle};

fn main() {
// In this file test_in_input is being used while in the python script,
// that generates the saved model from Keras model it has a name "test_in".
// For multiple inputs _input is not being appended to the op name.
let input_op_name = "test_in_input";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These aren't op names.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable has been renamed.

let output_op_name = "test_out";
let save_dir = "examples/keras_signle_input_saved_model";
let v: Vec<f32> = vec![0.1, 0.2, 0.3, 0.4, 0.5];

let tensor = vector_to_tensor(&v);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with the other file, this can be simplified to:

let tensor = Tensor::from(&[0.1, 0.2, 0.3, 0.4, 0.5][..]);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it did not work for me because your code is creating tensor of dims:[5], but dim:[1, 5] is expected, so I used the following code:

let tensor: Tensor<f32> = Tensor::new(&[1, 5])
        .with_values(&[0.1, 0.2, 0.3, 0.4, 0.5])
        .expect("Can't create tensor");

let mut graph = Graph::new();

let bundle = SavedModelBundle::load(
&SessionOptions::new(),
&["serve"],
&mut graph,
save_dir,
).expect("Can't load saved model");

let session = &bundle.session;

let signature = bundle.meta_graph_def().get_signature("serving_default").unwrap();
let input_info = signature.get_input(input_op_name).unwrap();
let output_info = signature.get_output(output_op_name).unwrap();
let input_op = graph.operation_by_name_required(&input_info.name().name).unwrap();
let output_op = graph.operation_by_name_required(&output_info.name().name).unwrap();
let mut args = SessionRunArgs::new();
args.add_feed(&input_op, 0, &tensor);
let out = args.request_fetch(&output_op, 0);

let result = session.run(&mut args);
if result.is_err() {
panic!("Error occured during calculations: {:?}", result);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can use expect.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect has been added.

let out_res:f32 = args.fetch(out).unwrap()[0];
println!("Results: {:?}", out_res);
}

pub fn vector_to_tensor(v: &Vec<f32>) -> Tensor<f32> {
let dimension = v.len();
let tensor = Tensor::new(&[1, dimension as u64]).with_values(&v[..]).unwrap();
return tensor;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file name has a typo: signle should be single.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File has been renamed

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import tensorflow as tf;
import tensorboard;
from tensorflow.python import keras
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense

import json;
import numpy as np;


tensorboard_callback = keras.callbacks.TensorBoard(log_dir="/tmp/logs")

classifier = Sequential()
classifier.add(Dense(5, activation='relu', kernel_initializer='random_normal', name="test_in", input_dim=5))
classifier.add(Dense(5, activation='relu'))
classifier.add(Dense(1, activation='sigmoid', name="test_out"))



classifier.compile(optimizer ='adam',loss='binary_crossentropy', metrics = ['accuracy'])


classifier.fit([[0.1, 0.2, 0.3, 0.4, 0.5]], [[1]], batch_size=1, epochs=1, callbacks=[tensorboard_callback]);
result = classifier.predict([[0.1, 0.2, 0.3, 0.4, 0.5]])

print(result);
classifier.summary();

for layer in classifier.layers:
print(layer.name)

classifier.save('examples/keras_signle_input_saved_model', save_format='tf')
Binary file not shown.
Binary file not shown.
Binary file not shown.