BrainTumorTest / train_efficientnetb0_finetuned.py
starpreeda's picture
Upload train_efficientnetb0_finetuned.py
e335787 verified
Raw
History Blame Contribute Delete
4.95 kB
import tensorflow as tf
from tensorflow.keras.applications import EfficientNetB0
from tensorflow.keras.applications.efficientnet import preprocess_input
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping
import numpy as np
TRAIN_DIR = r'C:\Python_CV\mritest\Training'
TEST_DIR = r'C:\Python_CV\mritest\Testing'
IMG_SIZE = (224, 224)
BATCH_SIZE = 16 # ลด Batch Size ลงเพื่อเพิ่ม Generalization
# 1. Data Augmentation แบบเข้มข้น
train_datagen = ImageDataGenerator(
preprocessing_function=preprocess_input,
rotation_range=15,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.1,
zoom_range=0.15,
horizontal_flip=True,
fill_mode='nearest'
)
test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
train_gen = train_datagen.flow_from_directory(
TRAIN_DIR, target_size=IMG_SIZE, batch_size=BATCH_SIZE, class_mode='categorical', shuffle=True
)
test_gen = test_datagen.flow_from_directory(
TEST_DIR, target_size=IMG_SIZE, batch_size=BATCH_SIZE, class_mode='categorical', shuffle=False
)
# 2. สร้างโครงสร้างโมเดล
base_model = EfficientNetB0(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# Unfreeze 40 ชั้นสุดท้ายของ EfficientNetB0 เพื่อ Fine-Tune
base_model.trainable = True
for layer in base_model.layers[:-40]:
layer.trainable = False
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = BatchNormalization()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.4)(x) # ลด Overfitting
outputs = Dense(4, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=outputs)
# 3. คอมไพล์โมเดลด้วย Learning Rate ต่ำสำหรับ Fine-tuning
model.compile(
optimizer=Adam(learning_rate=1e-4),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 4. Callbacks ปรับ Learning Rate อัตโนมัติเมื่อ Accuracy เริ่มนิ่ง
callbacks = [
ReduceLROnPlateau(monitor='val_accuracy', factor=0.3, patience=3, verbose=1, min_lr=1e-6),
EarlyStopping(monitor='val_accuracy', patience=7, restore_best_weights=True)
]
# 5. เทรนโมเดล
print("Starting Fine-Tuning Training...")
history = model.fit(
train_gen,
epochs=25,
validation_data=test_gen,
callbacks=callbacks
)
# 6. ประเมินผลความแม่นยำ
test_loss, test_acc = model.evaluate(test_gen)
print(f"\n>>> Final Test Accuracy: {test_acc * 100:.2f}% <<<")
# บันทึกโมเดลไว้ในโฟลเดอร์โครงการ
model.save(r'C:\Python_CV\mritest\efficientnetb0_finetuned_brain_mri.keras')
print("เซฟโมเดลแบบ .keras เรียบร้อยแล้ว!")
from sklearn.metrics import classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# 1. พยากรณ์ผลบนชุด Testing Data
test_gen.reset()
y_pred_prob = model.predict(test_gen, verbose=1)
y_pred = np.argmax(y_pred_prob, axis=1)
y_true = test_gen.classes
class_labels = list(test_gen.class_indices.keys())
# 2. พิมพ์รายงาน Classification Report (Precision, Recall, F1-score)
print("\n================ Classification Report ================")
print(classification_report(y_true, y_pred, target_names=class_labels))
# 3. วาดกราฟ Confusion Matrix
cm = confusion_matrix(y_true, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=class_labels, yticklabels=class_labels)
plt.title('Fine-Tuned EfficientNetB0 - Confusion Matrix')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()
# พล็อต กราฟ Loss & Accuracy
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(len(acc))
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation/Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation/Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()