How to create an image classifier using transfer learning in Azure ML
This tutorial shows how to create an image classifier using transfer learning in Azure AI & Machine Learning, useful to speed up training with few images and obtain a model ready for inference. It explains the reasoning behind the choices and provides a practical step-by-step to train and deploy using a compute instance/cluster.
Prerequisites
- Azure account with an active subscription and permissions to create resources.
- Azure Machine Learning workspace created.
- Images organized in folders by class (e.g.: data/train/<class>).
- Azure CLI and Azure ML SDK for Python installed (or use Azure ML Studio).
- Basic knowledge of Python and terminal commands.
Step 1: Why use transfer learning
Transfer learning allows you to leverage pretrained networks (e.g.: ResNet, EfficientNet) for specific tasks with less data and shorter training time. In Azure ML, this integrates well with compute and pipelines, and reduces overfitting when you have few images.
Step 2: Prepare the environment and data in the Workspace
Create a compute resource (Compute Instance for development, Compute Cluster for training) and register the data in the Workspace datastore. Organize the images into train/val/test.
# Exemplo mínimo para registar dados no Workspace via Python
from azureml.core import Workspace, Dataset
ws = Workspace.from_config()
datastore = ws.get_default_datastore()
# Carrega uma pasta local para o datastore
datastore.upload(src_dir='data', target_path='image-data', overwrite=True)
# Regista como Dataset
dataset = Dataset.File.from_files(path=(datastore, 'image-data/'))
Step 3: Write the training script with transfer learning
Create a file train.py that uses PyTorch or TensorFlow. Here is a minimal example with PyTorch and a pretrained backbone (ResNet18). The script loads the images, replaces the final head and trains only the final weights.
# train.py (resumo mínimo)
import argparse
from torchvision import models, transforms, datasets
import torch, torch.nn as nn, torch.optim as optim
def main(args):
transform = transforms.Compose([transforms.Resize((224,224)), transforms.ToTensor()])
train_ds = datasets.ImageFolder(args.train_dir, transform=transform)
train_loader = torch.utils.data.DataLoader(train_ds, batch_size=16, shuffle=True)
model = models.resnet18(pretrained=True)
for param in model.parameters():
param.requires_grad = False
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, args.num_classes)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.fc.parameters(), lr=1e-3)
model.train()
for epoch in range(args.epochs):
for imgs, labels in train_loader:
imgs, labels = imgs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(imgs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# Guarda o modelo
torch.save(model.state_dict(), args.output_model)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--train_dir')
parser.add_argument('--num_classes', type=int)
parser.add_argument('--epochs', type=int, default=3)
parser.add_argument('--output_model', default='model.pth')
args = parser.parse_args()
main(args)
Step 4: Create an Experiment and submit the training to Azure ML
Package the script into an Estimator/ScriptRunConfig and submit it to the compute. This allows you to control the environment, dependencies and logs.
# submit_job.py (resumo usando Azure ML SDK v1)
from azureml.core import Workspace, Experiment, Environment, ScriptRunConfig
ws = Workspace.from_config()
exp = Experiment(ws, 'transfer-learning-images')
env = Environment.from_conda_specification(name='env-tl', file_path='conda_dependencies.yml')
src = ScriptRunConfig(source_directory='.', script='train.py', arguments=['--train_dir','/mnt/data/train','--num_classes', '3','--epochs','5'], compute_target='cpu-cluster', environment=env)
run = exp.submit(src)
run.wait_for_completion(show_output=True)
Step 5: Register and deploy the model
After training, register the model in the Workspace and create an image/container for inference or use an Azure ML endpoint for deployment.
# registar_model.py
from azureml.core import Workspace, Model
ws = Workspace.from_config()
model = Model.register(ws, model_path='model.pth', model_name='resnet_transfer')
# Para um deploy rápido podes usar os endpoints online do Azure ML (ex.: ACI) via SDK/Studio
Verify the result
Perform a test inference by loading the registered model in an environment similar to production. Confirm that the predictions make sense and that accuracy on validation data is acceptable. Check the run logs and metrics in Studio for common errors: missing GPU, incorrect paths, version incompatibilities.
Conclusion
You completed a full flow: prepare data, write a transfer learning script, submit training in Azure ML and register the model for deployment. Next steps: try different backbones (EfficientNet), tune the learning rate and layer freezing, and create an endpoint for production inference. Tip: start by training for few epochs and validate frequently to avoid overfitting — which class is hardest for you to distinguish?