Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add layer name and test folder address #3

Merged
merged 7 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,16 @@ on:
branches:
- main
- master
- '*'
- 'feature/*'
tags:
- "v*.*.*"
pull_request:
types:
- closed
branches:
- master
- main


jobs:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ neural_network_model/__pycache__/
tests/__pycache__/
/.coverage
__pycache__/
/dataset/
/dataset_augmented/
/dataset_train_test_val/
/deep_model/
Binary file modified figures/grad_cam_pdc_Image_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified figures/history.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified figures/prediction_pdc_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified figures/prediction_rollercone_bit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 54 additions & 23 deletions neural_network_model/bit_vision.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@
from tensorflow import keras
from tensorflow.keras.applications.resnet50 import decode_predictions, preprocess_input
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from tensorflow.keras.preprocessing.image import (
ImageDataGenerator,
img_to_array,
load_img,
)
from keras import Sequential
from keras.callbacks import ModelCheckpoint
from keras.layers import BatchNormalization, Conv2D, Dense, Dropout, Flatten, MaxPooling2D
from keras.layers import (
BatchNormalization,
Conv2D,
Dense,
Dropout,
Flatten,
MaxPooling2D,
)

from neural_network_model.model import SETTING

Expand Down Expand Up @@ -321,7 +332,8 @@ def _filter_out_list(
def predict(self, *args, **kwargs):
"""
This function is used to predict the test data.
:param args:
:param args: test_folder_dir needs to have a suborder called test and there needs to have categories folders
same structure as train_test_val directory
:param kwargs: fig_save_address: the address of the folder to save the figure,
model_path: the path of the model to be used for prediction
:return:
Expand All @@ -339,10 +351,10 @@ def predict(self, *args, **kwargs):
if model_path is None:
logger.info(f"model_path from SETTING is was used - {model_path}")

test_folder_address = kwargs.get(
"test_folder_address", SETTING.DATA_ADDRESS_SETTING.TEST_DIR_ADDRESS
test_folder_dir = kwargs.get(
"test_folder_dir", SETTING.DATA_ADDRESS_SETTING.TEST_DIR_ADDRESS
)
if test_folder_address is None:
if test_folder_dir is None:
raise ValueError("test_folder_address is None")

model = keras.models.load_model(model_path)
Expand All @@ -353,10 +365,17 @@ def predict(self, *args, **kwargs):
number_of_cols = SETTING.FIGURE_SETTING.NUM_COLS_IN_PRED_MODEL
number_of_rows = SETTING.FIGURE_SETTING.NUM_ROWS_IN_PRED_MODEL
number_of_test_to_pred = SETTING.MODEL_SETTING.NUMBER_OF_TEST_TO_PRED
train_test_val_dir = (
self.train_test_val_dir
or SETTING.PREPROCESSING_SETTING.TRAIN_TEST_VAL_SPLIT_DIR_ADDRESS
)
if test_folder_dir:
train_test_val_dir = (
test_folder_dir
or SETTING.PREPROCESSING_SETTING.TRAIN_TEST_VAL_SPLIT_DIR_ADDRESS
)
else:
train_test_val_dir = (
self.train_test_val_dir
or SETTING.PREPROCESSING_SETTING.TRAIN_TEST_VAL_SPLIT_DIR_ADDRESS
)

# get the list of test images
test_images_list = os.listdir(
train_test_val_dir
Expand Down Expand Up @@ -413,7 +432,7 @@ def predict(self, *args, **kwargs):

datagen = image.ImageDataGenerator(SETTING.DATA_GEN_SETTING.RESCALE)
DoubleCheck_generator = datagen.flow_from_directory(
directory=test_folder_address,
directory=test_folder_dir / "test",
target_size=SETTING.FLOW_FROM_DIRECTORY_SETTING.TARGET_SIZE,
color_mode=SETTING.FLOW_FROM_DIRECTORY_SETTING.COLOR_MODE,
classes=None,
Expand Down Expand Up @@ -448,22 +467,27 @@ def grad_cam_viz(self, *args, **kwargs):
"img_to_be_applied_path", SETTING.GRAD_CAM_SETTING.IMG_PATH
)

print_layer_names = kwargs.get("print_layer_names", False)

fig_address = fig_to_save_address / gradcam_fig_name
if model_path is None:
raise ValueError("model_path is None")

model = keras.models.load_model(model_path)
logger.info(f"Model loaded from {model_path}")

# print the model layers
for idx in range(len(model.layers)):
print(model.get_layer(index=idx).name)
if print_layer_names:
# print the model layers
for idx in range(len(model.layers)):
print(model.get_layer(index=idx).name)

# model_builder = keras.applications.xception.Xception
preprocess_input = keras.applications.xception.preprocess_input
# decode_predictions = keras.applications.xception.decode_predictions

last_conv_layer_name = SETTING.GRAD_CAM_SETTING.LAST_CONV_LAYER_NAME
conv_layer_name_tobe_used = kwargs.get(
"layer_name", SETTING.GRAD_CAM_SETTING.LAST_CONV_LAYER_NAME
)

# The local path to our target image
img_path = img_to_be_applied_path
Expand All @@ -490,7 +514,7 @@ def grad_cam_viz(self, *args, **kwargs):
# print("Predicted:", decode_predictions(preds, top=1)[0])
# Generate class activation heatmap
heatmap = BitVision._make_gradcam_heatmap(
img_array, model, last_conv_layer_name
img_array, model, conv_layer_name_tobe_used
)

# Display heatmap
Expand Down Expand Up @@ -611,11 +635,18 @@ def return_best_model_name(
obj = BitVision(
train_test_val_dir=Path(__file__).parent / ".." / "dataset_train_test_val"
)
print(obj.categories)
print(obj.data_details)
obj.plot_image_category()
obj.compile_model()
obj.train_model()
obj.plot_history()
# print(obj.categories)
# print(obj.data_details)
# obj.plot_image_category()
# obj.compile_model()
# obj.train_model(epochs=8)
# obj.plot_history()
obj.predict()
obj.grad_cam_viz(gradcam_fig_name="test.png")
obj.grad_cam_viz(
gradcam_fig_name="test.png",
print_layer_names=True,
test_folder_dir=Path(__file__).parent
/ ".."
/ "dataset_train_test_val"
/ "test",
)
4 changes: 2 additions & 2 deletions neural_network_model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class DataAddressSetting(BaseModel):
Path(__file__).parent
/ ".."
/ "dataset_train_test_val"
/ "test" # check the TRAIN_TEST_SPLIT_DIR_NAMES in
# / "test" # check the TRAIN_TEST_SPLIT_DIR_NAMES in
# the PreprocessingSetting make sure test is in the list
)

Expand Down Expand Up @@ -75,7 +75,7 @@ class ModelSetting(BaseModel):

# fit generator
EPOCHS: int = 3
FIT_GEN_VERBOSE: int = 1
FIT_GEN_VERBOSE: int = 0
VALIDATION_STEPS: int = 4
CLASS_WEIGHT: dict = None
MAX_QUEUE_SIZE: int = 10
Expand Down
10 changes: 7 additions & 3 deletions neural_network_model/process_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@

from bing_image_downloader import downloader
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator, img_to_array, load_img
from tensorflow.keras.preprocessing.image import (
ImageDataGenerator,
img_to_array,
load_img,
)
from tqdm import tqdm

from neural_network_model.model import SETTING
Expand Down Expand Up @@ -354,7 +358,7 @@ def _copy_images(

if __name__ == "__main__":
obj = Preprocessing(dataset_address=Path(__file__).parent / ".." / "dataset")
# obj.download_images()
obj.download_images()

# or download the data from s3. this is after you have downloaded the data
# using Process.download_images() and uploaded it to s3
Expand All @@ -363,5 +367,5 @@ def _copy_images(
# obj.download_images(from_s3=True)

print(obj.image_dict)
obj.augment_data(number_of_images_tobe_gen=10)
obj.augment_data(number_of_images_tobe_gen=20)
obj.train_test_split()
File renamed without changes.
11 changes: 11 additions & 0 deletions tests/test_bitvision.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import pytest


import sys
from pathlib import Path

# Get the parent directory of the current file (assuming the script is in the test folder)
current_dir = Path(__file__).resolve().parent
# Get the parent directory of the current directory (assuming the test folder is one level below the main folder)
main_dir = current_dir.parent
# Add the main directory to the Python path
sys.path.append(str(main_dir))

from neural_network_model.bit_vision import BitVision


Expand Down
11 changes: 10 additions & 1 deletion tests/test_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
from typing import List, Union
from unittest import mock
from unittest.mock import MagicMock, PropertyMock, patch

import sys

# Get the parent directory of the current file (assuming the script is in the test folder)
current_dir = Path(__file__).resolve().parent
# Get the parent directory of the current directory (assuming the test folder is one level below the main folder)
main_dir = current_dir.parent
# Add the main directory to the Python path
sys.path.append(str(main_dir))
import pytest

import neural_network_model
Expand Down Expand Up @@ -38,6 +45,8 @@ def test_download_images_2(_object):
assert mock_bing_downloader.download.call_count == 2


# skip this test
@pytest.mark.skip
def test_download_images_3(mocker, _object):
mock_bing_downloader_download = mocker.patch(
"neural_network_model.process_data.downloader.download"
Expand Down
11 changes: 9 additions & 2 deletions tests/test_run.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import argparse
import os
from pathlib import Path
import sys

# Get the parent directory of the current file (assuming the script is in the test folder)
current_dir = Path(__file__).resolve().parent
# Get the parent directory of the current directory (assuming the test folder is one level below the main folder)
main_dir = current_dir.parent
# Add the main directory to the Python path
sys.path.append(str(main_dir))
# skip this test TODO: fix this test later
import pytest

from neural_network_model.bit_vision import BitVision
from neural_network_model.process_data import Preprocessing


@pytest.mark.skip
@pytest.mark.skip(reason="no way of currently testing this")
def test_run():
# check if a dir name test_resouces exists if not create one
# check if a dir name test_resources exists if not create one
if not os.path.exists(Path(__file__).parent / "test_resources"):
os.mkdir(Path(__file__).parent / "test_resources")

Expand Down