{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'f:\\\\Projects\\\\End-to-End-Chest-Cancer-Classification-using-MLflow-and-DVC\\\\research'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%pwd" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "os.chdir(\"../\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'f:\\\\Projects\\\\End-to-End-Chest-Cancer-Classification-using-MLflow-and-DVC'" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%pwd" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "os.environ[\"MLFLOW_TRACKING_URI\"]=\"https://dagshub.com/AlyyanAhmed21/End-to-End-Chest-Cancer-Classification-using-MLflow-and-DVC.mlflow\"\n", "os.environ[\"MLFLOW_TRACKING_USERNAME\"]=\"AlyyanAhmed21\"\n", "os.environ[\"MLFLOW_TRACKING_PASSWORD\"]=\"776454e991d86ea3a96179a4dc1ef72fbc134642\"" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "model = tf.keras.models.load_model(\"artifacts/training/model.h5\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from dataclasses import dataclass\n", "from pathlib import Path\n", "\n", "@dataclass(frozen=True)\n", "class EvaluationConfig:\n", " path_of_model: Path\n", " training_data: Path\n", " all_params: dict\n", " mlflow_uri: str\n", " params_image_size: list\n", " params_batch_size: int" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "from cnnClassifier.constants import *\n", "from cnnClassifier.utils.common import read_yaml, create_directories, save_json" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "class ConfigurationManager:\n", " def __init__(\n", " self, \n", " config_filepath = CONFIG_FILE_PATH,\n", " params_filepath = PARAMS_FILE_PATH):\n", " self.config = read_yaml(config_filepath)\n", " self.params = read_yaml(params_filepath)\n", " create_directories([self.config.artifacts_root])\n", "\n", " \n", " def get_evaluation_config(self) -> EvaluationConfig:\n", " eval_config = EvaluationConfig(\n", " path_of_model=\"artifacts/training/model.h5\",\n", " training_data=\"artifacts/data_ingestion/Chest-CT-Scan-data\",\n", " mlflow_uri=\"https://dagshub.com/AlyyanAhmed21/End-to-End-Chest-Cancer-Classification-using-MLflow-and-DVC.mlflow\",\n", " all_params=self.params,\n", " params_image_size=self.params.IMAGE_SIZE,\n", " params_batch_size=self.params.BATCH_SIZE\n", " )\n", " return eval_config\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf\n", "from pathlib import Path\n", "import mlflow\n", "import mlflow.keras\n", "from urllib.parse import urlparse" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "class Evaluation:\n", " def __init__(self, config: EvaluationConfig):\n", " self.config = config\n", "\n", " \n", " def _valid_generator(self):\n", "\n", " datagenerator_kwargs = dict(\n", " rescale = 1./255,\n", " validation_split=0.30\n", " )\n", "\n", " dataflow_kwargs = dict(\n", " target_size=self.config.params_image_size[:-1],\n", " batch_size=self.config.params_batch_size,\n", " interpolation=\"bilinear\"\n", " )\n", "\n", " valid_datagenerator = tf.keras.preprocessing.image.ImageDataGenerator(\n", " **datagenerator_kwargs\n", " )\n", "\n", " self.valid_generator = valid_datagenerator.flow_from_directory(\n", " directory=self.config.training_data,\n", " subset=\"validation\",\n", " shuffle=False,\n", " **dataflow_kwargs\n", " )\n", "\n", "\n", " @staticmethod\n", " def load_model(path: Path) -> tf.keras.Model:\n", " return tf.keras.models.load_model(path)\n", " \n", "\n", " def evaluation(self):\n", " self.model = self.load_model(self.config.path_of_model)\n", " self._valid_generator()\n", " self.score = model.evaluate(self.valid_generator)\n", " self.save_score()\n", "\n", " def save_score(self):\n", " scores = {\"loss\": self.score[0], \"accuracy\": self.score[1]}\n", " save_json(path=Path(\"scores.json\"), data=scores)\n", "\n", " \n", " def log_into_mlflow(self):\n", " mlflow.set_registry_uri(self.config.mlflow_uri)\n", " tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme\n", " \n", " with mlflow.start_run():\n", " mlflow.log_params(self.config.all_params)\n", " mlflow.log_metrics(\n", " {\"loss\": self.score[0], \"accuracy\": self.score[1]}\n", " )\n", " # Model registry does not work with file store\n", " if tracking_url_type_store != \"file\":\n", "\n", " # Register the model\n", " # There are other ways to use the Model Registry, which depends on the use case,\n", " # please refer to the doc for more information:\n", " # https://mlflow.org/docs/latest/model-registry.html#api-workflow\n", " mlflow.keras.log_model(self.model, \"model\", registered_model_name=\"VGG16Model\")\n", " else:\n", " mlflow.keras.log_model(self.model, \"model\")\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2025-08-20 04:01:28,984: INFO: common: yaml file: config\\config.yaml loaded successfully]\n", "[2025-08-20 04:01:28,988: INFO: common: yaml file: params.yaml loaded successfully]\n", "[2025-08-20 04:01:28,991: INFO: common: created directory at: artifacts]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Found 102 images belonging to 2 classes.\n", "7/7 [==============================] - 16s 2s/step - loss: 57.2713 - accuracy: 0.4314\n", "[2025-08-20 04:01:45,268: INFO: common: json file saved at: scores.json]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2025/08/20 04:01:47 WARNING mlflow.tensorflow: You are saving a TensorFlow Core model or Keras model without a signature. Inference with mlflow.pyfunc.spark_udf() will not work unless the model's pyfunc representation accepts pandas DataFrames as inference inputs.\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "[2025-08-20 04:01:48,249: WARNING: save: Found untraced functions such as _jit_compiled_convolution_op, _jit_compiled_convolution_op, _jit_compiled_convolution_op, _jit_compiled_convolution_op, _jit_compiled_convolution_op while saving (showing 5 of 14). These functions will not be directly callable after loading.]\n", "INFO:tensorflow:Assets written to: E:\\Temp\\tmp32wvm7sm\\model\\data\\model\\assets\n", "[2025-08-20 04:01:49,538: INFO: builder_impl: Assets written to: E:\\Temp\\tmp32wvm7sm\\model\\data\\model\\assets]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "f:\\Projects\\End-to-End-Chest-Cancer-Classification-using-MLflow-and-DVC\\cnn_env\\Lib\\site-packages\\_distutils_hack\\__init__.py:33: UserWarning: Setuptools is replacing distutils.\n", " warnings.warn(\"Setuptools is replacing distutils.\")\n", "Registered model 'VGG16Model' already exists. Creating a new version of this model...\n", "2025/08/20 04:02:45 INFO mlflow.tracking._model_registry.client: Waiting up to 300 seconds for model version to finish creation. Model name: VGG16Model, version 2\n", "Created version '2' of model 'VGG16Model'.\n" ] } ], "source": [ "try:\n", " config = ConfigurationManager()\n", " eval_config = config.get_evaluation_config()\n", " evaluation = Evaluation(eval_config)\n", " evaluation.evaluation()\n", " evaluation.log_into_mlflow()\n", "\n", "except Exception as e:\n", " raise e" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "cnn_env", "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.3" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }