Downloads · 30 days
0
Alfakurt46/Multimodality_Breast_Cancer_Detection_Project
Multimodality_Breast_Cancer_Detection_Project is a machine learning model from Alfakurt46. Use it for the machine learning task on the model card, and read the license before you ship it in a product.
"""Çok Modaliteli Meme Kanseri Tespiti Projesi.ipynb
Downloads · 30 days
0
Access
Public
Updated Mar 6, 2025
Repo size
—
Likes
0
Public
Click a slice to open those files.
.md24 KB · 94%
From the Hugging Face model README
"""Çok Modaliteli Meme Kanseri Tespiti Projesi.ipynb
Automatically generated by Colab.
Original file is located at https://colab.research.google.com/drive/1iRYBNFcFPCbFxvIgtkKobOufHoSUvInz """
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)
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
from google.colab import drive drive.mount('/content/gdrive', force_remount=True)
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")
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ış.")
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.")
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ş!")
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")
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
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)
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}")
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_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)
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()
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)