Hi, I followed the tutorial. I am trying to implement the CPU runtime with a model I built in Keras.
I have converted it to an ONNX file, and confirmed the ONNX model was predicting the correct class, but when I run inference in UE5 it always returns category 25 (out of 29 categories).
I am a C++ / NNE beginner. Here is my code. Please let me know if this you see any errors.
// 5: hexagon
TArray<TArray<TArray<float>>> Hexagon = {{
{0.05490196, 0.0 },
{0.17254902, 0.02745098},
{0.34901961, 0.04313725},
{0.62352941, 0.04313725},
{1.0, 0.64705882},
{0.76862745, 0.77254902},
{0.60784314, 0.91764706},
{0.13333333, 0.90980392},
{0.0, 0.54509804},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0}}};
TArray<TArray<TArray<float>>> Squiggle = {{
{0.0,0.16078431}, // squiggle / item 26
{0.03137255, 0.10588235},
{0.08235294, 0.05490196},
{0.13333333, 0.05882353},
{0.23137255, 0.1254902 },
{0.27058824, 0.13333333},
{0.30588235, 0.11372549},
{0.36078431, 0.03921569},
{0.42745098, 0.01176471},
{0.50196078, 0.03921569},
{0.58431373, 0.12156863},
{0.62745098, 0.14117647},
{0.6745098, 0.11372549},
{0.72941176, 0.02352941},
{0.79215686, 0.0},
{0.91764706, 0.03921569},
{0.96470588, 0.08627451},
{1.0, 0.14901961},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0},
{0.0,0.0}}};
// 18: 'tornado'
TArray<TArray<TArray<float>>> Tornado = {{
{ 0.0, 0.0 },
{ 0.04313725, 0.02352941},
{ 0.20784314, 0.0627451 },
{ 0.54117647, 0.08235294},
{ 0.86666667, 0.0745098 },
{ 0.23137255, 0.11372549},
{ 0.08627451, 0.14901961},
{ 0.90980392, 0.15686275},
{ 0.78431373, 0.18431373},
{ 0.14509804, 0.21960784},
{ 0.19607843, 0.23921569},
{ 0.4, 0.27058824},
{ 0.91372549, 0.29411765},
{ 0.68627451, 0.31764706},
{ 0.19607843, 0.33333333},
{ 0.28235294, 0.35686275},
{ 0.76078431, 0.40784314},
{ 0.75294118, 0.41960784},
{ 0.70196078, 0.43137255},
{ 0.42745098, 0.44705882},
{ 0.5372549, 0.49803922},
{ 0.78431373, 0.54509804},
{ 0.50196078, 0.6 },
{ 0.53333333, 0.62745098},
{ 0.82745098, 0.7254902 },
{ 0.6, 0.76078431},
{ 0.61960784, 0.78039216},
{ 0.81568627, 0.80784314},
{ 0.60392157, 0.85490196},
{ 0.7372549, 0.92156863},
{ 0.67843137, 0.94901961},
{ 0.71372549, 0.95294118},
{ 0.66666667, 0.98039216},
{ 0.68627451, 1.0 },
{ 0.0, 0.0 },
{ 0.0, 0.0 },
{ 0.0, 0.0 },
{ 0.0, 0.0 },
{ 0.0, 0.0 },
{ 0.0, 0.0 }
}};
TWeakInterfacePtr<INNERuntimeCPU> Runtime = UE::NNE::GetRuntime<INNERuntimeCPU>(FString("NNERuntimeORTCpu"));
if (Runtime.IsValid())
{
TUniquePtr<UE::NNE::IModelCPU> Model = Runtime->CreateModel(PreLoadedModelData);
if (Model.IsValid())
{
TUniquePtr<UE::NNE::IModelInstanceCPU> ModelInstance = Model->CreateModelInstance();
if (ModelInstance.IsValid())
{
TConstArrayView<uint32> InputDims = { 1, 40, 2 };
TConstArrayView<uint32> OutputDims = { 29 };
TArray<UE::NNE::FTensorShape> InputTensorShapes = { UE::NNE::FTensorShape::Make(InputDims) };
ModelInstance->SetInputTensorShapes(InputTensorShapes);
TArray<UE::NNE::FTensorShape> OutputTensorShapes = { UE::NNE::FTensorShape::Make(OutputDims) };
TArray<TArray<TArray<float>>> InputData = Tornado;
TArray<float> OutputData;
TArray<UE::NNE::FTensorBindingCPU> InputBindings;
TArray<UE::NNE::FTensorBindingCPU> OutputBindings;
InputData.SetNumZeroed(InputTensorShapes[0].Volume());
InputBindings.SetNumZeroed(1);
InputBindings[0].Data = InputData.GetData();
InputBindings[0].SizeInBytes = InputData.Num() * sizeof(float);
OutputData.SetNumZeroed(OutputTensorShapes[0].Volume());
OutputBindings.SetNumZeroed(1);
OutputBindings[0].Data = OutputData.GetData();
OutputBindings[0].SizeInBytes = OutputData.Num() * sizeof(float);
if (ModelInstance->RunSync(InputBindings, OutputBindings) != 0) {
UE_LOG(LogTemp, Error, TEXT("Failed to run the model"));
}
float max = 0;
int j = 0;
for (int i=0; i < OutputData.Num(); i++){
UE_LOG(LogTemp, Warning, TEXT("%d"), i);
UE_LOG(LogTemp, Warning, TEXT("%f"), OutputData[i]);
if (max < OutputData[i]){
max = OutputData[i];
j = i;
}
}
UE_LOG(LogTemp, Warning, TEXT("Output: %f"), max);
UE_LOG(LogTemp, Warning, TEXT("Output: %d"), j);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create the model instance"));
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create the model"));
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Cannot find runtime NNERuntimeORTCpu, please enable the corresponding plugin"));
}