Using the thyroid-nodule classifier (tn_final.pt)

tn_final.pt is a trained deep-learning model that classifies a cropped thyroid-nodule B-mode ultrasound image as benign or malignant (architecture: ResNet-18, 2 classes). This note is everything you need to run it.

For research use; not a medical device and not for clinical decision-making.

Requirements

Python 3 with PyTorch, torchvision, timm, and Pillow:

pip install torch torchvision timm pillow

The model file

tn_final.pt is a PyTorch checkpoint (a torch.save dictionary). It holds the trained weights plus metadata (model_name, num_classes, class_names), so it is self-describing โ€” no separate config file is needed.

Load the model

import torch, timm
ck = torch.load("tn_final.pt", map_location="cpu", weights_only=False)
model = timm.create_model(ck["model_name"], num_classes=ck["num_classes"])
model.load_state_dict(ck["model_state_dict"])
model.eval()

(weights_only=False is required because the checkpoint stores metadata, not just tensors; PyTorch โ‰ฅ 2.6 defaults it to True.)

Preprocess and predict

Inputs must be preprocessed exactly as below โ€” this matches how the model was trained. Do not change the sizes or the normalization values.

from PIL import Image
from torchvision import transforms

eval_tf = transforms.Compose([
    transforms.Resize(256),          # shorter side -> 256 (bilinear)
    transforms.CenterCrop(224),
    transforms.ToTensor(),           # -> float [0,1], CHW
    transforms.Normalize([0.485, 0.456, 0.406],   # keep these values exactly
                         [0.229, 0.224, 0.225]),
])

img = Image.open("nodule.png").convert("RGB")     # RGB, even though ultrasound is grayscale
x = eval_tf(img).unsqueeze(0)                       # shape [1, 3, 224, 224]
with torch.no_grad():
    prob = model(x).softmax(1)[0]
print(f"benign {prob[0]:.3f}   malignant {prob[1]:.3f}")

Input-image requirements

  1. It must be a cropped nodule image, not a full ultrasound frame. The model was trained on the pre-cropped single-nodule images from the public TN5000 dataset on HuggingFace (Johnyquest7/TN5000-thyroid-nodule-classification) โ€” each a thyroid nodule plus a little surrounding context. Provide inputs of the same kind; if your data are full frames, crop to the nodule region so the framing resembles those images. See that dataset for the expected input format.
  2. RGB, 3 channels. .convert("RGB") replicates the grayscale channel to three. Do not feed a 1-channel image.
  3. Do not resize to 224 yourself. The transform (Resize(256) โ†’ CenterCrop(224)) does the sizing; feed the image at its native resolution.
  4. Use the exact Normalize values above.

Output

A 2-class softmax. Index 0 = benign, index 1 = malignant. Threshold the malignant probability at 0.5, or choose your own operating point.

The model expects cropped thyroid-nodule B-mode ultrasound like its training data; behavior on other image types is not characterized.

Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support