{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "os.chdir('../')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'d:\\\\MLOps-Project\\\\Kidney-disease-classification-mlops'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%pwd" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "import tensorflow as tf" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "model = tf.keras.models.load_model('artifacts/training/model.h5')" ] }, { "cell_type": "code", "execution_count": 5, "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\n", " " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "from cnnClassifier.utils.common import read_yaml, create_directories,save_json\n", "from cnnClassifier.constant import *\n", "\n", "from cnnClassifier.utils.common import read_yaml, create_directories\n", "from cnnClassifier.constant import *\n", "# Configuration\n", "class ConfigurationManager:\n", " def __init__(\n", " self,\n", " config_filepath = CONFIG_FILE_PATH,\n", " params_filepath = PARAMS_FILE_PATH):\n", "\n", " self.config = read_yaml(config_filepath)\n", " self.params = read_yaml(params_filepath)\n", "\n", " create_directories([self.config.atifacts_root])\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/unzip/kidney-ct-scan-image',\n", " mlflow_uri='https://dagshub.com/azizulhakim8291/Kidney-disease-classification-mlops.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", " " ] }, { "cell_type": "code", "execution_count": 13, "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": 17, "metadata": {}, "outputs": [], "source": [ "class Evaluation:\n", " def __init__(self, config: EvaluationConfig):\n", " self.config = config\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", " @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", " 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": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2024-08-01 23:40:02,445: INFO: _client: HTTP Request: GET https://dagshub.com/api/v1/repos/azizulhakim8291/Kidney-disease-classification-mlops \"HTTP/1.1 200 OK\"]\n" ] }, { "data": { "text/html": [ "
Initialized MLflow to track repo \"azizulhakim8291/Kidney-disease-classification-mlops\"\n",
       "
\n" ], "text/plain": [ "Initialized MLflow to track repo \u001b[32m\"azizulhakim8291/Kidney-disease-classification-mlops\"\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[2024-08-01 23:40:02,453: INFO: helpers: Initialized MLflow to track repo \"azizulhakim8291/Kidney-disease-classification-mlops\"]\n" ] }, { "data": { "text/html": [ "
Repository azizulhakim8291/Kidney-disease-classification-mlops initialized!\n",
       "
\n" ], "text/plain": [ "Repository azizulhakim8291/Kidney-disease-classification-mlops initialized!\n" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "[2024-08-01 23:40:02,458: INFO: helpers: Repository azizulhakim8291/Kidney-disease-classification-mlops initialized!]\n" ] } ], "source": [ "import dagshub\n", "dagshub.init(repo_owner='azizulhakim8291', repo_name='Kidney-disease-classification-mlops', mlflow=True)\n", "\n", "import mlflow\n", "with mlflow.start_run():\n", " mlflow.log_param('parameter name', 'value')\n", " mlflow.log_metric('metric name', 1)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2024-08-01 23:44:03,754: INFO: common: yaml file: config\\config.yaml loaded successfully]\n", "[2024-08-01 23:44:03,764: INFO: common: yaml file: params.yaml loaded successfully]\n", "[2024-08-01 23:44:03,770: INFO: common: Created directory at: artifacts]\n", "Found 139 images belonging to 2 classes.\n", "9/9 [==============================] - 13s 1s/step - loss: 0.5003 - accuracy: 0.9568\n", "[2024-08-01 23:44:17,498: INFO: common: Json file saved at: scores.json]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "2024/08/01 23:44:20 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": [ "[2024-08-01 23:44:22,432: 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: C:\\Users\\User\\AppData\\Local\\Temp\\tmp8n0wc3k0\\model\\data\\model\\assets\n", "[2024-08-01 23:44:24,256: INFO: builder_impl: Assets written to: C:\\Users\\User\\AppData\\Local\\Temp\\tmp8n0wc3k0\\model\\data\\model\\assets]\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Registered model 'VGG16Model' already exists. Creating a new version of this model...\n", "2024/08/01 23:47:06 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": "Python 3", "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.0" } }, "nbformat": 4, "nbformat_minor": 2 }