shrey-patel-710 commited on
Commit
35c4f9e
1 Parent(s): d1760e8

all files added

Browse files
Files changed (47) hide show
  1. Kidney-Disease-Classifcation/.dvc/.gitignore +3 -0
  2. Kidney-Disease-Classifcation/.dvc/config +0 -0
  3. Kidney-Disease-Classifcation/.dvcignore +3 -0
  4. Kidney-Disease-Classifcation/.gitattributes +2 -0
  5. Kidney-Disease-Classifcation/.github/workflows/.gitkeep +0 -0
  6. Kidney-Disease-Classifcation/.gitignore +161 -0
  7. Kidney-Disease-Classifcation/.pre-commit-config.yaml +10 -0
  8. Kidney-Disease-Classifcation/README.md +70 -0
  9. Kidney-Disease-Classifcation/app.py +50 -0
  10. Kidney-Disease-Classifcation/config/config.yaml +19 -0
  11. Kidney-Disease-Classifcation/dvc.lock +112 -0
  12. Kidney-Disease-Classifcation/dvc.yaml +50 -0
  13. Kidney-Disease-Classifcation/main.py +62 -0
  14. Kidney-Disease-Classifcation/model/model.h5 +3 -0
  15. Kidney-Disease-Classifcation/params.yaml +6 -0
  16. Kidney-Disease-Classifcation/requirements.txt +18 -0
  17. Kidney-Disease-Classifcation/research/01_data_ingestion.ipynb +252 -0
  18. Kidney-Disease-Classifcation/research/02_prepare_base_model.ipynb +281 -0
  19. Kidney-Disease-Classifcation/research/03_model_training.ipynb +341 -0
  20. Kidney-Disease-Classifcation/research/04_model_evaluation_with_mlflow.ipynb +346 -0
  21. Kidney-Disease-Classifcation/research/trials.ipynb +91 -0
  22. Kidney-Disease-Classifcation/scores.json +4 -0
  23. Kidney-Disease-Classifcation/setup.py +27 -0
  24. Kidney-Disease-Classifcation/src/kidney_classification/__init__.py +18 -0
  25. Kidney-Disease-Classifcation/src/kidney_classification/components/__init__.py +0 -0
  26. Kidney-Disease-Classifcation/src/kidney_classification/components/data_ingestion.py +45 -0
  27. Kidney-Disease-Classifcation/src/kidney_classification/components/model_evaluation_mlflow.py +59 -0
  28. Kidney-Disease-Classifcation/src/kidney_classification/components/model_training.py +49 -0
  29. Kidney-Disease-Classifcation/src/kidney_classification/components/prepare_base_model.py +46 -0
  30. Kidney-Disease-Classifcation/src/kidney_classification/config/__init__.py +0 -0
  31. Kidney-Disease-Classifcation/src/kidney_classification/config/configuration.py +83 -0
  32. Kidney-Disease-Classifcation/src/kidney_classification/constants/__init__.py +4 -0
  33. Kidney-Disease-Classifcation/src/kidney_classification/entity/__init__.py +0 -0
  34. Kidney-Disease-Classifcation/src/kidney_classification/entity/config_entity.py +42 -0
  35. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/__init__.py +0 -0
  36. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/prediction.py +31 -0
  37. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_01_data_ingestion.py +31 -0
  38. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_02_prepare_base_model.py +30 -0
  39. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_03_model_training.py +32 -0
  40. Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py +32 -0
  41. Kidney-Disease-Classifcation/src/kidney_classification/utils/__init__.py +0 -0
  42. Kidney-Disease-Classifcation/src/kidney_classification/utils/common.py +79 -0
  43. Kidney-Disease-Classifcation/templates.py +44 -0
  44. Kidney-Disease-Classifcation/templates/dagshub-kidney_disease_classification.png +0 -0
  45. Kidney-Disease-Classifcation/templates/index.html +353 -0
  46. Kidney-Disease-Classifcation/templates/kidney_ctscan.png +0 -0
  47. Kidney-Disease-Classifcation/templates/mlflow-kidney_disease_classification.png +0 -0
Kidney-Disease-Classifcation/.dvc/.gitignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ /config.local
2
+ /tmp
3
+ /cache
Kidney-Disease-Classifcation/.dvc/config ADDED
File without changes
Kidney-Disease-Classifcation/.dvcignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Add patterns of files dvc should ignore, which could improve
2
+ # the performance. Learn more at
3
+ # https://dvc.org/doc/user-guide/dvcignore
Kidney-Disease-Classifcation/.gitattributes ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
Kidney-Disease-Classifcation/.github/workflows/.gitkeep ADDED
File without changes
Kidney-Disease-Classifcation/.gitignore ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
105
+ __pypackages__/
106
+
107
+ # Celery stuff
108
+ celerybeat-schedule
109
+ celerybeat.pid
110
+
111
+ # SageMath parsed files
112
+ *.sage.py
113
+
114
+ # Environments
115
+ .env
116
+ .venv
117
+ env/
118
+ venv/
119
+ ENV/
120
+ env.bak/
121
+ venv.bak/
122
+
123
+ # Spyder project settings
124
+ .spyderproject
125
+ .spyproject
126
+
127
+ # Rope project settings
128
+ .ropeproject
129
+
130
+ # mkdocs documentation
131
+ /site
132
+
133
+ # mypy
134
+ .mypy_cache/
135
+ .dmypy.json
136
+ dmypy.json
137
+
138
+ # Pyre type checker
139
+ .pyre/
140
+
141
+ # pytype static type analyzer
142
+ .pytype/
143
+
144
+ # Cython debug symbols
145
+ cython_debug/
146
+
147
+ # Data Artifacts
148
+ artifacts/*
149
+
150
+ # PyCharm
151
+ # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
152
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
153
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
154
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
155
+ #.idea/
156
+
157
+ #mlflow runs
158
+ mlruns/
159
+
160
+ #input images
161
+ inputImage.jpg
Kidney-Disease-Classifcation/.pre-commit-config.yaml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.5.0
4
+ hooks:
5
+ - id: trailing-whitespace
6
+ - id: end-of-file-fixer
7
+ - repo: https://github.com/psf/black
8
+ rev: 23.3.0
9
+ hooks:
10
+ - id: black
Kidney-Disease-Classifcation/README.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Kidney Tumor, Cyst, or Stone Classification
2
+ ![alt text](https://github.com/Shrey-patel-07/Kidney-Disease-Classifcation/blob/b19262be45c45d9e375e2119d89462ccfc7475c1/templates/kidney_ctscan.png)
3
+
4
+ ## Project Overview
5
+ The main goal of this project is to develop a reliable and efficient deep-learning model that can accurately classify kidney tumors and Stone from medical images.
6
+
7
+ ## Introduction
8
+ Kidney Disease Classification is a project utilizing deep learning techniques to classify Kidney Tumor and Stone diseases from [medical images dataset](https://www.kaggle.com/datasets/nazmul0087/ct-kidney-dataset-normal-cyst-tumor-and-stone/). This project leverages the power of Deep Learning, Machine Learning Operations (MLOps) practices, Data Version Control (DVC). It integrates with DagsHub for collaboration and versioning.
9
+
10
+ ## Dagshub Project Pipeline
11
+ ![alt text](https://github.com/Shrey-patel-07/Kidney-Disease-Classifcation/blob/2ad0c02af659c2c1e82798524897d831349b1071/templates/dagshub-kidney_disease_classification.png)
12
+
13
+ ## Mlflow Stats
14
+ ![alt text](https://github.com/Shrey-patel-07/Kidney-Disease-Classifcation/blob/2ad0c02af659c2c1e82798524897d831349b1071/templates/mlflow-kidney_disease_classification.png)
15
+
16
+ ## Importance of the Project
17
+ - **Enhancing Healthcare**: By providing accurate and quick disease classification, this project aims to improve patient care and diagnostic accuracy significantly.
18
+ - **Research and Development**: It serves as a tool for researchers to analyze medical images more effectively, paving the way for discoveries in the medical field.
19
+ - **Educational Value**: This project can be a learning platform for students and professionals interested in deep learning and medical image analysis.
20
+
21
+ ## Technical Overview
22
+ - **Deep Learning Frameworks**: Utilizes popular frameworks like TensorFlow or PyTorch for building and training the classification models.
23
+ - **Data Version Control (DVC)**: Manages and versions large datasets and machine learning models, ensuring reproducibility and streamlined data pipelines.
24
+ - **Git Integration**: For source code management and version control, making the project easily maintainable and scalable.
25
+ - **MLOps Practices**: Incorporates best practices in machine learning operations to automate workflows, from data preparation to model deployment.
26
+ - **DagsHub Integration**: Facilitates collaboration, data and model versioning, experiment tracking, and more in a user-friendly platform.
27
+
28
+ ## How to run?
29
+ ### STEPS:
30
+
31
+ Clone the repository
32
+
33
+ ```bash
34
+ https://github.com/krishnaik06/Kidney-Disease-Classification-Deep-Learning-Project
35
+ ```
36
+ ### STEP 01- Create a conda environment after opening the repository
37
+
38
+ ```bash
39
+ conda create -n venv python=3.11 -y
40
+ ```
41
+
42
+ ```bash
43
+ conda activate venv
44
+ ```
45
+
46
+
47
+ ### STEP 02- install the requirements
48
+ ```bash
49
+ pip install -r requirements.txt
50
+ ```
51
+
52
+ ```bash
53
+ # Finally run the following command
54
+ python app.py
55
+ ```
56
+
57
+ Now,
58
+ ```bash
59
+ open up your local host and port
60
+ ```
61
+
62
+ ## To Run the Pipeline
63
+ ```bash
64
+ dvc repro
65
+ ```
66
+ ---
67
+
68
+ This project is still in development, and we welcome contributions of all kinds: from model development and data processing to documentation and bug fixes.
69
+
70
+ **Join me in this exciting journey to revolutionize the field of medical image classification with AI!**
Kidney-Disease-Classifcation/app.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+
5
+ from kidney_classification.pipeline.prediction import PredictionPipeline
6
+ from kidney_classification.utils.common import decodeImage
7
+ from flask_cors import CORS, cross_origin
8
+ import os
9
+ from flask import Flask, request, jsonify, render_template
10
+
11
+
12
+ os.putenv("LANG", "en_US.UTF-8")
13
+ os.putenv("LC_ALL", "en_US.UTF-8")
14
+
15
+ app = Flask(__name__)
16
+ CORS(app)
17
+
18
+
19
+ class ClientApp:
20
+ def __init__(self):
21
+ self.filename = "inputImage.jpg"
22
+ self.classifier = PredictionPipeline(self.filename)
23
+
24
+
25
+ @app.route("/", methods=["GET"])
26
+ @cross_origin()
27
+ def home():
28
+ return render_template("index.html")
29
+
30
+
31
+ @app.route("/train", methods=["GET", "POST"])
32
+ @cross_origin()
33
+ def trainRoute():
34
+ os.system("dvc repro")
35
+ return "Training done successfully!"
36
+
37
+
38
+ @app.route("/predict", methods=["POST"])
39
+ @cross_origin()
40
+ def predictRoute():
41
+ image = request.json["image"]
42
+ decodeImage(image, clApp.filename)
43
+ result = clApp.classifier.predict()
44
+ return jsonify(result)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ clApp = ClientApp()
49
+
50
+ app.run(host="0.0.0.0", port=8080) # for AWS
Kidney-Disease-Classifcation/config/config.yaml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ artifacts_root: artifacts
2
+
3
+
4
+ data_ingestion:
5
+ root_dir: artifacts/data_ingestion
6
+ source_URL: https://drive.google.com/file/d/1BBxDX8JqV-WvNyOzYbqfrk3THFLBpEWF/view?usp=sharing
7
+ local_data_file: artifacts/data_ingestion/data.zip
8
+ unzip_dir: artifacts/data_ingestion
9
+
10
+
11
+ prepare_base_model:
12
+ root_dir: artifacts/prepare_base_model
13
+ base_model_path: artifacts/prepare_base_model/base_model.h5
14
+ updated_base_model_path: artifacts/prepare_base_model/base_model_updated.keras
15
+
16
+
17
+ training:
18
+ root_dir: artifacts/training
19
+ trained_model_path: artifacts/training/model.h5
Kidney-Disease-Classifcation/dvc.lock ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ schema: '2.0'
2
+ stages:
3
+ data_ingestion:
4
+ cmd: python src/kidney_classification/pipeline/stage_01_data_ingestion.py
5
+ deps:
6
+ - path: config/config.yaml
7
+ hash: md5
8
+ md5: 23d61aa500e4da63569da56d61ddb49e
9
+ size: 568
10
+ - path: src/kidney_classification/pipeline/stage_01_data_ingestion.py
11
+ hash: md5
12
+ md5: 0496157b33ff2c7182935a33c605f461
13
+ size: 955
14
+ outs:
15
+ - path: artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
16
+ hash: md5
17
+ md5: 47292b3e13804acbce0f2b4ce55edc57.dir
18
+ size: 887719156
19
+ nfiles: 5511
20
+ prepare_base_model:
21
+ cmd: python src/kidney_classification/pipeline/stage_02_prepare_base_model.py
22
+ deps:
23
+ - path: config/config.yaml
24
+ hash: md5
25
+ md5: 23d61aa500e4da63569da56d61ddb49e
26
+ size: 568
27
+ - path: src/kidney_classification/pipeline/stage_02_prepare_base_model.py
28
+ hash: md5
29
+ md5: 27f16408dee8b42a215b576052e54bb2
30
+ size: 950
31
+ params:
32
+ params.yaml:
33
+ CLASSES: 4
34
+ IMAGE_SIZE:
35
+ - 150
36
+ - 150
37
+ - 3
38
+ INCLUDE_TOP: false
39
+ WEIGHTS: imagenet
40
+ outs:
41
+ - path: artifacts/prepare_base_model
42
+ hash: md5
43
+ md5: 2721c46e50849883acd55e5d4e3dcefb.dir
44
+ size: 60010269
45
+ nfiles: 1
46
+ training:
47
+ cmd: python src/kidney_classification/pipeline/stage_03_model_training.py
48
+ deps:
49
+ - path: artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
50
+ hash: md5
51
+ md5: ec42dfce2ae993cf49f6d499a389c93e.dir
52
+ size: 1661580918
53
+ nfiles: 12446
54
+ - path: artifacts/prepare_base_model
55
+ hash: md5
56
+ md5: a4f718a24c253b4e539f7ba2dc9d3442.dir
57
+ size: 59997688
58
+ nfiles: 1
59
+ - path: config/config.yaml
60
+ hash: md5
61
+ md5: bc47b5f88a0220822ff7921144b69204
62
+ size: 565
63
+ - path: src/kidney_classification/pipeline/stage_03_model_training.py
64
+ hash: md5
65
+ md5: cb8342c5c2f23c4d395f299924161231
66
+ size: 941
67
+ params:
68
+ params.yaml:
69
+ BATCH_SIZE: 32
70
+ EPOCHS: 15
71
+ IMAGE_SIZE:
72
+ - 150
73
+ - 150
74
+ - 3
75
+ outs:
76
+ - path: artifacts/training/model.h5
77
+ hash: md5
78
+ md5: 17969099556c165c584938f53a3fc085
79
+ size: 62136448
80
+ evaluation:
81
+ cmd: python src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py
82
+ deps:
83
+ - path: artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
84
+ hash: md5
85
+ md5: ec42dfce2ae993cf49f6d499a389c93e.dir
86
+ size: 1661580918
87
+ nfiles: 12446
88
+ - path: artifacts/training/model.h5
89
+ hash: md5
90
+ md5: 17969099556c165c584938f53a3fc085
91
+ size: 62136448
92
+ - path: config/config.yaml
93
+ hash: md5
94
+ md5: bc47b5f88a0220822ff7921144b69204
95
+ size: 565
96
+ - path: src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py
97
+ hash: md5
98
+ md5: 7c91c2fdf529e4dcf7dec2684eb3d212
99
+ size: 892
100
+ params:
101
+ params.yaml:
102
+ BATCH_SIZE: 32
103
+ EPOCHS: 15
104
+ IMAGE_SIZE:
105
+ - 150
106
+ - 150
107
+ - 3
108
+ outs:
109
+ - path: scores.json
110
+ hash: md5
111
+ md5: e80b69c44a4cf771b208a549d9e5ae30
112
+ size: 58
Kidney-Disease-Classifcation/dvc.yaml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ stages:
2
+ data_ingestion:
3
+ cmd: python src/kidney_classification/pipeline/stage_01_data_ingestion.py
4
+ deps:
5
+ - src/kidney_classification/pipeline/stage_01_data_ingestion.py
6
+ - config/config.yaml
7
+ outs:
8
+ - artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
9
+
10
+ prepare_base_model:
11
+ cmd: python src/kidney_classification/pipeline/stage_02_prepare_base_model.py
12
+ deps:
13
+ - src/kidney_classification/pipeline/stage_02_prepare_base_model.py
14
+ - config/config.yaml
15
+ params:
16
+ - IMAGE_SIZE
17
+ - INCLUDE_TOP
18
+ - CLASSES
19
+ - WEIGHTS
20
+ outs:
21
+ - artifacts/prepare_base_model
22
+
23
+ training:
24
+ cmd: python src/kidney_classification/pipeline/stage_03_model_training.py
25
+ deps:
26
+ - src/kidney_classification/pipeline/stage_03_model_training.py
27
+ - config/config.yaml
28
+ - artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
29
+ - artifacts/prepare_base_model
30
+ params:
31
+ - IMAGE_SIZE
32
+ - BATCH_SIZE
33
+ - EPOCHS
34
+ outs:
35
+ - artifacts/training/model.h5
36
+
37
+ evaluation:
38
+ cmd: python src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py
39
+ deps:
40
+ - src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py
41
+ - config/config.yaml
42
+ - artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone
43
+ - artifacts/training/model.h5
44
+ params:
45
+ - IMAGE_SIZE
46
+ - BATCH_SIZE
47
+ - EPOCHS
48
+ metrics:
49
+ - scores.json:
50
+ cache: false
Kidney-Disease-Classifcation/main.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+ from kidney_classification.pipeline.stage_04_model_evaluation_with_mlflow import (
5
+ EvaluationPipeline,
6
+ )
7
+ from kidney_classification.pipeline.stage_03_model_training import ModelTrainingPipeline
8
+ from kidney_classification.pipeline.stage_02_prepare_base_model import (
9
+ PrepareBaseModelTrainingPipeline,
10
+ )
11
+ from kidney_classification.pipeline.stage_01_data_ingestion import (
12
+ DataIngestionTrainingPipeline,
13
+ )
14
+ from kidney_classification import logger
15
+
16
+
17
+ STAGE_NAME = "Data Ingestion"
18
+
19
+ try:
20
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
21
+ pipeline = DataIngestionTrainingPipeline()
22
+ pipeline.main()
23
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
24
+ except Exception as e:
25
+ logger.exception(e)
26
+ raise e
27
+
28
+
29
+ STAGE_NAME = "Prepare base model"
30
+
31
+ try:
32
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
33
+ pipeline = PrepareBaseModelTrainingPipeline()
34
+ pipeline.main()
35
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
36
+ except Exception as e:
37
+ logger.exception(e)
38
+ raise e
39
+
40
+
41
+ STAGE_NAME = "Training Model"
42
+
43
+ try:
44
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
45
+ pipeline = ModelTrainingPipeline()
46
+ pipeline.main()
47
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
48
+ except Exception as e:
49
+ logger.exception(e)
50
+ raise e
51
+
52
+
53
+ STAGE_NAME = "Evaluation Stage"
54
+
55
+ try:
56
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
57
+ pipeline = EvaluationPipeline()
58
+ pipeline.main()
59
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
60
+ except Exception as e:
61
+ logger.exception(e)
62
+ raise e
Kidney-Disease-Classifcation/model/model.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:909a0b1a2101b57412a20ecda3513ab35e757cbf565875ea9c7803fdc3e8b6ab
3
+ size 62136504
Kidney-Disease-Classifcation/params.yaml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ IMAGE_SIZE: [150, 150, 3]
2
+ BATCH_SIZE: 32
3
+ INCLUDE_TOP: False
4
+ EPOCHS: 15
5
+ CLASSES: 4
6
+ WEIGHTS: imagenet
Kidney-Disease-Classifcation/requirements.txt ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tensorflow==2.15.0.post1
2
+ pandas==2.1.4
3
+ dvc==3.35.0
4
+ mlflow==2.9.2
5
+ notebook==7.0.6
6
+ numpy==1.26.2
7
+ matplotlib==3.8.2
8
+ seaborn==0.13.0
9
+ python-box==7.1.1
10
+ PyYAML==6.0.1
11
+ tqdm==4.66.1
12
+ ensure==1.0.4
13
+ joblib==1.3.2
14
+ types-PyYAML==6.0.12.12
15
+ scipy==1.11.4
16
+ Flask==3.0.0
17
+ Flask-Cors==4.0.0
18
+ gdown==4.7.1
Kidney-Disease-Classifcation/research/01_data_ingestion.ipynb ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 2,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 29,
15
+ "metadata": {},
16
+ "outputs": [
17
+ {
18
+ "data": {
19
+ "text/plain": [
20
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation/src'"
21
+ ]
22
+ },
23
+ "execution_count": 29,
24
+ "metadata": {},
25
+ "output_type": "execute_result"
26
+ }
27
+ ],
28
+ "source": [
29
+ "%pwd"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": 30,
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "os.chdir('../')"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": 31,
44
+ "metadata": {},
45
+ "outputs": [
46
+ {
47
+ "data": {
48
+ "text/plain": [
49
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation'"
50
+ ]
51
+ },
52
+ "execution_count": 31,
53
+ "metadata": {},
54
+ "output_type": "execute_result"
55
+ }
56
+ ],
57
+ "source": [
58
+ "%pwd"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 32,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "from dataclasses import dataclass\n",
68
+ "from pathlib import Path\n",
69
+ "\n",
70
+ "\n",
71
+ "@dataclass(frozen=True)\n",
72
+ "class DataIngestionConfig:\n",
73
+ " root_dir: Path\n",
74
+ " source_URL: str\n",
75
+ " local_data_file: Path\n",
76
+ " unzip_dir: Path"
77
+ ]
78
+ },
79
+ {
80
+ "cell_type": "code",
81
+ "execution_count": 33,
82
+ "metadata": {},
83
+ "outputs": [],
84
+ "source": [
85
+ "from kidney_classification.constants import *\n",
86
+ "from kidney_classification.utils.common import read_yaml, create_directories"
87
+ ]
88
+ },
89
+ {
90
+ "cell_type": "code",
91
+ "execution_count": 34,
92
+ "metadata": {},
93
+ "outputs": [],
94
+ "source": [
95
+ "class ConfigurationManager:\n",
96
+ " def __init__(\n",
97
+ " self,\n",
98
+ " config_filepath=CONFIG_FILE_PATH,\n",
99
+ " params_filepath=PARAMS_FILE_PATH):\n",
100
+ "\n",
101
+ " self.config = read_yaml(config_filepath)\n",
102
+ " self.params = read_yaml(params_filepath)\n",
103
+ "\n",
104
+ " create_directories([self.config.artifacts_root])\n",
105
+ "\n",
106
+ " def get_data_ingestion_config(self) -> DataIngestionConfig:\n",
107
+ " config = self.config.data_ingestion\n",
108
+ "\n",
109
+ " create_directories([config.root_dir])\n",
110
+ "\n",
111
+ " data_ingestion_config = DataIngestionConfig(\n",
112
+ " root_dir=config.root_dir,\n",
113
+ " source_URL=config.source_URL,\n",
114
+ " local_data_file=config.local_data_file,\n",
115
+ " unzip_dir=config.unzip_dir\n",
116
+ " )\n",
117
+ "\n",
118
+ " return data_ingestion_config"
119
+ ]
120
+ },
121
+ {
122
+ "cell_type": "code",
123
+ "execution_count": 35,
124
+ "metadata": {},
125
+ "outputs": [],
126
+ "source": [
127
+ "import os\n",
128
+ "import zipfile\n",
129
+ "import gdown\n",
130
+ "from kidney_classification import logger"
131
+ ]
132
+ },
133
+ {
134
+ "cell_type": "code",
135
+ "execution_count": 36,
136
+ "metadata": {},
137
+ "outputs": [],
138
+ "source": [
139
+ "class DataIngestion:\n",
140
+ " def __init__(self, config: DataIngestionConfig):\n",
141
+ " self.config = config\n",
142
+ "\n",
143
+ " def download_file(self) -> str:\n",
144
+ " '''\n",
145
+ " Fetch data from the url\n",
146
+ " '''\n",
147
+ "\n",
148
+ " try:\n",
149
+ " dataset_url = self.config.source_URL\n",
150
+ " zip_download_dir = self.config.local_data_file\n",
151
+ " os.makedirs(\"artifacts/data_ingestion\", exist_ok=True)\n",
152
+ " logger.info(\n",
153
+ " f\"Downloading data from {dataset_url} into file {zip_download_dir}\")\n",
154
+ "\n",
155
+ " file_id = dataset_url.split(\"/\")[-2]\n",
156
+ " prefix = 'https://drive.google.com/uc?/export=download&id='\n",
157
+ " gdown.download(prefix+file_id, zip_download_dir)\n",
158
+ "\n",
159
+ " logger.info(\n",
160
+ " f\"Downloaded data from {dataset_url} into file {zip_download_dir}\")\n",
161
+ "\n",
162
+ " except Exception as e:\n",
163
+ " raise e\n",
164
+ "\n",
165
+ " def extract_zip_file(self):\n",
166
+ " \"\"\"\n",
167
+ " zip_file_path: str\n",
168
+ " Extracts the zip file into the data directory\n",
169
+ " Function returns None\n",
170
+ " \"\"\"\n",
171
+ " unzip_path = self.config.unzip_dir\n",
172
+ " os.makedirs(unzip_path, exist_ok=True)\n",
173
+ " with zipfile.ZipFile(self.config.local_data_file, 'r') as zip_ref:\n",
174
+ " zip_ref.extractall(unzip_path)"
175
+ ]
176
+ },
177
+ {
178
+ "cell_type": "code",
179
+ "execution_count": 37,
180
+ "metadata": {},
181
+ "outputs": [
182
+ {
183
+ "name": "stdout",
184
+ "output_type": "stream",
185
+ "text": [
186
+ "[2023-12-23 01:06:36,655: INFO: common yaml file: config/config.yaml loaded successfully]\n",
187
+ "[2023-12-23 01:06:36,656: INFO: common yaml file: params.yaml loaded successfully]\n",
188
+ "[2023-12-23 01:06:36,657: INFO: common created directory at: artifacts]\n",
189
+ "[2023-12-23 01:06:36,658: INFO: common created directory at: artifacts/data_ingestion]\n",
190
+ "[2023-12-23 01:06:36,659: INFO: 986331348 Downloading data from https://drive.google.com/file/d/1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK/view?usp=sharing into file artifacts/data_ingestion/data.zip]\n"
191
+ ]
192
+ },
193
+ {
194
+ "name": "stderr",
195
+ "output_type": "stream",
196
+ "text": [
197
+ "Downloading...\n",
198
+ "From (uriginal): https://drive.google.com/uc?/export=download&id=1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK\n",
199
+ "From (redirected): https://drive.google.com/uc?/export=download&id=1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK&confirm=t&uuid=3aeb0b9b-c680-4ec4-a1ab-78891e4f5025\n",
200
+ "To: /home/shrey/Desktop/Kidney-Disease-Classifcation/artifacts/data_ingestion/data.zip\n",
201
+ "100%|██████████| 1.63G/1.63G [02:31<00:00, 10.7MB/s]"
202
+ ]
203
+ },
204
+ {
205
+ "name": "stdout",
206
+ "output_type": "stream",
207
+ "text": [
208
+ "[2023-12-23 01:09:10,818: INFO: 986331348 Downloaded data from https://drive.google.com/file/d/1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK/view?usp=sharing into file artifacts/data_ingestion/data.zip]\n"
209
+ ]
210
+ },
211
+ {
212
+ "name": "stderr",
213
+ "output_type": "stream",
214
+ "text": [
215
+ "\n"
216
+ ]
217
+ }
218
+ ],
219
+ "source": [
220
+ "try:\n",
221
+ " config = ConfigurationManager()\n",
222
+ " data_ingestion_config = config.get_data_ingestion_config()\n",
223
+ " data_ingestion = DataIngestion(config=data_ingestion_config)\n",
224
+ " data_ingestion.download_file()\n",
225
+ " data_ingestion.extract_zip_file()\n",
226
+ "except Exception as e:\n",
227
+ " raise e"
228
+ ]
229
+ }
230
+ ],
231
+ "metadata": {
232
+ "kernelspec": {
233
+ "display_name": "env",
234
+ "language": "python",
235
+ "name": "python3"
236
+ },
237
+ "language_info": {
238
+ "codemirror_mode": {
239
+ "name": "ipython",
240
+ "version": 3
241
+ },
242
+ "file_extension": ".py",
243
+ "mimetype": "text/x-python",
244
+ "name": "python",
245
+ "nbconvert_exporter": "python",
246
+ "pygments_lexer": "ipython3",
247
+ "version": "3.11.6"
248
+ }
249
+ },
250
+ "nbformat": 4,
251
+ "nbformat_minor": 2
252
+ }
Kidney-Disease-Classifcation/research/02_prepare_base_model.ipynb ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 13,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 14,
15
+ "metadata": {},
16
+ "outputs": [
17
+ {
18
+ "data": {
19
+ "text/plain": [
20
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation'"
21
+ ]
22
+ },
23
+ "execution_count": 14,
24
+ "metadata": {},
25
+ "output_type": "execute_result"
26
+ }
27
+ ],
28
+ "source": [
29
+ "%pwd"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": 3,
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "os.chdir(\"../\")"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": 4,
44
+ "metadata": {},
45
+ "outputs": [
46
+ {
47
+ "data": {
48
+ "text/plain": [
49
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation'"
50
+ ]
51
+ },
52
+ "execution_count": 4,
53
+ "metadata": {},
54
+ "output_type": "execute_result"
55
+ }
56
+ ],
57
+ "source": [
58
+ "%pwd"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 15,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "os.chdir(\"src\")"
68
+ ]
69
+ },
70
+ {
71
+ "cell_type": "code",
72
+ "execution_count": 16,
73
+ "metadata": {},
74
+ "outputs": [],
75
+ "source": [
76
+ "from dataclasses import dataclass\n",
77
+ "from pathlib import Path\n",
78
+ "\n",
79
+ "\n",
80
+ "@dataclass(frozen=True)\n",
81
+ "class PrepareBaseModelConfig:\n",
82
+ " root_dir: Path\n",
83
+ " base_model_path: Path\n",
84
+ " updated_base_model_path: Path\n",
85
+ " params_image_size: list\n",
86
+ " params_include_top: bool\n",
87
+ " params_weights: str\n",
88
+ " params_classes: int"
89
+ ]
90
+ },
91
+ {
92
+ "cell_type": "code",
93
+ "execution_count": 17,
94
+ "metadata": {},
95
+ "outputs": [],
96
+ "source": [
97
+ "from kidney_classification.constants import *\n",
98
+ "from kidney_classification.utils.common import read_yaml, create_directories"
99
+ ]
100
+ },
101
+ {
102
+ "cell_type": "code",
103
+ "execution_count": 18,
104
+ "metadata": {},
105
+ "outputs": [],
106
+ "source": [
107
+ "class ConfigurationManager:\n",
108
+ " def __init__(\n",
109
+ " self,\n",
110
+ " config_filepath = CONFIG_FILE_PATH,\n",
111
+ " params_filepath = PARAMS_FILE_PATH):\n",
112
+ "\n",
113
+ " self.config = read_yaml(config_filepath)\n",
114
+ " self.params = read_yaml(params_filepath)\n",
115
+ "\n",
116
+ " create_directories([self.config.artifacts_root])\n",
117
+ "\n",
118
+ " \n",
119
+ "\n",
120
+ " def get_prepare_base_model_config(self) -> PrepareBaseModelConfig:\n",
121
+ " config = self.config.prepare_base_model\n",
122
+ " \n",
123
+ " create_directories([config.root_dir])\n",
124
+ "\n",
125
+ " prepare_base_model_config = PrepareBaseModelConfig(\n",
126
+ " root_dir=Path(config.root_dir),\n",
127
+ " base_model_path=Path(config.base_model_path),\n",
128
+ " updated_base_model_path=Path(config.updated_base_model_path),\n",
129
+ " params_image_size=self.params.IMAGE_SIZE,\n",
130
+ " params_include_top=self.params.INCLUDE_TOP,\n",
131
+ " params_weights=self.params.WEIGHTS,\n",
132
+ " params_classes=self.params.CLASSES\n",
133
+ " )\n",
134
+ "\n",
135
+ " return prepare_base_model_config"
136
+ ]
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": 19,
141
+ "metadata": {},
142
+ "outputs": [],
143
+ "source": [
144
+ "import tensorflow as tf\n",
145
+ "from tensorflow.keras.layers import Dense, Flatten, BatchNormalization, Dropout\n",
146
+ "from tensorflow.keras.models import Sequential"
147
+ ]
148
+ },
149
+ {
150
+ "cell_type": "code",
151
+ "execution_count": 26,
152
+ "metadata": {},
153
+ "outputs": [],
154
+ "source": [
155
+ "class PrepareBaseModel:\n",
156
+ " @staticmethod\n",
157
+ " def prepare_full_model():\n",
158
+ " VGG_model = Sequential()\n",
159
+ "\n",
160
+ " pretrained_model= tf.keras.applications.VGG16(\n",
161
+ " include_top=False,\n",
162
+ " input_shape=(150, 150, 3),\n",
163
+ " pooling='max',\n",
164
+ " classes=4,\n",
165
+ " weights='imagenet'\n",
166
+ " )\n",
167
+ "\n",
168
+ " VGG_model.add(pretrained_model)\n",
169
+ " VGG_model.add(Flatten())\n",
170
+ " VGG_model.add(Dense(512, activation='relu'))\n",
171
+ " VGG_model.add(BatchNormalization())\n",
172
+ " VGG_model.add(Dropout(0.5))\n",
173
+ "\n",
174
+ " VGG_model.add(Dense(4, activation='softmax'))\n",
175
+ " pretrained_model.trainable = False\n",
176
+ "\n",
177
+ " VGG_model.compile(\n",
178
+ " optimizer='adam',\n",
179
+ " loss='sparse_categorical_crossentropy',\n",
180
+ " metrics=['accuracy']\n",
181
+ " )\n",
182
+ "\n",
183
+ " return VGG_model\n",
184
+ "\n",
185
+ " def update_base_model(self, config: PrepareBaseModelConfig):\n",
186
+ " full_model = self.prepare_full_model()\n",
187
+ "\n",
188
+ " full_model.summary()\n",
189
+ " full_model.save(config.updated_base_model_path)\n",
190
+ " \n",
191
+ " \n",
192
+ " @staticmethod\n",
193
+ " def save_model(path: Path, model: tf.keras.Model):\n",
194
+ " model.save(path)"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": 22,
200
+ "metadata": {},
201
+ "outputs": [],
202
+ "source": [
203
+ "os.chdir(\"../\")"
204
+ ]
205
+ },
206
+ {
207
+ "cell_type": "code",
208
+ "execution_count": 27,
209
+ "metadata": {},
210
+ "outputs": [
211
+ {
212
+ "name": "stdout",
213
+ "output_type": "stream",
214
+ "text": [
215
+ "[2024-01-03 15:58:32,485: INFO: common yaml file: config/config.yaml loaded successfully]\n",
216
+ "[2024-01-03 15:58:32,487: INFO: common yaml file: params.yaml loaded successfully]\n",
217
+ "Model: \"sequential_3\"\n",
218
+ "_________________________________________________________________\n",
219
+ " Layer (type) Output Shape Param # \n",
220
+ "=================================================================\n",
221
+ " vgg16 (Functional) (None, 512) 14714688 \n",
222
+ " \n",
223
+ " flatten_3 (Flatten) (None, 512) 0 \n",
224
+ " \n",
225
+ " dense_5 (Dense) (None, 512) 262656 \n",
226
+ " \n",
227
+ " batch_normalization_3 (Bat (None, 512) 2048 \n",
228
+ " chNormalization) \n",
229
+ " \n",
230
+ " dropout_3 (Dropout) (None, 512) 0 \n",
231
+ " \n",
232
+ " dense_6 (Dense) (None, 4) 2052 \n",
233
+ " \n",
234
+ "=================================================================\n",
235
+ "Total params: 14981444 (57.15 MB)\n",
236
+ "Trainable params: 265732 (1.01 MB)\n",
237
+ "Non-trainable params: 14715712 (56.14 MB)\n",
238
+ "_________________________________________________________________\n"
239
+ ]
240
+ }
241
+ ],
242
+ "source": [
243
+ "try:\n",
244
+ " config = ConfigurationManager()\n",
245
+ " prepare_base_model_config = config.get_prepare_base_model_config()\n",
246
+ " prepare_base_model = PrepareBaseModel()\n",
247
+ " prepare_base_model.update_base_model(prepare_base_model_config)\n",
248
+ "except Exception as e:\n",
249
+ " raise e"
250
+ ]
251
+ },
252
+ {
253
+ "cell_type": "code",
254
+ "execution_count": null,
255
+ "metadata": {},
256
+ "outputs": [],
257
+ "source": []
258
+ }
259
+ ],
260
+ "metadata": {
261
+ "kernelspec": {
262
+ "display_name": "env",
263
+ "language": "python",
264
+ "name": "python3"
265
+ },
266
+ "language_info": {
267
+ "codemirror_mode": {
268
+ "name": "ipython",
269
+ "version": 3
270
+ },
271
+ "file_extension": ".py",
272
+ "mimetype": "text/x-python",
273
+ "name": "python",
274
+ "nbconvert_exporter": "python",
275
+ "pygments_lexer": "ipython3",
276
+ "version": "3.11.6"
277
+ }
278
+ },
279
+ "nbformat": 4,
280
+ "nbformat_minor": 2
281
+ }
Kidney-Disease-Classifcation/research/03_model_training.ipynb ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 2,
15
+ "metadata": {},
16
+ "outputs": [
17
+ {
18
+ "data": {
19
+ "text/plain": [
20
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation/research'"
21
+ ]
22
+ },
23
+ "execution_count": 2,
24
+ "metadata": {},
25
+ "output_type": "execute_result"
26
+ }
27
+ ],
28
+ "source": [
29
+ "%pwd"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": 3,
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "os.chdir(\"../\")"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": 4,
44
+ "metadata": {},
45
+ "outputs": [
46
+ {
47
+ "data": {
48
+ "text/plain": [
49
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation'"
50
+ ]
51
+ },
52
+ "execution_count": 4,
53
+ "metadata": {},
54
+ "output_type": "execute_result"
55
+ }
56
+ ],
57
+ "source": [
58
+ "%pwd"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 5,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "from dataclasses import dataclass\n",
68
+ "from pathlib import Path\n",
69
+ "\n",
70
+ "\n",
71
+ "@dataclass(frozen=True)\n",
72
+ "class TrainingConfig:\n",
73
+ " root_dir: Path\n",
74
+ " trained_model_path: Path\n",
75
+ " updated_base_model_path: Path\n",
76
+ " training_data: Path\n",
77
+ " params_epochs: int\n",
78
+ " params_batch_size: int\n",
79
+ " params_image_size: list"
80
+ ]
81
+ },
82
+ {
83
+ "cell_type": "code",
84
+ "execution_count": 6,
85
+ "metadata": {},
86
+ "outputs": [],
87
+ "source": [
88
+ "os.chdir(\"./src\")"
89
+ ]
90
+ },
91
+ {
92
+ "cell_type": "code",
93
+ "execution_count": 7,
94
+ "metadata": {},
95
+ "outputs": [
96
+ {
97
+ "name": "stderr",
98
+ "output_type": "stream",
99
+ "text": [
100
+ "2024-01-03 15:58:59.001906: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
101
+ "2024-01-03 15:58:59.003769: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n",
102
+ "2024-01-03 15:58:59.032703: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
103
+ "2024-01-03 15:58:59.032753: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
104
+ "2024-01-03 15:58:59.033922: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
105
+ "2024-01-03 15:58:59.038705: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n",
106
+ "2024-01-03 15:58:59.039146: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
107
+ "To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
108
+ "2024-01-03 15:58:59.655806: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
109
+ ]
110
+ }
111
+ ],
112
+ "source": [
113
+ "from kidney_classification.constants import *\n",
114
+ "from kidney_classification.utils.common import read_yaml, create_directories\n",
115
+ "import tensorflow as tf"
116
+ ]
117
+ },
118
+ {
119
+ "cell_type": "code",
120
+ "execution_count": 8,
121
+ "metadata": {},
122
+ "outputs": [],
123
+ "source": [
124
+ "class ConfigurationManager:\n",
125
+ " def __init__(\n",
126
+ " self,\n",
127
+ " config_filepath = CONFIG_FILE_PATH,\n",
128
+ " params_filepath = PARAMS_FILE_PATH):\n",
129
+ "\n",
130
+ " self.config = read_yaml(config_filepath)\n",
131
+ " self.params = read_yaml(params_filepath)\n",
132
+ "\n",
133
+ " create_directories([self.config.artifacts_root])\n",
134
+ "\n",
135
+ "\n",
136
+ " \n",
137
+ " def get_training_config(self) -> TrainingConfig:\n",
138
+ " training = self.config.training\n",
139
+ " prepare_base_model = self.config.prepare_base_model\n",
140
+ " params = self.params\n",
141
+ " training_data = os.path.join(self.config.data_ingestion.unzip_dir, \"CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone\")\n",
142
+ " create_directories([\n",
143
+ " Path(training.root_dir)\n",
144
+ " ])\n",
145
+ "\n",
146
+ " training_config = TrainingConfig(\n",
147
+ " root_dir=Path(training.root_dir),\n",
148
+ " trained_model_path=Path(training.trained_model_path),\n",
149
+ " updated_base_model_path=Path(prepare_base_model.updated_base_model_path),\n",
150
+ " training_data=Path(training_data),\n",
151
+ " params_epochs=params.EPOCHS,\n",
152
+ " params_batch_size=params.BATCH_SIZE,\n",
153
+ " params_image_size=params.IMAGE_SIZE\n",
154
+ " )\n",
155
+ "\n",
156
+ " return training_config"
157
+ ]
158
+ },
159
+ {
160
+ "cell_type": "code",
161
+ "execution_count": 9,
162
+ "metadata": {},
163
+ "outputs": [],
164
+ "source": [
165
+ "class Training:\n",
166
+ " def __init__(self, config: TrainingConfig):\n",
167
+ " self.config = config\n",
168
+ "\n",
169
+ " \n",
170
+ " def get_base_model(self):\n",
171
+ " self.model = tf.keras.models.load_model(\n",
172
+ " self.config.updated_base_model_path\n",
173
+ " )\n",
174
+ "\n",
175
+ " def train_valid_generator(self):\n",
176
+ " img_height, img_width = self.config.params_image_size[:-1]\n",
177
+ "\n",
178
+ " train = tf.keras.utils.image_dataset_from_directory(\n",
179
+ " self.config.training_data,\n",
180
+ " image_size=(img_height, img_width),\n",
181
+ " validation_split=0.1,\n",
182
+ " subset='training',\n",
183
+ " seed=123\n",
184
+ " )\n",
185
+ " \n",
186
+ " val = tf.keras.utils.image_dataset_from_directory(\n",
187
+ " self.config.training_data,\n",
188
+ " image_size=(img_height, img_width),\n",
189
+ " validation_split=0.2,\n",
190
+ " subset='validation',\n",
191
+ " seed=123\n",
192
+ " )\n",
193
+ " train = train.map(lambda x, y: (x / 255, y))\n",
194
+ " val = val.map(lambda x, y: (x / 255, y))\n",
195
+ " AUTOTUNE = tf.data.AUTOTUNE\n",
196
+ "\n",
197
+ " self.train_dataset = train.cache().prefetch(buffer_size=AUTOTUNE)\n",
198
+ " self.val_dataset = val.cache().prefetch(buffer_size=AUTOTUNE)\n",
199
+ "\n",
200
+ " \n",
201
+ " @staticmethod\n",
202
+ " def save_model(path: Path, model: tf.keras.Model):\n",
203
+ " model.save(path)\n",
204
+ "\n",
205
+ " \n",
206
+ " def define_and_train_model(self):\n",
207
+ "\n",
208
+ " self.model.fit(\n",
209
+ " self.train_dataset,\n",
210
+ " validation_data=self.val_dataset,\n",
211
+ " epochs=self.config.params_epochs,\n",
212
+ " )\n",
213
+ "\n",
214
+ " self.save_model(\n",
215
+ " path=self.config.trained_model_path,\n",
216
+ " model=self.model\n",
217
+ " )"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": 10,
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": [
226
+ "os.chdir(\"../\")"
227
+ ]
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "execution_count": 11,
232
+ "metadata": {},
233
+ "outputs": [
234
+ {
235
+ "name": "stdout",
236
+ "output_type": "stream",
237
+ "text": [
238
+ "[2024-01-03 15:59:11,299: INFO: common yaml file: config/config.yaml loaded successfully]\n",
239
+ "[2024-01-03 15:59:11,301: INFO: common yaml file: params.yaml loaded successfully]\n"
240
+ ]
241
+ },
242
+ {
243
+ "name": "stderr",
244
+ "output_type": "stream",
245
+ "text": [
246
+ "2024-01-03 15:59:11.602362: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:274] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected\n"
247
+ ]
248
+ },
249
+ {
250
+ "name": "stdout",
251
+ "output_type": "stream",
252
+ "text": [
253
+ "[2024-01-03 15:59:12,070: WARNING: optimizer Skipping variable loading for optimizer 'Adam', because it has 13 variables whereas the saved optimizer has 1 variables. ]\n",
254
+ "Found 12446 files belonging to 4 classes.\n",
255
+ "Using 11202 files for training.\n",
256
+ "Found 12446 files belonging to 4 classes.\n",
257
+ "Using 2489 files for validation.\n",
258
+ "Epoch 1/15\n",
259
+ "351/351 [==============================] - 561s 2s/step - loss: 0.5099 - accuracy: 0.8103 - val_loss: 0.2366 - val_accuracy: 0.9152\n",
260
+ "Epoch 2/15\n",
261
+ "351/351 [==============================] - 566s 2s/step - loss: 0.2120 - accuracy: 0.9229 - val_loss: 0.2941 - val_accuracy: 0.8803\n",
262
+ "Epoch 3/15\n",
263
+ "351/351 [==============================] - 571s 2s/step - loss: 0.1573 - accuracy: 0.9466 - val_loss: 0.0994 - val_accuracy: 0.9667\n",
264
+ "Epoch 4/15\n",
265
+ "351/351 [==============================] - 547s 2s/step - loss: 0.1370 - accuracy: 0.9528 - val_loss: 0.0742 - val_accuracy: 0.9787\n",
266
+ "Epoch 5/15\n",
267
+ "351/351 [==============================] - 552s 2s/step - loss: 0.1217 - accuracy: 0.9565 - val_loss: 0.0564 - val_accuracy: 0.9835\n",
268
+ "Epoch 6/15\n",
269
+ "351/351 [==============================] - 550s 2s/step - loss: 0.1064 - accuracy: 0.9621 - val_loss: 0.0626 - val_accuracy: 0.9791\n",
270
+ "Epoch 7/15\n",
271
+ "351/351 [==============================] - 550s 2s/step - loss: 0.1028 - accuracy: 0.9622 - val_loss: 0.0845 - val_accuracy: 0.9658\n",
272
+ "Epoch 8/15\n",
273
+ "351/351 [==============================] - 551s 2s/step - loss: 0.0953 - accuracy: 0.9655 - val_loss: 0.0527 - val_accuracy: 0.9811\n",
274
+ "Epoch 9/15\n",
275
+ "351/351 [==============================] - 526s 2s/step - loss: 0.0900 - accuracy: 0.9692 - val_loss: 0.0698 - val_accuracy: 0.9731\n",
276
+ "Epoch 10/15\n",
277
+ "351/351 [==============================] - 526s 1s/step - loss: 0.0806 - accuracy: 0.9708 - val_loss: 0.0454 - val_accuracy: 0.9867\n",
278
+ "Epoch 11/15\n",
279
+ "351/351 [==============================] - 529s 2s/step - loss: 0.0756 - accuracy: 0.9723 - val_loss: 0.0404 - val_accuracy: 0.9871\n",
280
+ "Epoch 12/15\n",
281
+ "351/351 [==============================] - 533s 2s/step - loss: 0.0762 - accuracy: 0.9723 - val_loss: 0.0458 - val_accuracy: 0.9867\n",
282
+ "Epoch 13/15\n",
283
+ "351/351 [==============================] - 538s 2s/step - loss: 0.0651 - accuracy: 0.9760 - val_loss: 0.0331 - val_accuracy: 0.9912\n",
284
+ "Epoch 14/15\n",
285
+ "351/351 [==============================] - 547s 2s/step - loss: 0.0740 - accuracy: 0.9746 - val_loss: 0.0726 - val_accuracy: 0.9771\n",
286
+ "Epoch 15/15\n",
287
+ "351/351 [==============================] - 562s 2s/step - loss: 0.0742 - accuracy: 0.9744 - val_loss: 0.0441 - val_accuracy: 0.9859\n"
288
+ ]
289
+ },
290
+ {
291
+ "name": "stderr",
292
+ "output_type": "stream",
293
+ "text": [
294
+ "/home/shrey/Desktop/Kidney-Disease-Classifcation/env/lib/python3.11/site-packages/keras/src/engine/training.py:3103: UserWarning: You are saving your model as an HDF5 file via `model.save()`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')`.\n",
295
+ " saving_api.save_model(\n"
296
+ ]
297
+ }
298
+ ],
299
+ "source": [
300
+ "try:\n",
301
+ " config = ConfigurationManager()\n",
302
+ " training_config = config.get_training_config()\n",
303
+ " training = Training(config=training_config)\n",
304
+ " training.get_base_model()\n",
305
+ " training.train_valid_generator()\n",
306
+ " training.define_and_train_model()\n",
307
+ " \n",
308
+ "except Exception as e:\n",
309
+ " raise e"
310
+ ]
311
+ },
312
+ {
313
+ "cell_type": "code",
314
+ "execution_count": null,
315
+ "metadata": {},
316
+ "outputs": [],
317
+ "source": []
318
+ }
319
+ ],
320
+ "metadata": {
321
+ "kernelspec": {
322
+ "display_name": "env",
323
+ "language": "python",
324
+ "name": "python3"
325
+ },
326
+ "language_info": {
327
+ "codemirror_mode": {
328
+ "name": "ipython",
329
+ "version": 3
330
+ },
331
+ "file_extension": ".py",
332
+ "mimetype": "text/x-python",
333
+ "name": "python",
334
+ "nbconvert_exporter": "python",
335
+ "pygments_lexer": "ipython3",
336
+ "version": "3.11.6"
337
+ }
338
+ },
339
+ "nbformat": 4,
340
+ "nbformat_minor": 2
341
+ }
Kidney-Disease-Classifcation/research/04_model_evaluation_with_mlflow.ipynb ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import os"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 2,
15
+ "metadata": {},
16
+ "outputs": [
17
+ {
18
+ "data": {
19
+ "text/plain": [
20
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation/research'"
21
+ ]
22
+ },
23
+ "execution_count": 2,
24
+ "metadata": {},
25
+ "output_type": "execute_result"
26
+ }
27
+ ],
28
+ "source": [
29
+ "%pwd"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": 3,
35
+ "metadata": {},
36
+ "outputs": [],
37
+ "source": [
38
+ "os.chdir('../')"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": 4,
44
+ "metadata": {},
45
+ "outputs": [
46
+ {
47
+ "data": {
48
+ "text/plain": [
49
+ "'/home/shrey/Desktop/Kidney-Disease-Classifcation'"
50
+ ]
51
+ },
52
+ "execution_count": 4,
53
+ "metadata": {},
54
+ "output_type": "execute_result"
55
+ }
56
+ ],
57
+ "source": [
58
+ "%pwd"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 5,
64
+ "metadata": {},
65
+ "outputs": [],
66
+ "source": [
67
+ "os.environ[\"MLFLOW_TRACKING_URI\"]=\"https://dagshub.com/Shrey-patel-07/Kidney-Disease-Classifcation.mlflow\"\n",
68
+ "os.environ[\"MLFLOW_TRACKING_USERNAME\"]=\"Shrey-patel-07\"\n",
69
+ "os.environ[\"MLFLOW_TRACKING_PASSWORD\"]=\"6a425a20bb5b645c5efa1ca49ab28097a92a76ee\""
70
+ ]
71
+ },
72
+ {
73
+ "cell_type": "code",
74
+ "execution_count": 6,
75
+ "metadata": {},
76
+ "outputs": [
77
+ {
78
+ "name": "stderr",
79
+ "output_type": "stream",
80
+ "text": [
81
+ "2024-01-04 12:24:18.257148: I tensorflow/core/util/port.cc:113] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
82
+ "2024-01-04 12:24:18.258826: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n",
83
+ "2024-01-04 12:24:18.285564: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
84
+ "2024-01-04 12:24:18.285595: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
85
+ "2024-01-04 12:24:18.286297: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
86
+ "2024-01-04 12:24:18.290364: I external/local_tsl/tsl/cuda/cudart_stub.cc:31] Could not find cuda drivers on your machine, GPU will not be used.\n",
87
+ "2024-01-04 12:24:18.290802: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
88
+ "To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
89
+ "2024-01-04 12:24:18.864121: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
90
+ ]
91
+ }
92
+ ],
93
+ "source": [
94
+ "import tensorflow as tf"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "code",
99
+ "execution_count": 7,
100
+ "metadata": {},
101
+ "outputs": [
102
+ {
103
+ "name": "stderr",
104
+ "output_type": "stream",
105
+ "text": [
106
+ "2024-01-04 12:24:20.808055: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:274] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected\n"
107
+ ]
108
+ }
109
+ ],
110
+ "source": [
111
+ "model = tf.keras.models.load_model('artifacts/training/model.h5')"
112
+ ]
113
+ },
114
+ {
115
+ "cell_type": "code",
116
+ "execution_count": 8,
117
+ "metadata": {},
118
+ "outputs": [],
119
+ "source": [
120
+ "from dataclasses import dataclass\n",
121
+ "from pathlib import Path\n",
122
+ "\n",
123
+ "@dataclass(frozen=True)\n",
124
+ "class EvaluationConfig:\n",
125
+ " path_of_model: Path\n",
126
+ " training_data: Path\n",
127
+ " all_params: dict\n",
128
+ " mlflow_uri: str\n",
129
+ " params_image_size: list\n",
130
+ " params_batch_size: int"
131
+ ]
132
+ },
133
+ {
134
+ "cell_type": "code",
135
+ "execution_count": 9,
136
+ "metadata": {},
137
+ "outputs": [],
138
+ "source": [
139
+ "os.chdir('src/')"
140
+ ]
141
+ },
142
+ {
143
+ "cell_type": "code",
144
+ "execution_count": 10,
145
+ "metadata": {},
146
+ "outputs": [],
147
+ "source": [
148
+ "from kidney_classification.constants import *\n",
149
+ "from kidney_classification.utils.common import read_yaml, create_directories, save_json"
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "code",
154
+ "execution_count": 11,
155
+ "metadata": {},
156
+ "outputs": [],
157
+ "source": [
158
+ "class ConfigurationManager:\n",
159
+ " def __init__(\n",
160
+ " self,\n",
161
+ " config_filepath=CONFIG_FILE_PATH,\n",
162
+ " param_filepath=PARAMS_FILE_PATH\n",
163
+ " ):\n",
164
+ " self.config = read_yaml(config_filepath)\n",
165
+ " self.params = read_yaml(param_filepath)\n",
166
+ " create_directories([self.config.artifacts_root])\n",
167
+ "\n",
168
+ " def get_evaluation_config(self) -> EvaluationConfig:\n",
169
+ " eval_config = EvaluationConfig(\n",
170
+ " path_of_model=\"artifacts/training/model.h5\",\n",
171
+ " training_data=\"artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone\",\n",
172
+ " mlflow_uri=\"https://dagshub.com/Shrey-patel-07/Kidney-Disease-Classifcation.mlflow\",\n",
173
+ " all_params=self.params,\n",
174
+ " params_image_size=self.params.IMAGE_SIZE,\n",
175
+ " params_batch_size=self.params.BATCH_SIZE\n",
176
+ " )\n",
177
+ " return eval_config"
178
+ ]
179
+ },
180
+ {
181
+ "cell_type": "code",
182
+ "execution_count": 12,
183
+ "metadata": {},
184
+ "outputs": [],
185
+ "source": [
186
+ "import mlflow\n",
187
+ "import mlflow.keras\n",
188
+ "from urllib.parse import urlparse"
189
+ ]
190
+ },
191
+ {
192
+ "cell_type": "code",
193
+ "execution_count": 13,
194
+ "metadata": {},
195
+ "outputs": [],
196
+ "source": [
197
+ "class Evaluation:\n",
198
+ " def __init__(self, config: EvaluationConfig):\n",
199
+ " self.config = config\n",
200
+ " self.valid_generator = None # Initialize to None\n",
201
+ "\n",
202
+ " def _valid_generator(self):\n",
203
+ " img_height, img_width = self.config.params_image_size[:-1]\n",
204
+ "\n",
205
+ " self.valid_generator = tf.keras.utils.image_dataset_from_directory(\n",
206
+ " self.config.training_data,\n",
207
+ " image_size=(img_height, img_width),\n",
208
+ " validation_split=0.30,\n",
209
+ " subset='validation',\n",
210
+ " seed=123\n",
211
+ " )\n",
212
+ "\n",
213
+ " self.valid_generator = self.valid_generator.map(lambda x, y: (x / 255, y))\n",
214
+ " AUTOTUNE = tf.data.AUTOTUNE\n",
215
+ " self.valid_generator = self.valid_generator.cache().prefetch(buffer_size=AUTOTUNE)\n",
216
+ "\n",
217
+ "\n",
218
+ " @staticmethod\n",
219
+ " def load_model(path: Path) -> tf.keras.Model:\n",
220
+ " return tf.keras.models.load_model(path)\n",
221
+ " \n",
222
+ "\n",
223
+ " def evaluation(self):\n",
224
+ " self.model = self.load_model(self.config.path_of_model)\n",
225
+ " self._valid_generator()\n",
226
+ " self.score = self.model.evaluate(self.valid_generator)\n",
227
+ " self.save_score()\n",
228
+ "\n",
229
+ " def save_score(self):\n",
230
+ " scores = {\"loss\": self.score[0], \"accuracy\": self.score[1]}\n",
231
+ " save_json(path=Path(\"scores.json\"), data=scores)\n",
232
+ "\n",
233
+ " def log_into_mlflow(self):\n",
234
+ " mlflow.set_registry_uri(self.config.mlflow_uri)\n",
235
+ " tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme\n",
236
+ " \n",
237
+ " with mlflow.start_run():\n",
238
+ " mlflow.log_params(self.config.all_params)\n",
239
+ " mlflow.log_metrics(\n",
240
+ " {\"loss\": self.score[0], \"accuracy\": self.score[1]}\n",
241
+ " )\n",
242
+ " # Model registry does not work with file store\n",
243
+ " if tracking_url_type_store != \"file\":\n",
244
+ "\n",
245
+ " # Register the model\n",
246
+ " mlflow.keras.log_model(self.model, \"model\", registered_model_name=\"VGG16Model\")\n",
247
+ " else:\n",
248
+ " mlflow.keras.log_model(self.model, \"model\")"
249
+ ]
250
+ },
251
+ {
252
+ "cell_type": "code",
253
+ "execution_count": 14,
254
+ "metadata": {},
255
+ "outputs": [],
256
+ "source": [
257
+ "os.chdir('../')"
258
+ ]
259
+ },
260
+ {
261
+ "cell_type": "code",
262
+ "execution_count": 15,
263
+ "metadata": {},
264
+ "outputs": [
265
+ {
266
+ "name": "stdout",
267
+ "output_type": "stream",
268
+ "text": [
269
+ "[2024-01-04 12:24:51,908: INFO: common yaml file: config/config.yaml loaded successfully]\n",
270
+ "[2024-01-04 12:24:51,910: INFO: common yaml file: params.yaml loaded successfully]\n",
271
+ "Found 12446 files belonging to 1 classes.\n",
272
+ "Using 3733 files for validation.\n",
273
+ "117/117 [==============================] - 147s 1s/step - loss: 3.2269e-06 - accuracy: 1.0000\n",
274
+ "[2024-01-04 12:27:19,911: INFO: common json file saved at: scores.json]\n",
275
+ "[2024-01-04 12:27:19,912: INFO: common json file saved at: scores.json]\n"
276
+ ]
277
+ },
278
+ {
279
+ "name": "stderr",
280
+ "output_type": "stream",
281
+ "text": [
282
+ "2024/01/04 12:27:22 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"
283
+ ]
284
+ },
285
+ {
286
+ "name": "stdout",
287
+ "output_type": "stream",
288
+ "text": [
289
+ "INFO:tensorflow:Assets written to: /tmp/tmpdrlg6a4p/model/data/model/assets\n",
290
+ "[2024-01-04 12:27:23,234: INFO: builder_impl Assets written to: /tmp/tmpdrlg6a4p/model/data/model/assets]\n"
291
+ ]
292
+ },
293
+ {
294
+ "name": "stderr",
295
+ "output_type": "stream",
296
+ "text": [
297
+ "/home/shrey/Desktop/Kidney-Disease-Classifcation/env/lib/python3.11/site-packages/_distutils_hack/__init__.py:33: UserWarning: Setuptools is replacing distutils.\n",
298
+ " warnings.warn(\"Setuptools is replacing distutils.\")\n",
299
+ "Registered model 'VGG16Model' already exists. Creating a new version of this model...\n",
300
+ "2024/01/04 12:27:47 INFO mlflow.store.model_registry.abstract_store: Waiting up to 300 seconds for model version to finish creation. Model name: VGG16Model, version 3\n",
301
+ "Created version '3' of model 'VGG16Model'.\n"
302
+ ]
303
+ }
304
+ ],
305
+ "source": [
306
+ "try:\n",
307
+ " config = ConfigurationManager()\n",
308
+ " eval_config = config.get_evaluation_config()\n",
309
+ " evaluation = Evaluation(eval_config)\n",
310
+ " evaluation.evaluation()\n",
311
+ " evaluation.log_into_mlflow()\n",
312
+ " \n",
313
+ "except Exception as e:\n",
314
+ " raise e"
315
+ ]
316
+ },
317
+ {
318
+ "cell_type": "code",
319
+ "execution_count": null,
320
+ "metadata": {},
321
+ "outputs": [],
322
+ "source": []
323
+ }
324
+ ],
325
+ "metadata": {
326
+ "kernelspec": {
327
+ "display_name": "env",
328
+ "language": "python",
329
+ "name": "python3"
330
+ },
331
+ "language_info": {
332
+ "codemirror_mode": {
333
+ "name": "ipython",
334
+ "version": 3
335
+ },
336
+ "file_extension": ".py",
337
+ "mimetype": "text/x-python",
338
+ "name": "python",
339
+ "nbconvert_exporter": "python",
340
+ "pygments_lexer": "ipython3",
341
+ "version": "3.11.6"
342
+ }
343
+ },
344
+ "nbformat": 4,
345
+ "nbformat_minor": 2
346
+ }
Kidney-Disease-Classifcation/research/trials.ipynb ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "metadata": {},
7
+ "outputs": [],
8
+ "source": [
9
+ "import gdown"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 5,
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "url = \"https://drive.google.com/file/d/1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK/view?usp=sharing\""
19
+ ]
20
+ },
21
+ {
22
+ "cell_type": "code",
23
+ "execution_count": 6,
24
+ "metadata": {},
25
+ "outputs": [],
26
+ "source": [
27
+ "file_id = url.split(\"/\")[-2]"
28
+ ]
29
+ },
30
+ {
31
+ "cell_type": "code",
32
+ "execution_count": 7,
33
+ "metadata": {},
34
+ "outputs": [
35
+ {
36
+ "name": "stderr",
37
+ "output_type": "stream",
38
+ "text": [
39
+ "Downloading...\n",
40
+ "From (uriginal): https://drive.google.com/uc?export=download&id=1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK\n",
41
+ "From (redirected): https://drive.google.com/uc?export=download&id=1CGXriP_nlctsaWVbz0W3mFdPK05lQmHK&confirm=t&uuid=17666f87-2ddb-4a4f-a8fb-421ff82803bd\n",
42
+ "To: /home/shrey/Desktop/Kidney-Disease-Classifcation/research/kidney-CT-scan.zip\n",
43
+ "100%|██████████| 1.63G/1.63G [07:37<00:00, 3.56MB/s]\n"
44
+ ]
45
+ },
46
+ {
47
+ "data": {
48
+ "text/plain": [
49
+ "'kidney-CT-scan.zip'"
50
+ ]
51
+ },
52
+ "execution_count": 7,
53
+ "metadata": {},
54
+ "output_type": "execute_result"
55
+ }
56
+ ],
57
+ "source": [
58
+ "prefix = \"https://drive.google.com/uc?export=download&id=\"\n",
59
+ "gdown.download(prefix + file_id, \"kidney-CT-scan.zip\", quiet=False)"
60
+ ]
61
+ },
62
+ {
63
+ "cell_type": "code",
64
+ "execution_count": null,
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": []
68
+ }
69
+ ],
70
+ "metadata": {
71
+ "kernelspec": {
72
+ "display_name": "env",
73
+ "language": "python",
74
+ "name": "python3"
75
+ },
76
+ "language_info": {
77
+ "codemirror_mode": {
78
+ "name": "ipython",
79
+ "version": 3
80
+ },
81
+ "file_extension": ".py",
82
+ "mimetype": "text/x-python",
83
+ "name": "python",
84
+ "nbconvert_exporter": "python",
85
+ "pygments_lexer": "ipython3",
86
+ "version": "3.11.6"
87
+ }
88
+ },
89
+ "nbformat": 4,
90
+ "nbformat_minor": 2
91
+ }
Kidney-Disease-Classifcation/scores.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "loss": 0.013196375221014023,
3
+ "accuracy": 0.996370255947113
4
+ }
Kidney-Disease-Classifcation/setup.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import setuptools
2
+
3
+ with open("README.md", "r") as fh:
4
+ long_description = fh.read()
5
+
6
+ __version__ = "0.0.1"
7
+
8
+ REPO_NAME = "Kidney-Disease-Classification"
9
+ AUTHOR_NAME = "Shrey-patel-07"
10
+ SRC_REPO = "kidney_classification"
11
+ AUTHOR_EMAIL = "shrey07patel@gmail.com"
12
+
13
+ setuptools.setup(
14
+ name=SRC_REPO,
15
+ version=__version__,
16
+ author=AUTHOR_NAME,
17
+ author_email=AUTHOR_EMAIL,
18
+ description="A small package for kidney disease classification",
19
+ long_description=long_description,
20
+ long_description_content_type="text/markdown",
21
+ url=f"https://github.com/{AUTHOR_NAME}/{REPO_NAME}",
22
+ project_urls={
23
+ "Bug Tracker": f"https://github.com/{AUTHOR_NAME}/{REPO_NAME}/issues",
24
+ },
25
+ package_dir={"": "src"},
26
+ packages=setuptools.find_packages(where="src"),
27
+ )
Kidney-Disease-Classifcation/src/kidney_classification/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import logging
4
+
5
+ logging_str = "[%(asctime)s: %(levelname)s: %(module)s %(message)s]"
6
+
7
+ __name__ = "kidney_classification"
8
+ log_dir = "logs"
9
+ log_filepath = os.path.join(log_dir, "running_logs.log")
10
+ os.makedirs(log_dir, exist_ok=True)
11
+
12
+ logging.basicConfig(
13
+ level=logging.INFO,
14
+ format=logging_str,
15
+ handlers=[logging.FileHandler(log_filepath), logging.StreamHandler(sys.stdout)],
16
+ )
17
+
18
+ logger = logging.getLogger(__name__)
Kidney-Disease-Classifcation/src/kidney_classification/components/__init__.py ADDED
File without changes
Kidney-Disease-Classifcation/src/kidney_classification/components/data_ingestion.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import zipfile
3
+ import gdown
4
+ from kidney_classification import logger
5
+ from kidney_classification.entity.config_entity import DataIngestionConfig
6
+
7
+
8
+ class DataIngestion:
9
+ def __init__(self, config: DataIngestionConfig):
10
+ self.config = config
11
+
12
+ def download_file(self) -> str:
13
+ """
14
+ Fetch data from the url
15
+ """
16
+
17
+ try:
18
+ dataset_url = self.config.source_URL
19
+ zip_download_dir = self.config.local_data_file
20
+ os.makedirs("artifacts/data_ingestion", exist_ok=True)
21
+ logger.info(
22
+ f"Downloading data from {dataset_url} into file {zip_download_dir}"
23
+ )
24
+
25
+ file_id = dataset_url.split("/")[-2]
26
+ prefix = "https://drive.google.com/uc?/export=download&id="
27
+ gdown.download(prefix + file_id, zip_download_dir)
28
+
29
+ logger.info(
30
+ f"Downloaded data from {dataset_url} into file {zip_download_dir}"
31
+ )
32
+
33
+ except Exception as e:
34
+ raise e
35
+
36
+ def extract_zip_file(self):
37
+ """
38
+ zip_file_path: str
39
+ Extracts the zip file into the data directory
40
+ Function returns None
41
+ """
42
+ unzip_path = self.config.unzip_dir
43
+ os.makedirs(unzip_path, exist_ok=True)
44
+ with zipfile.ZipFile(self.config.local_data_file, "r") as zip_ref:
45
+ zip_ref.extractall(unzip_path)
Kidney-Disease-Classifcation/src/kidney_classification/components/model_evaluation_mlflow.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tensorflow as tf
2
+ from urllib.parse import urlparse
3
+ import mlflow
4
+ import mlflow.keras
5
+ from pathlib import Path
6
+ from kidney_classification.utils.common import save_json
7
+ from kidney_classification.entity.config_entity import EvaluationConfig
8
+
9
+
10
+ class Evaluation:
11
+ def __init__(self, config: EvaluationConfig):
12
+ self.config = config
13
+ self.valid_generator = None # Initialize to None
14
+
15
+ def _valid_generator(self):
16
+ img_height, img_width = self.config.params_image_size[:-1]
17
+
18
+ self.valid_generator = tf.keras.utils.image_dataset_from_directory(
19
+ self.config.training_data,
20
+ image_size=(img_height, img_width),
21
+ validation_split=0.30,
22
+ subset="validation",
23
+ seed=123,
24
+ )
25
+
26
+ self.valid_generator = self.valid_generator.map(lambda x, y: (x / 255, y))
27
+ AUTOTUNE = tf.data.AUTOTUNE
28
+ self.valid_generator = self.valid_generator.cache().prefetch(
29
+ buffer_size=AUTOTUNE
30
+ )
31
+
32
+ @staticmethod
33
+ def load_model(path: Path) -> tf.keras.Model:
34
+ return tf.keras.models.load_model(path)
35
+
36
+ def evaluation(self):
37
+ self.model = self.load_model(self.config.path_of_model)
38
+ self._valid_generator()
39
+ self.score = self.model.evaluate(self.valid_generator)
40
+ self.save_score()
41
+
42
+ def save_score(self):
43
+ scores = {"loss": self.score[0], "accuracy": self.score[1]}
44
+ save_json(path=Path("scores.json"), data=scores)
45
+
46
+ def log_into_mlflow(self):
47
+ mlflow.set_registry_uri(self.config.mlflow_uri)
48
+ tracking_url_type_store = urlparse(mlflow.get_tracking_uri()).scheme
49
+
50
+ with mlflow.start_run():
51
+ mlflow.log_params(self.config.all_params)
52
+ mlflow.log_metrics({"loss": self.score[0], "accuracy": self.score[1]})
53
+ # Model registry does not work with file store
54
+ if tracking_url_type_store != "file":
55
+ mlflow.keras.log_model(
56
+ self.model, "model", registered_model_name="VGG16Model"
57
+ )
58
+ else:
59
+ mlflow.keras.log_model(self.model, "model")
Kidney-Disease-Classifcation/src/kidney_classification/components/model_training.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tensorflow as tf
2
+ from pathlib import Path
3
+ from kidney_classification.entity.config_entity import TrainingConfig
4
+
5
+
6
+ class Training:
7
+ def __init__(self, config: TrainingConfig):
8
+ self.config = config
9
+
10
+ def get_base_model(self):
11
+ self.model = tf.keras.models.load_model(self.config.updated_base_model_path)
12
+
13
+ def train_valid_generator(self):
14
+ img_height, img_width = self.config.params_image_size[:-1]
15
+
16
+ train = tf.keras.utils.image_dataset_from_directory(
17
+ self.config.training_data,
18
+ image_size=(img_height, img_width),
19
+ validation_split=0.1,
20
+ subset="training",
21
+ seed=123,
22
+ )
23
+
24
+ val = tf.keras.utils.image_dataset_from_directory(
25
+ self.config.training_data,
26
+ image_size=(img_height, img_width),
27
+ validation_split=0.2,
28
+ subset="validation",
29
+ seed=123,
30
+ )
31
+ train = train.map(lambda x, y: (x / 255, y))
32
+ val = val.map(lambda x, y: (x / 255, y))
33
+ AUTOTUNE = tf.data.AUTOTUNE
34
+
35
+ self.train_dataset = train.cache().prefetch(buffer_size=AUTOTUNE)
36
+ self.val_dataset = val.cache().prefetch(buffer_size=AUTOTUNE)
37
+
38
+ @staticmethod
39
+ def save_model(path: Path, model: tf.keras.Model):
40
+ model.save(path)
41
+
42
+ def define_and_train_model(self):
43
+ self.model.fit(
44
+ self.train_dataset,
45
+ validation_data=self.val_dataset,
46
+ epochs=self.config.params_epochs,
47
+ )
48
+
49
+ self.save_model(path=self.config.trained_model_path, model=self.model)
Kidney-Disease-Classifcation/src/kidney_classification/components/prepare_base_model.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tensorflow as tf
2
+ from pathlib import Path
3
+ from kidney_classification.entity.config_entity import PrepareBaseModelConfig
4
+ from tensorflow.keras.models import Sequential
5
+ from tensorflow.keras.layers import Dense, Flatten, BatchNormalization, Dropout
6
+
7
+
8
+ class PrepareBaseModel:
9
+ @staticmethod
10
+ def prepare_full_model():
11
+ VGG_model = Sequential()
12
+
13
+ pretrained_model = tf.keras.applications.VGG16(
14
+ include_top=False,
15
+ input_shape=(150, 150, 3),
16
+ pooling="max",
17
+ classes=4,
18
+ weights="imagenet",
19
+ )
20
+
21
+ VGG_model.add(pretrained_model)
22
+ VGG_model.add(Flatten())
23
+ VGG_model.add(Dense(512, activation="relu"))
24
+ VGG_model.add(BatchNormalization())
25
+ VGG_model.add(Dropout(0.5))
26
+
27
+ VGG_model.add(Dense(4, activation="softmax"))
28
+ pretrained_model.trainable = False
29
+
30
+ VGG_model.compile(
31
+ optimizer="adam",
32
+ loss="sparse_categorical_crossentropy",
33
+ metrics=["accuracy"],
34
+ )
35
+
36
+ return VGG_model
37
+
38
+ def update_base_model(self, config: PrepareBaseModelConfig):
39
+ full_model = self.prepare_full_model()
40
+
41
+ full_model.summary()
42
+ full_model.save(config.updated_base_model_path)
43
+
44
+ @staticmethod
45
+ def save_model(path: Path, model: tf.keras.Model):
46
+ model.save(path)
Kidney-Disease-Classifcation/src/kidney_classification/config/__init__.py ADDED
File without changes
Kidney-Disease-Classifcation/src/kidney_classification/config/configuration.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from kidney_classification.constants import *
3
+ from kidney_classification.utils.common import read_yaml, create_directories, save_json
4
+ from kidney_classification.entity.config_entity import (
5
+ DataIngestionConfig,
6
+ PrepareBaseModelConfig,
7
+ TrainingConfig,
8
+ EvaluationConfig,
9
+ )
10
+
11
+
12
+ class ConfigurationManager:
13
+ def __init__(
14
+ self, config_filepath=CONFIG_FILE_PATH, params_filepath=PARAMS_FILE_PATH
15
+ ):
16
+ self.config = read_yaml(config_filepath)
17
+ self.params = read_yaml(params_filepath)
18
+
19
+ create_directories([self.config.artifacts_root])
20
+
21
+ def get_data_ingestion_config(self) -> DataIngestionConfig:
22
+ config = self.config.data_ingestion
23
+
24
+ create_directories([config.root_dir])
25
+
26
+ data_ingestion_config = DataIngestionConfig(
27
+ root_dir=config.root_dir,
28
+ source_URL=config.source_URL,
29
+ local_data_file=config.local_data_file,
30
+ unzip_dir=config.unzip_dir,
31
+ )
32
+
33
+ return data_ingestion_config
34
+
35
+ def get_prepare_base_model_config(self) -> PrepareBaseModelConfig:
36
+ config = self.config.prepare_base_model
37
+
38
+ create_directories([config.root_dir])
39
+
40
+ prepare_base_model_config = PrepareBaseModelConfig(
41
+ root_dir=Path(config.root_dir),
42
+ base_model_path=Path(config.base_model_path),
43
+ updated_base_model_path=Path(config.updated_base_model_path),
44
+ params_image_size=self.params.IMAGE_SIZE,
45
+ params_include_top=self.params.INCLUDE_TOP,
46
+ params_weights=self.params.WEIGHTS,
47
+ params_classes=self.params.CLASSES,
48
+ )
49
+
50
+ return prepare_base_model_config
51
+
52
+ def get_training_config(self) -> TrainingConfig:
53
+ training = self.config.training
54
+ prepare_base_model = self.config.prepare_base_model
55
+ params = self.params
56
+ training_data = os.path.join(
57
+ self.config.data_ingestion.unzip_dir,
58
+ "CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone",
59
+ )
60
+ create_directories([Path(training.root_dir)])
61
+
62
+ training_config = TrainingConfig(
63
+ root_dir=Path(training.root_dir),
64
+ trained_model_path=Path(training.trained_model_path),
65
+ updated_base_model_path=Path(prepare_base_model.updated_base_model_path),
66
+ training_data=Path(training_data),
67
+ params_epochs=params.EPOCHS,
68
+ params_batch_size=params.BATCH_SIZE,
69
+ params_image_size=params.IMAGE_SIZE,
70
+ )
71
+
72
+ return training_config
73
+
74
+ def get_evaluation_config(self) -> EvaluationConfig:
75
+ eval_config = EvaluationConfig(
76
+ path_of_model="artifacts/training/model.h5",
77
+ training_data="artifacts/data_ingestion/CT-KIDNEY-DATASET-Normal-Cyst-Tumor-Stone",
78
+ mlflow_uri="https://dagshub.com/Shrey-patel-07/Kidney-Disease-Classifcation.mlflow",
79
+ all_params=self.params,
80
+ params_image_size=self.params.IMAGE_SIZE,
81
+ params_batch_size=self.params.BATCH_SIZE,
82
+ )
83
+ return eval_config
Kidney-Disease-Classifcation/src/kidney_classification/constants/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ CONFIG_FILE_PATH = Path("config/config.yaml")
4
+ PARAMS_FILE_PATH = Path("params.yaml")
Kidney-Disease-Classifcation/src/kidney_classification/entity/__init__.py ADDED
File without changes
Kidney-Disease-Classifcation/src/kidney_classification/entity/config_entity.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+
4
+
5
+ @dataclass(frozen=True)
6
+ class DataIngestionConfig:
7
+ root_dir: Path
8
+ source_URL: str
9
+ local_data_file: Path
10
+ unzip_dir: Path
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class PrepareBaseModelConfig:
15
+ root_dir: Path
16
+ base_model_path: Path
17
+ updated_base_model_path: Path
18
+ params_image_size: list
19
+ params_include_top: bool
20
+ params_weights: str
21
+ params_classes: int
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class TrainingConfig:
26
+ root_dir: Path
27
+ trained_model_path: Path
28
+ updated_base_model_path: Path
29
+ training_data: Path
30
+ params_epochs: int
31
+ params_batch_size: int
32
+ params_image_size: list
33
+
34
+
35
+ @dataclass(frozen=True)
36
+ class EvaluationConfig:
37
+ path_of_model: Path
38
+ training_data: Path
39
+ all_params: dict
40
+ mlflow_uri: str
41
+ params_image_size: list
42
+ params_batch_size: int
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/__init__.py ADDED
File without changes
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/prediction.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from tensorflow.keras.models import load_model
3
+ from tensorflow.keras.preprocessing import image
4
+ import os
5
+
6
+
7
+ class PredictionPipeline:
8
+ def __init__(self, filename):
9
+ self.filename = filename
10
+
11
+ def predict(self):
12
+ model = load_model(os.path.join("model", "model.h5"))
13
+
14
+ imagename = self.filename
15
+ test_image = image.load_img(imagename, target_size=(150, 150))
16
+ test_image = image.img_to_array(test_image)
17
+ test_image = np.expand_dims(test_image, axis=0)
18
+ result = np.argmax(model.predict(test_image), axis=1)
19
+
20
+ if result[0] == 0:
21
+ prediction = "Cyst"
22
+ return [{"image": prediction}]
23
+ elif result[0] == 1:
24
+ prediction = "Normal"
25
+ return [{"image": prediction}]
26
+ elif result[0] == 2:
27
+ prediction = "Stone"
28
+ return [{"image": prediction}]
29
+ else:
30
+ prediction = "Tumor"
31
+ return [{"image": prediction}]
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_01_data_ingestion.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+ from kidney_classification.config.configuration import ConfigurationManager
5
+ from kidney_classification.components.data_ingestion import DataIngestion
6
+ from kidney_classification import logger
7
+
8
+ STAGE_NAME = "Data Ingestion"
9
+
10
+
11
+ class DataIngestionTrainingPipeline:
12
+ def __init__(self):
13
+ pass
14
+
15
+ def main(self):
16
+ config = ConfigurationManager()
17
+ data_ingestion_config = config.get_data_ingestion_config()
18
+ data_ingestion = DataIngestion(config=data_ingestion_config)
19
+ data_ingestion.download_file()
20
+ data_ingestion.extract_zip_file()
21
+
22
+
23
+ if __name__ == "__main__":
24
+ try:
25
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
26
+ pipeline = DataIngestionTrainingPipeline()
27
+ pipeline.main()
28
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
29
+ except Exception as e:
30
+ logger.exception(e)
31
+ raise e
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_02_prepare_base_model.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+ from kidney_classification.config.configuration import ConfigurationManager
5
+ from kidney_classification.components.prepare_base_model import PrepareBaseModel
6
+ from kidney_classification import logger
7
+
8
+ STAGE_NAME = "Prepare base model"
9
+
10
+
11
+ class PrepareBaseModelTrainingPipeline:
12
+ def __init__(self):
13
+ pass
14
+
15
+ def main(self):
16
+ config = ConfigurationManager()
17
+ prepare_base_model_config = config.get_prepare_base_model_config()
18
+ prepare_base_model = PrepareBaseModel()
19
+ prepare_base_model.update_base_model(prepare_base_model_config)
20
+
21
+
22
+ if __name__ == "__main__":
23
+ try:
24
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
25
+ pipeline = PrepareBaseModelTrainingPipeline()
26
+ pipeline.main()
27
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
28
+ except Exception as e:
29
+ logger.exception(e)
30
+ raise e
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_03_model_training.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+ from kidney_classification.config.configuration import ConfigurationManager
5
+ from kidney_classification.components.model_training import Training
6
+ from kidney_classification import logger
7
+
8
+ STAGE_NAME = "Training Model"
9
+
10
+
11
+ class ModelTrainingPipeline:
12
+ def __init__(self):
13
+ pass
14
+
15
+ def main(self):
16
+ config = ConfigurationManager()
17
+ training_config = config.get_training_config()
18
+ training = Training(config=training_config)
19
+ training.get_base_model()
20
+ training.train_valid_generator()
21
+ training.define_and_train_model()
22
+
23
+
24
+ if __name__ == "__main__":
25
+ try:
26
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
27
+ pipeline = ModelTrainingPipeline()
28
+ pipeline.main()
29
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
30
+ except Exception as e:
31
+ logger.exception(e)
32
+ raise e
Kidney-Disease-Classifcation/src/kidney_classification/pipeline/stage_04_model_evaluation_with_mlflow.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ sys.path.append("./src")
4
+ from kidney_classification.config.configuration import ConfigurationManager
5
+ from kidney_classification.components.model_evaluation_mlflow import Evaluation
6
+ from kidney_classification import logger
7
+
8
+
9
+ STAGE_NAME = "Evaluation Stage"
10
+
11
+
12
+ class EvaluationPipeline:
13
+ def __init__(self):
14
+ pass
15
+
16
+ def main(self):
17
+ config = ConfigurationManager()
18
+ eval_config = config.get_evaluation_config()
19
+ evaluation = Evaluation(eval_config)
20
+ evaluation.evaluation()
21
+ evaluation.log_into_mlflow()
22
+
23
+
24
+ if __name__ == "__main__":
25
+ try:
26
+ logger.info(f"-------------Running stage: {STAGE_NAME}-------------")
27
+ pipeline = EvaluationPipeline()
28
+ pipeline.main()
29
+ logger.info(f"-------------Stage: {STAGE_NAME} completed-------------")
30
+ except Exception as e:
31
+ logger.exception(e)
32
+ raise e
Kidney-Disease-Classifcation/src/kidney_classification/utils/__init__.py ADDED
File without changes
Kidney-Disease-Classifcation/src/kidney_classification/utils/common.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import yaml
4
+ import base64
5
+ import joblib
6
+ from typing import Any
7
+ from pathlib import Path
8
+ from box import ConfigBox
9
+ from ensure import ensure_annotations
10
+ from box.exceptions import BoxValueError
11
+ from kidney_classification import logger
12
+
13
+
14
+ @ensure_annotations
15
+ def read_yaml(path_to_yaml: Path) -> ConfigBox:
16
+ """reads yaml file and returns
17
+
18
+ Args:
19
+ path_to_yaml (str): path like input
20
+
21
+ Raises:
22
+ ValueError: if yaml file is empty
23
+ e: empty file
24
+
25
+ Returns:
26
+ ConfigBox: ConfigBox type
27
+ """
28
+ try:
29
+ with open(path_to_yaml) as yaml_file:
30
+ content = yaml.safe_load(yaml_file)
31
+ logger.info(f"yaml file: {path_to_yaml} loaded successfully")
32
+ return ConfigBox(content)
33
+ except BoxValueError:
34
+ raise ValueError("yaml file is empty")
35
+ except Exception as e:
36
+ raise e
37
+
38
+
39
+ @ensure_annotations
40
+ def create_directories(path_to_directories: list, verbose=True):
41
+ """create list of directories
42
+
43
+ Args:
44
+ path_to_directories (list): list of path of directories
45
+ ignore_log (bool, optional): ignore if multiple dirs is to be created. Defaults to False.
46
+ """
47
+ for path in path_to_directories:
48
+ if not os.path.exists(path):
49
+ os.makedirs(path)
50
+ if verbose:
51
+ logger.info(f"created directory at: {path}")
52
+ else:
53
+ continue
54
+
55
+
56
+ def decodeImage(imgstring, fileName):
57
+ imgdata = base64.b64decode(imgstring)
58
+ with open(fileName, "wb") as f:
59
+ f.write(imgdata)
60
+ f.close()
61
+
62
+
63
+ def encodeImageIntoBase64(croppedImagePath):
64
+ with open(croppedImagePath, "rb") as f:
65
+ return base64.b64encode(f.read())
66
+
67
+
68
+ @ensure_annotations
69
+ def save_json(path: Path, data: dict):
70
+ """save json data
71
+
72
+ Args:
73
+ path (Path): path to json file
74
+ data (dict): data to be saved in json file
75
+ """
76
+ with open(path, "w") as f:
77
+ json.dump(data, f, indent=4)
78
+
79
+ logger.info(f"json file saved at: {path}")
Kidney-Disease-Classifcation/templates.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from pathlib import Path
3
+ import logging
4
+
5
+ # logging string
6
+ logging.basicConfig(level=logging.INFO, format="[%(asctime)s]: %(message)s:")
7
+
8
+ project_name = "kidney_classification"
9
+
10
+ list_of_files = [
11
+ ".github/workflows/.gitkeep",
12
+ f"src/{project_name}/__init__.py",
13
+ f"src/{project_name}/components/__init__.py",
14
+ f"src/{project_name}/utils/__init__.py",
15
+ f"src/{project_name}/config/__init__.py",
16
+ f"src/{project_name}/config/configuration.py",
17
+ f"src/{project_name}/pipeline/__init__.py",
18
+ f"src/{project_name}/entity/__init__.py",
19
+ f"src/{project_name}/constants/__init__.py",
20
+ "config/config.yaml",
21
+ "dvc.yaml",
22
+ "params.yaml",
23
+ "requirements.txt",
24
+ "setup.py",
25
+ "research/trials.ipynb",
26
+ "templates/index.html",
27
+ ]
28
+
29
+
30
+ for filepath in list_of_files:
31
+ filepath = Path(filepath)
32
+ filedir, filename = os.path.split(filepath)
33
+
34
+ if filedir != "":
35
+ os.makedirs(filedir, exist_ok=True)
36
+ logging.info(f"Creating directory; {filedir} for the file: {filename}")
37
+
38
+ if (not os.path.exists(filepath)) or (os.path.getsize(filepath) == 0):
39
+ with open(filepath, "w") as f:
40
+ pass
41
+ logging.info(f"Creating empty file: {filepath}")
42
+
43
+ else:
44
+ logging.info(f"{filename} is already exists")
Kidney-Disease-Classifcation/templates/dagshub-kidney_disease_classification.png ADDED
Kidney-Disease-Classifcation/templates/index.html ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
+ <title>Kidney Disease Classification</title>
9
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
10
+ integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" />
12
+ <style>
13
+ body {
14
+ background-color: #eff2f9;
15
+ }
16
+
17
+ .iupload h3 {
18
+ color: #1b2d6b;
19
+ font-size: 30px;
20
+ font-weight: 700;
21
+ }
22
+
23
+ .img-part {
24
+ height: 300px;
25
+ width: 300px;
26
+ margin: 0px auto;
27
+ }
28
+
29
+ .image-part {
30
+ height: 300px;
31
+ width: 300px;
32
+ border: 1px solid #1b2d6b;
33
+ }
34
+
35
+ .image-part img {
36
+ position: absolute;
37
+ height: 300px;
38
+ width: 300px;
39
+ display: none;
40
+ padding: 5px;
41
+ }
42
+
43
+ .image-part #video {
44
+ display: block;
45
+ height: 300px;
46
+ width: 300px;
47
+ padding: 5px;
48
+ }
49
+
50
+ .res-part {
51
+ border: 1px solid #dedede;
52
+ margin-left: 20px;
53
+ height: 310px;
54
+ width: 100%;
55
+ padding: 5px;
56
+ margin: 0px auto;
57
+ overflow: auto;
58
+ }
59
+
60
+ .res-part2 {
61
+ border: 1px solid #dedede;
62
+ height: 310px;
63
+ width: 100%;
64
+ padding: 5px;
65
+ margin: 0px auto;
66
+ }
67
+
68
+ .resp-img {
69
+ height: 298px;
70
+ width: 233px;
71
+ margin: 0px auto;
72
+ }
73
+
74
+ .jsonRes {
75
+ margin-left: 30px;
76
+ }
77
+
78
+ #send {
79
+ cursor: pointer;
80
+ }
81
+
82
+ .btn-part {
83
+ width: 325px;
84
+ }
85
+
86
+ textarea,
87
+ select,
88
+ .form-control,
89
+ .custom-select,
90
+ button.btn,
91
+ .btn-primary,
92
+ input[type="text"],
93
+ input[type="url"],
94
+ .uneditable-input {
95
+ border: 1px solid #363e75;
96
+ outline: 0 !important;
97
+ border-radius: 0px;
98
+ box-shadow: none;
99
+ -webkit-box-shadow: none;
100
+ -moz-box-shadow: none;
101
+ }
102
+
103
+ textarea:focus,
104
+ select:focus,
105
+ .form-control:focus,
106
+ .btn:focus,
107
+ .btn-primary:focus,
108
+ .custom-select:focus,
109
+ input[type="text"]:focus,
110
+ .uneditable-input:focus {
111
+ border: 1px solid #007bff;
112
+ outline: 0 !important;
113
+ border-radius: 0px;
114
+ box-shadow: none;
115
+ -webkit-box-shadow: none;
116
+ -moz-box-shadow: none;
117
+ }
118
+
119
+ #loading {
120
+ position: fixed;
121
+ left: 0px;
122
+ top: 0px;
123
+ width: 100%;
124
+ height: 100%;
125
+ z-index: 9999999999;
126
+ overflow: hidden;
127
+ background: rgba(255, 255, 255, 0.7);
128
+ }
129
+
130
+ .loader {
131
+ border: 8px solid #f3f3f3;
132
+ border-top: 8px solid #363e75;
133
+ border-radius: 50%;
134
+ width: 60px;
135
+ height: 60px;
136
+ left: 50%;
137
+ margin-left: -4em;
138
+ display: block;
139
+ animation: spin 2s linear infinite;
140
+ }
141
+
142
+ .loader,
143
+ .loader:after {
144
+ display: block;
145
+ position: absolute;
146
+ top: 50%;
147
+ margin-top: -4.05em;
148
+ }
149
+
150
+ @keyframes spin {
151
+ 0% {
152
+ transform: rotate(0deg);
153
+ }
154
+
155
+ 100% {
156
+ transform: rotate(360deg);
157
+ }
158
+ }
159
+
160
+ .right-part {
161
+ border: 1px solid #dedede;
162
+ padding: 5px;
163
+ }
164
+
165
+ .socials {
166
+ position: fixed;
167
+ bottom: 20px;
168
+ left: 0;
169
+ width: 100%;
170
+ display: flex;
171
+ justify-content: center;
172
+ align-items: center;
173
+ }
174
+
175
+ .icons {
176
+ display: flex;
177
+ justify-content: center;
178
+ align-items: center;
179
+ }
180
+
181
+ .icons a {
182
+ margin: 0 10px;
183
+ color: #333;
184
+ font-size: 24px;
185
+ }
186
+
187
+ .credit {
188
+ position: absolute;
189
+ bottom: 0;
190
+ left: 10px;
191
+ color: #333;
192
+ }
193
+ </style>
194
+ </head>
195
+
196
+ <body>
197
+ <div class="main container">
198
+ <section class="iupload">
199
+ <h3 class="text-center py-4">Object Classification</h3>
200
+ <div class="row">
201
+ <div class="img-part col-md-6">
202
+ <div class="image-part">
203
+ <video autoplay id="video"
204
+ poster="https://img.freepik.com/free-vector/group-young-people-posing-photo_52683-18824.jpg?size=338&ext=jpg"></video>
205
+ <img src="" id="photo">
206
+ <canvas style="display:none;" id="canvas"></canvas>
207
+ </div>
208
+ <div class="btn-part">
209
+ <form id="upload-data pt-3" class="">
210
+ <div class="input-group mt-3 row">
211
+ <button type="button" class="btn btn-primary col-md-5 col-xs-5 ml-3 mr-4"
212
+ id="uload">Upload</button>
213
+ <button id="send" type="button"
214
+ class="btn btn-success col-md-5 col-xs-5">Predict</button>
215
+ </div>
216
+
217
+ <input type="hidden" class="form-control mr-2" id="url" placeholder="Enter REST Api url..."
218
+ value="../predict" />
219
+ <input name="upload" type="file" id="fileinput"
220
+ style="position:absolute;top:-500px;" /><br />
221
+ </form>
222
+ </div>
223
+ </div>
224
+ <div class="col-md-6 col-xs-12 right-part">
225
+ <h5 class="mb-2">
226
+ <center>Prediction Results</center>
227
+ </h5>
228
+ <div class="row">
229
+ <div class="res-part col-md-5 col-xs-12">
230
+ <div class="jsonRes"></div>
231
+ </div>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </section>
236
+ </div>
237
+ <div class="socials">
238
+ <div class="credit">Designed by Shrey Patel</div>
239
+ <div class="icons">
240
+ <a href="https://www.linkedin.com/in/shreypatel07" target="_blank">
241
+ <i class="fab fa-linkedin"></i>
242
+ </a>
243
+ <a href="https://github.com/Shrey-patel-07" target="_blank">
244
+ <i class="fab fa-github"></i>
245
+ </a>
246
+ <a href="https://x.com/Shrey_Patel_07" target="_blank">
247
+ <i class="fab fa-twitter"></i>
248
+ </a>
249
+ </div>
250
+ </div>
251
+
252
+
253
+ <div id="loading">
254
+ <div class="loader"></div>
255
+ </div>
256
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
257
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
258
+ integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
259
+ crossorigin="anonymous"></script>
260
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
261
+ integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
262
+ crossorigin="anonymous"></script>
263
+
264
+ <script>
265
+ var mybtn = document.getElementById('startbtn');
266
+ var myvideo = document.getElementById('video');
267
+ var mycanvas = document.getElementById('canvas');
268
+ var myphoto = document.getElementById('photo');
269
+ var base_data = "";
270
+
271
+ function sendRequest(base64Data) {
272
+ var type = "json";
273
+ if (base64Data != "" || base64Data != null) {
274
+ if (type == "imgtobase") {
275
+ $(".res-part").html("");
276
+ $(".res-part").html(base64Data);
277
+ }
278
+ else if (type == "basetoimg") {
279
+ var imageData = $("#imgstring").val();
280
+ $(".res-part").html("");
281
+ $(".res-part").append("<img src='data:image/jpeg;base64," + imageData + "' alt='' />");
282
+ }
283
+ else {
284
+ var url = $("#url").val();
285
+ $("#loading").show();
286
+ $.ajax({
287
+ url: url,
288
+ type: "post",
289
+ cache: false,
290
+ async: true,
291
+ crossDomain: true,
292
+ headers: {
293
+ 'Content-Type': 'application/json',
294
+ 'Access-Control-Allow-Origin': '*'
295
+ },
296
+ data: JSON.stringify({ image: base64Data }),
297
+ success: function (res) {
298
+ $(".res-part").html("");
299
+ $(".res-part2").html("");
300
+ try {
301
+ var imageData = res[1].image;
302
+ if (imageData.length > 100) {
303
+ if (imageData.length > 10) { $(".res-part2").append("<img class='resp-img' src='data:image/jpeg;base64," + imageData + "' alt='' />"); }
304
+ }
305
+ } catch (e) { }
306
+ $(".res-part").html("<pre>" + res[0].image + "</pre>");
307
+ $("#loading").hide();
308
+ }
309
+ });
310
+ }
311
+ }
312
+ }
313
+
314
+ $(document).ready(function () {
315
+ $("#loading").hide();
316
+
317
+ $('#send').click(function (evt) {
318
+ sendRequest(base_data);
319
+ });
320
+
321
+ $('#uload').click(function (evt) {
322
+ $('#fileinput').focus().trigger('click');
323
+ });
324
+ $("#fileinput").change(function () {
325
+ if (this.files && this.files[0]) {
326
+ var reader = new FileReader();
327
+ reader.onload = function (e) {
328
+ var url = e.target.result;
329
+ var img = new Image();
330
+ img.crossOrigin = 'Anonymous';
331
+ img.onload = function () {
332
+ var canvas = document.createElement('CANVAS');
333
+ var ctx = canvas.getContext('2d');
334
+ canvas.height = this.height;
335
+ canvas.width = this.width;
336
+ ctx.drawImage(this, 0, 0);
337
+ base_data = canvas.toDataURL('image/jpeg', 1.0).replace(/^data:image.+;base64,/, '');
338
+ canvas = null;
339
+ };
340
+ img.src = url;
341
+ $('#photo').attr('src', url);
342
+ $('#photo').show();
343
+ $('#video').hide();
344
+ }
345
+ reader.readAsDataURL(this.files[0]);
346
+ }
347
+ });
348
+ });
349
+
350
+ </script>
351
+ </body>
352
+
353
+ </html>
Kidney-Disease-Classifcation/templates/kidney_ctscan.png ADDED
Kidney-Disease-Classifcation/templates/mlflow-kidney_disease_classification.png ADDED