소스 정보
- 저장소
- tomevault-io/skills-registry
- 최근 소스 활동
- 2026년 5월 23일 22:30
- 감지된 SKILL.md 언어
- 영어
- 스타
- 0
- 포크
- 0
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/skills-registry --skill machine-learning명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | machine-learning |
| description | machine_learning skill Use when this capability is needed. |
| metadata | {"author":"brolag"} |
PathML provides comprehensive machine learning capabilities for computational pathology, including pre-built models for nucleus detection and segmentation, PyTorch-integrated training workflows, public dataset access, and ONNX-based inference deployment. The framework seamlessly bridges image preprocessing with deep learning to enable end-to-end pathology ML pipelines.
PathML includes state-of-the-art pre-trained models for nucleus analysis:
HoVer-Net (Horizontal and Vertical Network) performs simultaneous nucleus instance segmentation and classification.
Architecture:
Nucleus types:
Usage:
from pathml.ml import HoVerNet
import torch
# Load pre-trained model
model = HoVerNet(
num_types=5, # Number of nucleus types
mode='fast', # 'fast' or 'original'
pretrained=True # Load pre-trained weights
)
# Move to GPU if available
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = model.to(device)
# Inference on tile
tile_image = torch.from_numpy(tile.image).permute(2, 0, 1).unsqueeze(0).float()
tile_image = tile_image.to(device)
with torch.no_grad():
output = model(tile_image)
# Output contains:
# - output['np']: Nuclear pixel predictions
# - output['hv']: Horizontal-vertical maps
# - output['nc']: Classification predictions
Post-processing:
from pathml.ml import hovernet_postprocess
# Convert model outputs to instance segmentation
instance_map, type_map = hovernet_postprocess(
np_pred=output['np'],
hv_pred=output['hv'],
nc_pred=output['nc']
)
# instance_map: Each nucleus has unique ID
# type_map: Each nucleus assigned a type (1-5)
HACTNet (Hierarchical Cell-Type Network) performs hierarchical nucleus classification with uncertainty quantification.
Features:
from pathml.ml import HACTNet
# Load model
model = HACTNet(
num_classes_coarse=3,
num_classes_fine=8,
pretrained=True
)
# Inference
output = model(tile_image)
coarse_pred = output['coarse'] # Broad categories
fine_pred = output['fine'] # Specific cell types
uncertainty = output['uncertainty'] # Prediction confidence
PathML provides PyTorch-compatible dataset classes:
TileDataset:
from pathml.ml import TileDataset
from pathml.core import SlideDataset
# Create dataset from processed slides
tile_dataset = TileDataset(
slide_dataset,
tile_size=256,
transform=None # Optional augmentation transforms
)
# Access tiles
image, label = tile_dataset[0]
DataModule Integration:
from pathml.ml import PathMLDataModule
# Create train/val/test splits
data_module = PathMLDataModule(
train_dataset=train_tile_dataset,
val_dataset=val_tile_dataset,
test_dataset=test_tile_dataset,
batch_size=32,
num_workers=4
)
# Use with PyTorch Lightning
trainer = pl.Trainer(max_epochs=100)
trainer.fit(model, data_module)
Complete workflow for training HoVer-Net on custom data:
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
from pathml.ml import HoVerNet
from pathml.ml.datasets import PanNukeDataModule
# 1. Prepare data
data_module = PanNukeDataModule(
data_dir='path/to/pannuke',
batch_size=8,
num_workers=4,
tissue_types=['Breast', 'Colon'] # Specific tissue types
)
# 2. Initialize model
model = HoVerNet(
num_types=5,
mode='fast',
pretrained=False # Train from scratch or use pretrained=True for fine-tuning
)
# 3. Define loss function
class HoVerNetLoss(nn.Module):
def __init__(self):
super().__init__()
self.mse_loss = nn.MSELoss()
self.bce_loss = nn.BCEWithLogitsLoss()
self.ce_loss = nn.CrossEntropyLoss()
def forward(self, output, target):
# Nuclear pixel branch loss
np_loss = self.bce_loss(output['np'], target['np'])
# Horizontal-vertical branch loss
hv_loss = self.mse_loss(output['hv'], target['hv'])
# Classification branch loss
nc_loss = .ce_loss(output[], target[])
total_loss = np_loss + hv_loss + * nc_loss
total_loss, {: np_loss, : hv_loss, : nc_loss}
criterion = HoVerNetLoss()
optimizer = torch.optim.Adam(
model.parameters(),
lr=,
weight_decay=
)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
optimizer,
mode=,
factor=,
patience=
)
device = torch.device( torch.cuda.is_available() )
model = model.to(device)
num_epochs =
epoch (num_epochs):
model.train()
train_loss =
batch data_module.train_dataloader():
images = batch[].to(device)
targets = {
: batch[].to(device),
: batch[].to(device),
: batch[].to(device)
}
optimizer.zero_grad()
outputs = model(images)
loss, loss_dict = criterion(outputs, targets)
loss.backward()
optimizer.step()
train_loss += loss.item()
model.()
val_loss =
torch.no_grad():
batch data_module.val_dataloader():
images = batch[].to(device)
targets = {
: batch[].to(device),
: batch[].to(device),
: batch[].to(device)
}
outputs = model(images)
loss, _ = criterion(outputs, targets)
val_loss += loss.item()
scheduler.step(val_loss)
()
()
()
(epoch + ) % == :
torch.save({
: epoch,
: model.state_dict(),
: optimizer.state_dict(),
: val_loss,
}, )
PathML models integrate with PyTorch Lightning for streamlined training:
import pytorch_lightning as pl
from pathml.ml import HoVerNet
from pathml.ml.datasets import PanNukeDataModule
class HoVerNetModule(pl.LightningModule):
def __init__(self, num_types=5, lr=1e-4):
super().__init__()
self.model = HoVerNet(num_types=num_types, pretrained=True)
self.lr = lr
self.criterion = HoVerNetLoss()
def forward(self, x):
return self.model(x)
def training_step(self, batch, batch_idx):
images = batch['image']
targets = {
'np': batch['np_map'],
'hv': batch['hv_map'],
'nc': batch['type_map']
}
outputs = self(images)
loss, loss_dict = self.criterion(outputs, targets)
# Log metrics
self.log('train_loss', loss, prog_bar=True)
for key, val in loss_dict.items():
self.log(f'train_{key}_loss', val)
return loss
():
images = batch[]
targets = {
: batch[],
: batch[],
: batch[]
}
outputs = (images)
loss, loss_dict = .criterion(outputs, targets)
.log(, loss, prog_bar=)
key, val loss_dict.items():
.log(, val)
loss
():
optimizer = torch.optim.Adam(.parameters(), lr=.lr)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
optimizer, mode=, factor=, patience=
)
{
: optimizer,
: {
: scheduler,
:
}
}
data_module = PanNukeDataModule(data_dir=, batch_size=)
model = HoVerNetModule(num_types=, lr=)
trainer = pl.Trainer(
max_epochs=,
accelerator=,
devices=,
callbacks=[
pl.callbacks.ModelCheckpoint(monitor=, mode=),
pl.callbacks.EarlyStopping(monitor=, patience=)
]
)
trainer.fit(model, data_module)
PathML provides convenient access to public pathology datasets:
PanNuke contains 7,901 histology image patches from 19 tissue types with nucleus annotations for 5 cell types.
from pathml.ml.datasets import PanNukeDataModule
# Load PanNuke dataset
pannuke = PanNukeDataModule(
data_dir='path/to/pannuke',
batch_size=16,
num_workers=4,
tissue_types=None, # Use all tissue types, or specify list
fold='all' # 'fold1', 'fold2', 'fold3', or 'all'
)
# Access dataloaders
train_loader = pannuke.train_dataloader()
val_loader = pannuke.val_dataloader()
test_loader = pannuke.test_dataloader()
# Batch structure
for batch in train_loader:
images = batch['image'] # Shape: (B, 3, 256, 256)
inst_map = batch['inst_map'] # Instance segmentation map
type_map = batch['type_map'] # Cell type map
np_map = batch['np_map'] # Nuclear pixel map
hv_map = batch['hv_map'] # Horizontal-vertical distance maps
tissue_type = batch['tissue_type'] # Tissue category
Tissue types available: Breast, Colon, Prostate, Lung, Kidney, Stomach, Bladder, Esophagus, Cervix, Liver, Thyroid, Head & Neck, Testis, Adrenal, Pancreas, Bile Duct, Ovary, Skin, Uterus
Access The Cancer Genome Atlas datasets:
from pathml.ml.datasets import TCGADataModule
# Load TCGA dataset
tcga = TCGADataModule(
data_dir='path/to/tcga',
cancer_type='BRCA', # Breast cancer
batch_size=32,
tile_size=224
)
Create custom datasets for PathML workflows:
from torch.utils.data import Dataset
import numpy as np
from pathlib import Path
class CustomPathologyDataset(Dataset):
def __init__(self, data_dir, transform=None):
self.data_dir = Path(data_dir)
self.image_paths = list(self.data_dir.glob('images/*.png'))
self.transform = transform
def __len__(self):
return len(self.image_paths)
def __getitem__(self, idx):
# Load image
image_path = self.image_paths[idx]
image = np.array(Image.open(image_path))
# Load corresponding annotation
annot_path = self.data_dir / 'annotations' / f'{image_path.stem}.npy'
annotation = np.load(annot_path)
# Apply transforms
if self.transform:
image = self.transform(image)
return {
'image': torch.from_numpy(image).permute(2, 0, 1).(),
: torch.from_numpy(annotation).long(),
: (image_path)
}
dataset = CustomPathologyDataset()
dataloader = DataLoader(dataset, batch_size=, shuffle=, num_workers=)
Apply augmentations to improve model generalization:
import albumentations as A
from albumentations.pytorch import ToTensorV2
# Define augmentation pipeline
train_transform = A.Compose([
A.RandomRotate90(p=0.5),
A.Flip(p=0.5),
A.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1, p=0.5),
A.GaussianBlur(blur_limit=(3, 7), p=0.3),
A.ElasticTransform(alpha=1, sigma=50, alpha_affine=50, p=0.3),
A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
ToTensorV2()
])
val_transform = A.Compose([
A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
ToTensorV2()
])
# Apply to dataset
train_dataset = TileDataset(slide_dataset, transform=train_transform)
val_dataset = TileDataset(val_slide_dataset, transform=val_transform)
Evaluate model performance with pathology-specific metrics:
from pathml.ml.metrics import (
dice_coefficient,
aggregated_jaccard_index,
panoptic_quality
)
# Dice coefficient for segmentation
dice = dice_coefficient(pred_mask, true_mask)
# Aggregated Jaccard Index (AJI) for instance segmentation
aji = aggregated_jaccard_index(pred_inst, true_inst)
# Panoptic Quality (PQ) for joint segmentation and classification
pq, sq, rq = panoptic_quality(pred_inst, true_inst, pred_types, true_types)
print(f"Dice: {dice:.4f}")
print(f"AJI: {aji:.4f}")
print(f"PQ: {pq:.4f}, SQ: {sq:.4f}, RQ: {rq:.4f}")
from pathml.ml.metrics import evaluate_hovernet
# Comprehensive HoVer-Net evaluation
model.eval()
all_preds = []
all_targets = []
with torch.no_grad():
for batch in test_loader:
images = batch['image'].to(device)
outputs = model(images)
# Post-process predictions
for i in range(len(images)):
inst_pred, type_pred = hovernet_postprocess(
outputs['np'][i],
outputs['hv'][i],
outputs['nc'][i]
)
all_preds.append({'inst': inst_pred, 'type': type_pred})
all_targets.append({
'inst': batch['inst_map'][i],
'type': batch['type_map'][i]
})
# Compute metrics
results = evaluate_hovernet(all_preds, all_targets)
print(f"Detection F1: {results['detection_f1']:.4f}")
print(f"Classification Accuracy: {results['classification_acc']:.4f}")
print(f"Panoptic Quality: {results['pq']:.4f}")
Deploy models using ONNX for production inference:
import torch
from pathml.ml import HoVerNet
# Load trained model
model = HoVerNet(num_types=5, pretrained=True)
model.eval()
# Create dummy input
dummy_input = torch.randn(1, 3, 256, 256)
# Export to ONNX
torch.onnx.export(
model,
dummy_input,
'hovernet_model.onnx',
export_params=True,
opset_version=11,
input_names=['input'],
output_names=['np_output', 'hv_output', 'nc_output'],
dynamic_axes={
'input': {0: 'batch_size'},
'np_output': {0: 'batch_size'},
'hv_output': {0: 'batch_size'},
'nc_output': {0: 'batch_size'}
}
)
import onnxruntime as ort
import numpy as np
# Load ONNX model
session = ort.InferenceSession('hovernet_model.onnx')
# Prepare input
input_name = session.get_inputs()[0].name
tile_image = preprocess_tile(tile) # Normalize, transpose to (1, 3, H, W)
# Run inference
outputs = session.run(None, {input_name: tile_image})
np_output, hv_output, nc_output = outputs
# Post-process
inst_map, type_map = hovernet_postprocess(np_output, hv_output, nc_output)
from pathml.core import SlideData
from pathml.preprocessing import Pipeline
import onnxruntime as ort
def run_onnx_inference_pipeline(slide_path, onnx_model_path):
# Load slide
wsi = SlideData.from_slide(slide_path)
wsi.generate_tiles(level=1, tile_size=256, stride=256)
# Load ONNX model
session = ort.InferenceSession(onnx_model_path)
input_name = session.get_inputs()[0].name
# Inference on all tiles
results = []
for tile in wsi.tiles:
# Preprocess
tile_array = preprocess_tile(tile.image)
# Inference
outputs = session.run(None, {input_name: tile_array})
# Post-process
inst_map, type_map = hovernet_postprocess(*outputs)
results.append({
'coords': tile.coords,
'instance_map': inst_map,
'type_map': type_map
})
return results
# Run on slide
results = run_onnx_inference_pipeline('slide.svs', 'hovernet_model.onnx')
Fine-tune pre-trained models on custom datasets:
from pathml.ml import HoVerNet
# Load pre-trained model
model = HoVerNet(num_types=5, pretrained=True)
# Freeze encoder layers for initial training
for name, param in model.named_parameters():
if 'encoder' in name:
param.requires_grad = False
# Fine-tune only decoder and classification heads
optimizer = torch.optim.Adam(
filter(lambda p: p.requires_grad, model.parameters()),
lr=1e-4
)
# Train for a few epochs
train_for_n_epochs(model, train_loader, optimizer, num_epochs=10)
# Unfreeze all layers for full fine-tuning
for param in model.parameters():
param.requires_grad = True
# Continue training with lower learning rate
optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)
train_for_n_epochs(model, train_loader, optimizer, num_epochs=50)
Use pre-trained models when available:
Apply appropriate data augmentation:
Monitor multiple metrics:
Handle class imbalance:
Validate on diverse tissue types:
Optimize for inference:
Save checkpoints regularly:
Issue: Poor segmentation at nucleus boundaries
Issue: Misclassification of similar cell types
Issue: Training unstable or not converging
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)Issue: Out of memory during training
torch.cuda.ampIssue: Model overfits to training data
Invoke this skill with:
$machine_learning [arguments]
Or let Codex auto-select based on your prompt.
Source: brolag/claude-code-templates — distributed by TomeVault.