Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Fine-tuning Cellpose-SAM

Same task and same data as 01_training_instance_segmentation.ipynb. There we trained a U-Net from scratch. Here we start from Cellpose-SAM, which already is trained on a cell or nucleus looks like, and only finetune it towards our nuclei-from-actin task. That usually needs far fewer images.

Run 01_training_instance_segmentation.ipynb up to the end of section 2 first (or python organize_data.py): this notebook uses the same dataset/ split.

Kernel: the Cellpose kernel on Research Cloud, nlbi26-day3-cellpose on your own laptop.

creating new log file
[GUI INFO] : WRITING LOG OUTPUT TO /home/mpaul2/.cellpose/run.log

cellpose version: 	4.2.1.1 
platform:       	linux 
python version: 	3.11.15 
torch version:  	2.12.1+cu130
2026-09-17 23:21:17,409 [io INFO] WRITING LOG OUTPUT TO /home/mpaul2/.cellpose/run.log
2026-09-17 23:21:17,409 [io INFO] 
cellpose version: 	4.2.1.1 
platform:       	linux 
python version: 	3.11.15 
torch version:  	2.12.1+cu130
(<Logger cellpose (DEBUG)>, PosixPath('/home/mpaul2/.cellpose/run.log'))
78 train, 20 test

1. Cellpose out of the box

Before fine-tuning, see what the pretrained model already does. Cellpose-SAM needs no model_type, no channels and no diameter — it works those out itself.

2026-09-17 23:21:27,225 [core INFO] ** TORCH CUDA version installed and working. **
2026-09-17 23:21:27,226 [core INFO] >>>> using GPU (CUDA)
2026-09-17 23:21:27,227 [models INFO] Downloading: "https://huggingface.co/mouseland/cellpose-sam/resolve/main/cpsam_v2" to /home/mpaul2/.cellpose/models/cpsam_v2

100%|██████████| 1.15G/1.15G [00:14<00:00, 82.6MB/s]   
2026-09-17 23:21:44,420 [models INFO] >>>> loading model /home/mpaul2/.cellpose/models/cpsam_v2
2026-09-17 23:21:44,987 [utils INFO] 0%|          | 0/20 [00:00<?, ?it/s]
/opt/AI_tools_pixi/cellpose/.pixi/envs/default/lib/python3.11/site-packages/cellpose/dynamics.py:541: UserWarning: Sparse invariant checks are implicitly disabled. Memory errors (e.g. SEGFAULT) will occur when operating on a sparse tensor which violates the invariants, but checks incur performance overhead. To silence this warning, explicitly opt in or out. See `torch.sparse.check_sparse_tensor_invariants.__doc__` for guidance.  (Triggered internally at /pytorch/aten/src/ATen/Context.cpp:760.)
  coo = torch.sparse_coo_tensor(pt, torch.ones(pt.shape[1], device=pt.device, dtype=torch.int),
2026-09-17 23:21:58,612 [utils INFO] 100%|##########| 20/20 [00:13<00:00,  1.47it/s]
found [np.uint16(135), np.uint16(138), np.uint16(122), np.uint16(4), np.uint16(35)] ...
labels [np.uint16(137), np.uint16(135), np.uint16(107), np.uint16(2), np.uint16(35)] ...

Score it. average_precision gives us TP, FP and FN per image at each IoU threshold, and precision, recall and F1 follow from those three — the same numbers as in 01.

TP 2.300000 FP 103.000000 FN 95.199997 precision 0.020000 recall 0.020000 F1 0.020000 dtype: float32

2. Fine-tune it

One call. The settings below are the ones the Cellpose docs recommend for fine-tuning; the only one we lowered is n_epochs, so it finishes inside the session.

2026-09-17 23:22:57,115 [core INFO] ** TORCH CUDA version installed and working. **
2026-09-17 23:22:57,115 [core INFO] >>>> using GPU (CUDA)
2026-09-17 23:22:58,740 [models INFO] >>>> loading model /home/mpaul2/.cellpose/models/cpsam_v2
2026-09-17 23:22:59,112 [train INFO] >>> converting bfloat16 network to float32 for training
2026-09-17 23:22:59,118 [dynamics INFO] computing flows for labels
100%|██████████| 78/78 [00:02<00:00, 34.09it/s]
2026-09-17 23:23:01,455 [dynamics INFO] computing flows for labels

100%|██████████| 20/20 [00:00<00:00, 36.85it/s]
2026-09-17 23:23:02,011 [train INFO] >>> computing diameters

100%|██████████| 78/78 [00:00<00:00, 869.59it/s]
100%|██████████| 20/20 [00:00<00:00, 864.54it/s]
2026-09-17 23:23:02,127 [train INFO] >>> normalizing {'lowhigh': None, 'percentile': None, 'normalize': True, 'norm3D': True, 'sharpen_radius': 0, 'smooth_radius': 0, 'tile_norm_blocksize': 0, 'tile_norm_smooth3D': 1, 'invert': False}

2026-09-17 23:23:02,671 [train INFO] >>> n_epochs=20, n_train=78, n_test=20, bsize=256, batch_size=1, nimg_per_epoch=78
2026-09-17 23:23:02,671 [train INFO] >>> AdamW, learning_rate=0.00001, weight_decay=0.10000
2026-09-17 23:23:02,673 [train INFO] >>> saving model to cellpose_output/models/nuclei_from_phalloidin
2026-09-17 23:23:22,243 [train INFO] 0, train_loss=6.2226, test_loss=5.6097, LR=0.000000, time 19.57s
2026-09-17 23:24:53,307 [train INFO] 5, train_loss=1.1026, test_loss=0.3278, LR=0.000006, time 110.63s
2026-09-17 23:26:24,711 [train INFO] 10, train_loss=0.3824, test_loss=0.2842, LR=0.000010, time 202.04s
2026-09-17 23:29:07,513 [train INFO] saving network parameters to cellpose_output/models/nuclei_from_phalloidin
2026-09-17 23:29:11,670 [train INFO] >>> converting network back to torch.bfloat16 after training
saved to cellpose_output/models/nuclei_from_phalloidin
<Figure size 640x480 with 1 Axes>

3. Score it again

2026-09-17 23:29:11,816 [core INFO] ** TORCH CUDA version installed and working. **
2026-09-17 23:29:11,817 [core INFO] >>>> using GPU (CUDA)
2026-09-17 23:29:13,265 [models INFO] >>>> loading model cellpose_output/models/nuclei_from_phalloidin
2026-09-17 23:29:13,636 [utils INFO] 0%|          | 0/20 [00:00<?, ?it/s]
2026-09-17 23:29:22,703 [utils INFO] 100%|##########| 20/20 [00:09<00:00,  2.21it/s]
Loading...
<Figure size 2000x500 with 4 Axes>

The pretrained model was never asked to find nuclei in an actin image. The fine-tuned one has seen our training images. Where does it still get it wrong?

If you have time

  • Try to train longer for n_epochs=100

  • Fine-tune on 10 images instead of all (train_images[:10], train_labels[:10]). This is the argument for fine-tuning: how far down can you go before the score drops?