Vbai-TS 2.4 Sürümü (TR)

Boyut Parametre F1 Skoru mAPᵛᵃᴵ Doğruluk Duyarlılık Kesinlik
224 77.19M %97.49 %96.10 %97.50 %97.50 %97.73

Tanım

Vbai-TS 2.4 (Tumor Segmentation) modeli, MRI veya fMRI görüntüsü üzerinden beyin hastalıklarını teşhis etmek amacıyla eğitilmiş ve geliştirilmiştir. Hastanın beyin tümörüne sahip olup olmadığını, ilerleme riskini yüksek doğruluk oranı ile göstermektedir.

Kitle / Hedef

Vbai modelleri tamamen öncelik olarak hastaneler, sağlık merkezleri ve bilim merkezleri için geliştirilmiştir.

Sınıflar

  • Glioma Tümörü: Kişide bulunan tümör agresif bir tutumdadır.
  • Meningioma Tümörü: Kişide bulunan tümör ilerlemektedir.
  • Hipofiz Tümör: Kişide bulunan tümör yavaş ilerlemektedir.
  • Tümör Yok: Kişide tümör bulunmamaktadır.

----------------------------------------

Vbai-TS 2.4 Version (EN)

Size Params F1 Score mAPᵛᵃᴵ Accuracy Recall Precision
224 77.19M 97.49% 96.10% 97.50% 97.50% 97.73%

Description

The Vbai-TS 2.4 (Tumor Segmentation) model is trained and developed to diagnose brain diseases from MRI or fMRI images. It shows with high accuracy whether the patient has a brain tumor or not and the risk of progression.

Audience / Target

Vbai models are developed exclusively for hospitals, health centers and science centers.

Classes

  • Glioma Tumor: The tumor in the person has an aggressive behavior.
  • Meningioma Tumor: The tumor is progressing.
  • Pituitary Tumor: The tumor in the person is progressing slowly.
  • No Tumor: The person does not have a tumor.

Kullanım / Usage

import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import transforms
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import cv2
import os
import argparse
from pathlib import Path
from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix, average_precision_score
from sklearn.preprocessing import label_binarize


transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

edge_transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.Grayscale(num_output_channels=1),
    transforms.ToTensor()
])


class BrainStructureAnalyzer:
    @staticmethod
    def detect_tumor_edges(image_tensor):
        try:
            if len(image_tensor.shape) == 4:
                image = image_tensor[0].squeeze().cpu().numpy()
            else:
                image = image_tensor.squeeze().cpu().numpy()

            image = ((image - image.min()) / (image.max() - image.min()) * 255).astype(np.uint8)
            blurred = cv2.GaussianBlur(image, (5, 5), 0)
            edges = cv2.Canny(blurred, 50, 150)
            kernel = np.ones((3, 3), np.uint8)
            edges = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)

            return edges
        except Exception as e:
            print(f"Edge detection hatası: {e}")
            return np.zeros((224, 224), dtype=np.uint8)

    @staticmethod
    def analyze_tumor_structure(image_tensor):
        edges = BrainStructureAnalyzer.detect_tumor_edges(image_tensor)

        try:
            contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

            if contours:
                contours = sorted(contours, key=cv2.contourArea, reverse=True)[:3]
            else:
                contours = []
        except Exception as e:
            print(f"Kontur analizi hatası: {e}")
            contours = []

        return edges, contours


class AttentionModule(nn.Module):

    def __init__(self, in_channels):
        super(AttentionModule, self).__init__()
        self.conv1 = nn.Conv2d(in_channels, max(1, in_channels // 8), 1)
        self.conv2 = nn.Conv2d(max(1, in_channels // 8), 1, 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        attention = self.conv1(x)
        attention = F.relu(attention)
        attention = self.conv2(attention)
        attention = self.sigmoid(attention)
        return x * attention, attention


class EnhancedCNN(nn.Module):

    def __init__(self, num_classes=4):
        super(EnhancedCNN, self).__init__()
        self.num_classes = num_classes
        self.model_type = 'c'

        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)

        self.attention1 = AttentionModule(64)
        self.attention2 = AttentionModule(128)

        self.fc1 = nn.Linear(128 * 28 * 28, 512)
        self.dropout = nn.Dropout(0.5)
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)

        self.edge_conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
        self.edge_conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.edge_pool = nn.AdaptiveAvgPool2d(56)
        self.edge_fc = nn.Linear(64 * 56 * 56, 128)

        self.fc2 = nn.Linear(512, num_classes)
        self.combined_fc = nn.Linear(512 + 128, num_classes)

    def forward(self, x, edge_x=None):
        x = self.pool(self.relu(self.conv1(x)))

        x = self.relu(self.conv2(x))
        x, attention_map1 = self.attention1(x)
        x = self.pool(x)

        x = self.relu(self.conv3(x))
        x, attention_map2 = self.attention2(x)
        x = self.pool(x)

        x_flat = x.view(x.size(0), -1)
        x_flat = self.relu(self.fc1(x_flat))
        x_flat = self.dropout(x_flat)

        if edge_x is not None:
            try:
                edge_x = self.pool(self.relu(self.edge_conv1(edge_x)))
                edge_x = self.pool(self.relu(self.edge_conv2(edge_x)))
                edge_x = self.edge_pool(edge_x)
                edge_features = edge_x.view(edge_x.size(0), -1)
                edge_features = self.relu(self.edge_fc(edge_features))

                x_flat = torch.cat([x_flat, edge_features], dim=1)
                output = self.combined_fc(x_flat)
            except Exception as e:
                print(f"Edge branch hatası: {e}")
                output = self.fc2(x_flat)
        else:
            output = self.fc2(x_flat)

        return output, attention_map2


class VisualizationManager:

    @staticmethod
    def denormalize_image(image_tensor):
        mean = torch.tensor([0.485, 0.456, 0.406]).view(3, 1, 1)
        std = torch.tensor([0.229, 0.224, 0.225]).view(3, 1, 1)
        if image_tensor.device.type == 'cuda':
            mean = mean.cuda()
            std = std.cuda()
        image = image_tensor * std + mean
        image = torch.clamp(image, 0, 1)
        return image

    @staticmethod
    def create_tumor_visualization(image, attention_map, prediction, class_names, edges=None,
                                   save_path=None, confidence=None, show_plot=False):
        try:
            fig, axes = plt.subplots(2, 2, figsize=(15, 12))

            if isinstance(image, torch.Tensor):
                image = VisualizationManager.denormalize_image(image)
                image = image.permute(1, 2, 0).cpu().numpy()

            axes[0, 0].imshow(image)
            axes[0, 0].set_title('Orijinal MRI Görüntüsü', fontsize=12, fontweight='bold')
            axes[0, 0].axis('off')

            if attention_map is not None:
                attention = attention_map.squeeze().cpu().numpy()
                if attention.ndim > 2:
                    attention = np.mean(attention, axis=0)
                attention = cv2.resize(attention, (224, 224))

                im = axes[0, 1].imshow(attention, cmap='jet', alpha=0.8)
                axes[0, 1].set_title('Dikkat Haritası (Tümör Bölgeleri)', fontsize=12, fontweight='bold')
                axes[0, 1].axis('off')
                plt.colorbar(im, ax=axes[0, 1], fraction=0.046)
            else:
                axes[0, 1].text(0.5, 0.5, 'Dikkat Haritası\nMevcut Değil',
                                ha='center', va='center', transform=axes[0, 1].transAxes)
                axes[0, 1].axis('off')

            if edges is not None:
                axes[1, 0].imshow(edges, cmap='gray')
                axes[1, 0].set_title('Tümör Yapısı Çizgileri', fontsize=12, fontweight='bold')
                axes[1, 0].axis('off')
            else:
                axes[1, 0].text(0.5, 0.5, 'Tümör Yapısı\nAnalizi Mevcut Değil',
                                ha='center', va='center', transform=axes[1, 0].transAxes)
                axes[1, 0].axis('off')

            axes[1, 1].imshow(image)
            if attention_map is not None:
                attention_overlay = cv2.resize(attention, (224, 224))
                axes[1, 1].imshow(attention_overlay, cmap='jet', alpha=0.4)

            predicted_class = class_names[prediction] if prediction < len(class_names) else "Bilinmeyen"
            title_text = f'Teşhis: {predicted_class}'
            if confidence is not None:
                title_text += f'\nGüven: {confidence:.2f}%'
            axes[1, 1].set_title(title_text, fontsize=12, fontweight='bold', color='red')
            axes[1, 1].axis('off')

            plt.tight_layout()

            if save_path:
                try:
                    plt.savefig(save_path, dpi=300, bbox_inches='tight')
                    print(f"✅ Görselleştirme kaydedildi: {save_path}")
                except Exception as e:
                    print(f"⚠️ Görselleştirme kaydetme hatası: {e}")

            if show_plot:
                plt.show()
            else:
                plt.close(fig)

            return fig

        except Exception as e:
            print(f"❌ Görselleştirme oluşturma hatası: {e}")
            return None


def count_parameters(model):
    total_params = sum(p.numel() for p in model.parameters())
    trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
    return total_params, trainable_params


def load_model(model_path, device):
    print(f"📦 Model yükleniyor: {model_path}")

    if not os.path.exists(model_path):
        raise FileNotFoundError(f"Model dosyası bulunamadı: {model_path}")

    checkpoint = torch.load(model_path, map_location=device)

    model_config = checkpoint.get('model_config', {'num_classes': 4, 'model_type': 'c'})
    class_names = checkpoint.get('class_names', ['glioma_tumor', 'meningioma_tumor', 'no_tumor', 'pituitary_tumor'])

    model = EnhancedCNN(num_classes=model_config['num_classes']).to(device)
    model.load_state_dict(checkpoint['model_state_dict'])
    model.eval()

    total_params, trainable_params = count_parameters(model)

    print(f"✅ Model başarıyla yüklendi!")
    print(f"   Sınıflar: {class_names}")
    print(f"   Model tipi: {model_config['model_type']}")
    print(f"   Toplam parametre sayısı: {total_params:,}")
    print(f"   Eğitilebilir parametre sayısı: {trainable_params:,}")

    return model, class_names


def test_single_image(model, image_path, class_names, device, output_dir='test_results', show_plot=False):
    print(f"\n🔍 Görüntü analiz ediliyor: {image_path}")

    try:
        image = Image.open(image_path).convert('RGB')
        image_tensor = transform(image).unsqueeze(0).to(device)
        edge_tensor = edge_transform(image).unsqueeze(0).to(device)

        with torch.no_grad():
            outputs, attention_maps = model(image_tensor, edge_tensor)
            probabilities = F.softmax(outputs, dim=1)
            confidence, predicted = torch.max(probabilities, 1)

            confidence_value = confidence[0].item() * 100
            predicted_class = predicted[0].item()

            edges, contours = BrainStructureAnalyzer.analyze_tumor_structure(edge_tensor)

            print(f"\n{'='*60}")
            print(f"📊 SONUÇLAR")
            print(f"{'='*60}")
            print(f"🎯 Teşhis: {class_names[predicted_class]}")
            print(f"📈 Güven Skoru: {confidence_value:.2f}%")
            print(f"\n📉 Tüm Sınıf Olasılıkları:")
            for i, class_name in enumerate(class_names):
                prob = probabilities[0][i].item() * 100
                bar = '█' * int(prob / 2)
                print(f"   {class_name:25s}: {prob:6.2f}% {bar}")
            print(f"{'='*60}\n")

            os.makedirs(output_dir, exist_ok=True)
            image_name = Path(image_path).stem
            save_path = os.path.join(output_dir, f'{image_name}_analysis.png')

            VisualizationManager.create_tumor_visualization(
                image_tensor[0],
                attention_maps[0] if attention_maps is not None else None,
                predicted_class,
                class_names,
                edges,
                save_path,
                confidence_value,
                show_plot
            )

            return {
                'image_path': image_path,
                'prediction': class_names[predicted_class],
                'confidence': confidence_value,
                'probabilities': {class_names[i]: probabilities[0][i].item() * 100 for i in range(len(class_names))}
            }

    except Exception as e:
        print(f"❌ Görüntü analizi hatası: {e}")
        import traceback
        traceback.print_exc()
        return None


def calculate_metrics(y_true, y_pred, y_probs, class_names):
    accuracy = np.mean(np.array(y_true) == np.array(y_pred))

    precision = precision_score(y_true, y_pred, average='macro', zero_division=0)
    recall = recall_score(y_true, y_pred, average='macro', zero_division=0)
    f1 = f1_score(y_true, y_pred, average='macro', zero_division=0)

    precision_per_class = precision_score(y_true, y_pred, average=None, zero_division=0)
    recall_per_class = recall_score(y_true, y_pred, average=None, zero_division=0)
    f1_per_class = f1_score(y_true, y_pred, average=None, zero_division=0)

    n_classes = len(class_names)
    y_true_bin = label_binarize(y_true, classes=list(range(n_classes)))

    ap_scores = []
    for i in range(n_classes):
        try:
            ap = average_precision_score(y_true_bin[:, i], np.array(y_probs)[:, i])
            ap_scores.append(ap)
        except:
            ap_scores.append(0.0)

    mAP = np.mean(ap_scores)

    cm = confusion_matrix(y_true, y_pred)

    return {
        'accuracy': accuracy,
        'precision': precision,
        'recall': recall,
        'f1_score': f1,
        'precision_per_class': precision_per_class,
        'recall_per_class': recall_per_class,
        'f1_per_class': f1_per_class,
        'ap_scores': ap_scores,
        'mAP': mAP,
        'confusion_matrix': cm
    }


def test_directory(model, directory_path, class_names, device, output_dir='test_results', show_plot=False):
    print(f"\n📁 Klasör test ediliyor: {directory_path}")

    image_extensions = ['.png', '.jpg', '.jpeg', '.bmp', '.tiff']

    image_files = []
    ground_truths = []

    max_images_per_class = 10
    for class_idx, class_name in enumerate(class_names):
        class_dir = Path(directory_path) / class_name
        if class_dir.exists():
            class_files = []
            for ext in image_extensions:
                files = list(class_dir.glob(f'*{ext}'))
                files.extend(list(class_dir.glob(f'*{ext.upper()}')))
                class_files.extend(files)

            class_files = class_files[:max_images_per_class]
            image_files.extend(class_files)
            ground_truths.extend([class_idx] * len(class_files))
            print(f"   {class_name}: {len(class_files)} görüntü")

    if not image_files:
        print(f"⚠️ Klasörde görüntü bulunamadı: {directory_path}")
        return []

    print(f"✅ Toplam {len(image_files)} görüntü bulundu\n")

    results = []
    predictions = []
    probabilities_list = []

    for i, (image_file, true_label) in enumerate(zip(image_files, ground_truths), 1):
        print(f"\n{'='*70}")
        print(f"Görüntü {i}/{len(image_files)}")
        print(f"{'='*70}")

        result = test_single_image(model, str(image_file), class_names, device, output_dir, show_plot)
        if result:
            results.append(result)
            pred_class = class_names.index(result['prediction'])
            predictions.append(pred_class)

            probs = [result['probabilities'][cn] / 100.0 for cn in class_names]
            probabilities_list.append(probs)

    if results and len(predictions) == len(ground_truths):
        metrics = calculate_metrics(ground_truths, predictions, probabilities_list, class_names)

        print(f"\n\n{'='*70}")
        print(f"📊 DETAYLI TEST SONUÇLARI")
        print(f"{'='*70}")
        print(f"Toplam Test Edilen Görüntü: {len(results)}")
        print(f"\n📈 GENEL METRİKLER:")
        print(f"   Accuracy (Doğruluk):     {metrics['accuracy']*100:.2f}%")
        print(f"   Precision (Kesinlik):    {metrics['precision']*100:.2f}%")
        print(f"   Recall (Duyarlılık):     {metrics['recall']*100:.2f}%")
        print(f"   F1 Score:                {metrics['f1_score']*100:.2f}%")
        print(f"   mAP (mean AP):           {metrics['mAP']*100:.2f}%")

        print(f"\n📊 SINIF BAZINDA METRİKLER:")
        print(f"{'Sınıf':<25} {'Precision':<12} {'Recall':<12} {'F1 Score':<12} {'AP Score':<12}")
        print(f"{'-'*73}")
        for i, class_name in enumerate(class_names):
            print(f"{class_name:<25} {metrics['precision_per_class'][i]*100:>10.2f}%  "
                  f"{metrics['recall_per_class'][i]*100:>10.2f}%  "
                  f"{metrics['f1_per_class'][i]*100:>10.2f}%  "
                  f"{metrics['ap_scores'][i]*100:>10.2f}%")

        print(f"\n📋 CONFUSION MATRIX:")
        print(f"{'':>25}", end='')
        for cn in class_names:
            print(f"{cn[:10]:>12}", end='')
        print()
        for i, class_name in enumerate(class_names):
            print(f"{class_name:<25}", end='')
            for j in range(len(class_names)):
                print(f"{metrics['confusion_matrix'][i][j]:>12}", end='')
            print()

        class_counts = {}
        for result in results:
            pred = result['prediction']
            class_counts[pred] = class_counts.get(pred, 0) + 1

        print(f"\n🎯 TAHMİN DAĞILIMI:")
        for class_name, count in class_counts.items():
            percentage = (count / len(results)) * 100
            print(f"   {class_name:25s}: {count:3d} ({percentage:.1f}%)")

        avg_confidence = sum(r['confidence'] for r in results) / len(results)
        print(f"\n📈 Ortalama Güven Skoru: {avg_confidence:.2f}%")

        print(f"{'='*70}\n")

        return results, metrics
    else:
        print(f"\n⚠️ Metrik hesaplaması için yeterli veri yok")
        return results, None


def main():
    parser = argparse.ArgumentParser(description='MRI Tümör Tespiti Test Script')
    parser.add_argument('--model', type=str, required=True, help='Eğitilmiş model dosyasının yolu (.pt)')
    parser.add_argument('--image', type=str, help='Test edilecek tek görüntü yolu')
    parser.add_argument('--directory', type=str, help='Test edilecek klasör yolu')
    parser.add_argument('--output', type=str, default='test_results', help='Sonuçların kaydedileceği klasör')
    parser.add_argument('--show', action='store_true', help='Sonuçları ekranda göster')
    parser.add_argument('--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu',
                       help='Kullanılacak cihaz (cuda/cpu)')

    args = parser.parse_args()

    print("🧠 MRI Tümör Tespiti Test Sistemi")
    print("=" * 70)

    device = torch.device(args.device)
    print(f"🖥️ Kullanılan cihaz: {device}")
    if device.type == 'cuda':
        print(f"   GPU: {torch.cuda.get_device_name(0)}")
    print()

    try:
        model, class_names = load_model(args.model, device)
    except Exception as e:
        print(f"❌ Model yükleme hatası: {e}")
        return

    if args.image:
        test_single_image(model, args.image, class_names, device, args.output, args.show)
    elif args.directory:
        # Klasör testi
        results, metrics = test_directory(model, args.directory, class_names, device, args.output, args.show)
    else:
        print("⚠️ Lütfen --image veya --directory parametresi belirtin")
        parser.print_help()


if __name__ == '__main__':
    import sys
    if len(sys.argv) == 1:
        print("🧠 MRI Tümör Tespiti Test Sistemi - İnteraktif Mod")
        print("=" * 70)

        model_path = input("Model dosyası yolu (.pt): ").strip()
        test_type = input("Test tipi (1: Tek görüntü, 2: Klasör): ").strip()

        if not os.path.exists(model_path):
            print(f"❌ Model dosyası bulunamadı: {model_path}")
            sys.exit(1)

        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
        print(f"\n🖥️ Kullanılan cihaz: {device}\n")

        try:
            model, class_names = load_model(model_path, device)
        except Exception as e:
            print(f"❌ Model yükleme hatası: {e}")
            sys.exit(1)

        if test_type == '1':
            image_path = input("Görüntü dosyası yolu: ").strip()
            show = input("Sonuçları göster? (e/h): ").strip().lower() == 'e'
            test_single_image(model, image_path, class_names, device, 'test_results', show)
        elif test_type == '2':
            dir_path = input("Klasör yolu: ").strip()
            show = input("Sonuçları göster? (e/h): ").strip().lower() == 'e'
            results, metrics = test_directory(model, dir_path, class_names, device, 'test_results', show)
        else:
            print("❌ Geçersiz seçim")
    else:
        main()
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Collection including Neurazum/Vbai-TS-2.4