I am currently trying to transfer a tensorflow model I produced and have saved in python to something compatible with C++, my model is running succesfully apart from the fact that it gives wildly different numbers to the python version.
int main()
{
float data[1][3][3][3][15];
//********* Read model
TF_Graph* Graph = TF_NewGraph();
TF_Status* Status = TF_NewStatus();
TF_SessionOptions* SessionOpts = TF_NewSessionOptions();
TF_Buffer* RunOpts = NULL;
const char* saved_model_dir = "C:/Users/Tom/Desktop/Syngas_neural_network";
const char* tags = "serve"; // default model serving tag; can change in future
int ntags = 1;
TF_Session* Session = TF_LoadSessionFromSavedModel(SessionOpts, RunOpts, saved_model_dir, &tags, ntags, Graph, NULL, Status);
if (TF_GetCode(Status) == TF_OK)
{
printf("TF_LoadSessionFromSavedModel OK\n");
}
else
{
printf("%s", TF_Message(Status));
}
//****** Get input tensor
//TODO : need to use saved_model_cli to read saved_model arch
int NumInputs = 1;
TF_Output* Input = (TF_Output*)malloc(sizeof(TF_Output) * NumInputs);
TF_Output t0 = { TF_GraphOperationByName(Graph, "serving_default_conv3d_15_input"), 0 };
if (t0.oper == NULL)
printf("ERROR: Failed TF_GraphOperationByName serving_default_input_1\n");
else
printf("TF_GraphOperationByName serving_default_input_1 is OK\n");
Input[0] = t0;
//********* Get Output tensor
int NumOutputs = 1;
TF_Output* Output = (TF_Output*)malloc(sizeof(TF_Output) * NumOutputs);
TF_Output t2 = { TF_GraphOperationByName(Graph, "StatefulPartitionedCall"), 0 };
if (t2.oper == NULL)
printf("ERROR: Failed TF_GraphOperationByName StatefulPartitionedCall\n");
else
printf("TF_GraphOperationByName StatefulPartitionedCall is OK\n");
Output[0] = t2;
//********* Allocate data for inputs & outputs
TF_Tensor** InputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumInputs);
TF_Tensor** OutputValues = (TF_Tensor**)malloc(sizeof(TF_Tensor*)*NumOutputs);
int ndims = 5;
int64_t dims[] = { 1,3,3,3,15 };
int ndata = sizeof(float) * 1 * 3 * 3 * 3 * 15;// This is tricky, it number of bytes not number of element
int out_ndims = 2;
int64_t out_dims [] = { 1,15 };
int out_ndata = sizeof(float) * 1 * 15;
TF_Tensor* int_tensor = TF_NewTensor(TF_FLOAT, dims, ndims, data, ndata, &NoOpDeallocator, 0);
TF_Tensor* out_tensor = TF_AllocateTensor(TF_FLOAT, out_dims, out_ndims, out_ndata);
if (int_tensor != NULL)
{
printf("TF_NewTensor is OK\n");
}
else
printf("ERROR: Failed TF_NewTensor\n");
InputValues[0] = int_tensor;
OutputValues[0] = out_tensor;
// //Run the Session
TF_SessionRun(Session, NULL, Input, InputValues, NumInputs, Output, OutputValues, NumOutputs, NULL, 0, NULL, Status);
if (TF_GetCode(Status) == TF_OK)
{
printf("Session is OK\n");
}
else
{
printf("%s", TF_Message(Status));
}
// //Free memory
TF_DeleteGraph(Graph);
TF_DeleteSession(Session, Status);
TF_DeleteSessionOptions(SessionOpts);
TF_DeleteStatus(Status);
void* buff = TF_TensorData(OutputValues[0]);
float* offsets = (float*)buff;
printf("Result Tensor :\n");
for (int i = 0; i<15; i++)
{
printf("%f\n", offsets[i]); // not sure if should be &
}
system("pause");
}
I am attempting to run the code with an array of zeros intialised as floats (intialisation is in line 3) and my output in python is an array of 15 float32 which are all lower than one.
2.091127634048461914e-02 -1.615172624588012695e-02 -1.822745800018310547e-02 -1.710012555122375488e-02 -1.535907387733459473e-02 -1.523724198341369629e-02 1.263055205345153809e-02 1.584252715110778809e-02 -1.479363441467285156e-02 -1.776772737503051758e-02 1.312178373336791992e-02 1.684901118278503418e-02 1.728761196136474609e-02 -1.410549879074096680e-02 -1.425114274024963379e-02
The numbers above are the numpy array produced by the mdoel in python and the numbers below are the output from the C++ code shown.
Result Tensor :
5568243.000000
524631.625000
-3114723.500000
-2831625.500000
-934582.812500
-3011815.500000
-3105331.750000
965934.312500
2041.866211
-3588635.500000
-4056957.000000
157006.296875
870158.000000
4255018.000000
3537240.750000
Apologies for the long question, I didnt want to miss any useful information out, if someone has any idea why my outputs are so different I would appreciate the help.