This example demonstrates how to load and run a frozen graph developed in TensorFlow. More specific, we demonstrate how to port an example of _ofxMSATensorFlow_ to _ofxTensorFlow2_.

### TensorFlow
From Memo Akten's exmaple:
From Memo Akten's example:
> Models are trained and saved in python with this code (https://github.com/memo/char-rnn-tensorflow)
and loaded in openframeworks for prediction.
...
...
@@ -13,8 +15,8 @@ Note, all models are trained really quickly with no hyperparameter search or cro
using default architecture of 2 layer LSTM of size 128 with no dropout or any other regularisation.
### openFrameworks
By default `ofxTF2::Model` will use the `SavedModel` format. To use the `FrozenGraph` format you may either add the type to the constructor or call `setModelType()` afterwards.
As the default names differ from the names in the `SavedModel` format make sure to overwrite names of the ins and outs by calling `setup()`.
By default `ofxTF2::Model` will use the `SavedModel` format. To use the `FrozenGraph` format you may either add the type to the constructor or call `Model::setModelType()` afterwards.
As the default names differ from the names in the `SavedModel` format make sure to overwrite names of the ins and outs by calling `Model::setup()`.
In _ofxTensorFlow2_ we can use the `Model::run()` function (if we have a single input) or the more general `Model::runMultiModel()` function to execute the model on some input data:
In _ofxTensorFlow2_ we can use the `Model::run()` function (if we have a single input and output tensor) or the more general `Model::runMultiModel()` function to execute the model on some input data:
The class for the tensor also differs a little bit. In _ofxTensorFlow2_ we will use the `cppflow::tensor` class instead of `tensorflow::tensor`.
The class for the tensor also differs a little bit. In _ofxTensorFlow2_ we use the `cppflow::tensor` class instead of `tensorflow::tensor`.
As in _ofxMSATensorFlow_, we provide functions for coverting from a tensor to `ofImage, ofPixels` and `std::vector`, and the other way around, e.g. `ofxTF2::vectorToTensor`. Regarding the utilities section, there are now some new handy functions like `ofxTF2::setGPUMaxMemory` and `ofxTF2::ThreadedModel`, while other less general functions have been dropped. Especially `msa::tf::adjust_probs_with_temp` and `msa::tf::sample_from_prob` are not in the utilities anymore. For this reason, we put those functions into the example's source code.
Similar to _ofxMSATensorFlow_, we provide functions for converting from a tensor to `ofImage, ofPixels` and `std::vector`, and the other way around, e.g. `ofxTF2::vectorToTensor()`. Regarding other utilities, there are now some new handy functionalities like `ofxTF2::setGPUMaxMemory()` and `ofxTF2::ThreadedModel`, while other less general functions have been dropped.
For this example we have put dropped functions into the source code of the example.
__Note:__ With the current version of cppflow, calling `get_data<T>` or `shape()` on a default (uninitalised) `cppflow::tensor` will result in a segfault. Wile you usually don't need to call them yourself, this effects the previously mentioned conversion functions.
__Note:__ With the current version of _cppflow_, calling `tensor::get_data()` or `tensor::shape()` on a default (uninitialized) `cppflow::tensor` will result in a segfault. Wile you usually don't need to call them yourself, this effects the previously mentioned conversion functions.
Therefore, we've changed a few lines of code when priming the model with new data.
Please understand that we wont be able to invest a lot of time in supporting this feature in the future.