HuangYiYang's picture
Upload 4 files
995ef3a verified
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import AveragePooling2D, Dropout, Flatten, Dense, Input
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.regularizers import l2
from tensorflow.keras.callbacks import EarlyStopping
from sklearn.model_selection import train_test_split
import os
from PIL import UnidentifiedImageError
import matplotlib.pyplot as plt
# --- Data Loading and Preprocessing ---
data_dir = "dataset"
categories = ["with_mask", "without_mask"]
data = []
labels = []
print("Loading and preprocessing images for final model training...")
for category in categories:
path = os.path.join(data_dir, category)
for img_name in os.listdir(path):
img_path = os.path.join(path, img_name)
try:
image = load_img(img_path, target_size=(224, 224))
image = img_to_array(image)
image = preprocess_input(image)
data.append(image)
labels.append(0 if category == "with_mask" else 1)
except UnidentifiedImageError:
print(f"Skipped invalid image file: {img_path}")
except Exception as e:
print(f"Error loading image {img_path}: {e}")
print(f"Loaded {len(data)} images.")
data = np.array(data, dtype="float32")
labels = to_categorical(labels)
x_train, x_test, y_train, y_test = train_test_split(data, labels, test_size=0.2, stratify=labels, random_state=42)
print(f"Training samples: {len(x_train)}, Validation samples: {len(x_test)}")
# --- Data Augmentation Configuration ---
aug = ImageDataGenerator(
rotation_range=30,
zoom_range=0.2,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
horizontal_flip=True,
brightness_range=[0.7, 1.3],
channel_shift_range=50,
fill_mode="nearest"
)
# --- Define Optimal Hyperparameters (THESE NEED TO BE FILLED IN MANUALLY) ---
OPTIMAL_UNITS = 128 # <--- Update this value
OPTIMAL_L2_REGULARIZER = 0.0001 # <--- Update this value
OPTIMAL_DROPOUT_RATE = 0.3 # <--- Update this value
OPTIMAL_LEARNING_RATE = 0.0001 # <--- Update this value
# --- Model Building with Optimal Hyperparameters ---
base_model = MobileNetV2(weights="imagenet", include_top=False, input_tensor=Input(shape=(224, 224, 3)))
for layer in base_model.layers[:-20]:
layer.trainable = False
head_model = base_model.output
head_model = AveragePooling2D(pool_size=(7, 7))(head_model)
head_model = Flatten()(head_model)
head_model = Dense(OPTIMAL_UNITS, activation="relu", kernel_regularizer=l2(OPTIMAL_L2_REGULARIZER))(head_model)
head_model = Dropout(OPTIMAL_DROPOUT_RATE)(head_model)
head_model = Dense(2, activation="softmax")(head_model)
model = Model(inputs=base_model.input, outputs=head_model)
model.compile(optimizer=Adam(learning_rate=OPTIMAL_LEARNING_RATE),
loss="categorical_crossentropy",
metrics=["accuracy"])
print("\nModel compiled with optimal hyperparameters. Starting final training...")
# --- Training the Final Model ---
early_stopping_final = EarlyStopping(
monitor='val_loss',
patience=10,
restore_best_weights=True
)
history = model.fit(
aug.flow(x_train, y_train, batch_size=32),
validation_data=(x_test, y_test),
steps_per_epoch=len(x_train) // 32,
epochs=100,
callbacks=[early_stopping_final]
)
print("\nFinal training complete.")
# --- Evaluation and Plotting ---
final_train_loss = history.history['loss'][-1]
final_train_accuracy = history.history['accuracy'][-1]
final_val_loss = history.history['val_loss'][-1]
final_val_accuracy = history.history['val_accuracy'][-1]
print("\nFinal Training Metrics:")
print(f"Training Loss: {final_train_loss:.4f}")
print(f"Training Accuracy: {final_train_accuracy:.4f}")
print("\nFinal Validation Metrics:")
print(f"Validation Loss: {final_val_loss:.4f}")
print(f"Validation Accuracy: {final_val_accuracy:.4f}")
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
# --- Save the Final Trained Model ---
model.save("mask_detector_final_model.keras")
print("Final model saved as mask_detector_final_model.keras")