Using a FastAI resnet18 model with ONNX

Hello,

I’m fairly new to deep learning and I’ve managed to train a resnet18 model with FastAI for multilabel prediction.

learn = cnn_learner(dls, resnet18, metrics=partial(accuracy_multi, thresh=0.2))

Next, I exported the model to Torch:

torch.save(learn.model, "resnet18_5_epochs.pth")

And then I converted it to ONNX:

import torch

model_path = "resnet18_5_epochs.pth"

model = torch.load(model_path)
model.eval()

dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(model, dummy_input, "resnet18_5_epochs.onnx", export_params=True)

Then I queried the ONNX model:

import onnxruntime as ort

ort_sess = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider'])

# transform image to tensor
import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(
       mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225]
    )
])

from PIL import Image

img = Image.open("12.jpg")
x = transform(img)
x = x.unsqueeze(0)  # add batch dimension

# run model
outputs = ort_sess.run(None, {'input.1': x.numpy()})

I am stuck in interpreting the output of the model. I’ve tried using a softmax function but I got the wrong classes.
For example, the top class is wrong:

top = np.argmax(outputs)
print(categories[top])

I have no clue what the cause of my problem is and why the ONNX model outputs the predictions wrong. The predictions are right when I query the model with FastAI.

I’ve also used the following code to export the output categories from the FastAI model. And tried to use the Pytorch model but I still get wrong classes.

categories = dls.vocab
with open("categories.txt", "w") as f:
    for category in categories:
        f.write(category + "\n")

Has anyone encountered a similar issue and managed to solve it?

Thank you!

I’ve managed to get the model running.

import onnxruntime as ort

model_path = "models/resnet18_5_epochs.onnx"
ort_sess = ort.InferenceSession(model_path, providers=['CUDAExecutionProvider'])

# load model categories
categories_path = "models/categories.txt"

with open(categories_path, "r") as f:
    categories = [s.strip() for s in f.readlines()]

# transform image to tensor
import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(
       mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225]
    )
])

from PIL import Image

img = Image.open("Downloads/1.jpg")
x = transform(img)
x = x.unsqueeze(0)  # add batch dimension

# run model
outputs = ort_sess.run(None, {'input.1': x.numpy()})

# get top prediction
import numpy as np

top = np.argmax(outputs)
print(categories[top])

# get top 5 predictions -- sorted from highest to lowest
sorted_predictions = np.argsort(outputs)[0][0][::-1]

for prediction in sorted_predictions:
    value = outputs[0][0][prediction]
    if value < -0.5:
        break
    print(categories[prediction], value)
1 Like