YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

-- coding: utf-8 --

"""Çok Modaliteli Meme Kanseri Tespiti Projesi.ipynb

Automatically generated by Colab.

Original file is located at https://colab.research.google.com/drive/1iRYBNFcFPCbFxvIgtkKobOufHoSUvInz """

GPU bellek kullanımını sınırlandır

import tensorflow as tf gpus = tf.config.experimental.list_physical_devices('GPU') if gpus: try: for gpu in gpus: tf.config.experimental.set_memory_growth(gpu, True) except RuntimeError as e: print(e)

=============================================================================

0. Gerekli Kütüphaneler ve Ayarlar

=============================================================================

=============================================================================

0. Gerekli Kütüphaneler ve Ayarlar

=============================================================================

import os import zipfile import cv2 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import tensorflow as tf from sklearn.model_selection import StratifiedKFold from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_curve, auc, confusion_matrix from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.models import Model, Sequential from tensorflow.keras.layers import Input, Dense, Dropout, BatchNormalization, GlobalAveragePooling2D, concatenate, Reshape, Add, LayerNormalization from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau from tensorflow.keras.optimizers import Adam !pip install gradio import gradio as gr import zipfile

=============================================================================

1. Google Drive'ı Mount Et ve Veri Dizini Tanımla

=============================================================================

from google.colab import drive drive.mount('/content/gdrive', force_remount=True)

Veri dizin yapınız:

/content/breast/breast/

├── mamogram/

│ ├── benign/

│ └── malignant/

├── ultrasound/

│ ├── benign/

│ ├── malignant/

│ └── normal/ (bu klasördeki görüntüler benign kabul edilecek)

└── histopathology/

├── benign/ (örn: Adenosis, Fibroadenoma, Tubular Adenoma, Phyllodes Tumor)

└── malignant/ (örn: Ductal Carcinoma, Lobular Carcinoma, Mucinous Carcinoma, Papillary Carcinoma)

BASE_DIR = "/content/breast/breast/breast/breast" MAMOGRAM_DIR = os.path.join(BASE_DIR, "mamogram") ULTRASOUND_DIR = os.path.join(BASE_DIR, "ultrasound") HISTOPATH_DIR = os.path.join(BASE_DIR, "histopathology")

Ultrasound klasöründe "normal" varsa, içeriğini benign altına taşıyalım.

normal_dir = os.path.join(ULTRASOUND_DIR, "normal") benign_ultrasound_dir = os.path.join(ULTRASOUND_DIR, "benign") if os.path.exists(normal_dir): os.makedirs(benign_ultrasound_dir, exist_ok=True) for root, dirs, files in os.walk(normal_dir): for file in files: if file.lower().endswith(('.png','.jpg','.jpeg','.bmp')): src = os.path.join(root, file) dest = os.path.join(benign_ultrasound_dir, file) os.rename(src, dest) os.rmdir(normal_dir) print("Ultrasound 'normal' klasöründeki görüntüler 'benign' altına taşındı.") else: print("Ultrasound 'normal' klasörü bulunamadı veya zaten taşınmış.")

=============================================================================

2. (Varsa) Zip Dosyasından Verileri Çıkartma

=============================================================================

zip_path = "/content/gdrive/MyDrive/breast.zip" # Zip dosyanızın yolu extract_path = BASE_DIR # Zip içeriği bu dizine çıkarılacak if os.path.exists(zip_path): with zipfile.ZipFile(zip_path, 'r') as zip_ref: zip_ref.extractall(extract_path) print("Zip dosyası başarıyla çıkarıldı.") else: print("Zip dosyası bulunamadı; verileriniz zaten çıkarılmış olabilir.")

=============================================================================

3. Görüntü Ön İşleme ve Veri Yükleme Fonksiyonları

=============================================================================

IMG_SIZE ayarı: 128x128

IMG_SIZE = (128, 128) image_extensions = ('.png', '.jpg', '.jpeg', '.bmp')

def preprocess_image(image_path, target_size, data_type): """Görüntüyü yükler, yeniden boyutlandırır ve modality'ye uygun önişleme uygular.""" img = cv2.imread(image_path) if img is None: print(f"Hata: {image_path} yüklenemedi") return None img = cv2.resize(img, target_size) if data_type == "mamogram": lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB) l, a, b = cv2.split(lab) clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) cl = clahe.apply(l) updated_lab = cv2.merge((cl, a, b)) img = cv2.cvtColor(updated_lab, cv2.COLOR_LAB2BGR) elif data_type == "histopath": img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) elif data_type == "ultrasound": img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_eq = cv2.equalizeHist(img_gray) img = cv2.cvtColor(img_eq, cv2.COLOR_GRAY2BGR) return img / 255.0

def load_data_and_organize(data_dir, target_size, data_type): """ data_dir altındaki görüntüleri, alt klasör isimlerine göre etiketleyip yükler. Ultrasound için "normal" klasöründeki görüntüler benign kabul edilir. """ images, labels, file_paths = [], [], [] print(f"\n[{data_type.upper()}] Dosyaları aranıyor: {data_dir}") for root, dirs, files in os.walk(data_dir): lower_root = root.lower() if data_type == "ultrasound": if "benign" in lower_root or "normal" in lower_root: label = 0 elif "malignant" in lower_root: label = 1 else: continue else: if "benign" in lower_root: label = 0 elif "malignant" in lower_root: label = 1 else: continue for file in files: if file.lower().endswith(image_extensions): img_path = os.path.join(root, file) img = preprocess_image(img_path, target_size, data_type) if img is not None: images.append(img) labels.append(label) file_paths.append(img_path) else: print(f"Önişleme başarısız: {img_path}") print(f"\n[{data_type.upper()}] Toplam {len(images)} görüntü yüklendi.") return np.array(images), np.array(labels), pd.DataFrame({"filepath": file_paths, "label": labels})

mamogram_images, mamogram_labels, mamogram_df = load_data_and_organize(MAMOGRAM_DIR, IMG_SIZE, "mamogram") ultrasound_images, ultrasound_labels, ultrasound_df = load_data_and_organize(ULTRASOUND_DIR, IMG_SIZE, "ultrasound") histopath_images, histopath_labels, histopath_df = load_data_and_organize(HISTOPATH_DIR, IMG_SIZE, "histopath")

if mamogram_images.shape[0] == 0: print("Uyarı: Mamogram veri seti boş!") if ultrasound_images.shape[0] == 0: print("Uyarı: Ultrasound veri seti boş!") if histopath_images.shape[0] == 0: print("Uyarı: Histopatoloji veri seti boş!")

=============================================================================

4. Veri Artırma (Data Augmentation) ve Görselleştirme

=============================================================================

datagen = ImageDataGenerator( rotation_range=20, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest' )

def visualize_augmentation(dataset, title, num_images=5): augmented_images = [] if len(dataset) > 0: sample_image = np.expand_dims(dataset[0], 0) for i, batch in enumerate(datagen.flow(sample_image, batch_size=1)): augmented_images.append(batch[0]) if i >= num_images - 1: break plt.figure(figsize=(15,3)) for idx, aug_img in enumerate(augmented_images): plt.subplot(1, num_images, idx+1) plt.imshow(aug_img) plt.title(f"{title} aug {idx+1}") plt.axis("off") plt.show() else: print(f"{title} veri seti boş!")

print("Mamogram veri artırma örnekleri:") visualize_augmentation(mamogram_images, "Mamogram") print("Ultrasound veri artırma örnekleri:") visualize_augmentation(ultrasound_images, "Ultrasound") print("Histopatoloji veri artırma örnekleri:") visualize_augmentation(histopath_images, "Histopatoloji")

=============================================================================

6. Model Tanımları: MobileViT Blok ve Sınıflandırma Modeli Oluşturma

=============================================================================

from tensorflow.keras import regularizers

def mobilevit_block(x, transformer_dim=64, mlp_dim=128, patch_size=2, num_heads=2, dropout_rate=0.1): y = tf.keras.layers.Conv2D(transformer_dim, kernel_size=3, padding='same', activation='relu')(x) H, W = y.shape[1], y.shape[2] y_flat = tf.keras.layers.Reshape((H * W, transformer_dim))(y) attn_output = tf.keras.layers.MultiHeadAttention(num_heads=num_heads, key_dim=transformer_dim, dropout=dropout_rate)(y_flat, y_flat) y_flat = tf.keras.layers.Add()([y_flat, attn_output]) y_flat = tf.keras.layers.LayerNormalization()(y_flat) mlp_output = tf.keras.layers.Dense(mlp_dim, activation='relu')(y_flat) mlp_output = tf.keras.layers.Dense(transformer_dim)(mlp_output) y_flat = tf.keras.layers.Add()([y_flat, mlp_output]) y_flat = tf.keras.layers.LayerNormalization()(y_flat) y_reshaped = tf.keras.layers.Reshape((H, W, transformer_dim))(y_flat) output = tf.keras.layers.Conv2D(x.shape[-1], kernel_size=1, padding='same')(y_reshaped) return output

def create_mobilevit_branch(input_shape=(128,128,3)): inputs = tf.keras.Input(shape=input_shape) x = tf.keras.layers.Conv2D(32, kernel_size=3, strides=2, padding='same', activation='relu', kernel_regularizer=regularizers.l2(0.001))(inputs) x = tf.keras.layers.BatchNormalization()(x) x = mobilevit_block(x, transformer_dim=64, mlp_dim=128, patch_size=2, num_heads=2, dropout_rate=0.1) x = tf.keras.layers.Conv2D(64, kernel_size=3, strides=2, padding='same', activation='relu', kernel_regularizer=regularizers.l2(0.001))(x) x = tf.keras.layers.BatchNormalization()(x) x = mobilevit_block(x, transformer_dim=80, mlp_dim=160, patch_size=2, num_heads=2, dropout_rate=0.1) x = tf.keras.layers.GlobalAveragePooling2D()(x) x = tf.keras.layers.BatchNormalization()(x) x = tf.keras.layers.Dense(256, activation='relu', kernel_regularizer=regularizers.l2(0.001))(x) x = tf.keras.layers.Dropout(0.5)(x) # Sınıflandırma başlığı ekleyelim: output = tf.keras.layers.Dense(1, activation='sigmoid', kernel_regularizer=regularizers.l2(0.001))(x) model = tf.keras.Model(inputs, output) model.compile(optimizer=Adam(learning_rate=1e-4), loss='binary_crossentropy', metrics=['accuracy', tf.keras.metrics.AUC(), tf.keras.metrics.Precision(), tf.keras.metrics.Recall()]) return model

=============================================================================

7. Bölüm: K-Fold Çapraz Doğrulama ile Model Eğitimi (Tek Modalite) – Batch Size = 8

=============================================================================

def cross_validate_model(model_builder, images, labels, folds=5, batch_size=8, epochs=10): skf = StratifiedKFold(n_splits=folds, shuffle=True, random_state=42) fold_no = 1 histories = [] cv_metrics = [] for train_index, val_index in skf.split(images, labels): print(f"\n--- Fold {fold_no} ---") X_train, X_val = images[train_index], images[val_index] y_train, y_val = labels[train_index], labels[val_index]

    train_datagen = ImageDataGenerator(
        rotation_range=20,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest'
    )
    val_datagen = ImageDataGenerator()
    train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)
    val_generator = val_datagen.flow(X_val, y_val, batch_size=batch_size)

    model = model_builder()
    callbacks = [
        EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True, verbose=1),
        ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6, verbose=1)
    ]
    history = model.fit(
        train_generator,
        epochs=epochs,
        validation_data=val_generator,
        callbacks=callbacks,
        verbose=1
    )

    y_val_pred_prob = model.predict(X_val)
    y_val_pred = (y_val_pred_prob > 0.5).astype(int).flatten()
    acc = accuracy_score(y_val, y_val_pred)
    prec = precision_score(y_val, y_val_pred)
    rec = recall_score(y_val, y_val_pred)
    f1 = f1_score(y_val, y_val_pred)
    fpr, tpr, _ = roc_curve(y_val, y_val_pred_prob)
    roc_auc = auc(fpr, tpr)
    metrics = {'fold': fold_no, 'accuracy': acc, 'precision': prec, 'recall': rec, 'f1': f1, 'roc_auc': roc_auc}
    cv_metrics.append(metrics)
    print(f"Fold {fold_no} metrikleri: {metrics}")

    plt.figure(figsize=(12,5))
    plt.subplot(1,2,1)
    plt.plot(history.history['accuracy'], label='Eğitim Doğruluğu')
    plt.plot(history.history['val_accuracy'], label='Doğrulama Doğruluğu')
    plt.title(f'Fold {fold_no} Doğruluk')
    plt.xlabel('Epoch')
    plt.ylabel('Doğruluk')
    plt.legend()
    plt.subplot(1,2,2)
    plt.plot(history.history['loss'], label='Eğitim Kaybı')
    plt.plot(history.history['val_loss'], label='Doğrulama Kaybı')
    plt.title(f'Fold {fold_no} Kayıp')
    plt.xlabel('Epoch')
    plt.ylabel('Kayıp')
    plt.legend()
    plt.show()

    plt.figure()
    plt.plot(fpr, tpr, label=f'Fold {fold_no} ROC (AUC = {roc_auc:.2f})')
    plt.plot([0,1],[0,1],'k--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title(f'Fold {fold_no} ROC Eğrisi')
    plt.legend()
    plt.show()

    cm = confusion_matrix(y_val, y_val_pred)
    sns.heatmap(cm, annot=True, fmt="d", cmap="Blues")
    plt.title(f'Fold {fold_no} Confusion Matrix')
    plt.xlabel("Predicted")
    plt.ylabel("True")
    plt.show()

    histories.append(history)
    fold_no += 1
    tf.keras.backend.clear_session()
return histories, cv_metrics

print("\n--- Mamogram Modeli için 5-Fold Çapraz Doğrulama ---") mamogram_histories, mamogram_cv_metrics = cross_validate_model(create_mobilevit_branch, mamogram_images, mamogram_labels, epochs=10) print("\nMamogram CV Metrikleri:", mamogram_cv_metrics)

print("\n--- Ultrasound Modeli için 5-Fold Çapraz Doğrulama ---") ultrasound_histories, ultrasound_cv_metrics = cross_validate_model(create_mobilevit_branch, ultrasound_images, ultrasound_labels, epochs=10) print("\nUltrasound CV Metrikleri:", ultrasound_cv_metrics)

print("\n--- Histopatoloji Modeli için 5-Fold Çapraz Doğrulama ---") histopath_histories, histopath_cv_metrics = cross_validate_model(create_mobilevit_branch, histopath_images, histopath_labels, epochs=10) print("\nHistopatoloji CV Metrikleri:", histopath_cv_metrics)

=============================================================================

8. Bölüm: Final Ensemble Model Eğitimi (Tüm Veriler Üzerinde) – Batch Size = 8

=============================================================================

Final eğitim için üç modalitenin örnek sayıları farklı olabilir.

Bu durumda, ortak (rastgele) alt küme seçimi yaparak örnek sayısını eşitleyelim.

min_samples = min(len(mamogram_images), len(ultrasound_images), len(histopath_images)) print("Ortak örnek sayısı:", min_samples)

indices_m = np.random.choice(len(mamogram_images), min_samples, replace=False) indices_u = np.random.choice(len(ultrasound_images), min_samples, replace=False) indices_h = np.random.choice(len(histopath_images), min_samples, replace=False)

mamogram_images_eq = mamogram_images[indices_m] ultrasound_images_eq = ultrasound_images[indices_u] histopath_images_eq = histopath_images[indices_h] mamogram_labels_eq = mamogram_labels[indices_m] # Ground truth olarak mamogram etiketleri kullanılıyor

def create_ensemble_model_ensemble(): branch_mamogram = create_mobilevit_branch(input_shape=(128,128,3)) branch_ultrasound = create_mobilevit_branch(input_shape=(128,128,3)) branch_histopath = create_mobilevit_branch(input_shape=(128,128,3)) input_mamogram = tf.keras.Input(shape=(128,128,3)) input_ultrasound = tf.keras.Input(shape=(128,128,3)) input_histopath = tf.keras.Input(shape=(128,128,3)) feat_mamogram = branch_mamogram(input_mamogram) feat_ultrasound = branch_ultrasound(input_ultrasound) feat_histopath = branch_histopath(input_histopath) merged = concatenate([feat_mamogram, feat_ultrasound, feat_histopath]) x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.001))(merged) x = Dropout(0.5)(x) x = Dense(256, activation='relu', kernel_regularizer=regularizers.l2(0.001))(x) x = Dropout(0.5)(x) output = Dense(1, activation='sigmoid', kernel_regularizer=regularizers.l2(0.001))(x) model = tf.keras.Model(inputs=[input_mamogram, input_ultrasound, input_histopath], outputs=output) model.compile(optimizer=Adam(learning_rate=1e-4), loss='binary_crossentropy', metrics=['accuracy', tf.keras.metrics.AUC(), tf.keras.metrics.Precision(), tf.keras.metrics.Recall()]) return model

ensemble_model = create_ensemble_model_ensemble() ensemble_model.fit( [mamogram_images_eq, ultrasound_images_eq, histopath_images_eq], mamogram_labels_eq, validation_split=0.2, epochs=50, batch_size=8, callbacks=[ EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True, verbose=1), ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6, verbose=1) ], verbose=1 )

MODEL_SAVE_PATH = os.path.join("/content/gdrive/MyDrive/meme_kanseri_modelleri", "final_ensemble_model.keras") os.makedirs(os.path.dirname(MODEL_SAVE_PATH), exist_ok=True) ensemble_model.save(MODEL_SAVE_PATH) print(f"Final Ensemble Model kaydedildi: {MODEL_SAVE_PATH}")

=============================================================================

9. Bölüm: Final Model Performans Değerlendirmesi ve Eğrileri

=============================================================================

Test setine bölünme (rastgele alt küme kullanılarak)

X1 = mamogram_images_eq X2 = ultrasound_images_eq X3 = histopath_images_eq y = mamogram_labels_eq

X1_train, X1_test, X2_train, X2_test, X3_train, X3_test, y_train, y_test = train_test_split( X1, X2, X3, y, test_size=0.2, random_state=42 )

Final model eğitimi ve geçmişini kaydetme

final_history = ensemble_model.fit( [X1_train, X2_train, X3_train], y_train, validation_data=([X1_test, X2_test, X3_test], y_test), epochs=50, # veya önceki eğitimde kullanılan epoch sayısı batch_size=8, # veya önceki eğitimde kullanılan batch size callbacks=[ EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True, verbose=1), ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3, min_lr=1e-6, verbose=1) ], verbose=1 )

eval_results = ensemble_model.evaluate([X1_test, X2_test, X3_test], y_test, verbose=1) print("Test Loss:", eval_results[0]) print("Test Accuracy:", eval_results[1])

y_pred_prob = ensemble_model.predict([X1_test, X2_test, X3_test]) y_pred = (y_pred_prob > 0.5).astype(int).flatten()

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_curve, auc, confusion_matrix

acc = accuracy_score(y_test, y_pred) prec = precision_score(y_test, y_pred) rec = recall_score(y_test, y_pred) f1 = f1_score(y_test, y_pred) fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob) roc_auc = auc(fpr, tpr) cm = confusion_matrix(y_test, y_pred)

print("Test Accuracy:", acc) print("Test Precision:", prec) print("Test Recall:", rec) print("Test F1 Score:", f1) print("Test ROC AUC:", roc_auc)

plt.figure(figsize=(15,5)) plt.subplot(1,3,1) plt.plot(final_history.history['accuracy'], label='Eğitim Accuracy') plt.plot(final_history.history['val_accuracy'], label='Doğrulama Accuracy') plt.title('Final Model Accuracy Eğrisi') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.legend()

plt.subplot(1,3,2) plt.plot(final_history.history['loss'], label='Eğitim Loss') plt.plot(final_history.history['val_loss'], label='Doğrulama Loss') plt.title('Final Model Loss Eğrisi') plt.xlabel('Epoch') plt.ylabel('Loss') plt.legend()

plt.subplot(1,3,3)

Check for all possible 'auc' keys

for key in final_history.history.keys(): if 'auc' in key: auc_key = key break # Exit loop once the 'auc' key is found else: # Raise an error if no 'auc' key is found raise KeyError("AUC metric not found in history")

plt.plot(final_history.history[auc_key], label='Eğitim AUC') plt.plot(final_history.history['val_' + auc_key], label='Doğrulama AUC') plt.title('Final Model AUC Eğrisi') plt.xlabel('Epoch') plt.ylabel('AUC') plt.legend() plt.show()

plt.figure() plt.plot(fpr, tpr, label="ROC curve (AUC = {:.2f})".format(roc_auc)) plt.plot([0, 1], [0, 1], "k--") plt.xlim([0, 1]) plt.ylim([0, 1.05]) plt.xlabel("False Positive Rate") plt.ylabel("True Positive Rate") plt.title("Final Ensemble Model ROC Eğrisi") plt.legend(loc="lower right") plt.show()

plt.figure() sns.heatmap(cm, annot=True, fmt="d", cmap="Blues") plt.title("Final Ensemble Model Confusion Matrix") plt.xlabel("Predicted") plt.ylabel("True") plt.show()

=============================================================================

9. Bölüm: Gradio Web Arayüzü ile Tahmin

=============================================================================

def predict_ensemble(mamogram_img, ultrasound_img, histopath_img): mamogram_img = cv2.resize(mamogram_img, (128,128)) / 255.0 ultrasound_img = cv2.resize(ultrasound_img, (128,128)) / 255.0 histopath_img = cv2.resize(histopath_img, (128,128)) / 255.0 mamogram_img = np.expand_dims(mamogram_img, axis=0) ultrasound_img = np.expand_dims(ultrasound_img, axis=0) histopath_img = np.expand_dims(histopath_img, axis=0) pred = ensemble_model.predict([mamogram_img, ultrasound_img, histopath_img]) result = "Malignant" if pred[0][0] > 0.5 else "Benign" confidence = float(pred[0][0]) return {"Tahmin": result, "Güven": confidence}

interface = gr.Interface( fn=predict_ensemble, inputs=[ gr.Image(label="Mamogram Görüntüsü", type="numpy"), # Remove 'shape' and set type to 'numpy' gr.Image(label="Ultrasound Görüntüsü", type="numpy"), # Remove 'shape' and set type to 'numpy' gr.Image(label="Histopatoloji Görüntüsü", type="numpy") # Remove 'shape' and set type to 'numpy' ], outputs=[ gr.Label(label="Tahmin"), gr.Number(label="Güven") ], title="Meme Kanseri Tespiti - Ensemble Model", description="Mamogram, Ultrasound ve Histopatoloji görüntülerini yükleyin; ensemble modelimiz kanser tespiti yapsın." ) interface.launch(share=True)

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