{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Animal Images Detection  \n * ETL Process  \n * Data Augmentation\n * CNN Architecture Model for Detection\n * Debuging & Visualizing Model Outputs\n * Transfer Learning with VGG16 Model for Improving Accuracy","metadata":{}},{"cell_type":"markdown","source":"# **Importing**","metadata":{}},{"cell_type":"code","source":"# Import Libs\nimport numpy as np\nimport pandas as pd \nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\nimport os\nfrom zipfile import ZipFile\nimport tensorflow as tf\nfrom tensorflow.keras.optimizers import RMSprop\n!pip install visualkeras\nimport visualkeras\nfrom PIL import ImageFont\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-02T10:17:42.275431Z","iopub.execute_input":"2022-12-02T10:17:42.275789Z","iopub.status.idle":"2022-12-02T10:17:54.501445Z","shell.execute_reply.started":"2022-12-02T10:17:42.275759Z","shell.execute_reply":"2022-12-02T10:17:54.500231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check data file names\nprint(os.listdir(\"../input/dogs-vs-cats\"))\n","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:17:54.505596Z","iopub.execute_input":"2022-12-02T10:17:54.506371Z","iopub.status.idle":"2022-12-02T10:17:54.514403Z","shell.execute_reply.started":"2022-12-02T10:17:54.506336Z","shell.execute_reply":"2022-12-02T10:17:54.513275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract File Names \nZipFile(\"/kaggle/input/dogs-vs-cats/train.zip\",\"r\").extractall()  # os.listdir(\"../input/dogs-vs-cats\")[1]\nZipFile(\"/kaggle/input/dogs-vs-cats/test1.zip\", \"r\").extractall()  # os.listdir(\"../input/dogs-vs-cats\")[0]","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:18:11.407198Z","iopub.execute_input":"2022-12-02T10:18:11.407477Z","iopub.status.idle":"2022-12-02T10:18:25.598055Z","shell.execute_reply.started":"2022-12-02T10:18:11.407451Z","shell.execute_reply":"2022-12-02T10:18:25.597014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **ETL Process** ","metadata":{}},{"cell_type":"code","source":"# Loading Data \n\nfilenames_train = os.listdir(\"./train/\")\nfilenames_test = os.listdir(\"./test1/\")\n\n# Training data \ncategories = []\nfor filename in filenames_train:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        categories.append(\"dog\")\n    else:\n        categories.append(\"cat\")\n\ndataset = pd.DataFrame({\n    'filename': filenames_train,\n    'category': categories\n})\n\n# Testing Data \ntest_df = pd.DataFrame({\n    'filename': filenames_test\n})\n\nnb_samples = test_df.shape[0]\n\ndataset.head","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:18:25.602749Z","iopub.execute_input":"2022-12-02T10:18:25.603584Z","iopub.status.idle":"2022-12-02T10:18:25.679056Z","shell.execute_reply.started":"2022-12-02T10:18:25.603548Z","shell.execute_reply":"2022-12-02T10:18:25.678068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Show input sample \nload_img('./train/'+dataset.filename[150])\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:24:24.278355Z","iopub.execute_input":"2022-12-01T00:24:24.278814Z","iopub.status.idle":"2022-12-01T00:24:24.379444Z","shell.execute_reply.started":"2022-12-01T00:24:24.278777Z","shell.execute_reply":"2022-12-01T00:24:24.378511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Split Data \ndataset_train, dataset_validate = train_test_split(dataset, test_size = 0.28, random_state = 150)\ndataset_train = dataset_train.reset_index(drop=True)\ndataset_validate = dataset_validate.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:18:25.683163Z","iopub.execute_input":"2022-12-02T10:18:25.683561Z","iopub.status.idle":"2022-12-02T10:18:25.698917Z","shell.execute_reply.started":"2022-12-02T10:18:25.683529Z","shell.execute_reply":"2022-12-02T10:18:25.697819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Handle Image Generator + Augmenting Data \n\n## Trainning Gen\ntrain_datagen = ImageDataGenerator(rotation_range=40,\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.5,\n    horizontal_flip=True,\n    width_shift_range=0.2,\n    height_shift_range=0.2\n)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    dataset_train, \n    \"./train/\", \n    x_col='filename',\n    y_col='category',\n    target_size=(120,120),\n    class_mode='binary',\n    batch_size=64,\n    color_mode=\"rgb\",\n   shuffle=True\n)\n\n## Validation Gen\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\n\nvalidation_generator = validation_datagen.flow_from_dataframe(\n    dataset_validate, \n    \"./train/\", \n    x_col='filename',\n    y_col='category',\n    target_size=(120,120),\n    class_mode='binary',\n    batch_size=64,\n    color_mode=\"rgb\",\n    #shuffle=True\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:18:25.702941Z","iopub.execute_input":"2022-12-02T10:18:25.705192Z","iopub.status.idle":"2022-12-02T10:18:25.991524Z","shell.execute_reply.started":"2022-12-02T10:18:25.705157Z","shell.execute_reply":"2022-12-02T10:18:25.989865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Model Architecture**","metadata":{}},{"cell_type":"code","source":"# CNN Layer \n\nmodel = tf.keras.models.Sequential([\n    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(120, 120, 3)),\n    tf.keras.layers.Conv2D(32, (3,3), activation='relu',kernel_regularizer=tf.keras.regularizers.l2(0.01)),\n    tf.keras.layers.MaxPooling2D(2,2), \ntf.keras.layers.Conv2D(64, kernel_size=(4, 4), activation='relu' , ),\n        tf.keras.layers.Conv2D(128, (3,3), activation='relu'), \n    tf.keras.layers.MaxPooling2D(2,2),\n\n    \n    tf.keras.layers.Flatten(), \n    tf.keras.layers.Dense(1024, activation='relu'),\n        tf.keras.layers.Dense(2048, activation='relu'),\n    tf.keras.layers.Dropout(0.1),\n            tf.keras.layers.Dense(1024, activation='relu'),\n    tf.keras.layers.Dense(2048, activation='relu'),\n    tf.keras.layers.Dense(512, activation='relu'),\n    tf.keras.layers.Dense(1, activation='sigmoid')  \n])\n\n\n\n# Visualize Model Layers\nfont = ImageFont.truetype('../input/font-sample/alfont_com_SST-Arabic-Medium.ttf', 20)   \nvisualkeras.layered_view(model, legend=True, spacing=15   , font = font ) \n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:24:24.621211Z","iopub.execute_input":"2022-12-01T00:24:24.621837Z","iopub.status.idle":"2022-12-01T00:24:24.840481Z","shell.execute_reply.started":"2022-12-01T00:24:24.621800Z","shell.execute_reply":"2022-12-01T00:24:24.839390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Learning\nmodel.compile(optimizer=RMSprop(learning_rate=0.001),\n              loss='binary_crossentropy',\n              metrics = ['accuracy'])\n\nhistory = model.fit(\n    train_generator,\n    steps_per_epoch=250,\n    epochs=35,\n    validation_data=validation_generator,\n    validation_steps=100\n)\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:24:24.842482Z","iopub.execute_input":"2022-12-01T00:24:24.843185Z","iopub.status.idle":"2022-12-01T00:28:41.307301Z","shell.execute_reply.started":"2022-12-01T00:24:24.843145Z","shell.execute_reply":"2022-12-01T00:28:41.306232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Evaluate Model**","metadata":{}},{"cell_type":"code","source":"# Plot Loss & Accuracy \n\nacc      = history.history[  'accuracy' ]\nval_acc  = history.history[ 'val_accuracy' ]\nloss     = history.history[    'loss' ]\nval_loss = history.history['val_loss' ]\n\nepochs   = range(len(acc))  \n\n# Plot training and validation accuracy\nplt.plot  ( epochs,     acc  , label='Training acc')\nplt.plot  ( epochs, val_acc ,label='Validation acc')\nplt.title ('Training and validation accuracy')\nplt.legend()\n\nplt.figure()\n\n# Plot training and validation loss\n\nplt.plot  ( epochs,     loss ,label='Training loss')\nplt.plot  ( epochs, val_loss ,label='Validation loss')\nplt.title ('Training and validation loss'   )\nplt.legend()\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:28:41.312423Z","iopub.execute_input":"2022-12-01T00:28:41.313328Z","iopub.status.idle":"2022-12-01T00:28:42.123844Z","shell.execute_reply.started":"2022-12-01T00:28:41.313286Z","shell.execute_reply":"2022-12-01T00:28:42.122666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predicting images\nfrom keras.preprocessing import image\n\n\n\nimg = load_img('./train/'+dataset.filename[150],    target_size=(120,120),)\nx = image.img_to_array(img)\nx = np.expand_dims(x, axis=0)\n\nimages = np.vstack([x])\nclasses = model.predict(images,)\n\nprint( classes)","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:28:42.125559Z","iopub.execute_input":"2022-12-01T00:28:42.126074Z","iopub.status.idle":"2022-12-01T00:28:42.271164Z","shell.execute_reply.started":"2022-12-01T00:28:42.126025Z","shell.execute_reply":"2022-12-01T00:28:42.269965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Checking output coding \n\ny_true_labels = train_generator. class_indices\ny_true_labels\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:28:42.272942Z","iopub.execute_input":"2022-12-01T00:28:42.273359Z","iopub.status.idle":"2022-12-01T00:28:42.282999Z","shell.execute_reply.started":"2022-12-01T00:28:42.273316Z","shell.execute_reply":"2022-12-01T00:28:42.281476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Test Gen\n\ntest_datagen = ImageDataGenerator(rescale=1./255)\n \ntest_generator = test_datagen.flow_from_dataframe(\n     test_df,  \"./test1/\", \n     x_col='filename',\n     y_col=None,\n\n    shuffle = False,\n\n    target_size=(120,120),\n    class_mode=None,\n    batch_size=1,\n    color_mode=\"rgb\",\n )\n\npredict_test  = model.predict(test_generator,steps = len(filenames_test))\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:28:42.284761Z","iopub.execute_input":"2022-12-01T00:28:42.285119Z","iopub.status.idle":"2022-12-01T00:29:29.403665Z","shell.execute_reply.started":"2022-12-01T00:28:42.285077Z","shell.execute_reply":"2022-12-01T00:29:29.402641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Handle submission\ndataset_test = pd.read_csv('../input/dogs-vs-cats/sampleSubmission.csv')\ndataset_test.id=filenames_test \ndataset_test.label=[int(round(p[0])) for p in predict_test]\ndataset_test.to_csv(\"submission.csv\", index=False)\ndataset_test","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:29:29.405360Z","iopub.execute_input":"2022-12-01T00:29:29.405778Z","iopub.status.idle":"2022-12-01T00:29:29.457247Z","shell.execute_reply.started":"2022-12-01T00:29:29.405741Z","shell.execute_reply":"2022-12-01T00:29:29.456166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_test['label'].value_counts().plot.bar()\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:29:29.458653Z","iopub.execute_input":"2022-12-01T00:29:29.459097Z","iopub.status.idle":"2022-12-01T00:29:29.632506Z","shell.execute_reply.started":"2022-12-01T00:29:29.459059Z","shell.execute_reply":"2022-12-01T00:29:29.631623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Debugging Model's Output**","metadata":{}},{"cell_type":"code","source":"# handle image sample in model format\n\nfrom keras.preprocessing import image\n\nimg = load_img('./train/'+dataset.filename[350],    target_size=(120,120),)\nimg_tensor = image.img_to_array(img)\nimg_tensor = np.expand_dims(img_tensor, axis=0)\nimg_tensor = np.vstack([img_tensor])\n\n# Show input sample \nimg\n ","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:29:29.633848Z","iopub.execute_input":"2022-12-01T00:29:29.634182Z","iopub.status.idle":"2022-12-01T00:29:29.651028Z","shell.execute_reply.started":"2022-12-01T00:29:29.634148Z","shell.execute_reply":"2022-12-01T00:29:29.649967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get Layers' output\nfrom tensorflow.keras import models\n\nlayer_outputs = [layer.output for layer in model.layers[:3]]\nactivation_model = models.Model(inputs=model.input, outputs=layer_outputs)\nactivations = activation_model.predict(img_tensor)\n\nfirst_layer_activation = activations[1]\nprint(first_layer_activation.shape)","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:29:29.652358Z","iopub.execute_input":"2022-12-01T00:29:29.652808Z","iopub.status.idle":"2022-12-01T00:29:29.745549Z","shell.execute_reply.started":"2022-12-01T00:29:29.652769Z","shell.execute_reply":"2022-12-01T00:29:29.744529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Show Output Feature Maps\n\nfirst_layer_activation= np.delete(first_layer_activation, range(8,18) , 3)\n\nlayers_num=first_layer_activation.shape[3]\nfig, axes = plt.subplots(1,layers_num, figsize = (30,5))\n\nfor i in range(layers_num) : \n    axes[i].set_yticklabels([])\n    axes[i].set_xticklabels([])\n    axes[i].matshow(first_layer_activation[0, :, :, i], cmap='viridis')\n    axes[i].set_title(f'Output L{i}')\n\n    \nfig.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:29:29.746883Z","iopub.execute_input":"2022-12-01T00:29:29.747215Z","iopub.status.idle":"2022-12-01T00:29:31.685927Z","shell.execute_reply.started":"2022-12-01T00:29:29.747181Z","shell.execute_reply":"2022-12-01T00:29:31.681636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Transfer Learning with VGG16 Model**","metadata":{}},{"cell_type":"code","source":"# VGG Base Model\nfrom tensorflow.keras.applications import VGG16\n\nconv_base = VGG16(weights='imagenet',\n                  include_top=False,\n                  input_shape=(120, 120, 3))","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:17:05.328367Z","iopub.execute_input":"2022-12-02T10:17:05.330307Z","iopub.status.idle":"2022-12-02T10:17:15.097901Z","shell.execute_reply.started":"2022-12-02T10:17:05.330226Z","shell.execute_reply":"2022-12-02T10:17:15.096871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build Entire Model\nfrom tensorflow.keras import models\nfrom tensorflow.keras import layers\n\ntransfered_model = models.Sequential()\ntransfered_model.add(conv_base)\ntransfered_model.add(layers.Flatten())\ntransfered_model.add(layers.Dense(256, activation='relu'))\ntransfered_model.add(layers.Dense(1, activation='sigmoid'))\nconv_base.trainable = False\ntransfered_model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:17:17.441005Z","iopub.execute_input":"2022-12-02T10:17:17.441470Z","iopub.status.idle":"2022-12-02T10:17:17.735302Z","shell.execute_reply.started":"2022-12-02T10:17:17.441431Z","shell.execute_reply":"2022-12-02T10:17:17.734236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# learning\n\ntransfered_model.compile(optimizer=RMSprop(learning_rate=0.001),\n              loss='binary_crossentropy',\n              metrics = ['accuracy'])\n\nhistory_transfered_model = transfered_model.fit(\n    train_generator,\n    steps_per_epoch=150,\n    epochs=5,\n    validation_data=validation_generator,\n    validation_steps=100\n)\n","metadata":{"execution":{"iopub.status.busy":"2022-12-02T10:18:25.993083Z","iopub.execute_input":"2022-12-02T10:18:25.993433Z","iopub.status.idle":"2022-12-02T10:18:26.054284Z","shell.execute_reply.started":"2022-12-02T10:18:25.993398Z","shell.execute_reply":"2022-12-02T10:18:26.052830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"load_img('./train/'+dataset.filename[150],    target_size=(120,120),)\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:32:16.278930Z","iopub.execute_input":"2022-12-01T00:32:16.279335Z","iopub.status.idle":"2022-12-01T00:32:16.295978Z","shell.execute_reply.started":"2022-12-01T00:32:16.279299Z","shell.execute_reply":"2022-12-01T00:32:16.294943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predicting images\nfrom keras.preprocessing import image\n\n\nimg = load_img('./train/'+dataset.filename[150],    target_size=(120,120),)\nx = image.img_to_array(img)\nx = np.expand_dims(x, axis=0)\n\nimages = np.vstack([x])\nclasses = model.predict(images,)\n\nprint(classes)","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:32:16.297715Z","iopub.execute_input":"2022-12-01T00:32:16.298082Z","iopub.status.idle":"2022-12-01T00:32:16.350111Z","shell.execute_reply.started":"2022-12-01T00:32:16.298038Z","shell.execute_reply":"2022-12-01T00:32:16.349125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot Loss & Accuracy \n\nacc      = history_transfered_model.history[  'accuracy' ]\nval_acc  = history_transfered_model.history[ 'val_accuracy' ]\nloss     = history_transfered_model.history[    'loss' ]\nval_loss = history_transfered_model.history['val_loss' ]\n\nepochs   = range(len(acc))  \n\n# Plot training and validation accuracy \n \nplt.plot  ( epochs,     acc  , label='Training acc')\nplt.plot  ( epochs, val_acc ,label='Validation acc')\nplt.title ('Training and validation accuracy')\nplt.legend()\nplt.figure()\n\n# Plot training and validation loss \nplt.plot  ( epochs,     loss ,label='Training loss')\nplt.plot  ( epochs, val_loss ,label='Validation loss')\nplt.title ('Training and validation loss'   )\nplt.legend()\n","metadata":{"execution":{"iopub.status.busy":"2022-12-01T00:32:16.351497Z","iopub.execute_input":"2022-12-01T00:32:16.351818Z","iopub.status.idle":"2022-12-01T00:32:16.773053Z","shell.execute_reply.started":"2022-12-01T00:32:16.351785Z","shell.execute_reply":"2022-12-01T00:32:16.772164Z"},"trusted":true},"execution_count":null,"outputs":[]}]}