{ "cells": [ { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import mlflow\n", "\n", "mlflow_server_uri = \"https://champi.heuzef.com\"\n", "\n", "mlflow.set_tracking_uri(mlflow_server_uri)\n", "mlflow.set_experiment(\"champi\") # Le nom du projet\n", "\n", "with mlflow.start_run():\n", " for epoch, metrics in epochs_data.items():\n", " mlflow.log_metric(\"accuracy\", metrics[\"accuracy\"], step=epoch)\n", " mlflow.log_metric(\"loss\", metrics[\"loss\"], step=epoch)\n", " mlflow.log_metric(\"val_accuracy\", metrics[\"val_accuracy\"], step=epoch)\n", " mlflow.log_metric(\"val_loss\", metrics[\"val_loss\"], step=epoch)\n", " mlflow.log_metric(\"learning_rate\", metrics[\"learning_rate\"], step=epoch)\n", " mlflow.log_param(\"model\", \"resnet50_callbacks_5layers_unfreeze\")" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "epochs_data = {\n", " 1: {\n", " \"accuracy\": 0.0847,\n", " \"loss\": 5.8520,\n", " \"val_accuracy\": 0.4417,\n", " \"val_loss\": 3.9198,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 2: {\n", " \"accuracy\": 0.1360,\n", " \"loss\": 4.2380,\n", " \"val_accuracy\": 0.5399,\n", " \"val_loss\": 3.6218,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 3: {\n", " \"accuracy\": 0.2402,\n", " \"loss\": 3.9099,\n", " \"val_accuracy\": 0.6810,\n", " \"val_loss\": 3.2485,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 4: {\n", " \"accuracy\": 0.3660,\n", " \"loss\": 3.5690,\n", " \"val_accuracy\": 0.7362,\n", " \"val_loss\": 2.7518,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 5: {\n", " \"accuracy\": 0.4996,\n", " \"loss\": 3.1509,\n", " \"val_accuracy\": 0.7730,\n", " \"val_loss\": 2.3880,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 6: {\n", " \"accuracy\": 0.6404,\n", " \"loss\": 2.7446,\n", " \"val_accuracy\": 0.7914,\n", " \"val_loss\": 2.2776,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 7: {\n", " \"accuracy\": 0.7238,\n", " \"loss\": 2.4671,\n", " \"val_accuracy\": 0.8160,\n", " \"val_loss\": 2.2215,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 8: {\n", " \"accuracy\": 0.7835,\n", " \"loss\": 2.2709,\n", " \"val_accuracy\": 0.8221,\n", " \"val_loss\": 2.1896,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 9: {\n", " \"accuracy\": 0.8369,\n", " \"loss\": 2.0898,\n", " \"val_accuracy\": 0.8344,\n", " \"val_loss\": 2.1191,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 10: {\n", " \"accuracy\": 0.8759,\n", " \"loss\": 1.9587,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 2.1327,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 11: {\n", " \"accuracy\": 0.9061,\n", " \"loss\": 1.8641,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 2.0924,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 12: {\n", " \"accuracy\": 0.9285,\n", " \"loss\": 1.7836,\n", " \"val_accuracy\": 0.8405,\n", " \"val_loss\": 2.1150,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 13: {\n", " \"accuracy\": 0.9438,\n", " \"loss\": 1.7205,\n", " \"val_accuracy\": 0.8466,\n", " \"val_loss\": 2.0380,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 14: {\n", " \"accuracy\": 0.9596,\n", " \"loss\": 1.6534,\n", " \"val_accuracy\": 0.8405,\n", " \"val_loss\": 2.0600,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 15: {\n", " \"accuracy\": 0.9639,\n", " \"loss\": 1.6170,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 2.0319,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 16: {\n", " \"accuracy\": 0.9740,\n", " \"loss\": 1.5687,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 2.0340,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 17: {\n", " \"accuracy\": 0.9745,\n", " \"loss\": 1.5440,\n", " \"val_accuracy\": 0.8405,\n", " \"val_loss\": 2.0015,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 18: {\n", " \"accuracy\": 0.9821,\n", " \"loss\": 1.5040,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.9666,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 19: {\n", " \"accuracy\": 0.9877,\n", " \"loss\": 1.4689,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.9311,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 20: {\n", " \"accuracy\": 0.9911,\n", " \"loss\": 1.4414,\n", " \"val_accuracy\": 0.8773,\n", " \"val_loss\": 1.9213,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 21: {\n", " \"accuracy\": 0.9876,\n", " \"loss\": 1.4215,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 1.9028,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 22: {\n", " \"accuracy\": 0.9938,\n", " \"loss\": 1.3837,\n", " \"val_accuracy\": 0.8773,\n", " \"val_loss\": 1.8655,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 23: {\n", " \"accuracy\": 0.9908,\n", " \"loss\": 1.3609,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 1.9050,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 24: {\n", " \"accuracy\": 0.9949,\n", " \"loss\": 1.3233,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 1.8978,\n", " \"learning_rate\": 1.0000e-05\n", " },\n", " 25: {\n", " \"accuracy\": 0.9954,\n", " \"loss\": 1.2955,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8539,\n", " \"learning_rate\": 2.0000e-06\n", " },\n", " 26: {\n", " \"accuracy\": 0.9962,\n", " \"loss\": 1.2885,\n", " \"val_accuracy\": 0.8712,\n", " \"val_loss\": 1.8314,\n", " \"learning_rate\": 2.0000e-06\n", " },\n", " 27: {\n", " \"accuracy\": 0.9958,\n", " \"loss\": 1.2817,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8324,\n", " \"learning_rate\": 2.0000e-06\n", " },\n", " 28: {\n", " \"accuracy\": 0.9976,\n", " \"loss\": 1.2710,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 1.8316,\n", " \"learning_rate\": 2.0000e-06\n", " },\n", " 29: {\n", " \"accuracy\": 0.9963,\n", " \"loss\": 1.2652,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8263,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 30: {\n", " \"accuracy\": 0.9975,\n", " \"loss\": 1.2591,\n", " \"val_accuracy\": 0.8712,\n", " \"val_loss\": 1.8105,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 31: {\n", " \"accuracy\": 0.9979,\n", " \"loss\": 1.2559,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8199,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 32: {\n", " \"accuracy\": 0.9978,\n", " \"loss\": 1.2485,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8312,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 33: {\n", " \"accuracy\": 0.9972,\n", " \"loss\": 1.2443,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 1.8201,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 34: {\n", " \"accuracy\": 0.9980,\n", " \"loss\": 1.2402,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.8054,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 35: {\n", " \"accuracy\": 0.9987,\n", " \"loss\": 1.2324,\n", " \"val_accuracy\": 0.8528,\n", " \"val_loss\": 1.7969,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 36: {\n", " \"accuracy\": 0.9985,\n", " \"loss\": 1.2261,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 1.7965,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 37: {\n", " \"accuracy\": 0.9986,\n", " \"loss\": 1.2198,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 1.7878,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 38: {\n", " \"accuracy\": 0.9990,\n", " \"loss\": 1.2131,\n", " \"val_accuracy\": 0.8650,\n", " \"val_loss\": 1.7906,\n", " \"learning_rate\": 1.0000e-06\n", " },\n", " 39: {\n", " \"accuracy\": 0.9977,\n", " \"loss\": 1.2106,\n", " \"val_accuracy\": 0.8589,\n", " \"val_loss\": 1.7810,\n", " \"learning_rate\": 1.0000e-06\n", " }\n", "}\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import json\n", "import tensorflow as tf\n", "from tensorflow.keras.applications import ResNet50\n", "from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\n", "from tensorflow.keras.models import Model\n", "from tensorflow.keras.optimizers import Adam\n", "from tensorflow.keras.regularizers import l2\n", "from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau\n", "\n", "# Define paths to directories\n", "train_dir = 'C:/Users/vsavelev/GITHUB/DS_projet/LAYER2/MO/train'\n", "validation_dir = 'C:/Users/vsavelev/GITHUB/DS_projet/LAYER2/MO/validation'\n", "\n", "# Create Dataset from directories\n", "def create_dataset(directory, batch_size):\n", " dataset = tf.keras.preprocessing.image_dataset_from_directory(\n", " directory,\n", " image_size=(224, 224),\n", " batch_size=batch_size,\n", " label_mode='categorical', # Labels are one-hot encoded\n", " shuffle=True\n", " )\n", " return dataset\n", "\n", "# Load data from directories\n", "batch_size = 32\n", "train_dataset = create_dataset(train_dir, batch_size)\n", "validation_dataset = create_dataset(validation_dir, batch_size)\n", "\n", "# Build ResNet50 Model\n", "base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))\n", "x = base_model.output\n", "x = GlobalAveragePooling2D()(x)\n", "x = Dropout(0.7)(x)\n", "x = Dense(1024, activation='relu', kernel_regularizer=l2(0.001))(x)\n", "x = Dropout(0.7)(x)\n", "predictions = Dense(len(train_dataset.class_names), activation='softmax', kernel_regularizer=l2(0.01))(x)\n", "\n", "model = Model(inputs=base_model.input, outputs=predictions)\n", "\n", "# Unfreeze the last few layers\n", "for layer in base_model.layers[-5:]:\n", " layer.trainable = True\n", "\n", "# Compile the model\n", "model.compile(optimizer=Adam(learning_rate=1e-5),\n", " loss='categorical_crossentropy',\n", " metrics=['accuracy'])\n", "\n", "# Callbacks for early stopping and learning rate reduction\n", "early_stopping = EarlyStopping(\n", " monitor='val_loss', \n", " patience=3, \n", " restore_best_weights=True \n", ")\n", "\n", "reduce_lr = ReduceLROnPlateau(\n", " monitor='val_loss', \n", " factor=0.2, \n", " patience=2, \n", " min_lr=1e-6 \n", ")\n", "\n", "# Custom callback to save metrics per epoch to a JSON file\n", "class MetricsLogger(tf.keras.callbacks.Callback):\n", " def __init__(self, log_file='training_metrics.json'):\n", " super().__init__()\n", " self.log_file = log_file\n", " self.logs = []\n", "\n", " def on_epoch_end(self, epoch, logs=None):\n", " self.logs.append({\n", " 'epoch': epoch,\n", " 'loss': logs['loss'],\n", " 'accuracy': logs['accuracy'],\n", " 'val_loss': logs['val_loss'],\n", " 'val_accuracy': logs['val_accuracy']\n", " })\n", " with open(self.log_file, 'w') as f:\n", " json.dump(self.logs, f, indent=4)\n", "\n", "# Train the model and log metrics\n", "metrics_logger = MetricsLogger(log_file='training_metrics.json')\n", "\n", "history = model.fit(\n", " train_dataset,\n", " epochs=50,\n", " validation_data=validation_dataset,\n", " callbacks=[reduce_lr, early_stopping, metrics_logger]\n", ")\n", "\n", "# Save the model\n", "model.save('resnet50_model_callbacks.h5')\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import mlflow\n", "import mlflow.keras\n", "import json\n", "import matplotlib.pyplot as plt\n", "\n", "# Function to load metrics from JSON\n", "def load_metrics_from_json(log_file='training_metrics.json'):\n", " with open(log_file, 'r') as f:\n", " return json.load(f)\n", "\n", "# Function to plot training history\n", "def plot_training_history(metrics):\n", " epochs = [m['epoch'] for m in metrics]\n", " train_accuracy = [m['accuracy'] for m in metrics]\n", " val_accuracy = [m['val_accuracy'] for m in metrics]\n", " train_loss = [m['loss'] for m in metrics]\n", " val_loss = [m['val_loss'] for m in metrics]\n", " \n", " plt.figure(figsize=(12, 8))\n", " \n", " # Plot training & validation accuracy values\n", " plt.subplot(1, 2, 1)\n", " plt.plot(epochs, train_accuracy)\n", " plt.plot(epochs, val_accuracy)\n", " plt.title('Model accuracy')\n", " plt.ylabel('Accuracy')\n", " plt.xlabel('Epoch')\n", " plt.legend(['Train', 'Validation'], loc='upper left')\n", "\n", " # Plot training & validation loss values\n", " plt.subplot(1, 2, 2)\n", " plt.plot(epochs, train_loss)\n", " plt.plot(epochs, val_loss)\n", " plt.title('Model loss')\n", " plt.ylabel('Loss')\n", " plt.xlabel('Epoch')\n", " plt.legend(['Train', 'Validation'], loc='upper left')\n", "\n", " plt.savefig(\"training_history.png\")\n", " plt.show()\n", "\n", "# Load metrics and log to MLflow\n", "with mlflow.start_run():\n", " # Load metrics from JSON\n", " metrics = load_metrics_from_json('training_metrics.json')\n", "\n", " # Log metrics for each epoch\n", " for m in metrics:\n", " mlflow.log_metric('train_loss', m['loss'], step=m['epoch'])\n", " mlflow.log_metric('train_accuracy', m['accuracy'], step=m['epoch'])\n", " mlflow.log_metric('val_loss', m['val_loss'], step=m['epoch'])\n", " mlflow.log_metric('val_accuracy', m['val_accuracy'], step=m['epoch'])\n", "\n", " # Log hyperparameters\n", " mlflow.log_param(\"learning_rate\", 1e-5)\n", " mlflow.log_param(\"batch_size\", 32)\n", " mlflow.log_param(\"dropout_rate\", 0.7)\n", " mlflow.log_param(\"l2_regularization\", 0.01)\n", " \n", " # Plot and log training history\n", " plot_training_history(metrics)\n", " mlflow.log_artifact(\"training_history.png\")\n", "\n", " # Log the trained model\n", " mlflow.keras.log_model(tf.keras.models.load_model('resnet50_model_callbacks.h5'), \"resnet50_model\")\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.7" } }, "nbformat": 4, "nbformat_minor": 2 }