Diagnosis Models
Collection
Diagnosis with brain MRI or fMRI image. By Neurazum.
•
10 items
•
Updated
•
1
| Boyut | Parametre | F1 Skoru | mAPᵛᵃᴵ | Doğruluk | Duyarlılık | Kesinlik |
|---|---|---|---|---|---|---|
| 224 | 77.19M | %97.49 | %96.10 | %97.50 | %97.50 | %97.73 |
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.
Vbai modelleri tamamen öncelik olarak hastaneler, sağlık merkezleri ve bilim merkezleri için geliştirilmiştir.
| Size | Params | F1 Score | mAPᵛᵃᴵ | Accuracy | Recall | Precision |
|---|---|---|---|---|---|---|
| 224 | 77.19M | 97.49% | 96.10% | 97.50% | 97.50% | 97.73% |
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.
Vbai models are developed exclusively for hospitals, health centers and science centers.
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()