{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-12-28T13:17:09.278905Z","iopub.execute_input":"2022-12-28T13:17:09.279276Z","iopub.status.idle":"2022-12-28T13:17:11.689052Z","shell.execute_reply.started":"2022-12-28T13:17:09.279247Z","shell.execute_reply":"2022-12-28T13:17:11.688089Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras,os\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, MaxPool2D , Flatten\nfrom keras.preprocessing.image import ImageDataGenerator\nimport numpy as np\nfrom PIL import Image\nimport glob\nimport matplotlib.pyplot as plt\nimport random\nfrom tensorflow.keras.utils import plot_model\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:11.691018Z","iopub.execute_input":"2022-12-28T13:17:11.692765Z","iopub.status.idle":"2022-12-28T13:17:16.988443Z","shell.execute_reply.started":"2022-12-28T13:17:11.692726Z","shell.execute_reply":"2022-12-28T13:17:16.987071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ../input/dogs-vs-cats/","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:16.990685Z","iopub.execute_input":"2022-12-28T13:17:16.991692Z","iopub.status.idle":"2022-12-28T13:17:18.047584Z","shell.execute_reply.started":"2022-12-28T13:17:16.991650Z","shell.execute_reply":"2022-12-28T13:17:18.046444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import zipfile\n\nwith zipfile.ZipFile(\"../input/dogs-vs-cats/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/dogs-vs-cats/test1.zip\",\"r\") as z:\n    z.extractall(\".\")\n!ls /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:18.051036Z","iopub.execute_input":"2022-12-28T13:17:18.051428Z","iopub.status.idle":"2022-12-28T13:17:35.305441Z","shell.execute_reply.started":"2022-12-28T13:17:18.051392Z","shell.execute_reply":"2022-12-28T13:17:35.304320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# let's look at any five files in the train folder\nglob.glob(\"/kaggle/working/train/*.jpg\")[:5]","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:35.307624Z","iopub.execute_input":"2022-12-28T13:17:35.308030Z","iopub.status.idle":"2022-12-28T13:17:35.385829Z","shell.execute_reply.started":"2022-12-28T13:17:35.307987Z","shell.execute_reply":"2022-12-28T13:17:35.384804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_files = glob.glob(\"/kaggle/working/train/*.jpg\")\ntrain_labels = [i.strip('/kaggle/working/train/')[:3] for i in train_files]\ntrain_df = pd.DataFrame({'filename': train_files, 'class': train_labels})\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:35.387392Z","iopub.execute_input":"2022-12-28T13:17:35.387761Z","iopub.status.idle":"2022-12-28T13:17:35.486438Z","shell.execute_reply.started":"2022-12-28T13:17:35.387727Z","shell.execute_reply":"2022-12-28T13:17:35.485008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 2, figsize=(10,10))\naxs = axs.ravel()\nfor i in range(0,4):\n    idx = random.choice(train_df.index)\n    axs[i].imshow(Image.open(train_df['filename'][idx]))\n    axs[i].set_title(train_df['class'][idx])","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:35.488756Z","iopub.execute_input":"2022-12-28T13:17:35.489235Z","iopub.status.idle":"2022-12-28T13:17:36.248349Z","shell.execute_reply.started":"2022-12-28T13:17:35.489198Z","shell.execute_reply":"2022-12-28T13:17:36.247480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n    rotation_range=5,\n    rescale=1./255,\n    horizontal_flip=True,\n    shear_range=0.2,\n    zoom_range=0.2,\n    validation_split=0.2)\n\n# create a image data generator object. \n# all these are data augmentation parameters.\n\n# now let's specify the image size to which each image will be resized to\nimg_height, img_width = 224, 224\nbatch_size = 64","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:36.249721Z","iopub.execute_input":"2022-12-28T13:17:36.250744Z","iopub.status.idle":"2022-12-28T13:17:36.256858Z","shell.execute_reply.started":"2022-12-28T13:17:36.250705Z","shell.execute_reply":"2022-12-28T13:17:36.255608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(\n    train_df,\n    target_size=(img_height, img_width),\n    batch_size=batch_size,\n    class_mode='categorical',\n    subset='training') # set as training data\n\n# remember we put 0.2 validation split while defining ImageDataGenerator?\nvalidation_generator = train_datagen.flow_from_dataframe(\n    train_df, # same directory as training data\n    target_size=(img_height, img_width),\n    batch_size=batch_size,\n    class_mode='categorical',\n    subset='validation') # set as validation data\n\nprint(\"Class Indices:\", train_generator.class_indices)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:36.258263Z","iopub.execute_input":"2022-12-28T13:17:36.258923Z","iopub.status.idle":"2022-12-28T13:17:36.639725Z","shell.execute_reply.started":"2022-12-28T13:17:36.258846Z","shell.execute_reply":"2022-12-28T13:17:36.638697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:36.643713Z","iopub.execute_input":"2022-12-28T13:17:36.643995Z","iopub.status.idle":"2022-12-28T13:17:36.648868Z","shell.execute_reply.started":"2022-12-28T13:17:36.643968Z","shell.execute_reply":"2022-12-28T13:17:36.647788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nmodel = Sequential()\n\nmodel.add(Conv2D(32, (3, 3), activation='relu', \n                 input_shape=(img_width, img_height, 3)))\n# 32 here means this layer will contain 32 filters of size 3x3 being learnt\nmodel.add(BatchNormalization())\n# batchnorm is a useful layer that helps in convergence\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\n# maxpooling will reduce the size of the image\nmodel.add(Dropout(0.25))\n# dropout is used for regularization, ensuring that model doesn't overfit\n\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n\nmodel.add(Conv2D(128, (3, 3), activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# convolutional block is complete. now on to defining the \"head\"\n\n# first flatten the matrix to get a single array\nmodel.add(Flatten())\n# adding a dense hidden layer of neurons\nmodel.add(Dense(512, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.5))\n# finally the output layer with neurons=number of classes and softmax activation\nmodel.add(Dense(2, activation='softmax')) # 2 because we have cat and dog classes","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-12-28T13:17:36.650707Z","iopub.execute_input":"2022-12-28T13:17:36.651127Z","iopub.status.idle":"2022-12-28T13:17:39.766637Z","shell.execute_reply.started":"2022-12-28T13:17:36.651091Z","shell.execute_reply":"2022-12-28T13:17:39.765654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_model(model, show_shapes=True, show_layer_names=False, dpi=60)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:39.767924Z","iopub.execute_input":"2022-12-28T13:17:39.768270Z","iopub.status.idle":"2022-12-28T13:17:41.006831Z","shell.execute_reply.started":"2022-12-28T13:17:39.768235Z","shell.execute_reply":"2022-12-28T13:17:41.005689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# compile the model while defining a loss, optimizer, and metrics to track, \n# and add callbacks if necessary\nmodel.compile(loss='categorical_crossentropy', \n              optimizer='adam', \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:41.008651Z","iopub.execute_input":"2022-12-28T13:17:41.009555Z","iopub.status.idle":"2022-12-28T13:17:41.026998Z","shell.execute_reply.started":"2022-12-28T13:17:41.009496Z","shell.execute_reply":"2022-12-28T13:17:41.025988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs=10\nhistory = model.fit(\n    train_generator, \n    epochs=epochs,\n    validation_data=validation_generator,\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T13:17:41.028577Z","iopub.execute_input":"2022-12-28T13:17:41.028994Z","iopub.status.idle":"2022-12-28T14:13:01.034100Z","shell.execute_reply.started":"2022-12-28T13:17:41.028960Z","shell.execute_reply":"2022-12-28T14:13:01.033063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_loss(history):\n    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6, 6))\n    ax1.plot(history.history['loss'], color='b', label=\"Training loss\")\n    ax1.plot(history.history['val_loss'], color='r', label=\"validation loss\")\n    ax1.set_xticks(np.arange(1, epochs, 1))\n\n    ax2.plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\n    ax2.plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\n    ax2.set_xticks(np.arange(1, epochs, 1))\n\n    legend = plt.legend(loc='best', shadow=True)\n    plt.tight_layout()\n    plt.show()\nplot_loss(history)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:01.035929Z","iopub.execute_input":"2022-12-28T14:13:01.036291Z","iopub.status.idle":"2022-12-28T14:13:01.441878Z","shell.execute_reply.started":"2022-12-28T14:13:01.036255Z","shell.execute_reply":"2022-12-28T14:13:01.440986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Get the Predictions**","metadata":{}},{"cell_type":"code","source":"test_files = glob.glob('/kaggle/working/test1/*.jpg')\ntest_df = pd.DataFrame({'filename': test_files})\ntest_gen = ImageDataGenerator(rescale=1./255)\ntest_generator = test_gen.flow_from_dataframe(\n    test_df, \n    x_col='filename',\n    y_col=None,\n    class_mode=None,\n    target_size=(img_height, img_width),\n    batch_size=batch_size,\n    shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:01.445949Z","iopub.execute_input":"2022-12-28T14:13:01.448070Z","iopub.status.idle":"2022-12-28T14:13:01.639996Z","shell.execute_reply.started":"2022-12-28T14:13:01.448032Z","shell.execute_reply":"2022-12-28T14:13:01.639108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def visualize_predictions(test_generator, model):\n    plt.figure(figsize=(12, 12))\n    for i in range(0, 15):\n        plt.subplot(5, 3, i+1)\n        for X_batch in test_generator:\n            prediction = model.predict(X_batch)[0]\n            image = X_batch[0]\n            plt.imshow(image)\n            plt.title('cat' if np.argmax(prediction)==0 else \"dog\")\n            break\n    plt.tight_layout()\n    plt.show()\nvisualize_predictions(test_generator, model)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:01.643873Z","iopub.execute_input":"2022-12-28T14:13:01.646061Z","iopub.status.idle":"2022-12-28T14:13:08.319226Z","shell.execute_reply.started":"2022-12-28T14:13:01.646025Z","shell.execute_reply":"2022-12-28T14:13:08.318429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Transfer Learning**\n\n* ResNET 50 - pre trainied model.","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras import Input\nfrom tensorflow.keras.models import Model","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:08.320439Z","iopub.execute_input":"2022-12-28T14:13:08.321082Z","iopub.status.idle":"2022-12-28T14:13:08.327714Z","shell.execute_reply.started":"2022-12-28T14:13:08.321045Z","shell.execute_reply":"2022-12-28T14:13:08.326827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nbasemodel = ResNet50(include_top = False, \n                   weights = 'imagenet',\n                  input_shape=(img_height, img_width, 3))\n\n# use the output of the baseModel to create a \"head\"\nheadModel = basemodel.output\nheadModel = MaxPooling2D(pool_size=(5, 5))(headModel)\nheadModel = Flatten(name=\"flatten\")(headModel)\nheadModel = Dense(64, activation=\"relu\")(headModel)\nheadModel = Dropout(0.8)(headModel)\nheadModel = Dense(2, activation=\"softmax\")(headModel)\n# at the end, we'll have two neurons, for two of the classes\n\n# create a model object\nmodel = Model(inputs=basemodel.input, outputs=headModel)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:08.328990Z","iopub.execute_input":"2022-12-28T14:13:08.329877Z","iopub.status.idle":"2022-12-28T14:13:12.911075Z","shell.execute_reply.started":"2022-12-28T14:13:08.329842Z","shell.execute_reply":"2022-12-28T14:13:12.910105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in basemodel.layers[:-4]:\n    layer.trainable = False","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:12.912307Z","iopub.execute_input":"2022-12-28T14:13:12.912687Z","iopub.status.idle":"2022-12-28T14:13:12.923799Z","shell.execute_reply.started":"2022-12-28T14:13:12.912646Z","shell.execute_reply":"2022-12-28T14:13:12.922703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', \n              optimizer='adam', \n              metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:12.925145Z","iopub.execute_input":"2022-12-28T14:13:12.926082Z","iopub.status.idle":"2022-12-28T14:13:12.939650Z","shell.execute_reply.started":"2022-12-28T14:13:12.926020Z","shell.execute_reply":"2022-12-28T14:13:12.938725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs=5\nhistory = model.fit_generator(\n    train_generator,\n    epochs=epochs,\n    validation_data=validation_generator# comment this out if you're not using wandb\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:13:12.942012Z","iopub.execute_input":"2022-12-28T14:13:12.942272Z","iopub.status.idle":"2022-12-28T14:41:24.598014Z","shell.execute_reply.started":"2022-12-28T14:13:12.942249Z","shell.execute_reply":"2022-12-28T14:41:24.597038Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_loss(history)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:41:24.599896Z","iopub.execute_input":"2022-12-28T14:41:24.600251Z","iopub.status.idle":"2022-12-28T14:41:24.902417Z","shell.execute_reply.started":"2022-12-28T14:41:24.600216Z","shell.execute_reply":"2022-12-28T14:41:24.901480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualize_predictions(test_generator, model)","metadata":{"execution":{"iopub.status.busy":"2022-12-28T14:41:24.903640Z","iopub.execute_input":"2022-12-28T14:41:24.903976Z","iopub.status.idle":"2022-12-28T14:41:33.908825Z","shell.execute_reply.started":"2022-12-28T14:41:24.903948Z","shell.execute_reply":"2022-12-28T14:41:33.907971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}