Commit a67f14cd authored by Methmini-abeysekara's avatar Methmini-abeysekara

Mammogram model

parent e4377533
{
"cells": [
{
"cell_type": "code",
"execution_count": 21,
"id": "8534cec1",
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"import os"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "3ad804d6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Collecting tensorflow\n",
" Downloading tensorflow-2.11.0-cp38-cp38-win_amd64.whl (1.9 kB)\n",
"Collecting tensorflow-intel==2.11.0\n",
" Downloading tensorflow_intel-2.11.0-cp38-cp38-win_amd64.whl (266.3 MB)\n",
"Collecting astunparse>=1.6.0\n",
" Downloading astunparse-1.6.3-py2.py3-none-any.whl (12 kB)\n",
"Requirement already satisfied: numpy>=1.20 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (1.20.1)\n",
"Collecting keras<2.12,>=2.11.0\n",
" Downloading keras-2.11.0-py2.py3-none-any.whl (1.7 MB)\n",
"Collecting gast<=0.4.0,>=0.2.1\n",
" Downloading gast-0.4.0-py3-none-any.whl (9.8 kB)\n",
"Collecting opt-einsum>=2.3.2\n",
" Downloading opt_einsum-3.3.0-py3-none-any.whl (65 kB)\n",
"Collecting tensorboard<2.12,>=2.11\n",
" Downloading tensorboard-2.11.2-py3-none-any.whl (6.0 MB)\n",
"Collecting libclang>=13.0.0\n",
" Downloading libclang-15.0.6.1-py2.py3-none-win_amd64.whl (23.2 MB)\n",
"Requirement already satisfied: typing-extensions>=3.6.6 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (3.7.4.3)\n",
"Requirement already satisfied: packaging in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (20.9)\n",
"Requirement already satisfied: wrapt>=1.11.0 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (1.12.1)\n",
"Collecting protobuf<3.20,>=3.9.2\n",
" Downloading protobuf-3.19.6-cp38-cp38-win_amd64.whl (896 kB)\n",
"Collecting termcolor>=1.1.0\n",
" Downloading termcolor-2.2.0-py3-none-any.whl (6.6 kB)\n",
"Collecting grpcio<2.0,>=1.24.3\n",
" Downloading grpcio-1.51.1-cp38-cp38-win_amd64.whl (3.7 MB)\n",
"Requirement already satisfied: six>=1.12.0 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (1.15.0)\n",
"Collecting tensorflow-io-gcs-filesystem>=0.23.1\n",
" Downloading tensorflow_io_gcs_filesystem-0.30.0-cp38-cp38-win_amd64.whl (1.5 MB)\n",
"Collecting tensorflow-estimator<2.12,>=2.11.0\n",
" Downloading tensorflow_estimator-2.11.0-py2.py3-none-any.whl (439 kB)\n",
"Collecting flatbuffers>=2.0\n",
" Downloading flatbuffers-23.1.21-py2.py3-none-any.whl (26 kB)\n",
"Collecting google-pasta>=0.1.1\n",
" Downloading google_pasta-0.2.0-py3-none-any.whl (57 kB)\n",
"Requirement already satisfied: h5py>=2.9.0 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (2.10.0)\n",
"Requirement already satisfied: setuptools in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorflow-intel==2.11.0->tensorflow) (52.0.0.post20210125)\n",
"Collecting absl-py>=1.0.0\n",
" Downloading absl_py-1.4.0-py3-none-any.whl (126 kB)\n",
"Requirement already satisfied: wheel<1.0,>=0.23.0 in c:\\users\\user\\anaconda3\\lib\\site-packages (from astunparse>=1.6.0->tensorflow-intel==2.11.0->tensorflow) (0.36.2)\n",
"Requirement already satisfied: requests<3,>=2.21.0 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (2.25.1)\n",
"Collecting tensorboard-data-server<0.7.0,>=0.6.0\n",
" Downloading tensorboard_data_server-0.6.1-py3-none-any.whl (2.4 kB)\n",
"Collecting google-auth-oauthlib<0.5,>=0.4.1\n",
" Downloading google_auth_oauthlib-0.4.6-py2.py3-none-any.whl (18 kB)\n",
"Requirement already satisfied: werkzeug>=1.0.1 in c:\\users\\user\\anaconda3\\lib\\site-packages (from tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (1.0.1)\n",
"Collecting google-auth<3,>=1.6.3\n",
" Downloading google_auth-2.16.0-py2.py3-none-any.whl (177 kB)\n",
"Collecting markdown>=2.6.8\n",
" Downloading Markdown-3.4.1-py3-none-any.whl (93 kB)\n",
"Collecting tensorboard-plugin-wit>=1.6.0\n",
" Downloading tensorboard_plugin_wit-1.8.1-py3-none-any.whl (781 kB)\n",
"Collecting pyasn1-modules>=0.2.1\n",
" Downloading pyasn1_modules-0.2.8-py2.py3-none-any.whl (155 kB)\n",
"Collecting rsa<5,>=3.1.4\n",
" Downloading rsa-4.9-py3-none-any.whl (34 kB)\n",
"Collecting cachetools<6.0,>=2.0.0\n",
" Downloading cachetools-5.3.0-py3-none-any.whl (9.3 kB)\n",
"Collecting requests-oauthlib>=0.7.0\n",
" Downloading requests_oauthlib-1.3.1-py2.py3-none-any.whl (23 kB)\n",
"Collecting importlib-metadata>=4.4\n",
" Downloading importlib_metadata-6.0.0-py3-none-any.whl (21 kB)\n",
"Requirement already satisfied: zipp>=0.5 in c:\\users\\user\\anaconda3\\lib\\site-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (3.4.1)\n",
"Collecting pyasn1<0.5.0,>=0.4.6\n",
" Downloading pyasn1-0.4.8-py2.py3-none-any.whl (77 kB)\n",
"Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\user\\anaconda3\\lib\\site-packages (from requests<3,>=2.21.0->tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (2020.12.5)\n",
"Requirement already satisfied: chardet<5,>=3.0.2 in c:\\users\\user\\anaconda3\\lib\\site-packages (from requests<3,>=2.21.0->tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (4.0.0)\n",
"Requirement already satisfied: idna<3,>=2.5 in c:\\users\\user\\anaconda3\\lib\\site-packages (from requests<3,>=2.21.0->tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (2.10)\n",
"Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\\users\\user\\anaconda3\\lib\\site-packages (from requests<3,>=2.21.0->tensorboard<2.12,>=2.11->tensorflow-intel==2.11.0->tensorflow) (1.26.4)\n",
"Collecting oauthlib>=3.0.0\n",
" Downloading oauthlib-3.2.2-py3-none-any.whl (151 kB)\n",
"Requirement already satisfied: pyparsing>=2.0.2 in c:\\users\\user\\anaconda3\\lib\\site-packages (from packaging->tensorflow-intel==2.11.0->tensorflow) (2.4.7)\n",
"Installing collected packages: pyasn1, rsa, pyasn1-modules, oauthlib, cachetools, requests-oauthlib, importlib-metadata, google-auth, tensorboard-plugin-wit, tensorboard-data-server, protobuf, markdown, grpcio, google-auth-oauthlib, absl-py, termcolor, tensorflow-io-gcs-filesystem, tensorflow-estimator, tensorboard, opt-einsum, libclang, keras, google-pasta, gast, flatbuffers, astunparse, tensorflow-intel, tensorflow\n",
" Attempting uninstall: importlib-metadata\n",
" Found existing installation: importlib-metadata 3.10.0\n",
" Uninstalling importlib-metadata-3.10.0:\n",
" Successfully uninstalled importlib-metadata-3.10.0\n",
"Successfully installed absl-py-1.4.0 astunparse-1.6.3 cachetools-5.3.0 flatbuffers-23.1.21 gast-0.4.0 google-auth-2.16.0 google-auth-oauthlib-0.4.6 google-pasta-0.2.0 grpcio-1.51.1 importlib-metadata-6.0.0 keras-2.11.0 libclang-15.0.6.1 markdown-3.4.1 oauthlib-3.2.2 opt-einsum-3.3.0 protobuf-3.19.6 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-oauthlib-1.3.1 rsa-4.9 tensorboard-2.11.2 tensorboard-data-server-0.6.1 tensorboard-plugin-wit-1.8.1 tensorflow-2.11.0 tensorflow-estimator-2.11.0 tensorflow-intel-2.11.0 tensorflow-io-gcs-filesystem-0.30.0 termcolor-2.2.0\n"
]
}
],
"source": [
"!pip install tensorflow"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "5d192baa",
"metadata": {},
"outputs": [],
"source": [
"# Avoid OOM errors by setting GPU Memory Consumption Growth\n",
"gpus = tf.config.experimental.list_physical_devices('GPU')\n",
"for gpu in gpus: \n",
" tf.config.experimental.set_memory_growth(gpu, True)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "6fd495a5",
"metadata": {},
"outputs": [],
"source": [
"import cv2\n",
"import imghdr"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "5b629483",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from matplotlib import pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "9f0c5c8e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found 1131 files belonging to 2 classes.\n"
]
}
],
"source": [
"data = tf.keras.utils.image_dataset_from_directory('processed_dataset')"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "2984c4f2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['BENIGN', 'MALIGNANT']\n"
]
}
],
"source": [
"class_names = data.class_names\n",
"print(class_names)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "ffaabad4",
"metadata": {},
"outputs": [],
"source": [
"data = data.map(lambda x,y: (x/255, y))"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "359376dd",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"36"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(data)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "a9138317",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"25 7 4\n"
]
}
],
"source": [
"train_size = int(len(data)*.7)\n",
"val_size = int(len(data)*.2)\n",
"test_size = int(len(data)*.1)+1\n",
"print(train_size,val_size,test_size)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "30bb0cd2",
"metadata": {},
"outputs": [],
"source": [
"train = data.take(train_size)\n",
"val = data.skip(train_size).take(val_size)\n",
"test = data.skip(train_size+val_size).take(test_size)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "0fd51935",
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras.models import Sequential\n",
"from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "d71fbe4d",
"metadata": {},
"outputs": [],
"source": [
"model = Sequential()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "4e26604d",
"metadata": {},
"outputs": [],
"source": [
"model.add(Conv2D(16, (3,3), 1, activation='relu', input_shape=(256,256,3)))\n",
"model.add(MaxPooling2D())\n",
"model.add(Conv2D(32, (3,3), 1, activation='relu'))\n",
"model.add(MaxPooling2D())\n",
"model.add(Conv2D(16, (3,3), 1, activation='relu'))\n",
"model.add(MaxPooling2D())\n",
"model.add(Flatten())\n",
"model.add(Dense(256, activation='relu'))\n",
"model.add(Dense(1, activation='sigmoid'))"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "1a540174",
"metadata": {},
"outputs": [],
"source": [
"model.compile('adam', loss=tf.losses.BinaryCrossentropy(), metrics=['accuracy'])"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "00165625",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"sequential_1\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" conv2d_3 (Conv2D) (None, 254, 254, 16) 448 \n",
" \n",
" max_pooling2d_3 (MaxPooling (None, 127, 127, 16) 0 \n",
" 2D) \n",
" \n",
" conv2d_4 (Conv2D) (None, 125, 125, 32) 4640 \n",
" \n",
" max_pooling2d_4 (MaxPooling (None, 62, 62, 32) 0 \n",
" 2D) \n",
" \n",
" conv2d_5 (Conv2D) (None, 60, 60, 16) 4624 \n",
" \n",
" max_pooling2d_5 (MaxPooling (None, 30, 30, 16) 0 \n",
" 2D) \n",
" \n",
" flatten_1 (Flatten) (None, 14400) 0 \n",
" \n",
" dense_2 (Dense) (None, 256) 3686656 \n",
" \n",
" dense_3 (Dense) (None, 1) 257 \n",
" \n",
"=================================================================\n",
"Total params: 3,696,625\n",
"Trainable params: 3,696,625\n",
"Non-trainable params: 0\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "fb7a04e3",
"metadata": {},
"outputs": [],
"source": [
"logdir='logs'"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "cb6dbbf1",
"metadata": {},
"outputs": [],
"source": [
"tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)\n"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "5b017b4d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/20\n",
"25/25 [==============================] - 70s 2s/step - loss: 0.7364 - accuracy: 0.4712 - val_loss: 0.6920 - val_accuracy: 0.5625\n",
"Epoch 2/20\n",
"25/25 [==============================] - 67s 2s/step - loss: 0.6839 - accuracy: 0.6037 - val_loss: 0.6732 - val_accuracy: 0.5179\n",
"Epoch 3/20\n",
"25/25 [==============================] - 60s 2s/step - loss: 0.6430 - accuracy: 0.6225 - val_loss: 0.6657 - val_accuracy: 0.5580\n",
"Epoch 4/20\n",
"25/25 [==============================] - 61s 2s/step - loss: 0.5531 - accuracy: 0.7000 - val_loss: 0.6499 - val_accuracy: 0.5982\n",
"Epoch 5/20\n",
"25/25 [==============================] - 60s 2s/step - loss: 0.4560 - accuracy: 0.7412 - val_loss: 0.6654 - val_accuracy: 0.6473\n",
"Epoch 6/20\n",
"25/25 [==============================] - 60s 2s/step - loss: 0.4324 - accuracy: 0.7613 - val_loss: 0.6239 - val_accuracy: 0.6964\n",
"Epoch 7/20\n",
"25/25 [==============================] - 61s 2s/step - loss: 0.3637 - accuracy: 0.7937 - val_loss: 0.7912 - val_accuracy: 0.6875\n",
"Epoch 8/20\n",
"25/25 [==============================] - 58s 2s/step - loss: 0.3168 - accuracy: 0.8350 - val_loss: 0.8803 - val_accuracy: 0.6652\n",
"Epoch 9/20\n",
"25/25 [==============================] - 61s 2s/step - loss: 0.3016 - accuracy: 0.8250 - val_loss: 0.7722 - val_accuracy: 0.7143\n",
"Epoch 10/20\n",
"25/25 [==============================] - 58s 2s/step - loss: 0.3656 - accuracy: 0.8238 - val_loss: 0.6542 - val_accuracy: 0.7277\n",
"Epoch 11/20\n",
"25/25 [==============================] - 57s 2s/step - loss: 0.2801 - accuracy: 0.8338 - val_loss: 0.6995 - val_accuracy: 0.7411\n",
"Epoch 12/20\n",
"25/25 [==============================] - 57s 2s/step - loss: 0.2677 - accuracy: 0.8475 - val_loss: 0.7699 - val_accuracy: 0.7277\n",
"Epoch 13/20\n",
"25/25 [==============================] - 70s 3s/step - loss: 0.2497 - accuracy: 0.8625 - val_loss: 0.7676 - val_accuracy: 0.7321\n",
"Epoch 14/20\n",
"25/25 [==============================] - 68s 2s/step - loss: 0.2718 - accuracy: 0.8512 - val_loss: 0.7479 - val_accuracy: 0.7366\n",
"Epoch 15/20\n",
"25/25 [==============================] - 63s 2s/step - loss: 0.2722 - accuracy: 0.8637 - val_loss: 0.7188 - val_accuracy: 0.7500\n",
"Epoch 16/20\n",
"25/25 [==============================] - 69s 2s/step - loss: 0.2307 - accuracy: 0.8838 - val_loss: 0.6162 - val_accuracy: 0.7634\n",
"Epoch 17/20\n",
"25/25 [==============================] - 61s 2s/step - loss: 0.2317 - accuracy: 0.8900 - val_loss: 0.8517 - val_accuracy: 0.7946\n",
"Epoch 18/20\n",
"25/25 [==============================] - 62s 2s/step - loss: 0.1968 - accuracy: 0.9187 - val_loss: 0.6997 - val_accuracy: 0.7946\n",
"Epoch 19/20\n",
"25/25 [==============================] - 63s 2s/step - loss: 0.2113 - accuracy: 0.9175 - val_loss: 0.8132 - val_accuracy: 0.8036\n",
"Epoch 20/20\n",
"25/25 [==============================] - 61s 2s/step - loss: 0.1993 - accuracy: 0.9237 - val_loss: 0.6383 - val_accuracy: 0.8214\n"
]
}
],
"source": [
"hist = model.fit(train, epochs=20, validation_data=val, callbacks=[tensorboard_callback])"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "105cdaa1",
"metadata": {},
"outputs": [],
"source": [
"### cross validation"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "25df28be",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"plt.plot(hist.history['loss'], color='teal', label='loss')\n",
"plt.plot(hist.history['val_loss'], color='orange', label='val_loss')\n",
"fig.suptitle('Loss', fontsize=20)\n",
"plt.legend(loc=\"upper left\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "ab853124",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig = plt.figure()\n",
"plt.plot(hist.history['accuracy'], color='teal', label='accuracy')\n",
"plt.plot(hist.history['val_accuracy'], color='orange', label='val_accuracy')\n",
"fig.suptitle('Accuracy', fontsize=20)\n",
"plt.legend(loc=\"upper left\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "bd08d36b",
"metadata": {},
"outputs": [],
"source": [
"### Inference testing"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "9879cca6",
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras.metrics import Precision, Recall, BinaryAccuracy"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "ce197d60",
"metadata": {},
"outputs": [],
"source": [
"pre = Precision()\n",
"re = Recall()\n",
"acc = BinaryAccuracy()"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "259a0db3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1/1 [==============================] - 0s 331ms/step\n",
"1/1 [==============================] - 0s 202ms/step\n",
"1/1 [==============================] - 0s 206ms/step\n",
"1/1 [==============================] - 0s 167ms/step\n"
]
}
],
"source": [
"for batch in test.as_numpy_iterator(): \n",
" X, y = batch\n",
" yhat = model.predict(X)\n",
" pre.update_state(y, yhat)\n",
" re.update_state(y, yhat)\n",
" acc.update_state(y, yhat)"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "c807b24e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tf.Tensor(0.77272725, shape=(), dtype=float32) tf.Tensor(0.75555557, shape=(), dtype=float32) tf.Tensor(0.8037383, shape=(), dtype=float32)\n"
]
}
],
"source": [
"print(pre.result(), re.result(), acc.result())"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "0121c87e",
"metadata": {},
"outputs": [],
"source": [
"import cv2"
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "86070a3b",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"img = cv2.imread(r'C:\\Users\\user\\Documents\\mammogram\\processed_dataset\\BENIGN\\1-000.jpg')\n",
"# view the image\n",
"plt.imshow(img)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 69,
"id": "d8fdbaff",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD8CAYAAACVSwr3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAPhklEQVR4nO3db4xddZ3H8fe3M51qoA/oQrH0D4y1JJSoaJouSVd0NQjywMFENvVBaQxJjQGjCRtT5IEmhMTdoD5QMRkjsVldu5OooQnEpW2M8AjaEiy0bNuxFDq0UrBrWhYzwMx3H8xpvfQ307mduefeO/B+Jb/cc3/3nHu/99B++J3fPec0MhNJajSv0wVI6j4Gg6SCwSCpYDBIKhgMkgoGg6RCbcEQETdHxIGIGI6IzXV9jqTWizrOY4iIHuAgcCMwAuwCvpSZ+1v+YZJarq4Rw1pgODMPZ+abwFZgoKbPktRivTW971LgaMPzEeAfp1o5Ijz9Uqrfa5l5WTMr1hUMMUnfO/7yR8QmYFNNny+p9GKzK9YVDCPA8obny4BjjStk5iAwCI4YpG5T1xzDLmBVRPRHRB+wHthW02dJarFaRgyZ+XZE3AX8N9ADPJSZ++r4LEmtV8vPlRdchIcSUjvsycw1zazomY+SCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpILBIKlgMEgqGAySCgaDpELvbDaOiCPAaWAMeDsz10TEIuC/gKuAI8C/ZOb/zq5MSe3UihHDP2fmdZm5pnq+GdiZmauAndVzSXNIHYcSA8CWankLcGsNnyGpRrMNhgQei4g9EbGp6rs8M48DVI+LJ9swIjZFxO6I2D3LGiS12KzmGIB1mXksIhYD2yPif5rdMDMHgUGAiMhZ1iGphWY1YsjMY9XjCeC3wFrglYhYAlA9nphtkZLaa8bBEBEXRcTCM8vAZ4HngG3Axmq1jcDDsy1SUnvN5lDicuC3EXHmff4zM38XEbuAoYi4A3gJuG32ZUpqp8js/OG9cwxSW+xpOK3gvDzzUVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVJh2mCIiIci4kREPNfQtygitkfEoerxkobX7omI4Yg4EBE31VW4pPo0M2L4OXDzOX2bgZ2ZuQrYWT0nIlYD64Frq20ejIiellUrqS2mDYbMfBw4eU73ALClWt4C3NrQvzUzRzPzBWAYWNuaUiW1y0znGC7PzOMA1ePiqn8pcLRhvZGqT9Ic0tvi94tJ+nLSFSM2AZta/PmSWmCmI4ZXImIJQPV4ouofAZY3rLcMODbZG2TmYGauycw1M6xBUk1mGgzbgI3V8kbg4Yb+9RGxICL6gVXAU7MrUVK7TXsoERG/Aj4FXBoRI8C3ge8CQxFxB/AScBtAZu6LiCFgP/A2cGdmjtVUu6SaROakUwDtLSKi80VI7357mj1098xHSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUaPW1Eupy11xzDT09Pfztb3/j6NGjvPnmmwDMmzePlStXcvLkSZYsWcLo6Ch9fX1ElJe/zJs3j9HRUQ4cONDu8tUmBsMctGzZMtatWwfAI488wuuvv372tfnz5/OJT3yChQsX8thjj/H5z3/+HdsODg5y0UUXcfjwYX784x/z5z//GYD3ve993H///ezcuZMNGzYwMjLC4sWL6evr48xJcBFBRJCZjIyMsGLFijZ9Y7VdZna8MXEFpq3J9sUvfjHHx8czM/PBBx/M3t7eXLZsWd5///35wAMP5EsvvZSvv/56/vCHP8w6jI2N5de+9rWO7wfbBbfdTf+d7HQopMFwQW3FihW5a9eus8EwPj6ejz76aD7xxBNn++o0Pj6eGzZs6Ph+sM2oGQzvtrZt27Y8dOhQvvjii20JgHONj4/n4OBgfuQjH8ne3t78wAc+kAcPHsx777234/vG1nRrOhicY5gjVqxYwcqVKyedDGyXL3/5y9x+++2cPHmSzKSvr4/3v//9HatH9TEY5oi9e/fS39/PkSNH+PCHP9z2gIgIenp6OHjwIJ/85Cd57bXX2vr5arNmhxZ1Njo/xJoT7Zvf/GZeccUVuWPHjnqOF6YxPj6en/70p/Pqq6/u+L6wzag5x/Bubh/60Ifyrrvuyr179+bY2FjbJh2HhoZy+fLluXr16o7vA9uMWtPB4JmPc9Dw8DA/+tGPOHz4cFsPKT760Y+yaNEi9u/f37bPVGc4xzBH3X333XzmM59hbGyMnp76/k2fzGTPnj0MDAyQmfzlL3+p7bPUPby12xx15izEiODgwYP09/czPj7OX//6V/r6+rj44otnPJo4deoUp0+fPjusfPLJJ7ntttta/A3UAU3f2q3j8wvpHMOs28KFC3P79u05NDSUN9xwQ371q1/NU6dOveMkqP379+eOHTtydHR02rmE++67L+fPn9/x72VrefM8hveS06dPc+ONN559/vjjj3PZZZdxySVn/61htm7dylVXXcX111/P/PnzAd4xojhzmPCLX/yCP/zhD7z11lvt+wLqPp0eLThiaF9bv3593nffffnqq6/m4OBgvvHGG2dHCm+88UYODAx0vEZbra3pEYNzDO8hvb29LFiwgJUrV/Lyyy9z5ZVXnp24HBsb4+mnn+5whapZ03MMBoP03uG/KyFp5gwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSYVpgyEiHoqIExHxXEPfdyLi5Yh4pmq3NLx2T0QMR8SBiLiprsIl1aeZEcPPgZsn6f9BZl5XtUcBImI1sB64ttrmwYio7/ZCkmoxbTBk5uPAySbfbwDYmpmjmfkCMAysnUV9kjpgNnMMd0XE3upQ48wdQZYCRxvWGan6ChGxKSJ2R8TuWdQgqQYzDYafACuB64DjwPeq/sluMjjpJdWZOZiZa5q9DFRS+8woGDLzlcwcy8xx4Kf8/XBhBFjesOoy4NjsSpTUbjMKhohY0vD0C8CZXyy2AesjYkFE9AOrgKdmV6Kkdpv2ZrAR8SvgU8ClETECfBv4VERcx8RhwhHgKwCZuS8ihoD9wNvAnZk5Vkvlkmrjrd2k9w5v7SZp5gwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFaYNhohYHhG/j4jnI2JfRHy96l8UEdsj4lD1eEnDNvdExHBEHIiIm+r8ApJar5kRw9vA3Zl5DXA9cGdErAY2AzszcxWws3pO9dp64FrgZuDBiOipo3hJ9Zg2GDLzeGY+XS2fBp4HlgIDwJZqtS3ArdXyALA1M0cz8wVgGFjb4rol1eiC5hgi4irgY8CTwOWZeRwmwgNYXK22FDjasNlI1SdpjuhtdsWIuBj4NfCNzDwVEVOuOklfTvJ+m4BNzX6+pPZpasQQEfOZCIVfZuZvqu5XImJJ9foS4ETVPwIsb9h8GXDs3PfMzMHMXJOZa2ZavKR6NPOrRAA/A57PzO83vLQN2FgtbwQebuhfHxELIqIfWAU81bqSJdWtmUOJdcAG4NmIeKbq+xbwXWAoIu4AXgJuA8jMfRExBOxn4heNOzNzrNWFS6pPZBaH/+0vIqLzRUjvfnuaPXT3zEdJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUsFgkFQwGCQVDAZJBYNBUmHaYIiI5RHx+4h4PiL2RcTXq/7vRMTLEfFM1W5p2OaeiBiOiAMRcVOdX0BS6/U2sc7bwN2Z+XRELAT2RMT26rUfZOYDjStHxGpgPXAtcAWwIyKuzsyxVhYuqT7Tjhgy83hmPl0tnwaeB5aeZ5MBYGtmjmbmC8AwsLYVxUpqjwuaY4iIq4CPAU9WXXdFxN6IeCgiLqn6lgJHGzYbYZIgiYhNEbE7InZfeNmS6tR0METExcCvgW9k5ingJ8BK4DrgOPC9M6tOsnkWHZmDmbkmM9dcaNGS6tVUMETEfCZC4ZeZ+RuAzHwlM8cycxz4KX8/XBgBljdsvgw41rqSJdWtmV8lAvgZ8Hxmfr+hf0nDal8AnquWtwHrI2JBRPQDq4CnWleypLo186vEOmAD8GxEPFP1fQv4UkRcx8RhwhHgKwCZuS8ihoD9TPyicae/SEhzS2QWh//tLyLiVeD/gNc6XUsTLmVu1Alzp9a5UifMnVonq/PKzLysmY27IhgAImL3XJiInCt1wtypda7UCXOn1tnW6SnRkgoGg6RCNwXDYKcLaNJcqRPmTq1zpU6YO7XOqs6umWOQ1D26acQgqUt0PBgi4ubq8uzhiNjc6XrOFRFHIuLZ6tLy3VXfoojYHhGHqsdLpnufGup6KCJORMRzDX1T1tXJS+GnqLXrLts/zy0Gumq/tuVWCJnZsQb0AH8CPgj0AX8EVneypklqPAJcek7fvwObq+XNwL91oK4bgI8Dz01XF7C62rcLgP5qn/d0uNbvAP86ybodqxVYAny8Wl4IHKzq6ar9ep46W7ZPOz1iWAsMZ+bhzHwT2MrEZdvdbgDYUi1vAW5tdwGZ+Thw8pzuqerq6KXwU9Q6lY7VmlPfYqCr9ut56pzKBdfZ6WBo6hLtDkvgsYjYExGbqr7LM/M4TPxHAhZ3rLp3mqqubt3PM75sv27n3GKga/drK2+F0KjTwdDUJdodti4zPw58DrgzIm7odEEz0I37eVaX7ddpklsMTLnqJH1tq7XVt0Jo1Olg6PpLtDPzWPV4AvgtE0OwV85cXVo9nuhche8wVV1dt5+zSy/bn+wWA3Thfq37VgidDoZdwKqI6I+IPibuFbmtwzWdFREXVfe5JCIuAj7LxOXl24CN1WobgYc7U2Fhqrq67lL4brxsf6pbDNBl+7Utt0Jox2zvNDOstzAxq/on4N5O13NObR9kYjb3j8C+M/UB/wDsBA5Vj4s6UNuvmBguvsXE/xHuOF9dwL3VPj4AfK4Lav0P4Flgb/UHd0mnawX+iYkh9l7gmard0m379Tx1tmyfeuajpEKnDyUkdSGDQVLBYJBUMBgkFQwGSQWDQVLBYJBUMBgkFf4f8jeefYYrFU8AAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"resize = tf.image.resize(img, (256,256))\n",
"plt.imshow(resize.numpy().astype(int))\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 70,
"id": "32aa2b1d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1/1 [==============================] - 4s 4s/step\n",
"Benign\n"
]
}
],
"source": [
"yhat = model.predict(np.expand_dims(resize/255, 0))\n",
"if yhat > 0.3: \n",
" print(f'Malignant')\n",
"else:\n",
" print(f'Benign')"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "3e70fc76",
"metadata": {},
"outputs": [],
"source": [
"### Save the model"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "79c1d567",
"metadata": {},
"outputs": [],
"source": [
"from tensorflow.keras.models import load_model"
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "77a13006",
"metadata": {},
"outputs": [],
"source": [
"model.save(os.path.join('models','imageclassifier.h5'))"
]
},
{
"cell_type": "code",
"execution_count": 63,
"id": "079b7176",
"metadata": {},
"outputs": [],
"source": [
"new_model = load_model(r'C:\\Users\\user\\Documents\\mammogram\\models\\imageclassifier.h5')"
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "e88b9f8e",
"metadata": {},
"outputs": [],
"source": [
"### Custom function to get the prediction"
]
},
{
"cell_type": "code",
"execution_count": 65,
"id": "c80c9571",
"metadata": {},
"outputs": [],
"source": [
"def customPredict(img_url):\n",
" new_model = load_model('imageclassifier.h5')\n",
" img = cv2.imread(img_url)\n",
" resize = tf.image.resize(img, (256,256))\n",
" yhat = new_model.predict(np.expand_dims(resize/255, 0))\n",
" if yhat > 0.3: \n",
" return 'Malignant'\n",
" else:\n",
" return 'Benign'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3098eb4",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment