Use Keras models in C++ with ease
Would you like to build/train a model using Keras/Python? And would you like to run the prediction (forward pass) on your model in C++ without linking your application against TensorFlow? Then frugally-deep is exactly for you.
frugally-deep
model.predict
) not only for sequential models but also for computational graphs with a more complex topology, created with the functional API.Add
, Concatenate
, Subtract
, Multiply
, Average
, Maximum
, Minimum
, Dot
AveragePooling1D/2D/3D
, GlobalAveragePooling1D/2D/3D
TimeDistributed
Conv1D/2D
, SeparableConv2D
, DepthwiseConv2D
Cropping1D/2D/3D
, ZeroPadding1D/2D/3D
, CenterCrop
BatchNormalization
, Dense
, Flatten
, Normalization
Dropout
, AlphaDropout
, GaussianDropout
, GaussianNoise
SpatialDropout1D
, SpatialDropout2D
, SpatialDropout3D
ActivityRegularization
, LayerNormalization
, UnitNormalization
RandomContrast
, RandomFlip
, RandomHeight
RandomRotation
, RandomTranslation
, RandomWidth
, RandomZoom
MaxPooling1D/2D/3D
, GlobalMaxPooling1D/2D/3D
ELU
, LeakyReLU
, ReLU
, SeLU
, PReLU
Sigmoid
, Softmax
, Softplus
, Tanh
Exponential
, GELU
, Softsign
, Rescaling
UpSampling1D/2D
, Resizing
Reshape
, Permute
, RepeatVector
Embedding
, CategoryEncoding
Attention
, AdditiveAttention
, MultiHeadAttention
load_model
)Conv2DTranspose
(why),
Lambda
(why),
Conv3D
, ConvLSTM1D
, ConvLSTM2D
, Discretization
,
GRUCell
, Hashing
,
IntegerLookup
,
LocallyConnected1D
, LocallyConnected2D
,
LSTMCell
, Masking
,
RepeatVector
, RNN
, SimpleRNN
,
SimpleRNNCell
, StackedRNNCells
, StringLookup
, TextVectorization
,
Bidirectional
, GRU
, LSTM
, CuDNNGRU
, CuDNNLSTM
,
ThresholdedReLU
, Upsampling3D
, temporal
models
1) Use Keras/Python to build (model.compile(...)
), train (model.fit(...)
) and test (model.evaluate(...)
) your model as usual. Then save it to a single file using model.save('....keras')
. The image_data_format
in your model must be channels_last
, which is the default when using the TensorFlow backend. Models created with a different image_data_format
and other backends are not supported.
2) Now convert it to the frugally-deep file format with keras_export/convert_model.py
3) Finally load it in C++ (fdeep::load_model(...)
) and use model.predict(...)
to invoke a forward pass with your data.
The following minimal example shows the full workflow:
# create_model.py
import numpy as np
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
inputs = Input(shape=(4,))
x = Dense(5, activation='relu')(inputs)
predictions = Dense(3, activation='softmax')(x)
model = Model(inputs=inputs, outputs=predictions)
model.compile(loss='categorical_crossentropy', optimizer='nadam')
model.fit(
np.asarray([[1, 2, 3, 4], [2, 3, 4, 5]]),
np.asarray([[1, 0, 0], [0, 0, 1]]), epochs=10)
model.save('keras_model.keras')
python3 keras_export/convert_model.py keras_model.keras fdeep_model.json
// main.cpp
#include <fdeep/fdeep.hpp>
int main()
{
const auto model = fdeep::load_model("fdeep_model.json");
const auto result = model.predict(
{fdeep::tensor(fdeep::tensor_shape(static_cast<std::size_t>(4)),
std::vector<float>{1, 2, 3, 4})});
std::cout << fdeep::show_tensors(result) << std::endl;
}
When using convert_model.py
a test case (input and corresponding output values) is generated automatically and saved along with your model. fdeep::load_model
runs this test to make sure the results of a forward pass in frugally-deep are the same as in Keras.
For more integration examples please have a look at the FAQ.
Guides for different ways to install frugally-deep can be found in INSTALL.md
.
See FAQ.md
The API of this library still might change in the future. If you have any suggestions, find errors, or want to give general feedback/criticism, I'd love to hear from you. Of course, contributions are also very welcome.
Distributed under the MIT License.
(See accompanying file LICENSE
or at
https://opensource.org/licenses/MIT)