Machine Learning Academy · Pelajaran

Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad

Pelajar akan menggunakan pembelajaran pindahan daripada ImageNet kepada set data sinar-X dada, melaksanakan kehilangan berwajaran kelas untuk patologi tidak seimbang, dan menilai AUC-ROC.

Pelajaran 4 daripada 412 langkah

Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad ialah pelajaran Machine Learning Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Machine Learning Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.

Cabaran Pengimejan Perubatan

Pengimejan perubatan menghadirkan cabaran pembelajaran pemindahan yang unik. Tidak seperti foto semula jadi, sinar-X dada, imbasan MRI dan slaid histologi kelihatan sama sekali berbeza daripada imej ImageNet: imej tersebut berwarna kelabu atau mempunyai corak warna khusus domain, ciri yang penting (lesi, nodul dan kalsifikasi) adalah halus serta khusus domain, dan data berlabel memerlukan pakar radiologi — menyebabkan set data berlabel yang besar mahal dan sukar diperoleh.

Walaupun menghadapi cabaran ini, model terlatih awal ImageNet secara konsisten mengatasi latihan dari awal dalam tugasan pengimejan perubatan, walaupun rupa visualnya berbeza dengan ketara. Ciri peringkat rendah sejagat (pengesan tepi dan penapis tekstur) boleh dipindahkan merentas domain, lalu menyediakan pemulaan yang kukuh untuk mempercepat penumpuan dan meningkatkan keupayaan generalisasi apabila label terhad.

Set Data CheXpert: Pengelasan Sinar-X Berbilang Label

CheXpert ialah set data penanda aras sinar-X dada dengan 224,316 imej dan 14 label (Kardiomegali, Efusi Pleura, Pneumonia, Atelektasis dan sebagainya). Dalam senario label terhad kita, kita mensimulasikan penggunaan sebahagian kecil sahaja — katakan 1% (kira-kira 2,243 imej) — untuk meniru keadaan klinikal sebenar apabila belanjawan anotasi terhad.

Ini ialah masalah pengelasan berbilang label: setiap imej boleh mempunyai beberapa patologi serentak, tidak seperti pengelasan label tunggal. Sasaran ialah vektor yang mengandungi 14 nilai binari, dan kita menggunakan Entropi Silang Binari dengan Logit (BCE) yang digunakan pada setiap elemen. Penilaian menggunakan AUC-ROC bagi setiap patologi, kemudian dipuratakan merentas kesemua 14 label.

# Dataset setup (pseudo-code for illustration)
import torch
from torch.utils.data import Dataset
from PIL import Image
import pandas as pd

class CheXpertDataset(Dataset):
    def __init__(self, csv_path, img_dir, transform=None):
        self.df = pd.read_csv(csv_path)
        self.img_dir = img_dir
        self.transform = transform
        self.labels = ['Atelectasis', 'Cardiomegaly',
                       'Consolidation', 'Edema', 'Pleural Effusion']

    def __len__(self):
        return len(self.df)

    def __getitem__(self, idx):
        img_path = self.df.iloc[idx]['Path']
        img = Image.open(img_path).convert('RGB')  # Convert grayscale to 3-ch
        label = torch.tensor(self.df.iloc[idx][self.labels].values.astype(float))
        if self.transform:
            img = self.transform(img)
        return img, label

Menukar Skala Kelabu kepada RGB untuk Model Terlatih Awal

Kebanyakan imej perubatan (sinar-X dan imbasan CT) ialah skala kelabu (1 saluran), tetapi model terlatih awal ImageNet menjangkakan input RGB 3 saluran. Penyelesaian paling mudah ialah Image.convert('RGB'), yang menggandakan saluran tunggal itu sebanyak tiga kali, atau transforms.Grayscale(num_output_channels=3) dalam saluran paip transformasi.

Kaedah ini sedikit membazir — ketiga-tiga saluran adalah serupa — tetapi dalam amalan ia berfungsi dengan baik kerana model hanya belajar memberikan wajaran yang sama kepada ketiga-tiga saluran. Alternatifnya ialah menggantikan lapisan konvolusi pertama dengan Conv2d(1, 64, kernel_size=7, ...) yang baharu dan memulakannya dengan mempuratakan wajaran tiga saluran input. Kaedah ini lebih berprinsip, tetapi menambah kerumitan latihan.

from torchvision import transforms

# Method 1: Replicate channel at loading time (simplest)
# img = Image.open(path).convert('RGB')

# Method 2: Use transforms
medical_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.Grayscale(num_output_channels=3),  # 1 -> 3 channels
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],
                         std=[0.229, 0.224, 0.225])
])

# Method 3: Modify first conv layer for single-channel input
import torchvision.models as models
model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)
# Average the 3-channel weights into 1 channel
w = model.conv1.weight.mean(dim=1, keepdim=True)
model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3, bias=False)
model.conv1.weight.data = w

Ralat Berbilang Label: BCE dengan Logit

Untuk pengelasan berbilang label, setiap label ialah ramalan binari yang bebas. Kita menggunakan nn.BCEWithLogitsLoss() pada vektor yang mengandungi 14 logit. Ralat dikira pada setiap elemen dan dipuratakan merentas 14 kelas serta saiz kelompok.

Label tidak seimbang ialah cabaran utama dalam pengimejan perubatan: hanya 5–10% imej mempunyai Pneumonia atau Konsolidasi, manakala 40–60% mempunyai Efusi Pleura. Hantar pos_weight kepada BCEWithLogitsLoss untuk meningkatkan wajaran kelas positif yang jarang berlaku: nilai pos_weight sebanyak 10 menyebabkan model memberikan perhatian 10× lebih kepada contoh positif patologi tersebut.

import torch
import torch.nn as nn

# Multi-label BCE loss
criterion = nn.BCEWithLogitsLoss()

# With class weighting for imbalanced pathologies
# Compute pos_weight from training data frequencies
pos_counts = train_labels.sum(dim=0)  # Positives per class
neg_counts = len(train_labels) - pos_counts
pos_weight = (neg_counts / pos_counts.clamp(min=1)).clamp(max=20)  # Cap at 20

criterion = nn.BCEWithLogitsLoss(pos_weight=pos_weight)

print('pos_weight per label:', pos_weight)
# High values mean that class is rare and needs more emphasis

Seni Bina Model untuk Output Berbilang Label

Gantikan kepala pengelasan ResNet-50 dengan lapisan linear yang menghasilkan 14 logit (satu bagi setiap patologi), bukannya 1000 seperti lalai untuk ImageNet. Kita tidak menggunakan sigmoid dalam hantaran ke hadapan — BCEWithLogitsLoss menggunakannya secara dalaman untuk kestabilan berangka. Pada masa inferens, gunakan sigmoid secara manual untuk mendapatkan kebarangkalian.

Menambah lapisan dropout sebelum lapisan linear terakhir amat penting apabila data terhad, kerana pengregularan menghalang kepala model yang kecil daripada terlebih suai. Kebarangkalian dropout sebanyak 0.3–0.5 ialah nilai biasa untuk penalaan halus pengimejan perubatan.

import torchvision.models as models
import torch.nn as nn

NUM_CLASSES = 14  # One per CheXpert pathology label

model = models.resnet50(weights=models.ResNet50_Weights.IMAGENET1K_V1)

# Replace with multi-label head
model.fc = nn.Sequential(
    nn.Dropout(p=0.4),
    nn.Linear(model.fc.in_features, NUM_CLASSES)
)
# No sigmoid here - BCEWithLogitsLoss handles it internally

print('Model output shape for batch of 16:',
      model(torch.randn(16, 3, 224, 224)).shape)  # (16, 14)

AUC-ROC: Metrik yang Tepat untuk Tugasan Perubatan

Ketepatan tidak berguna untuk set data perubatan yang tidak seimbang. Jika hanya 5% pesakit menghidap Pneumonia, model yang sentiasa meramalkan 'tiada pneumonia' mencapai ketepatan 95% tetapi langsung tidak berguna secara klinikal. AUC-ROC (Luas Di Bawah Lengkung ROC) mengukur keupayaan membezakan merentas semua ambang.

Kita mengira AUC-ROC secara berasingan bagi setiap satu daripada 14 patologi dan melaporkan purata AUC merentas semua label. AUC 0.5 ialah kebarangkalian rawak; 0.7 boleh diterima; 0.85+ bertaraf klinikal; 0.9+ sering menghampiri prestasi peringkat radiologi. roc_auc_score daripada scikit-learn mengira nilai ini dengan cekap.

import numpy as np
from sklearn.metrics import roc_auc_score
import torch

def evaluate_auc(model, loader, device):
    model.eval()
    all_logits, all_labels = [], []
    with torch.no_grad():
        for images, labels in loader:
            logits = model(images.to(device))
            all_logits.append(torch.sigmoid(logits).cpu().numpy())
            all_labels.append(labels.numpy())
    probs = np.vstack(all_logits)    # (N, 14)
    targets = np.vstack(all_labels)  # (N, 14)
    # AUC per class, then average
    aucs = [roc_auc_score(targets[:, i], probs[:, i])
            for i in range(targets.shape[1])]
    return np.mean(aucs), aucs

Latihan dengan Label Terhad: Teknik Utama

Apabila anda hanya mempunyai ratusan atau beberapa ribu imej perubatan berlabel, beberapa teknik dapat membantu memanfaatkan data yang tersedia sepenuhnya. Pertambahan data yang kuat ialah perkara paling penting: pembalikan rawak, putaran, serta perubahan kontras dan kecerahan semuanya membantu, sambil memastikan pertambahan itu munasabah dari sudut klinikal (sinar-X dada tidak sepatutnya dibalikkan secara menegak — keadaan itu tidak pernah berlaku dalam amalan klinikal).

Penskalaan semula progresif (berlatih pada resolusi lebih rendah pada awalnya, kemudian meningkatkannya) ialah satu lagi teknik yang berkesan. Mulakan pada 128×128 untuk mengulangi proses dengan cepat, kemudian lakukan penalaan halus pada 224×224 atau malah 320×320 untuk ketepatan akhir. Kaedah ini jauh lebih pantas berbanding sentiasa berlatih pada resolusi penuh dan sering mencapai ketepatan yang setanding dengan resolusi penuh.

from torchvision import transforms

# Clinically appropriate augmentations for chest X-rays
medical_aug = transforms.Compose([
    transforms.RandomResizedCrop(224, scale=(0.85, 1.0)),  # Mild crop
    transforms.RandomHorizontalFlip(p=0.5),                 # OK: X-rays can be flipped
    # transforms.RandomVerticalFlip(p=0.5),                 # NOT OK: clinically invalid
    transforms.ColorJitter(brightness=0.2, contrast=0.3),  # Simulate scan variation
    transforms.RandomRotation(degrees=10),                  # Slight mis-alignment
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406],
                         [0.229, 0.224, 0.225])
])

Pra-latihan Kawal Selia Kendiri untuk Pengimejan Perubatan

Apabila ciri ImageNet tidak dapat dipindahkan dengan cukup baik, pra-latihan kawal selia kendiri pada imej perubatan tanpa label ialah alternatif yang berkuasa. Kaedah seperti SimCLR, MoCo dan DINO mempelajari perwakilan dengan melatih model untuk mengenal pasti bahawa dua versi yang ditambah baik bagi imej yang sama adalah serupa, tanpa sebarang label.

Aliran kerja: (1) lakukan pra-latihan pada set data perubatan besar tanpa label (CheXpert mempunyai 224K imej tanpa label), (2) lakukan penalaan halus menggunakan set berlabel yang kecil. Kaedah ini secara konsisten mengatasi pemindahan ImageNet dalam tugasan perubatan kerana model mempelajari ciri khusus domain perubatan, bukannya ciri umum pengecaman objek.

# Self-supervised pre-training concept (SimCLR-style)
# No labels needed during this phase

class SimCLRLoss(torch.nn.Module):
    def __init__(self, temperature=0.07):
        super().__init__()
        self.temperature = temperature

    def forward(self, z_i, z_j):
        # z_i, z_j: augmented views of the same images
        # Maximise agreement between paired views
        # Minimise agreement between all other pairs in batch
        z = torch.cat([z_i, z_j], dim=0)
        z = torch.nn.functional.normalize(z, dim=1)
        sim = torch.matmul(z, z.T) / self.temperature
        # Contrastive loss computation...
        return sim  # Simplified illustration

Pengkuantitian Ketidakpastian dalam AI Perubatan

Dalam sokongan keputusan perubatan, mengetahui sejauh mana keyakinan model sama pentingnya dengan ramalan itu sendiri. Model yang menyatakan 'Pneumonia: kebarangkalian 95%' sepatutnya lebih dipercayai berbanding model yang menyatakan 'kebarangkalian 52%'. Kebarangkalian softmax piawai sering terlalu yakin dan tidak menggambarkan ketidakpastian sebenar.

Monte Carlo Dropout (MC Dropout) menghampiri ketidakpastian Bayesian dengan mengekalkan dropout aktif pada masa inferens dan menjalankan hantaran ke hadapan beberapa kali. Varians ramalan merentas larian menganggarkan ketidakpastian. Ramalan dengan varians tinggi hendaklah ditandakan untuk semakan manusia dan bukannya digunakan secara automatik.

import torch

def mc_dropout_predict(model, x, n_samples=30):
    model.train()  # Keep dropout active during inference
    predictions = []
    with torch.no_grad():
        for _ in range(n_samples):
            logits = model(x)
            probs = torch.sigmoid(logits)
            predictions.append(probs)
    preds = torch.stack(predictions)  # (n_samples, batch, num_classes)
    mean_pred = preds.mean(dim=0)     # Average prediction
    uncertainty = preds.std(dim=0)    # Std = uncertainty estimate
    return mean_pred, uncertainty

# High uncertainty cases should be reviewed by a radiologist
MEAN_THRESHOLD = 0.5
UNCERTAINTY_THRESHOLD = 0.15

Pertimbangan Etika dalam ML Perubatan

Pelaksanaan model ML dalam persekitaran perubatan membawa tanggungjawab etika yang serius. Bias set data ialah kebimbangan kritikal: model yang dilatih terutamanya menggunakan imej daripada pengimbas, demografi pesakit atau pengeluar pengimbas di satu hospital mungkin gagal pada imej daripada persekitaran yang berbeza — masalah yang diketahui dalam AI radiologi.

Sebelum pelaksanaan, sentiasa nilai prestasi model merentas subkumpulan demografi (umur, jantina dan kaum) serta peralatan pengimbasan yang berbeza. Rangka kerja kawal selia seperti garis panduan Perisian sebagai Peranti Perubatan (SaMD) berasaskan AI/ML FDA di US dan Peraturan Peranti Perubatan (MDR) EU memerlukan pengesahan klinikal yang ketat sebelum pelaksanaan. Model hendaklah membantu radiologi, bukannya menggantikan mereka — terutamanya bagi patologi berisiko tinggi yang kesilapannya boleh membawa akibat hidup atau mati.

Semakan Pantas

Uji pemahaman anda tentang penyesuaian domain untuk pengimejan perubatan daripada pelajaran ini.

Imbas Kembali Pelajaran

Dalam pelajaran ini, anda mempelajari bahawa: pembelajaran pemindahan untuk pengimejan perubatan menggunakan model terlatih awal ImageNet pada domain yang mempunyai imej skala kelabu dan label terhad dengan menukar saluran serta menggantikan kepala pengelasan; ralat BCE berbilang label dengan pos_weight menangani ketidakseimbangan kelas ekstrem yang lazim dalam set data patologi; dan AUC-ROC ialah metrik penilaian yang tepat kerana mengukur keupayaan membezakan tanpa bergantung pada keseimbangan kelas. Setelah menguasai kemahiran pembelajaran pemindahan ini, anda bersedia untuk meneroka NLP dengan BERT dalam kursus seterusnya.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad” percuma?

Ya — teks penuh “Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Machine Learning Academy, tingkat taraf kepada CoddyKit PRO. Kursus Machine Learning Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad”?

Pelajar akan menggunakan pembelajaran pindahan daripada ImageNet kepada set data sinar-X dada, melaksanakan kehilangan berwajaran kelas untuk patologi tidak seimbang, dan menilai AUC-ROC. Anda berlatih Machine Learning Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Machine Learning Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Machine Learning Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Machine Learning Academy ini?

Ya. Setiap pelajaran Machine Learning Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Model Terlatih Awal dalam torchvision: ResNet, EfficientNet dan ViT
  2. Pengekstrakan Ciri: Membekukan Tulang Belakang
  3. Penalaan Halus: Menyahbeku dan Kadar Pembelajaran Rendah
  4. Penyesuaian Domain: Pengimejan Perubatan dengan Label Terhad
← Kembali ke Machine Learning Academy