0

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.

  • I don't want to be a scandalmonger but there is no C++ here. Please don't mix C and C++ as if it was the same language (there are completely different languages). – Fareanor Jul 29 '20 at 13:01
  • oh true thats my bad, got it mixed up with something else in the project – Perigee Jul 29 '20 at 13:10

1 Answers1

0

Just realised my array initialisation was wrong. I fixed by replacing line 3 with

float data[1][3][3][3][15]{};
Dharman
  • 30,962
  • 25
  • 85
  • 135